Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
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);