diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2002-04-18 20:01:11 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2002-04-18 20:01:11 +0000 |
commit | b3120804ad1692322a6d905b352df7fa0d7cdd80 (patch) | |
tree | 93aaf632df82db20e63c952be8a6fd1e4ec15629 /src/backend/commands/comment.c | |
parent | 4e08a625b006ba3992be881b516773adba5863e4 (diff) | |
download | postgresql-b3120804ad1692322a6d905b352df7fa0d7cdd80.tar.gz postgresql-b3120804ad1692322a6d905b352df7fa0d7cdd80.zip |
Rule names are now unique per-relation, rather than unique globally.
DROP RULE and COMMENT ON RULE syntax adds an 'ON tablename' clause,
similar to TRIGGER syntaxes. To allow loading of existing pg_dump
files containing COMMENT ON RULE, the COMMENT code will still accept
the old syntax --- but only if the target rulename is unique across
the whole database.
Diffstat (limited to 'src/backend/commands/comment.c')
-rw-r--r-- | src/backend/commands/comment.c | 101 |
1 files changed, 81 insertions, 20 deletions
diff --git a/src/backend/commands/comment.c b/src/backend/commands/comment.c index 3eb9a5eb67a..07b14ca4fe2 100644 --- a/src/backend/commands/comment.c +++ b/src/backend/commands/comment.c @@ -7,7 +7,7 @@ * Copyright (c) 1999-2001, PostgreSQL Global Development Group * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/comment.c,v 1.41 2002/04/16 23:08:10 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/comment.c,v 1.42 2002/04/18 20:01:09 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -472,44 +472,105 @@ CommentDatabase(List *qualname, char *comment) * CommentRule -- * * This routine is used to add/drop any user-comments a user might - * have regarding a specified RULE. The rule is specified by name - * and, if found, and the user has appropriate permissions, a - * comment will be added/dropped using the CreateComments() routine. + * have regarding a specified RULE. The rule for commenting is determined by + * both its name and the relation to which it refers. The arguments to this + * function are the rule name and relation name (merged into a qualified + * name), and the comment to add/drop. + * + * Before PG 7.3, rules had unique names across the whole database, and so + * the syntax was just COMMENT ON RULE rulename, with no relation name. + * For purposes of backwards compatibility, we support that as long as there + * is only one rule by the specified name in the database. */ static void CommentRule(List *qualname, char *comment) { - char *rule; + int nnames; + List *relname; + char *rulename; + RangeVar *rel; + Relation relation; HeapTuple tuple; Oid reloid; Oid ruleoid; Oid classoid; int32 aclcheck; - /* XXX this is gonna change soon */ - if (length(qualname) != 1) - elog(ERROR, "CommentRule: rule name may not be qualified"); - rule = strVal(lfirst(qualname)); - - /* Find the rule's pg_rewrite tuple, get its OID and its table's OID */ + /* Separate relname and trig name */ + nnames = length(qualname); + if (nnames == 1) + { + /* Old-style: only a rule name is given */ + Relation RewriteRelation; + HeapScanDesc scanDesc; + ScanKeyData scanKeyData; + + rulename = strVal(lfirst(qualname)); + + /* Search pg_rewrite for such a rule */ + ScanKeyEntryInitialize(&scanKeyData, + 0, + Anum_pg_rewrite_rulename, + F_NAMEEQ, + PointerGetDatum(rulename)); + + RewriteRelation = heap_openr(RewriteRelationName, AccessShareLock); + scanDesc = heap_beginscan(RewriteRelation, + 0, SnapshotNow, 1, &scanKeyData); + + tuple = heap_getnext(scanDesc, 0); + if (HeapTupleIsValid(tuple)) + { + reloid = ((Form_pg_rewrite) GETSTRUCT(tuple))->ev_class; + ruleoid = tuple->t_data->t_oid; + } + else + { + elog(ERROR, "rule '%s' does not exist", rulename); + reloid = ruleoid = 0; /* keep compiler quiet */ + } - tuple = SearchSysCache(RULENAME, - PointerGetDatum(rule), - 0, 0, 0); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "rule '%s' does not exist", rule); + if (HeapTupleIsValid(tuple = heap_getnext(scanDesc, 0))) + elog(ERROR, "There are multiple rules '%s'" + "\n\tPlease specify a relation name as well as a rule name", + rulename); - reloid = ((Form_pg_rewrite) GETSTRUCT(tuple))->ev_class; - ruleoid = tuple->t_data->t_oid; + heap_endscan(scanDesc); + heap_close(RewriteRelation, AccessShareLock); - ReleaseSysCache(tuple); + /* Open the owning relation to ensure it won't go away meanwhile */ + relation = heap_open(reloid, AccessShareLock); + } + else + { + /* New-style: rule and relname both provided */ + Assert(nnames >= 2); + relname = ltruncate(nnames-1, listCopy(qualname)); + rulename = strVal(nth(nnames-1, qualname)); + + /* Open the owning relation to ensure it won't go away meanwhile */ + rel = makeRangeVarFromNameList(relname); + relation = heap_openrv(rel, AccessShareLock); + reloid = RelationGetRelid(relation); + + /* Find the rule's pg_rewrite tuple, get its OID */ + tuple = SearchSysCache(RULERELNAME, + ObjectIdGetDatum(reloid), + PointerGetDatum(rulename), + 0, 0); + if (!HeapTupleIsValid(tuple)) + elog(ERROR, "rule '%s' does not exist", rulename); + Assert(reloid == ((Form_pg_rewrite) GETSTRUCT(tuple))->ev_class); + ruleoid = tuple->t_data->t_oid; + ReleaseSysCache(tuple); + } /* Check object security */ aclcheck = pg_class_aclcheck(reloid, GetUserId(), ACL_RULE); if (aclcheck != ACLCHECK_OK) elog(ERROR, "you are not permitted to comment on rule '%s'", - rule); + rulename); /* pg_rewrite doesn't have a hard-coded OID, so must look it up */ |