summaryrefslogtreecommitdiff
path: root/src/backend/commands
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2002-04-09 20:35:55 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2002-04-09 20:35:55 +0000
commitf2d70d32ebd6c38d4fe93c1a684f5f29e5e76938 (patch)
tree5d041018177cdf6e9ca3ef0cc2eafac580a5bb0b /src/backend/commands
parentc419c224142eb4bbf6e9a47d2d3626f212fda0fc (diff)
Functions live in namespaces. Qualified function names work, eg
SELECT schema1.func2(...). Aggregate names can be qualified at the syntactic level, but the qualification is ignored for the moment.
Diffstat (limited to 'src/backend/commands')
-rw-r--r--src/backend/commands/comment.c314
-rw-r--r--src/backend/commands/define.c71
-rw-r--r--src/backend/commands/indexcmds.c11
-rw-r--r--src/backend/commands/proclang.c29
-rw-r--r--src/backend/commands/remove.c67
-rw-r--r--src/backend/commands/trigger.c20
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);