diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/commands/comment.c | 96 | ||||
-rw-r--r-- | src/backend/parser/gram.y | 3 | ||||
-rw-r--r-- | src/bin/pg_dump/pg_dump.c | 18 | ||||
-rw-r--r-- | src/bin/psql/describe.c | 10 |
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" |