PostgreSQL Source Code git master
rewriteSupport.c
Go to the documentation of this file.
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"
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 */
31bool
32IsDefinedRewriteRule(Oid owningRel, const char *ruleName)
33{
34 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 */
52void
53SetRelationRuleStatus(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 relationRelation = table_open(RelationRelationId, RowExclusiveLock);
63 tuple = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(relationId));
64 if (!HeapTupleIsValid(tuple))
65 elog(ERROR, "cache lookup failed for relation %u", relationId);
66 classForm = (Form_pg_class) GETSTRUCT(tuple);
67
68 if (classForm->relhasrules != relHasRules)
69 {
70 /* Do the update */
71 classForm->relhasrules = relHasRules;
72
73 CatalogTupleUpdate(relationRelation, &tuple->t_self, tuple);
74 }
75 else
76 {
77 /* no need to change tuple, but force relcache rebuild anyway */
79 }
80
81 heap_freetuple(tuple);
82 table_close(relationRelation, RowExclusiveLock);
83}
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 */
91Oid
92get_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 tuple = SearchSysCache2(RULERELNAME,
100 ObjectIdGetDatum(relid),
101 PointerGetDatum(rulename));
102 if (!HeapTupleIsValid(tuple))
103 {
104 if (missing_ok)
105 return InvalidOid;
107 (errcode(ERRCODE_UNDEFINED_OBJECT),
108 errmsg("rule \"%s\" for relation \"%s\" does not exist",
109 rulename, get_rel_name(relid))));
110 }
111 ruleform = (Form_pg_rewrite) GETSTRUCT(tuple);
112 Assert(relid == ruleform->ev_class);
113 ruleoid = ruleform->oid;
114 ReleaseSysCache(tuple);
115 return ruleoid;
116}
#define Assert(condition)
Definition: c.h:815
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:225
#define ereport(elevel,...)
Definition: elog.h:149
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1435
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
static void * GETSTRUCT(const HeapTupleData *tuple)
Definition: htup_details.h:728
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:313
void CacheInvalidateRelcacheByTuple(HeapTuple classTuple)
Definition: inval.c:1587
#define RowExclusiveLock
Definition: lockdefs.h:38
char * get_rel_name(Oid relid)
Definition: lsyscache.c:1928
FormData_pg_class * Form_pg_class
Definition: pg_class.h:153
FormData_pg_rewrite * Form_pg_rewrite
Definition: pg_rewrite.h:52
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:327
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:257
#define InvalidOid
Definition: postgres_ext.h:37
unsigned int Oid
Definition: postgres_ext.h:32
void SetRelationRuleStatus(Oid relationId, bool relHasRules)
bool IsDefinedRewriteRule(Oid owningRel, const char *ruleName)
Oid get_rewrite_oid(Oid relid, const char *rulename, bool missing_ok)
ItemPointerData t_self
Definition: htup.h:65
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:269
HeapTuple SearchSysCache2(int cacheId, Datum key1, Datum key2)
Definition: syscache.c:232
#define SearchSysCacheCopy1(cacheId, key1)
Definition: syscache.h:91
#define SearchSysCacheExists2(cacheId, key1, key2)
Definition: syscache.h:102
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:126
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:40