OSDN Git Service

Add COMMENT ON CONSTRAINT facility (from Rod Taylor's pg_constraint patch).
authorTom Lane <tgl@sss.pgh.pa.us>
Sun, 14 Jul 2002 23:38:13 +0000 (23:38 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Sun, 14 Jul 2002 23:38:13 +0000 (23:38 +0000)
Fix comment.c to not depend on parser token values, per discussion awhile
back.

src/backend/commands/comment.c
src/backend/parser/gram.y
src/include/nodes/parsenodes.h

index b1ce1b2..aede51e 100644 (file)
@@ -7,7 +7,7 @@
  * Copyright (c) 1996-2001, PostgreSQL Global Development Group
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/commands/comment.c,v 1.50 2002/07/12 18:43:15 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/commands/comment.c,v 1.51 2002/07/14 23:38:13 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -19,6 +19,7 @@
 #include "catalog/catname.h"
 #include "catalog/indexing.h"
 #include "catalog/namespace.h"
+#include "catalog/pg_constraint.h"
 #include "catalog/pg_database.h"
 #include "catalog/pg_description.h"
 #include "catalog/pg_namespace.h"
@@ -30,7 +31,6 @@
 #include "parser/parse_func.h"
 #include "parser/parse_oper.h"
 #include "parser/parse_type.h"
-#include "parser/parse.h"
 #include "utils/acl.h"
 #include "utils/builtins.h"
 #include "utils/fmgroids.h"
@@ -57,6 +57,7 @@ static void CommentAggregate(List *aggregate, List *arguments, char *comment);
 static void CommentProc(List *function, List *arguments, char *comment);
 static void CommentOperator(List *opername, List *arguments, char *comment);
 static void CommentTrigger(List *qualname, char *comment);
+static void CommentConstraint(List *qualname, char *comment);
 
 
 /*
@@ -70,39 +71,42 @@ CommentObject(CommentStmt *stmt)
 {
        switch (stmt->objtype)
        {
-               case INDEX:
-               case SEQUENCE:
-               case TABLE:
-               case VIEW:
+               case COMMENT_ON_INDEX:
+               case COMMENT_ON_SEQUENCE:
+               case COMMENT_ON_TABLE:
+               case COMMENT_ON_VIEW:
                        CommentRelation(stmt->objtype, stmt->objname, stmt->comment);
                        break;
-               case COLUMN:
+               case COMMENT_ON_COLUMN:
                        CommentAttribute(stmt->objname, stmt->comment);
                        break;
-               case DATABASE:
+               case COMMENT_ON_DATABASE:
                        CommentDatabase(stmt->objname, stmt->comment);
                        break;
-               case RULE:
+               case COMMENT_ON_RULE:
                        CommentRule(stmt->objname, stmt->comment);
                        break;
-               case TYPE_P:
+               case COMMENT_ON_TYPE:
                        CommentType(stmt->objname, stmt->comment);
                        break;
-               case AGGREGATE:
+               case COMMENT_ON_AGGREGATE:
                        CommentAggregate(stmt->objname, stmt->objargs, stmt->comment);
                        break;
-               case FUNCTION:
+               case COMMENT_ON_FUNCTION:
                        CommentProc(stmt->objname, stmt->objargs, stmt->comment);
                        break;
-               case OPERATOR:
+               case COMMENT_ON_OPERATOR:
                        CommentOperator(stmt->objname, stmt->objargs, stmt->comment);
                        break;
-               case TRIGGER:
+               case COMMENT_ON_TRIGGER:
                        CommentTrigger(stmt->objname, stmt->comment);
                        break;
-               case SCHEMA:
+               case COMMENT_ON_SCHEMA:
                        CommentNamespace(stmt->objname, stmt->comment);
                        break;
+               case COMMENT_ON_CONSTRAINT:
+                       CommentConstraint(stmt->objname, stmt->comment);
+                       break;
                default:
                        elog(ERROR, "An attempt was made to comment on a unknown type: %d",
                                 stmt->objtype);
@@ -309,26 +313,26 @@ CommentRelation(int objtype, List *relname, char *comment)
 
        switch (objtype)
        {
-               case INDEX:
+               case COMMENT_ON_INDEX:
                        if (relation->rd_rel->relkind != RELKIND_INDEX)
                                elog(ERROR, "relation \"%s\" is not an index",
                                         RelationGetRelationName(relation));
                        break;
-               case TABLE:
+               case COMMENT_ON_SEQUENCE:
+                       if (relation->rd_rel->relkind != RELKIND_SEQUENCE)
+                               elog(ERROR, "relation \"%s\" is not a sequence",
+                                        RelationGetRelationName(relation));
+                       break;
+               case COMMENT_ON_TABLE:
                        if (relation->rd_rel->relkind != RELKIND_RELATION)
                                elog(ERROR, "relation \"%s\" is not a table",
                                         RelationGetRelationName(relation));
                        break;
-               case VIEW:
+               case COMMENT_ON_VIEW:
                        if (relation->rd_rel->relkind != RELKIND_VIEW)
                                elog(ERROR, "relation \"%s\" is not a view",
                                         RelationGetRelationName(relation));
                        break;
-               case SEQUENCE:
-                       if (relation->rd_rel->relkind != RELKIND_SEQUENCE)
-                               elog(ERROR, "relation \"%s\" is not a sequence",
-                                        RelationGetRelationName(relation));
-                       break;
        }
 
        /* Create the comment using the relation's oid */
@@ -439,7 +443,7 @@ CommentDatabase(List *qualname, char *comment)
                elog(ERROR, "you are not permitted to comment on database \"%s\"",
                         database);
 
-       /* Create the comments with the pg_database oid */
+       /* Create the comment with the pg_database oid */
 
        CreateComments(oid, RelOid_pg_database, 0, comment);
 
@@ -805,7 +809,7 @@ CommentTrigger(List *qualname, char *comment)
 
        systable_endscan(scan);
 
-       /* Create the comments with the pg_trigger oid */
+       /* Create the comment with the pg_trigger oid */
 
        CreateComments(oid, RelationGetRelid(pg_trigger), 0, comment);
 
@@ -814,3 +818,83 @@ CommentTrigger(List *qualname, char *comment)
        heap_close(pg_trigger, AccessShareLock);
        heap_close(relation, NoLock);
 }
+
+
+/*
+ * CommentConstraint --
+ *
+ * Enable commenting on constraints held within the pg_constraint
+ * table.  A qualified name is required as constraint names are
+ * unique per relation.
+ */
+static void
+CommentConstraint(List *qualname, char *comment)
+{
+       int                     nnames;
+       List       *relName;
+       char       *conName;
+       RangeVar   *rel;
+       Relation        pg_constraint,
+                               relation;
+       HeapTuple       tuple;
+       SysScanDesc     scan;
+       ScanKeyData skey[1];
+       Oid                     conOid = InvalidOid;
+
+       /* Separate relname and constraint name */
+       nnames = length(qualname);
+       if (nnames < 2)
+               elog(ERROR, "CommentConstraint: must specify relation and constraint");
+       relName = ltruncate(nnames-1, listCopy(qualname));
+       conName = 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);
+
+       /* Check object security */
+
+       if (!pg_class_ownercheck(RelationGetRelid(relation), GetUserId()))
+               aclcheck_error(ACLCHECK_NOT_OWNER, RelationGetRelationName(relation));
+
+       /*
+        * Fetch the constraint tuple from pg_constraint.  There may be more than
+        * one match, because constraints are not required to have unique names;
+        * if so, error out.
+        */
+       pg_constraint = heap_openr(ConstraintRelationName, AccessShareLock);
+
+       ScanKeyEntryInitialize(&skey[0], 0x0,
+                                                  Anum_pg_constraint_conrelid, F_OIDEQ,
+                                                  ObjectIdGetDatum(RelationGetRelid(relation)));
+
+       scan = systable_beginscan(pg_constraint, ConstraintRelidIndex, true,
+                                                         SnapshotNow, 1, skey);
+
+       while (HeapTupleIsValid(tuple = systable_getnext(scan)))
+       {
+               Form_pg_constraint      con = (Form_pg_constraint) GETSTRUCT(tuple);
+
+               if (strcmp(NameStr(con->conname), conName) == 0)
+               {
+                       if (OidIsValid(conOid))
+                               elog(ERROR, "Relation \"%s\" has multiple constraints named \"%s\"",
+                                        RelationGetRelationName(relation), conName);
+                       conOid = tuple->t_data->t_oid;
+               }
+       }
+
+       systable_endscan(scan);
+
+       /* If no constraint exists for the relation specified, notify user */
+       if (!OidIsValid(conOid))
+               elog(ERROR, "constraint \"%s\" for relation \"%s\" does not exist",
+                        conName, RelationGetRelationName(relation));
+
+       /* Create the comment with the pg_constraint oid */
+       CreateComments(conOid, RelationGetRelid(pg_constraint), 0, comment);
+
+       /* Done, but hold lock on relation */
+       heap_close(pg_constraint, AccessShareLock);
+       heap_close(relation, NoLock);
+}
index 17128a8..ef83d92 100644 (file)
@@ -11,7 +11,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.339 2002/07/12 18:43:17 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.340 2002/07/14 23:38:13 tgl Exp $
  *
  * HISTORY
  *       AUTHOR                        DATE                    MAJOR EVENT
@@ -2364,7 +2364,7 @@ CommentStmt:
                        IS comment_text
                                {
                                        CommentStmt *n = makeNode(CommentStmt);
-                                       n->objtype = AGGREGATE;
+                                       n->objtype = COMMENT_ON_AGGREGATE;
                                        n->objname = $4;
                                        n->objargs = makeList1($6);
                                        n->comment = $9;
@@ -2373,7 +2373,7 @@ CommentStmt:
                        | COMMENT ON FUNCTION func_name func_args IS comment_text
                                {
                                        CommentStmt *n = makeNode(CommentStmt);
-                                       n->objtype = FUNCTION;
+                                       n->objtype = COMMENT_ON_FUNCTION;
                                        n->objname = $4;
                                        n->objargs = $5;
                                        n->comment = $7;
@@ -2383,16 +2383,16 @@ CommentStmt:
                        IS comment_text
                                {
                                        CommentStmt *n = makeNode(CommentStmt);
-                                       n->objtype = OPERATOR;
+                                       n->objtype = COMMENT_ON_OPERATOR;
                                        n->objname = $4;
                                        n->objargs = $6;
                                        n->comment = $9;
                                        $$ = (Node *) n;
                                }
-                       | COMMENT ON TRIGGER name ON any_name IS comment_text
+                       | COMMENT ON CONSTRAINT name ON any_name IS comment_text
                                {
                                        CommentStmt *n = makeNode(CommentStmt);
-                                       n->objtype = TRIGGER;
+                                       n->objtype = COMMENT_ON_CONSTRAINT;
                                        n->objname = lappend($6, makeString($4));
                                        n->objargs = NIL;
                                        n->comment = $8;
@@ -2401,7 +2401,7 @@ CommentStmt:
                        | COMMENT ON RULE name ON any_name IS comment_text
                                {
                                        CommentStmt *n = makeNode(CommentStmt);
-                                       n->objtype = RULE;
+                                       n->objtype = COMMENT_ON_RULE;
                                        n->objname = lappend($6, makeString($4));
                                        n->objargs = NIL;
                                        n->comment = $8;
@@ -2411,29 +2411,38 @@ CommentStmt:
                                {
                                        /* Obsolete syntax supported for awhile for compatibility */
                                        CommentStmt *n = makeNode(CommentStmt);
-                                       n->objtype = RULE;
+                                       n->objtype = COMMENT_ON_RULE;
                                        n->objname = makeList1(makeString($4));
                                        n->objargs = NIL;
                                        n->comment = $6;
                                        $$ = (Node *) n;
                                }
+                       | COMMENT ON TRIGGER name ON any_name IS comment_text
+                               {
+                                       CommentStmt *n = makeNode(CommentStmt);
+                                       n->objtype = COMMENT_ON_TRIGGER;
+                                       n->objname = lappend($6, makeString($4));
+                                       n->objargs = NIL;
+                                       n->comment = $8;
+                                       $$ = (Node *) n;
+                               }
                ;
 
 comment_type:
-                       COLUMN                                                                  { $$ = COLUMN; }
-                       | DATABASE                                                              { $$ = DATABASE; }
-                       | SCHEMA                                                                { $$ = SCHEMA; }
-                       | INDEX                                                                 { $$ = INDEX; }
-                       | SEQUENCE                                                              { $$ = SEQUENCE; }
-                       | TABLE                                                                 { $$ = TABLE; }
-                       | DOMAIN_P                                                              { $$ = TYPE_P; }
-                       | TYPE_P                                                                { $$ = TYPE_P; }
-                       | VIEW                                                                  { $$ = VIEW; }
+                       COLUMN                                                          { $$ = COMMENT_ON_COLUMN; }
+                       | DATABASE                                                      { $$ = COMMENT_ON_DATABASE; }
+                       | SCHEMA                                                        { $$ = COMMENT_ON_SCHEMA; }
+                       | INDEX                                                         { $$ = COMMENT_ON_INDEX; }
+                       | SEQUENCE                                                      { $$ = COMMENT_ON_SEQUENCE; }
+                       | TABLE                                                         { $$ = COMMENT_ON_TABLE; }
+                       | DOMAIN_P                                                      { $$ = COMMENT_ON_TYPE; }
+                       | TYPE_P                                                        { $$ = COMMENT_ON_TYPE; }
+                       | VIEW                                                          { $$ = COMMENT_ON_VIEW; }
                ;
 
 comment_text:
-                       Sconst                                                                  { $$ = $1; }
-                       | NULL_P                                                                { $$ = NULL; }
+                       Sconst                                                          { $$ = $1; }
+                       | NULL_P                                                        { $$ = NULL; }
                ;
 
 /*****************************************************************************
index 2fec7f6..f054299 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: parsenodes.h,v 1.185 2002/07/12 18:43:19 tgl Exp $
+ * $Id: parsenodes.h,v 1.186 2002/07/14 23:38:13 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1165,10 +1165,25 @@ typedef struct TruncateStmt
  *                             Comment On Statement
  * ----------------------
  */
+#define COMMENT_ON_AGGREGATE   100
+#define COMMENT_ON_COLUMN              101
+#define COMMENT_ON_CONSTRAINT  102
+#define COMMENT_ON_DATABASE            103
+#define COMMENT_ON_FUNCTION            104
+#define COMMENT_ON_INDEX               105
+#define COMMENT_ON_OPERATOR            106
+#define COMMENT_ON_RULE                        107
+#define COMMENT_ON_SCHEMA              108
+#define COMMENT_ON_SEQUENCE            109
+#define COMMENT_ON_TABLE               110
+#define COMMENT_ON_TRIGGER             111
+#define COMMENT_ON_TYPE                        112
+#define COMMENT_ON_VIEW                        113
+
 typedef struct CommentStmt
 {
        NodeTag         type;
-       int                     objtype;                /* Object's type */
+       int                     objtype;                /* Object's type, see codes above */
        List       *objname;            /* Qualified name of the object */
        List       *objargs;            /* Arguments if needed (eg, for functions) */
        char       *comment;            /* Comment to insert, or NULL to remove */