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-2024, 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 {
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  */
52 void
53 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  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  */
91 Oid
92 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  tuple = SearchSysCache2(RULERELNAME,
100  ObjectIdGetDatum(relid),
101  PointerGetDatum(rulename));
102  if (!HeapTupleIsValid(tuple))
103  {
104  if (missing_ok)
105  return InvalidOid;
106  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  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:861
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:1434
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define GETSTRUCT(TUP)
Definition: htup_details.h:653
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:313
void CacheInvalidateRelcacheByTuple(HeapTuple classTuple)
Definition: inval.c:1396
#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:322
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:252
#define InvalidOid
Definition: postgres_ext.h:36
unsigned int Oid
Definition: postgres_ext.h:31
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