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 13 : IsDefinedRewriteRule(Oid owningRel, const char *ruleName)
33 : {
34 13 : 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 9395 : SetRelationRuleStatus(Oid relationId, bool relHasRules)
54 : {
55 : Relation relationRelation;
56 : HeapTuple tuple;
57 : Form_pg_class classForm;
58 :
59 : /*
60 : * Find the tuple to update in pg_class, using syscache for the lookup.
61 : */
62 9395 : relationRelation = table_open(RelationRelationId, RowExclusiveLock);
63 9395 : tuple = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(relationId));
64 9395 : if (!HeapTupleIsValid(tuple))
65 0 : elog(ERROR, "cache lookup failed for relation %u", relationId);
66 9395 : classForm = (Form_pg_class) GETSTRUCT(tuple);
67 :
68 9395 : if (classForm->relhasrules != relHasRules)
69 : {
70 : /* Do the update */
71 8900 : classForm->relhasrules = relHasRules;
72 :
73 8900 : CatalogTupleUpdate(relationRelation, &tuple->t_self, tuple);
74 : }
75 : else
76 : {
77 : /* no need to change tuple, but force relcache rebuild anyway */
78 495 : CacheInvalidateRelcacheByTuple(tuple);
79 : }
80 :
81 9395 : heap_freetuple(tuple);
82 9395 : table_close(relationRelation, RowExclusiveLock);
83 9395 : }
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 119 : get_rewrite_oid(Oid relid, const char *rulename, bool missing_ok)
93 : {
94 : HeapTuple tuple;
95 : Form_pg_rewrite ruleform;
96 : Oid ruleoid;
97 :
98 : /* Find the rule's pg_rewrite tuple, get its OID */
99 119 : tuple = SearchSysCache2(RULERELNAME,
100 : ObjectIdGetDatum(relid),
101 : PointerGetDatum(rulename));
102 119 : if (!HeapTupleIsValid(tuple))
103 : {
104 9 : if (missing_ok)
105 3 : return InvalidOid;
106 6 : ereport(ERROR,
107 : (errcode(ERRCODE_UNDEFINED_OBJECT),
108 : errmsg("rule \"%s\" for relation \"%s\" does not exist",
109 : rulename, get_rel_name(relid))));
110 : }
111 110 : ruleform = (Form_pg_rewrite) GETSTRUCT(tuple);
112 : Assert(relid == ruleform->ev_class);
113 110 : ruleoid = ruleform->oid;
114 110 : ReleaseSysCache(tuple);
115 110 : return ruleoid;
116 : }
|