Line data Source code
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 26 : IsDefinedRewriteRule(Oid owningRel, const char *ruleName) 33 : { 34 26 : 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 16512 : 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 16512 : relationRelation = table_open(RelationRelationId, RowExclusiveLock); 63 16512 : tuple = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(relationId)); 64 16512 : if (!HeapTupleIsValid(tuple)) 65 0 : elog(ERROR, "cache lookup failed for relation %u", relationId); 66 16512 : classForm = (Form_pg_class) GETSTRUCT(tuple); 67 : 68 16512 : if (classForm->relhasrules != relHasRules) 69 : { 70 : /* Do the update */ 71 15558 : classForm->relhasrules = relHasRules; 72 : 73 15558 : CatalogTupleUpdate(relationRelation, &tuple->t_self, tuple); 74 : } 75 : else 76 : { 77 : /* no need to change tuple, but force relcache rebuild anyway */ 78 954 : CacheInvalidateRelcacheByTuple(tuple); 79 : } 80 : 81 16512 : heap_freetuple(tuple); 82 16512 : table_close(relationRelation, RowExclusiveLock); 83 16512 : } 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 214 : 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 214 : tuple = SearchSysCache2(RULERELNAME, 100 : ObjectIdGetDatum(relid), 101 : PointerGetDatum(rulename)); 102 214 : if (!HeapTupleIsValid(tuple)) 103 : { 104 18 : if (missing_ok) 105 6 : return InvalidOid; 106 12 : 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 196 : ruleform = (Form_pg_rewrite) GETSTRUCT(tuple); 112 : Assert(relid == ruleform->ev_class); 113 196 : ruleoid = ruleform->oid; 114 196 : ReleaseSysCache(tuple); 115 196 : return ruleoid; 116 : }