Coverage Report

Created: 2025-06-15 06:31

/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
}