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