summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/commands/comment.c134
-rw-r--r--src/backend/parser/gram.y47
-rw-r--r--src/include/nodes/parsenodes.h19
3 files changed, 154 insertions, 46 deletions
diff --git a/src/backend/commands/comment.c b/src/backend/commands/comment.c
index b1ce1b2ce65..aede51e0c98 100644
--- a/src/backend/commands/comment.c
+++ b/src/backend/commands/comment.c
@@ -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);
+}
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 17128a814e5..ef83d92a6d3 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -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; }
;
/*****************************************************************************
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index 2fec7f66fbd..f0542990f2e 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -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 */