From 6eb9c5a5657d1fe77b55cc261450f3538d35a94d Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 4 May 2024 14:19:15 +0200 Subject: Adding upstream version 13.4. Signed-off-by: Daniel Baumann --- src/backend/rewrite/rewriteSupport.c | 117 +++++++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 src/backend/rewrite/rewriteSupport.c (limited to 'src/backend/rewrite/rewriteSupport.c') diff --git a/src/backend/rewrite/rewriteSupport.c b/src/backend/rewrite/rewriteSupport.c new file mode 100644 index 0000000..fc9a3b1 --- /dev/null +++ b/src/backend/rewrite/rewriteSupport.c @@ -0,0 +1,117 @@ +/*------------------------------------------------------------------------- + * + * rewriteSupport.c + * + * + * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * + * IDENTIFICATION + * src/backend/rewrite/rewriteSupport.c + * + *------------------------------------------------------------------------- + */ +#include "postgres.h" + +#include "access/htup_details.h" +#include "access/table.h" +#include "catalog/indexing.h" +#include "catalog/pg_rewrite.h" +#include "rewrite/rewriteSupport.h" +#include "utils/fmgroids.h" +#include "utils/inval.h" +#include "utils/lsyscache.h" +#include "utils/rel.h" +#include "utils/syscache.h" + + +/* + * Is there a rule by the given name? + */ +bool +IsDefinedRewriteRule(Oid owningRel, const char *ruleName) +{ + return SearchSysCacheExists2(RULERELNAME, + ObjectIdGetDatum(owningRel), + PointerGetDatum(ruleName)); +} + + +/* + * SetRelationRuleStatus + * Set the value of the relation's relhasrules field in pg_class. + * + * NOTE: caller must be holding an appropriate lock on the relation. + * + * NOTE: an important side-effect of this operation is that an SI invalidation + * message is sent out to all backends --- including me --- causing relcache + * entries to be flushed or updated with the new set of rules for the table. + * This must happen even if we find that no change is needed in the pg_class + * row. + */ +void +SetRelationRuleStatus(Oid relationId, bool relHasRules) +{ + Relation relationRelation; + HeapTuple tuple; + Form_pg_class classForm; + + /* + * Find the tuple to update in pg_class, using syscache for the lookup. + */ + relationRelation = table_open(RelationRelationId, RowExclusiveLock); + tuple = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(relationId)); + if (!HeapTupleIsValid(tuple)) + elog(ERROR, "cache lookup failed for relation %u", relationId); + classForm = (Form_pg_class) GETSTRUCT(tuple); + + if (classForm->relhasrules != relHasRules) + { + /* Do the update */ + classForm->relhasrules = relHasRules; + + CatalogTupleUpdate(relationRelation, &tuple->t_self, tuple); + } + else + { + /* no need to change tuple, but force relcache rebuild anyway */ + CacheInvalidateRelcacheByTuple(tuple); + } + + heap_freetuple(tuple); + table_close(relationRelation, RowExclusiveLock); +} + +/* + * Find rule oid. + * + * If missing_ok is false, throw an error if rule name not found. If + * true, just return InvalidOid. + */ +Oid +get_rewrite_oid(Oid relid, const char *rulename, bool missing_ok) +{ + HeapTuple tuple; + Form_pg_rewrite ruleform; + Oid ruleoid; + + /* Find the rule's pg_rewrite tuple, get its OID */ + tuple = SearchSysCache2(RULERELNAME, + ObjectIdGetDatum(relid), + PointerGetDatum(rulename)); + if (!HeapTupleIsValid(tuple)) + { + if (missing_ok) + return InvalidOid; + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("rule \"%s\" for relation \"%s\" does not exist", + rulename, get_rel_name(relid)))); + } + ruleform = (Form_pg_rewrite) GETSTRUCT(tuple); + Assert(relid == ruleform->ev_class); + ruleoid = ruleform->oid; + ReleaseSysCache(tuple); + return ruleoid; +} -- cgit v1.2.3