Branch data Line data Source code
1 : : /*-------------------------------------------------------------------------
2 : : *
3 : : * rewriteSupport.c
4 : : *
5 : : *
6 : : * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
7 : : * Portions Copyright (c) 1994, Regents of the University of California
8 : : *
9 : : *
10 : : * IDENTIFICATION
11 : : * src/backend/rewrite/rewriteSupport.c
12 : : *
13 : : *-------------------------------------------------------------------------
14 : : */
15 : : #include "postgres.h"
16 : :
17 : : #include "access/htup_details.h"
18 : : #include "access/table.h"
19 : : #include "catalog/indexing.h"
20 : : #include "catalog/pg_class.h"
21 : : #include "catalog/pg_rewrite.h"
22 : : #include "rewrite/rewriteSupport.h"
23 : : #include "utils/inval.h"
24 : : #include "utils/lsyscache.h"
25 : : #include "utils/syscache.h"
26 : :
27 : :
28 : : /*
29 : : * Is there a rule by the given name?
30 : : */
31 : : bool
32 : 4 : IsDefinedRewriteRule(Oid owningRel, const char *ruleName)
33 : : {
34 : 4 : return SearchSysCacheExists2(RULERELNAME,
35 : : ObjectIdGetDatum(owningRel),
36 : : PointerGetDatum(ruleName));
37 : : }
38 : :
39 : :
40 : : /*
41 : : * SetRelationRuleStatus
42 : : * Set the value of the relation's relhasrules field in pg_class.
43 : : *
44 : : * NOTE: caller must be holding an appropriate lock on the relation.
45 : : *
46 : : * NOTE: an important side-effect of this operation is that an SI invalidation
47 : : * message is sent out to all backends --- including me --- causing relcache
48 : : * entries to be flushed or updated with the new set of rules for the table.
49 : : * This must happen even if we find that no change is needed in the pg_class
50 : : * row.
51 : : */
52 : : void
53 : 755 : SetRelationRuleStatus(Oid relationId, bool relHasRules)
54 : : {
55 : 755 : Relation relationRelation;
56 : 755 : HeapTuple tuple;
57 : 755 : Form_pg_class classForm;
58 : :
59 : : /*
60 : : * Find the tuple to update in pg_class, using syscache for the lookup.
61 : : */
62 : 755 : relationRelation = table_open(RelationRelationId, RowExclusiveLock);
63 : 755 : tuple = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(relationId));
64 [ + - ]: 755 : if (!HeapTupleIsValid(tuple))
65 [ # # # # ]: 0 : elog(ERROR, "cache lookup failed for relation %u", relationId);
66 : 755 : classForm = (Form_pg_class) GETSTRUCT(tuple);
67 : :
68 [ + + ]: 755 : if (classForm->relhasrules != relHasRules)
69 : : {
70 : : /* Do the update */
71 : 632 : classForm->relhasrules = relHasRules;
72 : :
73 : 632 : CatalogTupleUpdate(relationRelation, &tuple->t_self, tuple);
74 : 632 : }
75 : : else
76 : : {
77 : : /* no need to change tuple, but force relcache rebuild anyway */
78 : 123 : CacheInvalidateRelcacheByTuple(tuple);
79 : : }
80 : :
81 : 755 : heap_freetuple(tuple);
82 : 755 : table_close(relationRelation, RowExclusiveLock);
83 : 755 : }
84 : :
85 : : /*
86 : : * Find rule oid.
87 : : *
88 : : * If missing_ok is false, throw an error if rule name not found. If
89 : : * true, just return InvalidOid.
90 : : */
91 : : Oid
92 : 37 : get_rewrite_oid(Oid relid, const char *rulename, bool missing_ok)
93 : : {
94 : 37 : HeapTuple tuple;
95 : 37 : Form_pg_rewrite ruleform;
96 : 37 : Oid ruleoid;
97 : :
98 : : /* Find the rule's pg_rewrite tuple, get its OID */
99 : 37 : tuple = SearchSysCache2(RULERELNAME,
100 : 37 : ObjectIdGetDatum(relid),
101 : 37 : PointerGetDatum(rulename));
102 [ + + ]: 37 : if (!HeapTupleIsValid(tuple))
103 : : {
104 [ + + ]: 3 : if (missing_ok)
105 : 1 : return InvalidOid;
106 [ + - + - ]: 2 : ereport(ERROR,
107 : : (errcode(ERRCODE_UNDEFINED_OBJECT),
108 : : errmsg("rule \"%s\" for relation \"%s\" does not exist",
109 : : rulename, get_rel_name(relid))));
110 : 0 : }
111 : 34 : ruleform = (Form_pg_rewrite) GETSTRUCT(tuple);
112 [ + - ]: 34 : Assert(relid == ruleform->ev_class);
113 : 34 : ruleoid = ruleform->oid;
114 : 34 : ReleaseSysCache(tuple);
115 : 34 : return ruleoid;
116 : 35 : }
|