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