aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/commands/comment.c96
-rw-r--r--src/backend/parser/gram.y3
-rw-r--r--src/bin/pg_dump/pg_dump.c18
-rw-r--r--src/bin/psql/describe.c10
4 files changed, 83 insertions, 44 deletions
diff --git a/src/backend/commands/comment.c b/src/backend/commands/comment.c
index 0eb59b912f3..1c12061ba55 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.45 2002/04/27 03:45:00 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/comment.c,v 1.46 2002/05/13 17:45:30 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -50,6 +50,7 @@
static void CommentRelation(int objtype, List *relname, char *comment);
static void CommentAttribute(List *qualname, char *comment);
static void CommentDatabase(List *qualname, char *comment);
+static void CommentNamespace(List *qualname, char *comment);
static void CommentRule(List *qualname, char *comment);
static void CommentType(List *typename, char *comment);
static void CommentAggregate(List *aggregate, List *arguments, char *comment);
@@ -99,6 +100,9 @@ CommentObject(CommentStmt *stmt)
case TRIGGER:
CommentTrigger(stmt->objname, stmt->comment);
break;
+ case SCHEMA:
+ CommentNamespace(stmt->objname, stmt->comment);
+ break;
default:
elog(ERROR, "An attempt was made to comment on a unknown type: %d",
stmt->objtype);
@@ -332,22 +336,22 @@ CommentRelation(int objtype, List *relname, char *comment)
{
case INDEX:
if (relation->rd_rel->relkind != RELKIND_INDEX)
- elog(ERROR, "relation '%s' is not an index",
+ elog(ERROR, "relation \"%s\" is not an index",
RelationGetRelationName(relation));
break;
case TABLE:
if (relation->rd_rel->relkind != RELKIND_RELATION)
- elog(ERROR, "relation '%s' is not a table",
+ elog(ERROR, "relation \"%s\" is not a table",
RelationGetRelationName(relation));
break;
case VIEW:
if (relation->rd_rel->relkind != RELKIND_VIEW)
- elog(ERROR, "relation '%s' is not a 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",
+ elog(ERROR, "relation \"%s\" is not a sequence",
RelationGetRelationName(relation));
break;
}
@@ -400,7 +404,7 @@ CommentAttribute(List *qualname, char *comment)
attnum = get_attnum(RelationGetRelid(relation), attrname);
if (attnum == InvalidAttrNumber)
- elog(ERROR, "'%s' is not an attribute of class '%s'",
+ elog(ERROR, "\"%s\" is not an attribute of class \"%s\"",
attrname, RelationGetRelationName(relation));
/* Create the comment using the relation's oid */
@@ -451,13 +455,13 @@ CommentDatabase(List *qualname, char *comment)
/* Validate database exists, and fetch the db oid */
if (!HeapTupleIsValid(dbtuple))
- elog(ERROR, "database '%s' does not exist", database);
+ elog(ERROR, "database \"%s\" does not exist", database);
oid = dbtuple->t_data->t_oid;
/* Allow if the user matches the database dba or is a superuser */
if (!(superuser() || is_dbadmin(oid)))
- elog(ERROR, "you are not permitted to comment on database '%s'",
+ elog(ERROR, "you are not permitted to comment on database \"%s\"",
database);
/* Create the comments with the pg_database oid */
@@ -471,6 +475,51 @@ CommentDatabase(List *qualname, char *comment)
}
/*
+ * CommentNamespace --
+ *
+ * This routine is used to add/drop any user-comments a user might
+ * have regarding the specified namespace. The routine will check
+ * security for owner permissions, and, if succesful, will then
+ * attempt to find the oid of the namespace specified. Once found,
+ * a comment is added/dropped using the CreateComments() routine.
+ */
+static void
+CommentNamespace(List *qualname, char *comment)
+{
+ Oid oid;
+ Oid classoid;
+ HeapTuple tp;
+ char *namespace;
+
+ if (length(qualname) != 1)
+ elog(ERROR, "CommentSchema: schema name may not be qualified");
+ namespace = strVal(lfirst(qualname));
+
+ tp = SearchSysCache(NAMESPACENAME,
+ CStringGetDatum(namespace),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(tp))
+ elog(ERROR, "CommentSchema: Schema \"%s\" could not be found",
+ namespace);
+
+ oid = tp->t_data->t_oid;
+
+ /* Check object security */
+ if (!pg_namespace_ownercheck(oid, GetUserId()))
+ aclcheck_error(ACLCHECK_NOT_OWNER, namespace);
+
+ /* pg_namespace doesn't have a hard-coded OID, so must look it up */
+ classoid = get_relname_relid(NamespaceRelationName, PG_CATALOG_NAMESPACE);
+ Assert(OidIsValid(classoid));
+
+ /* Call CreateComments() to create/drop the comments */
+ CreateComments(oid, classoid, 0, comment);
+
+ /* Cleanup */
+ ReleaseSysCache(tp);
+}
+
+/*
* CommentRule --
*
* This routine is used to add/drop any user-comments a user might
@@ -528,12 +577,12 @@ CommentRule(List *qualname, char *comment)
}
else
{
- elog(ERROR, "rule '%s' does not exist", rulename);
+ elog(ERROR, "rule \"%s\" does not exist", rulename);
reloid = ruleoid = 0; /* keep compiler quiet */
}
if (HeapTupleIsValid(tuple = heap_getnext(scanDesc, 0)))
- elog(ERROR, "There are multiple rules '%s'"
+ elog(ERROR, "There are multiple rules \"%s\""
"\n\tPlease specify a relation name as well as a rule name",
rulename);
@@ -561,7 +610,7 @@ CommentRule(List *qualname, char *comment)
PointerGetDatum(rulename),
0, 0);
if (!HeapTupleIsValid(tuple))
- elog(ERROR, "rule '%s' does not exist", rulename);
+ 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);
@@ -574,7 +623,6 @@ CommentRule(List *qualname, char *comment)
aclcheck_error(aclcheck, rulename);
/* pg_rewrite doesn't have a hard-coded OID, so must look it up */
-
classoid = get_relname_relid(RewriteRelationName, PG_CATALOG_NAMESPACE);
Assert(OidIsValid(classoid));
@@ -689,12 +737,7 @@ CommentProc(List *function, List *arguments, char *comment)
* its name and its argument list which defines the left and right
* hand types the operator will operate on. The argument list is
* expected to be a couple of parse nodes pointed to be a List
- * object. If the comments string is empty, the associated comment
- * is dropped.
- *
- * NOTE: we actually attach the comment to the procedure that underlies
- * the operator. This is a feature, not a bug: we want the same comment
- * to be visible for both operator and function.
+ * object.
*/
static void
CommentOperator(List *opername, List *arguments, char *comment)
@@ -702,27 +745,22 @@ CommentOperator(List *opername, List *arguments, char *comment)
TypeName *typenode1 = (TypeName *) lfirst(arguments);
TypeName *typenode2 = (TypeName *) lsecond(arguments);
Oid oid;
+ Oid classoid;
/* Look up the operator */
-
oid = LookupOperNameTypeNames(opername, typenode1, typenode2,
"CommentOperator");
/* Valid user's ability to comment on this operator */
-
if (!pg_oper_ownercheck(oid, GetUserId()))
aclcheck_error(ACLCHECK_NOT_OWNER, NameListToString(opername));
- /* Get the procedure associated with the operator */
-
- oid = get_opcode(oid);
- if (oid == InvalidOid)
- elog(ERROR, "operator '%s' does not have an underlying function",
- NameListToString(opername));
+ /* pg_operator doesn't have a hard-coded OID, so must look it up */
+ classoid = get_relname_relid(OperatorRelationName, PG_CATALOG_NAMESPACE);
+ Assert(OidIsValid(classoid));
/* Call CreateComments() to create/drop the comments */
-
- CreateComments(oid, RelOid_pg_proc, 0, comment);
+ CreateComments(oid, classoid, 0, comment);
}
/*
@@ -784,7 +822,7 @@ CommentTrigger(List *qualname, char *comment)
/* If no trigger exists for the relation specified, notify user */
if (!HeapTupleIsValid(triggertuple))
- elog(ERROR, "trigger '%s' for relation '%s' does not exist",
+ elog(ERROR, "trigger \"%s\" for relation \"%s\" does not exist",
trigname, RelationGetRelationName(relation));
oid = triggertuple->t_data->t_oid;
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 6b7469f2bd7..bd3a7a0832b 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.314 2002/05/12 20:10:04 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.315 2002/05/13 17:45:30 tgl Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
@@ -2278,6 +2278,7 @@ CommentStmt: COMMENT ON comment_type any_name IS comment_text
comment_type: COLUMN { $$ = COLUMN; }
| DATABASE { $$ = DATABASE; }
+ | SCHEMA { $$ = SCHEMA; }
| INDEX { $$ = INDEX; }
| SEQUENCE { $$ = SEQUENCE; }
| TABLE { $$ = TABLE; }
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index c3f89cb85df..f3b8f8a19b1 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -22,7 +22,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.259 2002/05/10 22:36:26 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.260 2002/05/13 17:45:30 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -2686,7 +2686,6 @@ dumpNamespaces(Archive *fout, NamespaceInfo *nsinfo, int numNamespaces)
nsinfo[i].usename, "SCHEMA", NULL,
q->data, delq->data, NULL, NULL, NULL);
-#ifdef NOTYET /* suppress till COMMENT ON SCHEMA works */
/*** Dump Schema Comments ***/
resetPQExpBuffer(q);
appendPQExpBuffer(q, "SCHEMA %s",
@@ -2694,7 +2693,6 @@ dumpNamespaces(Archive *fout, NamespaceInfo *nsinfo, int numNamespaces)
dumpComment(fout, q->data,
NULL, nsinfo[i].usename,
nsinfo[i].oid, "pg_namespace", 0, NULL);
-#endif
}
destroyPQExpBuffer(q);
@@ -3396,7 +3394,7 @@ dumpOneFunc(Archive *fout, FuncInfo *finfo)
/*** Dump Function Comments ***/
resetPQExpBuffer(q);
- appendPQExpBuffer(q, "FUNCTION %s ", fn->data);
+ appendPQExpBuffer(q, "FUNCTION %s", fn->data);
dumpComment(fout, q->data,
finfo->pronamespace->nspname, finfo->usename,
finfo->oid, "pg_proc", 0, NULL);
@@ -3655,11 +3653,13 @@ dumpOneOpr(Archive *fout, OprInfo *oprinfo,
q->data, delq->data,
NULL, NULL, NULL);
- /*
- * Note: no need to dump operator comment; we expect that the comment
- * is attached to the underlying function instead. (If the function
- * isn't getting dumped ... you lose.)
- */
+ /*** Dump Operator Comments ***/
+
+ resetPQExpBuffer(q);
+ appendPQExpBuffer(q, "OPERATOR %s", oprid->data);
+ dumpComment(fout, q->data,
+ oprinfo->oprnamespace->nspname, oprinfo->usename,
+ oprinfo->oid, "pg_operator", 0, NULL);
PQclear(res);
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index 2f163f63762..297875e0bec 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -3,7 +3,7 @@
*
* Copyright 2000 by PostgreSQL Global Development Group
*
- * $Header: /cvsroot/pgsql/src/bin/psql/describe.c,v 1.53 2002/04/25 02:56:56 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/bin/psql/describe.c,v 1.54 2002/05/13 17:45:30 tgl Exp $
*/
#include "postgres_fe.h"
#include "describe.h"
@@ -210,7 +210,8 @@ describeOperators(const char *name)
" CASE WHEN o.oprkind='l' THEN NULL ELSE format_type(o.oprleft, NULL) END AS \"%s\",\n"
" CASE WHEN o.oprkind='r' THEN NULL ELSE format_type(o.oprright, NULL) END AS \"%s\",\n"
" format_type(o.oprresult, NULL) AS \"%s\",\n"
- " obj_description(o.oprcode, 'pg_proc') AS \"%s\"\n"
+ " coalesce(obj_description(o.oid, 'pg_operator'),"
+ " obj_description(o.oprcode, 'pg_proc')) AS \"%s\"\n"
"FROM pg_operator o\n",
_("Name"), _("Left arg type"), _("Right arg type"),
_("Result type"), _("Description"));
@@ -359,10 +360,9 @@ objectDescription(const char *object)
" FROM pg_proc p\n"
" WHERE (p.pronargs = 0 or oidvectortypes(p.proargtypes) <> '') AND NOT p.proisagg\n"
- /* Operator descriptions (must get comment via associated function) */
+ /* Operator descriptions (only if operator has its own comment) */
"UNION ALL\n"
- " SELECT CAST(o.oprcode AS oid) as oid,\n"
- " (SELECT oid FROM pg_class WHERE relname = 'pg_proc') as tableoid,\n"
+ " SELECT o.oid as oid, o.tableoid as tableoid,\n"
" CAST(o.oprname AS text) as name, CAST('%s' AS text) as object\n"
" FROM pg_operator o\n"