diff options
Diffstat (limited to 'src/backend/commands')
-rw-r--r-- | src/backend/commands/comment.c | 314 | ||||
-rw-r--r-- | src/backend/commands/define.c | 71 | ||||
-rw-r--r-- | src/backend/commands/indexcmds.c | 11 | ||||
-rw-r--r-- | src/backend/commands/proclang.c | 29 | ||||
-rw-r--r-- | src/backend/commands/remove.c | 67 | ||||
-rw-r--r-- | src/backend/commands/trigger.c | 20 |
6 files changed, 235 insertions, 277 deletions
diff --git a/src/backend/commands/comment.c b/src/backend/commands/comment.c index f8e5bc6fc6f..b7d57f6cce5 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.38 2002/03/29 19:06:04 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/comment.c,v 1.39 2002/04/09 20:35:47 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -18,6 +18,7 @@ #include "access/heapam.h" #include "catalog/catname.h" #include "catalog/indexing.h" +#include "catalog/namespace.h" #include "catalog/pg_database.h" #include "catalog/pg_description.h" #include "catalog/pg_namespace.h" @@ -40,87 +41,74 @@ #include "utils/syscache.h" -/*------------------------------------------------------------------ +/* * Static Function Prototypes -- * * The following protoypes are declared static so as not to conflict * with any other routines outside this module. These routines are * called by the public function CommentObject() routine to create * the appropriate comment for the specific object type. - *------------------------------------------------------------------ */ -static void CommentRelation(int objtype, char * schemaname, char *relation, - char *comment); -static void CommentAttribute(char * schemaname, char *relation, - char *attrib, char *comment); -static void CommentDatabase(char *database, char *comment); -static void CommentRewrite(char *rule, char *comment); -static void CommentType(char *type, char *comment); -static void CommentAggregate(char *aggregate, List *arguments, char *comment); -static void CommentProc(char *function, List *arguments, char *comment); -static void CommentOperator(char *opname, List *arguments, char *comment); -static void CommentTrigger(char *trigger, char *schemaname, char *relation, - char *comments); - - -/*------------------------------------------------------------------ +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 CommentRule(List *qualname, char *comment); +static void CommentType(List *typename, char *comment); +static void CommentAggregate(List *aggregate, List *arguments, char *comment); +static void CommentProc(List *function, List *arguments, char *comment); +static void CommentOperator(List *qualname, List *arguments, char *comment); +static void CommentTrigger(List *qualname, char *comment); + + +/* * CommentObject -- * * This routine is used to add the associated comment into - * pg_description for the object specified by the paramters handed - * to this routine. If the routine cannot determine an Oid to - * associated with the parameters handed to this routine, an - * error is thrown. Otherwise the comment is added to pg_description - * by calling the CreateComments() routine. If the comment string is - * empty, CreateComments() will drop any comments associated with - * the object. - *------------------------------------------------------------------ -*/ - + * pg_description for the object specified by the given SQL command. + */ void -CommentObject(int objtype, char *schemaname, char *objname, char *objproperty, - List *objlist, char *comment) +CommentObject(CommentStmt *stmt) { - switch (objtype) + switch (stmt->objtype) { case INDEX: case SEQUENCE: case TABLE: case VIEW: - CommentRelation(objtype, schemaname, objname, comment); + CommentRelation(stmt->objtype, stmt->objname, stmt->comment); break; case COLUMN: - CommentAttribute(schemaname, objname, objproperty, comment); + CommentAttribute(stmt->objname, stmt->comment); break; case DATABASE: - CommentDatabase(objname, comment); + CommentDatabase(stmt->objname, stmt->comment); break; case RULE: - CommentRewrite(objname, comment); + CommentRule(stmt->objname, stmt->comment); break; case TYPE_P: - CommentType(objname, comment); + CommentType(stmt->objname, stmt->comment); break; case AGGREGATE: - CommentAggregate(objname, objlist, comment); + CommentAggregate(stmt->objname, stmt->objargs, stmt->comment); break; case FUNCTION: - CommentProc(objname, objlist, comment); + CommentProc(stmt->objname, stmt->objargs, stmt->comment); break; case OPERATOR: - CommentOperator(objname, objlist, comment); + CommentOperator(stmt->objname, stmt->objargs, stmt->comment); break; case TRIGGER: - CommentTrigger(objname, schemaname, objproperty, comment); + CommentTrigger(stmt->objname, stmt->comment); break; default: elog(ERROR, "An attempt was made to comment on a unknown type: %d", - objtype); + stmt->objtype); } } -/*------------------------------------------------------------------ +/* * CreateComments -- * * Create a comment for the specified object descriptor. Inserts a new @@ -128,9 +116,7 @@ CommentObject(int objtype, char *schemaname, char *objname, char *objproperty, * * If the comment given is null or an empty string, instead delete any * existing comment for the specified key. - *------------------------------------------------------------------ */ - void CreateComments(Oid oid, Oid classoid, int32 subid, char *comment) { @@ -254,15 +240,13 @@ CreateComments(Oid oid, Oid classoid, int32 subid, char *comment) heap_close(description, NoLock); } -/*------------------------------------------------------------------ +/* * DeleteComments -- * * This routine is used to purge all comments associated with an object, * regardless of their objsubid. It is called, for example, when a relation * is destroyed. - *------------------------------------------------------------------ */ - void DeleteComments(Oid oid, Oid classoid) { @@ -316,7 +300,7 @@ DeleteComments(Oid oid, Oid classoid) heap_close(description, NoLock); } -/*------------------------------------------------------------------ +/* * CommentRelation -- * * This routine is used to add/drop a comment from a relation, where @@ -324,20 +308,14 @@ DeleteComments(Oid oid, Oid classoid) * finds the relation name by searching the system cache, locating * the appropriate tuple, and inserting a comment using that * tuple's oid. Its parameters are the relation name and comments. - *------------------------------------------------------------------ */ - static void -CommentRelation(int reltype, char *schemaname, char *relname, char *comment) +CommentRelation(int objtype, List *relname, char *comment) { Relation relation; - RangeVar *tgtrel = makeNode(RangeVar); - - - tgtrel->relname = relname; - tgtrel->schemaname = schemaname; - /* FIXME SCHEMA: Can we add comments to temp relations? */ - tgtrel->istemp = false; + RangeVar *tgtrel; + + tgtrel = makeRangeVarFromNameList(relname); /* * Open the relation. We do this mainly to acquire a lock that @@ -349,27 +327,32 @@ CommentRelation(int reltype, char *schemaname, char *relname, char *comment) /* Check object security */ if (!pg_class_ownercheck(RelationGetRelid(relation), GetUserId())) - elog(ERROR, "you are not permitted to comment on class '%s'", relname); + elog(ERROR, "you are not permitted to comment on class '%s'", + RelationGetRelationName(relation)); /* Next, verify that the relation type matches the intent */ - switch (reltype) + switch (objtype) { case INDEX: if (relation->rd_rel->relkind != RELKIND_INDEX) - elog(ERROR, "relation '%s' is not an index", relname); + 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", relname); + 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", relname); + 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", relname); + elog(ERROR, "relation '%s' is not a sequence", + RelationGetRelationName(relation)); break; } @@ -381,7 +364,7 @@ CommentRelation(int reltype, char *schemaname, char *relname, char *comment) relation_close(relation, NoLock); } -/*------------------------------------------------------------------ +/* * CommentAttribute -- * * This routine is used to add/drop a comment from an attribute @@ -390,34 +373,40 @@ CommentRelation(int reltype, char *schemaname, char *relname, char *comment) * attribute. If successful, a comment is added/dropped, else an * elog() exception is thrown. The parameters are the relation * and attribute names, and the comments - *------------------------------------------------------------------ -*/ - + */ static void -CommentAttribute(char *schemaname, char *relname, char *attrname, char *comment) +CommentAttribute(List *qualname, char *comment) { - RangeVar *rel = makeNode(RangeVar); + int nnames; + List *relname; + char *attrname; + RangeVar *rel; Relation relation; AttrNumber attnum; - /* Open the containing relation to ensure it won't go away meanwhile */ + /* Separate relname and attr name */ + nnames = length(qualname); + if (nnames < 2) + elog(ERROR, "CommentAttribute: must specify relation.attribute"); + relname = ltruncate(nnames-1, listCopy(qualname)); + attrname = strVal(nth(nnames-1, qualname)); - rel->relname = relname; - rel->schemaname = schemaname; - rel->istemp = false; + /* Open the containing 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())) - elog(ERROR, "you are not permitted to comment on class '%s'", relname); + elog(ERROR, "you are not permitted to comment on class '%s'", + RelationGetRelationName(relation)); /* Now, fetch the attribute number from the system cache */ attnum = get_attnum(RelationGetRelid(relation), attrname); if (attnum == InvalidAttrNumber) elog(ERROR, "'%s' is not an attribute of class '%s'", - attrname, relname); + attrname, RelationGetRelationName(relation)); /* Create the comment using the relation's oid */ @@ -429,7 +418,7 @@ CommentAttribute(char *schemaname, char *relname, char *attrname, char *comment) heap_close(relation, NoLock); } -/*------------------------------------------------------------------ +/* * CommentDatabase -- * * This routine is used to add/drop any user-comments a user might @@ -437,23 +426,26 @@ CommentAttribute(char *schemaname, char *relname, char *attrname, char *comment) * security for owner permissions, and, if succesful, will then * attempt to find the oid of the database specified. Once found, * a comment is added/dropped using the CreateComments() routine. - *------------------------------------------------------------------ -*/ - + */ static void -CommentDatabase(char *database, char *comment) +CommentDatabase(List *qualname, char *comment) { + char *database; Relation pg_database; ScanKeyData entry; HeapScanDesc scan; HeapTuple dbtuple; Oid oid; + if (length(qualname) != 1) + elog(ERROR, "CommentDatabase: database name may not be qualified"); + database = strVal(lfirst(qualname)); + /* First find the tuple in pg_database for the database */ pg_database = heap_openr(DatabaseRelationName, AccessShareLock); ScanKeyEntryInitialize(&entry, 0, Anum_pg_database_datname, - F_NAMEEQ, NameGetDatum(database)); + F_NAMEEQ, CStringGetDatum(database)); scan = heap_beginscan(pg_database, 0, SnapshotNow, 1, &entry); dbtuple = heap_getnext(scan, 0); @@ -479,25 +471,29 @@ CommentDatabase(char *database, char *comment) heap_close(pg_database, AccessShareLock); } -/*------------------------------------------------------------------ - * CommentRewrite -- +/* + * 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. - *------------------------------------------------------------------ -*/ - + */ static void -CommentRewrite(char *rule, char *comment) +CommentRule(List *qualname, char *comment) { + char *rule; 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 */ tuple = SearchSysCache(RULENAME, @@ -528,7 +524,7 @@ CommentRewrite(char *rule, char *comment) CreateComments(ruleoid, classoid, 0, comment); } -/*------------------------------------------------------------------ +/* * CommentType -- * * This routine is used to add/drop any user-comments a user might @@ -536,42 +532,43 @@ CommentRewrite(char *rule, char *comment) * and, if found, and the user has appropriate permissions, a * comment will be added/dropped using the CreateComments() routine. * The type's name and the comments are the paramters to this routine. - *------------------------------------------------------------------ -*/ - + */ static void -CommentType(char *type, char *comment) +CommentType(List *typename, char *comment) { + TypeName *tname; Oid oid; + /* XXX a bit of a crock; should accept TypeName in COMMENT syntax */ + tname = makeNode(TypeName); + tname->names = typename; + tname->typmod = -1; + /* Find the type's oid */ - /* XXX WRONG: need to deal with qualified type names */ - oid = typenameTypeId(makeTypeName(type)); + oid = typenameTypeId(tname); /* Check object security */ if (!pg_type_ownercheck(oid, GetUserId())) - elog(ERROR, "you are not permitted to comment on type '%s'", - type); + elog(ERROR, "you are not permitted to comment on type %s", + TypeNameToString(tname)); /* Call CreateComments() to create/drop the comments */ CreateComments(oid, RelOid_pg_type, 0, comment); } -/*------------------------------------------------------------------ +/* * CommentAggregate -- * * This routine is used to allow a user to provide comments on an * aggregate function. The aggregate function is determined by both * its name and its argument type, which, with the comments are * the three parameters handed to this routine. - *------------------------------------------------------------------ -*/ - + */ static void -CommentAggregate(char *aggregate, List *arguments, char *comment) +CommentAggregate(List *aggregate, List *arguments, char *comment) { TypeName *aggtype = (TypeName *) lfirst(arguments); Oid baseoid, @@ -587,7 +584,7 @@ CommentAggregate(char *aggregate, List *arguments, char *comment) /* Now, attempt to find the actual tuple in pg_aggregate */ oid = GetSysCacheOid(AGGNAME, - PointerGetDatum(aggregate), + PointerGetDatum(strVal(lfirst(aggregate))), /* XXX */ ObjectIdGetDatum(baseoid), 0, 0); if (!OidIsValid(oid)) @@ -598,11 +595,11 @@ CommentAggregate(char *aggregate, List *arguments, char *comment) if (!pg_aggr_ownercheck(oid, GetUserId())) { if (baseoid == InvalidOid) - elog(ERROR, "you are not permitted to comment on aggregate '%s' for all types", - aggregate); + elog(ERROR, "you are not permitted to comment on aggregate %s for all types", + NameListToString(aggregate)); else - elog(ERROR, "you are not permitted to comment on aggregate '%s' for type %s", - aggregate, format_type_be(baseoid)); + elog(ERROR, "you are not permitted to comment on aggregate %s for type %s", + NameListToString(aggregate), format_type_be(baseoid)); } /* pg_aggregate doesn't have a hard-coded OID, so must look it up */ @@ -615,7 +612,7 @@ CommentAggregate(char *aggregate, List *arguments, char *comment) CreateComments(oid, classoid, 0, comment); } -/*------------------------------------------------------------------ +/* * CommentProc -- * * This routine is used to allow a user to provide comments on an @@ -623,64 +620,29 @@ CommentAggregate(char *aggregate, List *arguments, char *comment) * its name and its argument list. The argument list is expected to * be a series of parsed nodes pointed to by a List object. If the * comments string is empty, the associated comment is dropped. - *------------------------------------------------------------------ -*/ - + */ static void -CommentProc(char *function, List *arguments, char *comment) +CommentProc(List *function, List *arguments, char *comment) { - Oid oid, - argoids[FUNC_MAX_ARGS]; - int i, - argcount; - - /* First, initialize function's argument list with their type oids */ - - MemSet(argoids, 0, FUNC_MAX_ARGS * sizeof(Oid)); - argcount = length(arguments); - if (argcount > FUNC_MAX_ARGS) - elog(ERROR, "functions cannot have more than %d arguments", - FUNC_MAX_ARGS); - for (i = 0; i < argcount; i++) - { - TypeName *t = (TypeName *) lfirst(arguments); - - argoids[i] = LookupTypeName(t); - if (!OidIsValid(argoids[i])) - { - char *typnam = TypeNameToString(t); - - if (strcmp(typnam, "opaque") == 0) - argoids[i] = InvalidOid; - else - elog(ERROR, "Type \"%s\" does not exist", typnam); - } + Oid oid; - arguments = lnext(arguments); - } + /* Look up the procedure */ - /* Now, find the corresponding oid for this procedure */ - - oid = GetSysCacheOid(PROCNAME, - PointerGetDatum(function), - Int32GetDatum(argcount), - PointerGetDatum(argoids), - 0); - if (!OidIsValid(oid)) - func_error("CommentProc", function, argcount, argoids, NULL); + oid = LookupFuncNameTypeNames(function, arguments, + true, "CommentProc"); /* Now, validate the user's ability to comment on this function */ if (!pg_proc_ownercheck(oid, GetUserId())) - elog(ERROR, "you are not permitted to comment on function '%s'", - function); + elog(ERROR, "you are not permitted to comment on function %s", + NameListToString(function)); /* Call CreateComments() to create/drop the comments */ CreateComments(oid, RelOid_pg_proc, 0, comment); } -/*------------------------------------------------------------------ +/* * CommentOperator -- * * This routine is used to allow a user to provide comments on an @@ -694,12 +656,11 @@ CommentProc(char *function, List *arguments, char *comment) * 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. - *------------------------------------------------------------------ -*/ - + */ static void -CommentOperator(char *opername, List *arguments, char *comment) +CommentOperator(List *qualname, List *arguments, char *comment) { + char *opername = strVal(lfirst(qualname)); /* XXX */ TypeName *typenode1 = (TypeName *) lfirst(arguments); TypeName *typenode2 = (TypeName *) lsecond(arguments); char oprtype = 0; @@ -760,21 +721,22 @@ CommentOperator(char *opername, List *arguments, char *comment) CreateComments(oid, RelOid_pg_proc, 0, comment); } -/*------------------------------------------------------------------ +/* * CommentTrigger -- * * This routine is used to allow a user to provide comments on a * trigger event. The trigger for commenting is determined by both * its name and the relation to which it refers. The arguments to this - * function are the trigger name, the relation name, and the comments - * to add/drop. - *------------------------------------------------------------------ -*/ - + * function are the trigger name and relation name (merged into a qualified + * name), and the comment to add/drop. + */ static void -CommentTrigger(char *trigger, char *schemaname, char *relname, char *comment) +CommentTrigger(List *qualname, char *comment) { - RangeVar *rel = makeNode(RangeVar); + int nnames; + List *relname; + char *trigname; + RangeVar *rel; Relation pg_trigger, relation; HeapTuple triggertuple; @@ -782,16 +744,22 @@ CommentTrigger(char *trigger, char *schemaname, char *relname, char *comment) ScanKeyData entry[2]; Oid oid; - /* First, validate the user's action */ + /* Separate relname and trig name */ + nnames = length(qualname); + if (nnames < 2) + elog(ERROR, "CommentTrigger: must specify relation and trigger"); + relname = ltruncate(nnames-1, listCopy(qualname)); + trigname = strVal(nth(nnames-1, qualname)); - rel->relname = relname; - rel->schemaname = schemaname; - rel->istemp = false; + /* 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())) - elog(ERROR, "you are not permitted to comment on trigger '%s' %s '%s'", - trigger, "defined for relation", relname); + elog(ERROR, "you are not permitted to comment on trigger '%s' for relation '%s'", + trigname, RelationGetRelationName(relation)); /* Fetch the trigger oid from pg_trigger */ @@ -801,15 +769,15 @@ CommentTrigger(char *trigger, char *schemaname, char *relname, char *comment) ObjectIdGetDatum(RelationGetRelid(relation))); ScanKeyEntryInitialize(&entry[1], 0x0, Anum_pg_trigger_tgname, F_NAMEEQ, - NameGetDatum(trigger)); + CStringGetDatum(trigname)); scan = heap_beginscan(pg_trigger, 0, SnapshotNow, 2, entry); triggertuple = heap_getnext(scan, 0); /* If no trigger exists for the relation specified, notify user */ if (!HeapTupleIsValid(triggertuple)) - elog(ERROR, "trigger '%s' defined for relation '%s' does not exist", - trigger, relname); + elog(ERROR, "trigger '%s' for relation '%s' does not exist", + trigname, RelationGetRelationName(relation)); oid = triggertuple->t_data->t_oid; diff --git a/src/backend/commands/define.c b/src/backend/commands/define.c index eaff4e66dfa..cccbcdfaa59 100644 --- a/src/backend/commands/define.c +++ b/src/backend/commands/define.c @@ -10,7 +10,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/define.c,v 1.73 2002/04/05 00:31:25 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/define.c,v 1.74 2002/04/09 20:35:47 tgl Exp $ * * DESCRIPTION * The "DefineFoo" routines take the parse tree and pick out the @@ -60,9 +60,10 @@ #include "utils/syscache.h" -static Oid findTypeIOFunction(const char *procname, bool isOutput); +static Oid findTypeIOFunction(List *procname, bool isOutput); static char *defGetString(DefElem *def); static double defGetNumeric(DefElem *def); +static List *defGetQualifiedName(DefElem *def); static TypeName *defGetTypeName(DefElem *def); static int defGetTypeLength(DefElem *def); @@ -474,8 +475,8 @@ DefineAggregate(List *names, List *parameters) { char *aggName; Oid aggNamespace; - char *transfuncName = NULL; - char *finalfuncName = NULL; + List *transfuncName = NIL; + List *finalfuncName = NIL; TypeName *baseType = NULL; TypeName *transType = NULL; char *initval = NULL; @@ -495,11 +496,11 @@ DefineAggregate(List *names, List *parameters) * spellings for sfunc, stype, initcond. */ if (strcasecmp(defel->defname, "sfunc") == 0) - transfuncName = defGetString(defel); + transfuncName = defGetQualifiedName(defel); else if (strcasecmp(defel->defname, "sfunc1") == 0) - transfuncName = defGetString(defel); + transfuncName = defGetQualifiedName(defel); else if (strcasecmp(defel->defname, "finalfunc") == 0) - finalfuncName = defGetString(defel); + finalfuncName = defGetQualifiedName(defel); else if (strcasecmp(defel->defname, "basetype") == 0) baseType = defGetTypeName(defel); else if (strcasecmp(defel->defname, "stype") == 0) @@ -522,7 +523,7 @@ DefineAggregate(List *names, List *parameters) elog(ERROR, "Define: \"basetype\" unspecified"); if (transType == NULL) elog(ERROR, "Define: \"stype\" unspecified"); - if (transfuncName == NULL) + if (transfuncName == NIL) elog(ERROR, "Define: \"sfunc\" unspecified"); /* @@ -800,10 +801,10 @@ DefineType(List *names, List *parameters) int16 internalLength = -1; /* int2 */ int16 externalLength = -1; /* int2 */ Oid elemType = InvalidOid; - char *inputName = NULL; - char *outputName = NULL; - char *sendName = NULL; - char *receiveName = NULL; + List *inputName = NIL; + List *outputName = NIL; + List *sendName = NIL; + List *receiveName = NIL; char *defaultValue = NULL; bool byValue = false; char delimiter = DEFAULT_TYPDELIM; @@ -838,13 +839,13 @@ DefineType(List *names, List *parameters) else if (strcasecmp(defel->defname, "externallength") == 0) externalLength = defGetTypeLength(defel); else if (strcasecmp(defel->defname, "input") == 0) - inputName = defGetString(defel); + inputName = defGetQualifiedName(defel); else if (strcasecmp(defel->defname, "output") == 0) - outputName = defGetString(defel); + outputName = defGetQualifiedName(defel); else if (strcasecmp(defel->defname, "send") == 0) - sendName = defGetString(defel); + sendName = defGetQualifiedName(defel); else if (strcasecmp(defel->defname, "receive") == 0) - receiveName = defGetString(defel); + receiveName = defGetQualifiedName(defel); else if (strcasecmp(defel->defname, "delimiter") == 0) { char *p = defGetString(defel); @@ -909,9 +910,9 @@ DefineType(List *names, List *parameters) /* * make sure we have our required definitions */ - if (inputName == NULL) + if (inputName == NIL) elog(ERROR, "Define: \"input\" unspecified"); - if (outputName == NULL) + if (outputName == NIL) elog(ERROR, "Define: \"output\" unspecified"); /* Convert I/O proc names to OIDs */ @@ -989,7 +990,7 @@ DefineType(List *names, List *parameters) } static Oid -findTypeIOFunction(const char *procname, bool isOutput) +findTypeIOFunction(List *procname, bool isOutput) { Oid argList[FUNC_MAX_ARGS]; int nargs; @@ -1001,11 +1002,7 @@ findTypeIOFunction(const char *procname, bool isOutput) */ MemSet(argList, 0, FUNC_MAX_ARGS * sizeof(Oid)); - procOid = GetSysCacheOid(PROCNAME, - PointerGetDatum(procname), - Int32GetDatum(1), - PointerGetDatum(argList), - 0); + procOid = LookupFuncName(procname, 1, argList); if (!OidIsValid(procOid)) { @@ -1028,11 +1025,7 @@ findTypeIOFunction(const char *procname, bool isOutput) argList[1] = OIDOID; argList[2] = INT4OID; } - procOid = GetSysCacheOid(PROCNAME, - PointerGetDatum(procname), - Int32GetDatum(nargs), - PointerGetDatum(argList), - 0); + procOid = LookupFuncName(procname, nargs, argList); if (!OidIsValid(procOid)) func_error("TypeCreate", procname, 1, argList, NULL); @@ -1094,6 +1087,26 @@ defGetNumeric(DefElem *def) return 0; /* keep compiler quiet */ } +static List * +defGetQualifiedName(DefElem *def) +{ + if (def->arg == NULL) + elog(ERROR, "Define: \"%s\" requires a parameter", + def->defname); + switch (nodeTag(def->arg)) + { + case T_TypeName: + return ((TypeName *) def->arg)->names; + case T_String: + /* Allow quoted name for backwards compatibility */ + return makeList1(def->arg); + default: + elog(ERROR, "Define: argument of \"%s\" must be a name", + def->defname); + } + return NIL; /* keep compiler quiet */ +} + static TypeName * defGetTypeName(DefElem *def) { diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c index b5067f99278..43539cd625a 100644 --- a/src/backend/commands/indexcmds.c +++ b/src/backend/commands/indexcmds.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.67 2002/04/05 00:31:26 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.68 2002/04/09 20:35:47 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -36,7 +36,7 @@ #include "utils/syscache.h" -#define IsFuncIndex(ATTR_LIST) (((IndexElem*)lfirst(ATTR_LIST))->args != NIL) +#define IsFuncIndex(ATTR_LIST) (((IndexElem*)lfirst(ATTR_LIST))->funcname != NIL) /* non-export function prototypes */ static void CheckPredicate(List *predList, List *rangeTable, Oid baseRelOid); @@ -297,7 +297,7 @@ FuncIndexArgs(IndexInfo *indexInfo, * that. So, check to make sure that the selected function has * exact-match or binary-compatible input types. */ - fdresult = func_get_detail(funcIndex->name, funcIndex->args, + fdresult = func_get_detail(funcIndex->funcname, funcIndex->args, nargs, argTypes, &funcid, &rettype, &retset, &true_typeids); @@ -307,7 +307,8 @@ FuncIndexArgs(IndexInfo *indexInfo, elog(ERROR, "DefineIndex: functional index must use a real function, not a type coercion" "\n\tTry specifying the index opclass you want to use, instead"); else - func_error("DefineIndex", funcIndex->name, nargs, argTypes, NULL); + func_error("DefineIndex", funcIndex->funcname, nargs, argTypes, + NULL); } if (retset) @@ -316,7 +317,7 @@ FuncIndexArgs(IndexInfo *indexInfo, for (i = 0; i < nargs; i++) { if (!IsBinaryCompatible(argTypes[i], true_typeids[i])) - func_error("DefineIndex", funcIndex->name, nargs, argTypes, + func_error("DefineIndex", funcIndex->funcname, nargs, argTypes, "Index function must be binary-compatible with table datatype"); } diff --git a/src/backend/commands/proclang.c b/src/backend/commands/proclang.c index d9cf0f0814a..4ef8d8f72a0 100644 --- a/src/backend/commands/proclang.c +++ b/src/backend/commands/proclang.c @@ -7,7 +7,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/proclang.c,v 1.29 2002/02/18 23:11:11 petere Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/proclang.c,v 1.30 2002/04/09 20:35:48 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -18,12 +18,15 @@ #include "access/heapam.h" #include "catalog/catname.h" #include "catalog/indexing.h" +#include "catalog/namespace.h" #include "catalog/pg_language.h" #include "catalog/pg_proc.h" #include "commands/proclang.h" #include "fmgr.h" #include "miscadmin.h" +#include "parser/parse_func.h" #include "utils/builtins.h" +#include "utils/lsyscache.h" #include "utils/syscache.h" @@ -50,15 +53,13 @@ void CreateProceduralLanguage(CreatePLangStmt *stmt) { char languageName[NAMEDATALEN]; - HeapTuple procTup; - + Oid procOid; Oid typev[FUNC_MAX_ARGS]; char nulls[Natts_pg_language]; Datum values[Natts_pg_language]; Relation rel; HeapTuple tup; TupleDesc tupDesc; - int i; /* @@ -83,18 +84,14 @@ CreateProceduralLanguage(CreatePLangStmt *stmt) * Lookup the PL handler function and check that it is of return type * Opaque */ - memset(typev, 0, sizeof(typev)); - procTup = SearchSysCache(PROCNAME, - PointerGetDatum(stmt->plhandler), - Int32GetDatum(0), - PointerGetDatum(typev), - 0); - if (!HeapTupleIsValid(procTup)) + MemSet(typev, 0, sizeof(typev)); + procOid = LookupFuncName(stmt->plhandler, 0, typev); + if (!OidIsValid(procOid)) elog(ERROR, "PL handler function %s() doesn't exist", - stmt->plhandler); - if (((Form_pg_proc) GETSTRUCT(procTup))->prorettype != InvalidOid) + NameListToString(stmt->plhandler)); + if (get_func_rettype(procOid) != InvalidOid) elog(ERROR, "PL handler function %s() isn't of return type Opaque", - stmt->plhandler); + NameListToString(stmt->plhandler)); /* * Insert the new language into pg_language @@ -109,13 +106,11 @@ CreateProceduralLanguage(CreatePLangStmt *stmt) values[i++] = PointerGetDatum(languageName); values[i++] = BoolGetDatum(true); /* lanispl */ values[i++] = BoolGetDatum(stmt->pltrusted); - values[i++] = ObjectIdGetDatum(procTup->t_data->t_oid); + values[i++] = ObjectIdGetDatum(procOid); values[i++] = DirectFunctionCall1(textin, CStringGetDatum(stmt->plcompiler)); nulls[i] = 'n'; /* lanacl */ - ReleaseSysCache(procTup); - rel = heap_openr(LanguageRelationName, RowExclusiveLock); tupDesc = rel->rd_att; diff --git a/src/backend/commands/remove.c b/src/backend/commands/remove.c index fb73fe3bd02..8969b9cdc13 100644 --- a/src/backend/commands/remove.c +++ b/src/backend/commands/remove.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/Attic/remove.c,v 1.72 2002/03/29 19:06:06 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/Attic/remove.c,v 1.73 2002/04/09 20:35:48 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -16,6 +16,7 @@ #include "access/heapam.h" #include "catalog/catname.h" +#include "catalog/namespace.h" #include "catalog/pg_language.h" #include "catalog/pg_proc.h" #include "catalog/pg_type.h" @@ -357,60 +358,38 @@ RemoveDomain(List *names, int behavior) * ... */ void -RemoveFunction(char *functionName, /* function name to be removed */ +RemoveFunction(List *functionName, /* function name to be removed */ List *argTypes) /* list of TypeName nodes */ { - int nargs = length(argTypes); + Oid funcOid; Relation relation; HeapTuple tup; - Oid argList[FUNC_MAX_ARGS]; - int i; - - if (nargs > FUNC_MAX_ARGS) - elog(ERROR, "functions cannot have more than %d arguments", - FUNC_MAX_ARGS); - MemSet(argList, 0, FUNC_MAX_ARGS * sizeof(Oid)); - for (i = 0; i < nargs; i++) - { - TypeName *t = (TypeName *) lfirst(argTypes); - - argList[i] = LookupTypeName(t); - if (!OidIsValid(argList[i])) - { - char *typnam = TypeNameToString(t); - - if (strcmp(typnam, "opaque") == 0) - argList[i] = InvalidOid; - else - elog(ERROR, "Type \"%s\" does not exist", typnam); - } - argTypes = lnext(argTypes); - } + funcOid = LookupFuncNameTypeNames(functionName, argTypes, + true, "RemoveFunction"); relation = heap_openr(ProcedureRelationName, RowExclusiveLock); - tup = SearchSysCache(PROCNAME, - PointerGetDatum(functionName), - Int32GetDatum(nargs), - PointerGetDatum(argList), - 0); - - if (!HeapTupleIsValid(tup)) - func_error("RemoveFunction", functionName, nargs, argList, NULL); + tup = SearchSysCache(PROCOID, + ObjectIdGetDatum(funcOid), + 0, 0, 0); + if (!HeapTupleIsValid(tup)) /* should not happen */ + elog(ERROR, "RemoveFunction: couldn't find tuple for function %s", + NameListToString(functionName)); - if (!pg_proc_ownercheck(tup->t_data->t_oid, GetUserId())) + if (!pg_proc_ownercheck(funcOid, GetUserId())) elog(ERROR, "RemoveFunction: function '%s': permission denied", - functionName); + NameListToString(functionName)); if (((Form_pg_proc) GETSTRUCT(tup))->prolang == INTERNALlanguageId) { /* "Helpful" WARNING when removing a builtin function ... */ - elog(WARNING, "Removing built-in function \"%s\"", functionName); + elog(WARNING, "Removing built-in function \"%s\"", + NameListToString(functionName)); } /* Delete any comments associated with this function */ - DeleteComments(tup->t_data->t_oid, RelationGetRelid(relation)); + DeleteComments(funcOid, RelationGetRelid(relation)); simple_heap_delete(relation, &tup->t_self); @@ -420,7 +399,7 @@ RemoveFunction(char *functionName, /* function name to be removed */ } void -RemoveAggregate(char *aggName, TypeName *aggType) +RemoveAggregate(List *aggName, TypeName *aggType) { Relation relation; HeapTuple tup; @@ -443,7 +422,7 @@ RemoveAggregate(char *aggName, TypeName *aggType) relation = heap_openr(AggregateRelationName, RowExclusiveLock); tup = SearchSysCache(AGGNAME, - PointerGetDatum(aggName), + PointerGetDatum(strVal(llast(aggName))), ObjectIdGetDatum(basetypeID), 0, 0); @@ -453,11 +432,11 @@ RemoveAggregate(char *aggName, TypeName *aggType) if (!pg_aggr_ownercheck(tup->t_data->t_oid, GetUserId())) { if (basetypeID == InvalidOid) - elog(ERROR, "RemoveAggregate: aggregate '%s' for all types: permission denied", - aggName); + elog(ERROR, "RemoveAggregate: aggregate %s for all types: permission denied", + NameListToString(aggName)); else - elog(ERROR, "RemoveAggregate: aggregate '%s' for type %s: permission denied", - aggName, format_type_be(basetypeID)); + elog(ERROR, "RemoveAggregate: aggregate %s for type %s: permission denied", + NameListToString(aggName), format_type_be(basetypeID)); } /* Remove any comments related to this aggregate */ diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c index c05b2ec51a3..72f13d3db49 100644 --- a/src/backend/commands/trigger.c +++ b/src/backend/commands/trigger.c @@ -7,7 +7,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.111 2002/04/01 22:36:10 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.112 2002/04/09 20:35:48 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -26,6 +26,7 @@ #include "commands/trigger.h" #include "executor/executor.h" #include "miscadmin.h" +#include "parser/parse_func.h" #include "utils/acl.h" #include "utils/builtins.h" #include "utils/fmgroids.h" @@ -163,18 +164,19 @@ CreateTrigger(CreateTrigStmt *stmt) * Find and validate the trigger function. */ MemSet(fargtypes, 0, FUNC_MAX_ARGS * sizeof(Oid)); - tuple = SearchSysCache(PROCNAME, - PointerGetDatum(stmt->funcname), - Int32GetDatum(0), - PointerGetDatum(fargtypes), - 0); + funcoid = LookupFuncName(stmt->funcname, 0, fargtypes); + if (!OidIsValid(funcoid)) + elog(ERROR, "CreateTrigger: function %s() does not exist", + NameListToString(stmt->funcname)); + tuple = SearchSysCache(PROCOID, + ObjectIdGetDatum(funcoid), + 0, 0, 0); if (!HeapTupleIsValid(tuple)) elog(ERROR, "CreateTrigger: function %s() does not exist", - stmt->funcname); + NameListToString(stmt->funcname)); if (((Form_pg_proc) GETSTRUCT(tuple))->prorettype != 0) elog(ERROR, "CreateTrigger: function %s() must return OPAQUE", - stmt->funcname); - funcoid = tuple->t_data->t_oid; + NameListToString(stmt->funcname)); funclang = ((Form_pg_proc) GETSTRUCT(tuple))->prolang; ReleaseSysCache(tuple); |