Functions live in namespaces. Qualified function names work, eg
authorTom Lane
Tue, 9 Apr 2002 20:35:55 +0000 (20:35 +0000)
committerTom Lane
Tue, 9 Apr 2002 20:35:55 +0000 (20:35 +0000)
SELECT schema1.func2(...).  Aggregate names can be qualified at the
syntactic level, but the qualification is ignored for the moment.

36 files changed:
src/backend/bootstrap/bootparse.y
src/backend/catalog/aclchk.c
src/backend/catalog/namespace.c
src/backend/catalog/pg_aggregate.c
src/backend/catalog/pg_operator.c
src/backend/catalog/pg_proc.c
src/backend/commands/comment.c
src/backend/commands/define.c
src/backend/commands/indexcmds.c
src/backend/commands/proclang.c
src/backend/commands/remove.c
src/backend/commands/trigger.c
src/backend/nodes/copyfuncs.c
src/backend/nodes/equalfuncs.c
src/backend/nodes/list.c
src/backend/nodes/outfuncs.c
src/backend/parser/analyze.c
src/backend/parser/gram.y
src/backend/parser/parse_agg.c
src/backend/parser/parse_coerce.c
src/backend/parser/parse_expr.c
src/backend/parser/parse_func.c
src/backend/parser/parse_target.c
src/backend/tcop/utility.c
src/backend/utils/cache/syscache.c
src/include/catalog/namespace.h
src/include/catalog/pg_aggregate.h
src/include/commands/comment.h
src/include/commands/defrem.h
src/include/nodes/parsenodes.h
src/include/nodes/pg_list.h
src/include/parser/gramparse.h
src/include/parser/parse_agg.h
src/include/parser/parse_func.h
src/include/utils/syscache.h
src/test/regress/expected/privileges.out

index 7afd6659e1af28620ea691a6f78a5d000b237f22..b5d039f9355ef63831e56edcf35786f811afee7c 100644 (file)
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/bootstrap/bootparse.y,v 1.43 2002/04/01 14:22:41 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/bootstrap/bootparse.y,v 1.44 2002/04/09 20:35:46 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -272,6 +272,7 @@ boot_index_param:
                {
                    IndexElem *n = makeNode(IndexElem);
                    n->name = LexIDStr($1);
+                   n->funcname = n->args = NIL; /* no func indexes */
                    n->class = LexIDStr($2);
                    $$ = n;
                }
index 00c52e89c4b80da4f5ff2836733ff1c75997d278..07f49c75ab2cffa3b4ac1c21a017730abb0c0d72 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.61 2002/03/31 06:26:29 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.62 2002/04/09 20:35:46 tgl Exp $
  *
  * NOTES
  *   See acl.h.
@@ -283,51 +283,6 @@ ExecuteGrantStmt_Table(GrantStmt *stmt)
 }
 
 
-static Oid
-find_function_with_arglist(char *name, List *arguments)
-{
-   Oid     oid;
-   Oid     argoids[FUNC_MAX_ARGS];
-   int     i;
-   int16   argcount;
-
-   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);
-       }
-
-       arguments = lnext(arguments);
-   }
-
-   oid = GetSysCacheOid(PROCNAME,
-                        PointerGetDatum(name),
-                        Int16GetDatum(argcount),
-                        PointerGetDatum(argoids),
-                        0);
-
-   if (!OidIsValid(oid))
-       func_error(NULL, name, argcount, argoids, NULL);
-
-   return oid;
-}
-
-
 static void
 ExecuteGrantStmt_Function(GrantStmt *stmt)
 {
@@ -365,7 +320,8 @@ ExecuteGrantStmt_Function(GrantStmt *stmt)
        char        nulls[Natts_pg_proc];
        char        replaces[Natts_pg_proc];
 
-       oid = find_function_with_arglist(func->funcname, func->funcargs);
+       oid = LookupFuncNameTypeNames(func->funcname, func->funcargs,
+                                     true, "GRANT");
        relation = heap_openr(ProcedureRelationName, RowExclusiveLock);
        tuple = SearchSysCache(PROCOID, ObjectIdGetDatum(oid), 0, 0, 0);
        if (!HeapTupleIsValid(tuple))
index a7d73bbf272240050e271d9d37508f2a44ab1541..6880dbe19e396e1b92424b79c1c8c54fddb88c42 100644 (file)
@@ -13,7 +13,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/catalog/namespace.c,v 1.6 2002/04/06 06:59:21 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/catalog/namespace.c,v 1.7 2002/04/09 20:35:47 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -28,6 +28,7 @@
 #include "catalog/pg_namespace.h"
 #include "catalog/pg_proc.h"
 #include "catalog/pg_shadow.h"
+#include "lib/stringinfo.h"
 #include "miscadmin.h"
 #include "nodes/makefuncs.h"
 #include "storage/backendid.h"
@@ -367,7 +368,7 @@ FuncnameGetCandidates(List *names, int nargs)
    }
 
    /* Search syscache by name and nargs only */
-   catlist = SearchSysCacheList(PROCNAME, 2,
+   catlist = SearchSysCacheList(PROCNAMENSP, 2,
                                 CStringGetDatum(funcname),
                                 Int16GetDatum(nargs),
                                 0, 0);
@@ -564,6 +565,29 @@ makeRangeVarFromNameList(List *names)
    return rel;
 }
 
+/*
+ * NameListToString
+ *     Utility routine to convert a qualified-name list into a string.
+ *     Used primarily to form error messages.
+ */
+char *
+NameListToString(List *names)
+{
+   StringInfoData string;
+   List        *l;
+
+   initStringInfo(&string);
+
+   foreach(l, names)
+   {
+       if (l != names)
+           appendStringInfoChar(&string, '.');
+       appendStringInfo(&string, "%s", strVal(lfirst(l)));
+   }
+
+   return string.data;
+}
+
 /*
  * isTempNamespace - is the given namespace my temporary-table namespace?
  */
index 1a73f42c3344a78792b6f28483dc3e64a9772043..a9f270fccf8afd718e3b17da992d2f3d5f9882c7 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/catalog/pg_aggregate.c,v 1.42 2002/03/29 19:06:01 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/catalog/pg_aggregate.c,v 1.43 2002/04/09 20:35:47 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -17,6 +17,7 @@
 #include "access/heapam.h"
 #include "catalog/catname.h"
 #include "catalog/indexing.h"
+#include "catalog/namespace.h"
 #include "catalog/pg_aggregate.h"
 #include "catalog/pg_proc.h"
 #include "catalog/pg_type.h"
@@ -33,8 +34,8 @@
 void
 AggregateCreate(const char *aggName,
                Oid aggNamespace,
-               char *aggtransfnName,
-               char *aggfinalfnName,
+               List *aggtransfnName,
+               List *aggfinalfnName,
                Oid aggBaseType,
                Oid aggTransType,
                const char *agginitval)
@@ -79,19 +80,18 @@ AggregateCreate(const char *aggName,
    }
    else
        nargs = 1;
-   tup = SearchSysCache(PROCNAME,
-                        PointerGetDatum(aggtransfnName),
-                        Int32GetDatum(nargs),
-                        PointerGetDatum(fnArgs),
-                        0);
+   transfn = LookupFuncName(aggtransfnName, nargs, fnArgs);
+   if (!OidIsValid(transfn))
+       func_error("AggregateCreate", aggtransfnName, nargs, fnArgs, NULL);
+   tup = SearchSysCache(PROCOID,
+                        ObjectIdGetDatum(transfn),
+                        0, 0, 0);
    if (!HeapTupleIsValid(tup))
        func_error("AggregateCreate", aggtransfnName, nargs, fnArgs, NULL);
-   transfn = tup->t_data->t_oid;
-   Assert(OidIsValid(transfn));
    proc = (Form_pg_proc) GETSTRUCT(tup);
    if (proc->prorettype != aggTransType)
        elog(ERROR, "return type of transition function %s is not %s",
-            aggtransfnName, typeidTypeName(aggTransType));
+            NameListToString(aggtransfnName), typeidTypeName(aggTransType));
 
    /*
     * If the transfn is strict and the initval is NULL, make sure input
@@ -111,15 +111,14 @@ AggregateCreate(const char *aggName,
    {
        fnArgs[0] = aggTransType;
        fnArgs[1] = 0;
-       tup = SearchSysCache(PROCNAME,
-                            PointerGetDatum(aggfinalfnName),
-                            Int32GetDatum(1),
-                            PointerGetDatum(fnArgs),
-                            0);
+       finalfn = LookupFuncName(aggfinalfnName, 1, fnArgs);
+       if (!OidIsValid(finalfn))
+           func_error("AggregateCreate", aggfinalfnName, 1, fnArgs, NULL);
+       tup = SearchSysCache(PROCOID,
+                            ObjectIdGetDatum(finalfn),
+                            0, 0, 0);
        if (!HeapTupleIsValid(tup))
            func_error("AggregateCreate", aggfinalfnName, 1, fnArgs, NULL);
-       finalfn = tup->t_data->t_oid;
-       Assert(OidIsValid(finalfn));
        proc = (Form_pg_proc) GETSTRUCT(tup);
        finaltype = proc->prorettype;
        ReleaseSysCache(tup);
index 8942c266fd6b9d68c41c37a50be3a6c3e74acee7..41023b7edc8c8266a09ebaf377e3bbad8a39aa7b 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/catalog/pg_operator.c,v 1.64 2002/03/29 19:06:01 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/catalog/pg_operator.c,v 1.65 2002/04/09 20:35:47 tgl Exp $
  *
  * NOTES
  *   these routines moved here from commands/define.c and somewhat cleaned up.
@@ -27,6 +27,7 @@
 #include "parser/parse_func.h"
 #include "utils/builtins.h"
 #include "utils/fmgroids.h"
+#include "utils/lsyscache.h"
 #include "utils/syscache.h"
 
 
@@ -42,13 +43,13 @@ static Oid OperatorShellMake(const char *operatorName,
 static void OperatorDef(const char *operatorName,
            Oid leftTypeId,
            Oid rightTypeId,
-           const char *procedureName,
+           List *procedureName,
            uint16 precedence,
            bool isLeftAssociative,
            const char *commutatorName,
            const char *negatorName,
-           const char *restrictionName,
-           const char *joinName,
+           List *restrictionName,
+           List *joinName,
            bool canHash,
            const char *leftSortName,
            const char *rightSortName);
@@ -373,13 +374,13 @@ static void
 OperatorDef(const char *operatorName,
            Oid leftTypeId,
            Oid rightTypeId,
-           const char *procedureName,
+           List *procedureName,
            uint16 precedence,
            bool isLeftAssociative,
            const char *commutatorName,
            const char *negatorName,
-           const char *restrictionName,
-           const char *joinName,
+           List *restrictionName,
+           List *joinName,
            bool canHash,
            const char *leftSortName,
            const char *rightSortName)
@@ -398,6 +399,7 @@ OperatorDef(const char *operatorName,
    const char *name[4];
    Oid         typeId[FUNC_MAX_ARGS];
    int         nargs;
+   Oid         procOid;
    NameData    oname;
    TupleDesc   tupDesc;
    ScanKeyData opKey[3];
@@ -456,19 +458,12 @@ OperatorDef(const char *operatorName,
        typeId[1] = rightTypeId;
        nargs = 2;
    }
-   tup = SearchSysCache(PROCNAME,
-                        PointerGetDatum(procedureName),
-                        Int32GetDatum(nargs),
-                        PointerGetDatum(typeId),
-                        0);
-   if (!HeapTupleIsValid(tup))
+   procOid = LookupFuncName(procedureName, nargs, typeId);
+   if (!OidIsValid(procOid))
        func_error("OperatorDef", procedureName, nargs, typeId, NULL);
 
-   values[Anum_pg_operator_oprcode - 1] = ObjectIdGetDatum(tup->t_data->t_oid);
-   values[Anum_pg_operator_oprresult - 1] = ObjectIdGetDatum(((Form_pg_proc)
-                                           GETSTRUCT(tup))->prorettype);
-
-   ReleaseSysCache(tup);
+   values[Anum_pg_operator_oprcode - 1] = ObjectIdGetDatum(procOid);
+   values[Anum_pg_operator_oprresult - 1] = ObjectIdGetDatum(get_func_rettype(procOid));
 
    /*
     * find restriction estimator
@@ -483,11 +478,7 @@ OperatorDef(const char *operatorName,
        typeId[2] = 0;          /* args list (opaque type) */
        typeId[3] = INT4OID;    /* varRelid */
 
-       restOid = GetSysCacheOid(PROCNAME,
-                                PointerGetDatum(restrictionName),
-                                Int32GetDatum(4),
-                                PointerGetDatum(typeId),
-                                0);
+       restOid = LookupFuncName(restrictionName, 4, typeId);
        if (!OidIsValid(restOid))
            func_error("OperatorDef", restrictionName, 4, typeId, NULL);
 
@@ -508,11 +499,7 @@ OperatorDef(const char *operatorName,
        typeId[1] = OIDOID;     /* operator OID */
        typeId[2] = 0;          /* args list (opaque type) */
 
-       joinOid = GetSysCacheOid(PROCNAME,
-                                PointerGetDatum(joinName),
-                                Int32GetDatum(3),
-                                PointerGetDatum(typeId),
-                                0);
+       joinOid = LookupFuncName(joinName, 3, typeId);
        if (!OidIsValid(joinOid))
            func_error("OperatorDef", joinName, 3, typeId, NULL);
 
@@ -950,13 +937,13 @@ OperatorCreate(const char *operatorName,
    OperatorDef(operatorName,
                leftTypeId,
                rightTypeId,
-               procedureName,
+               makeList1(makeString((char*) procedureName)), /* XXX */
                precedence,
                isLeftAssociative,
                commutatorName,
                negatorName,
-               restrictionName,
-               joinName,
+               restrictionName ? makeList1(makeString((char*) restrictionName)) : NIL, /* XXX */
+               joinName ? makeList1(makeString((char*) joinName)) : NIL, /* XXX */
                canHash,
                leftSortName,
                rightSortName);
index 02f76e7679a942f34b12bd59abfa3a9533c93ac3..8cb89b979cbab9f2a0d5f92a23e85743e1e19b94 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.68 2002/04/05 00:31:25 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.69 2002/04/09 20:35:47 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -271,11 +271,11 @@ ProcedureCreate(const char *procedureName,
    tupDesc = rel->rd_att;
 
    /* Check for pre-existing definition */
-   oldtup = SearchSysCache(PROCNAME,
+   oldtup = SearchSysCache(PROCNAMENSP,
                            PointerGetDatum(procedureName),
                            UInt16GetDatum(parameterCount),
                            PointerGetDatum(typev),
-                           0);
+                           ObjectIdGetDatum(procNamespace));
 
    if (HeapTupleIsValid(oldtup))
    {
index f8e5bc6fc6fd6fe3fe96c274ea191c6d0f5d9fe8..b7d57f6cce5959c3c1577a99d9d656cda4766d72 100644 (file)
@@ -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"
 #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;
 
index eaff4e66dfa80d262f50206828d62da93348cfcf..cccbcdfaa5922ec6bfed384e90cba9a86a634103 100644 (file)
@@ -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
 #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)
 {
index b5067f99278fa21659a2fb66759c54f369529483..43539cd625af170521eb1c6a8a4f1c4933a1d8fa 100644 (file)
@@ -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");
    }
 
index d9cf0f0814a380d9c4892a7d85a64865fb787f3e..4ef8d8f72a0bee3b3a69cab019cd467181aa6bd2 100644 (file)
@@ -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 $
  *
  *-------------------------------------------------------------------------
  */
 #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;
index fb73fe3bd0236c8ef2b4e2d6f0f37e64ccb66592..8969b9cdc13b9d6e896997bd722d1fc9d4b2dfc3 100644 (file)
@@ -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 */
index c05b2ec51a31b895cdeb882a56bb8ddd69ffd40f..72f13d3db491dd041cface0469dd567463a654ee 100644 (file)
@@ -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);
 
index b633b02b79d29bcfee773d80215f2d63c193f0da..873658774ca9acc2cdbbc648ce5b26313e94a1e6 100644 (file)
@@ -15,7 +15,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.175 2002/04/05 11:56:48 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.176 2002/04/09 20:35:49 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1587,8 +1587,7 @@ _copyFuncCall(FuncCall *from)
 {
    FuncCall   *newnode = makeNode(FuncCall);
 
-   if (from->funcname)
-       newnode->funcname = pstrdup(from->funcname);
+   Node_Copy(from, newnode, funcname);
    Node_Copy(from, newnode, args);
    newnode->agg_star = from->agg_star;
    newnode->agg_distinct = from->agg_distinct;
@@ -1719,6 +1718,7 @@ _copyIndexElem(IndexElem *from)
 
    if (from->name)
        newnode->name = pstrdup(from->name);
+   Node_Copy(from, newnode, funcname);
    Node_Copy(from, newnode, args);
    if (from->class)
        newnode->class = pstrdup(from->class);
@@ -1940,8 +1940,7 @@ _copyFuncWithArgs(FuncWithArgs *from)
 {
    FuncWithArgs *newnode = makeNode(FuncWithArgs);
 
-   if (from->funcname)
-       newnode->funcname = pstrdup(from->funcname);
+   Node_Copy(from, newnode, funcname);
    Node_Copy(from, newnode, funcargs);
 
    return newnode;
@@ -2052,13 +2051,10 @@ _copyCommentStmt(CommentStmt *from)
    CommentStmt *newnode = makeNode(CommentStmt);
 
    newnode->objtype = from->objtype;
-   if (from->objschema)
-       newnode->objschema = pstrdup(from->objschema);
-   newnode->objname = pstrdup(from->objname);
-   if (from->objproperty)
-       newnode->objproperty = pstrdup(from->objproperty);
-   Node_Copy(from, newnode, objlist);
-   newnode->comment = pstrdup(from->comment);
+   Node_Copy(from, newnode, objname);
+   Node_Copy(from, newnode, objargs);
+   if (from->comment)
+       newnode->comment = pstrdup(from->comment);
 
    return newnode;
 }
@@ -2114,7 +2110,7 @@ _copyRemoveAggrStmt(RemoveAggrStmt *from)
 {
    RemoveAggrStmt *newnode = makeNode(RemoveAggrStmt);
 
-   newnode->aggname = pstrdup(from->aggname);
+   Node_Copy(from, newnode, aggname);
    Node_Copy(from, newnode, aggtype);
 
    return newnode;
@@ -2125,7 +2121,7 @@ _copyRemoveFuncStmt(RemoveFuncStmt *from)
 {
    RemoveFuncStmt *newnode = makeNode(RemoveFuncStmt);
 
-   newnode->funcname = pstrdup(from->funcname);
+   Node_Copy(from, newnode, funcname);
    Node_Copy(from, newnode, args);
 
    return newnode;
@@ -2370,8 +2366,7 @@ _copyCreateTrigStmt(CreateTrigStmt *from)
    if (from->trigname)
        newnode->trigname = pstrdup(from->trigname);
    Node_Copy(from, newnode, relation);
-   if (from->funcname)
-       newnode->funcname = pstrdup(from->funcname);
+   Node_Copy(from, newnode, funcname);
    Node_Copy(from, newnode, args);
    newnode->before = from->before;
    newnode->row = from->row;
@@ -2411,8 +2406,7 @@ _copyCreatePLangStmt(CreatePLangStmt *from)
 
    if (from->plname)
        newnode->plname = pstrdup(from->plname);
-   if (from->plhandler)
-       newnode->plhandler = pstrdup(from->plhandler);
+   Node_Copy(from, newnode, plhandler);
    if (from->plcompiler)
        newnode->plcompiler = pstrdup(from->plcompiler);
    newnode->pltrusted = from->pltrusted;
index eceb8cb36f796e0aa0acb660dac9f6e8df433a51..9458ebc5b95568daf03dc25089151198f2e52867 100644 (file)
@@ -20,7 +20,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.123 2002/04/05 11:56:50 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.124 2002/04/09 20:35:50 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -769,7 +769,7 @@ _equalPrivGrantee(PrivGrantee *a, PrivGrantee *b)
 static bool
 _equalFuncWithArgs(FuncWithArgs *a, FuncWithArgs *b)
 {
-   return equalstr(a->funcname, b->funcname)
+   return equal(a->funcname, b->funcname)
        && equal(a->funcargs, b->funcargs);
 }
 
@@ -877,13 +877,9 @@ _equalCommentStmt(CommentStmt *a, CommentStmt *b)
 {
    if (a->objtype != b->objtype)
        return false;
-   if (!equalstr(a->objname, b->objname))
+   if (!equal(a->objname, b->objname))
        return false;
-   if (!equalstr(a->objschema, b->objschema))
-       return false;
-   if (!equalstr(a->objproperty, b->objproperty))
-       return false;
-   if (!equal(a->objlist, b->objlist))
+   if (!equal(a->objargs, b->objargs))
        return false;
    if (!equalstr(a->comment, b->comment))
        return false;
@@ -953,7 +949,7 @@ _equalProcedureStmt(ProcedureStmt *a, ProcedureStmt *b)
 static bool
 _equalRemoveAggrStmt(RemoveAggrStmt *a, RemoveAggrStmt *b)
 {
-   if (!equalstr(a->aggname, b->aggname))
+   if (!equal(a->aggname, b->aggname))
        return false;
    if (!equal(a->aggtype, b->aggtype))
        return false;
@@ -964,7 +960,7 @@ _equalRemoveAggrStmt(RemoveAggrStmt *a, RemoveAggrStmt *b)
 static bool
 _equalRemoveFuncStmt(RemoveFuncStmt *a, RemoveFuncStmt *b)
 {
-   if (!equalstr(a->funcname, b->funcname))
+   if (!equal(a->funcname, b->funcname))
        return false;
    if (!equal(a->args, b->args))
        return false;
@@ -1207,7 +1203,7 @@ _equalCreateTrigStmt(CreateTrigStmt *a, CreateTrigStmt *b)
        return false;
    if (!equal(a->relation, b->relation))
        return false;
-   if (!equalstr(a->funcname, b->funcname))
+   if (!equal(a->funcname, b->funcname))
        return false;
    if (!equal(a->args, b->args))
        return false;
@@ -1253,7 +1249,7 @@ _equalCreatePLangStmt(CreatePLangStmt *a, CreatePLangStmt *b)
 {
    if (!equalstr(a->plname, b->plname))
        return false;
-   if (!equalstr(a->plhandler, b->plhandler))
+   if (!equal(a->plhandler, b->plhandler))
        return false;
    if (!equalstr(a->plcompiler, b->plcompiler))
        return false;
@@ -1463,7 +1459,7 @@ _equalIdent(Ident *a, Ident *b)
 static bool
 _equalFuncCall(FuncCall *a, FuncCall *b)
 {
-   if (!equalstr(a->funcname, b->funcname))
+   if (!equal(a->funcname, b->funcname))
        return false;
    if (!equal(a->args, b->args))
        return false;
@@ -1601,6 +1597,8 @@ _equalIndexElem(IndexElem *a, IndexElem *b)
 {
    if (!equalstr(a->name, b->name))
        return false;
+   if (!equal(a->funcname, b->funcname))
+       return false;
    if (!equal(a->args, b->args))
        return false;
    if (!equalstr(a->class, b->class))
index 9b588150fda8be7757d8345626164ef383f7be59..a61991f38fa015aa095b52f4b407eeb74f8aee69 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/nodes/list.c,v 1.39 2001/03/22 03:59:32 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/nodes/list.c,v 1.40 2002/04/09 20:35:50 tgl Exp $
  *
  * NOTES
  *   XXX a few of the following functions are duplicated to handle
@@ -233,6 +233,36 @@ length(List *l)
    return i;
 }
 
+/*
+ * llast
+ *
+ * Get the last element of l ... error if empty list
+ */
+void *
+llast(List *l)
+{
+   if (l == NIL)
+       elog(ERROR, "llast: empty list");
+   while (lnext(l) != NIL)
+       l = lnext(l);
+   return lfirst(l);
+}
+
+/*
+ * llasti
+ *
+ * As above, but for integer lists
+ */
+int
+llasti(List *l)
+{
+   if (l == NIL)
+       elog(ERROR, "llasti: empty list");
+   while (lnext(l) != NIL)
+       l = lnext(l);
+   return lfirsti(l);
+}
+
 /*
  * freeList
  *
index 20d25c6439785068389070b7128b2d689f8e61a9..a495f5ed10b3e42cb7336d9f720014d94ac40dc0 100644 (file)
@@ -5,7 +5,7 @@
  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.152 2002/03/29 19:06:09 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.153 2002/04/09 20:35:50 tgl Exp $
  *
  * NOTES
  *   Every (plan) node in POSTGRES has an associated "out" routine which
@@ -160,7 +160,7 @@ static void
 _outFuncCall(StringInfo str, FuncCall *node)
 {
    appendStringInfo(str, "FUNCTION ");
-   _outToken(str, node->funcname);
+   _outNode(str, node->funcname);
    appendStringInfo(str, " :args ");
    _outNode(str, node->args);
    appendStringInfo(str, " :agg_star %s :agg_distinct %s ",
@@ -213,6 +213,8 @@ _outIndexElem(StringInfo str, IndexElem *node)
 {
    appendStringInfo(str, " INDEXELEM :name ");
    _outToken(str, node->name);
+   appendStringInfo(str, " :funcname ");
+   _outNode(str, node->funcname);
    appendStringInfo(str, " :args ");
    _outNode(str, node->args);
    appendStringInfo(str, " :class ");
index 0de9c5bb851b86f1bf2f87d5ebaec9518b90a1a5..8b3f218b83adc7d987c95f949ab254feb0fed4b3 100644 (file)
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.227 2002/04/05 11:56:51 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.228 2002/04/09 20:35:51 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -22,6 +22,7 @@
 #include "catalog/pg_type.h"
 #include "nodes/makefuncs.h"
 #include "parser/analyze.h"
+#include "parser/gramparse.h"
 #include "parser/parsetree.h"
 #include "parser/parse_agg.h"
 #include "parser/parse_clause.h"
@@ -859,7 +860,7 @@ transformColumnDefinition(ParseState *pstate, CreateStmtContext *cxt,
        snamenode->val.type = T_String;
        snamenode->val.val.str = qstring;
        funccallnode = makeNode(FuncCall);
-       funccallnode->funcname = "nextval";
+       funccallnode->funcname = SystemFuncName("nextval");
        funccallnode->args = makeList1(snamenode);
        funccallnode->agg_star = false;
        funccallnode->agg_distinct = false;
@@ -1197,7 +1198,7 @@ transformIndexConstraints(ParseState *pstate, CreateStmtContext *cxt)
            foreach(columns, index->indexParams)
            {
                iparam = (IndexElem *) lfirst(columns);
-               if (strcmp(key->name, iparam->name) == 0)
+               if (iparam->name && strcmp(key->name, iparam->name) == 0)
                    elog(ERROR, "%s: column \"%s\" appears twice in %s constraint",
                         cxt->stmtType, key->name,
                         index->primary ? "PRIMARY KEY" : "UNIQUE");
@@ -1206,6 +1207,7 @@ transformIndexConstraints(ParseState *pstate, CreateStmtContext *cxt)
            /* OK, add it to the index definition */
            iparam = makeNode(IndexElem);
            iparam->name = pstrdup(key->name);
+           iparam->funcname = NIL;
            iparam->args = NIL;
            iparam->class = NULL;
            index->indexParams = lappend(index->indexParams, iparam);
@@ -1281,7 +1283,9 @@ transformIndexConstraints(ParseState *pstate, CreateStmtContext *cxt)
        if (index->idxname == NULL && index->indexParams != NIL)
        {
            iparam = lfirst(index->indexParams);
-           index->idxname = CreateIndexName((cxt->relation)->relname, iparam->name,
+           index->idxname = CreateIndexName(cxt->relation->relname,
+                                            iparam->name ? iparam->name :
+                                            strVal(llast(iparam->funcname)),
                                             "key", cxt->alist);
        }
        if (index->idxname == NULL)     /* should not happen */
@@ -1292,7 +1296,7 @@ transformIndexConstraints(ParseState *pstate, CreateStmtContext *cxt)
             cxt->stmtType,
             (strcmp(cxt->stmtType, "ALTER TABLE") == 0) ? "ADD " : "",
             (index->primary ? "PRIMARY KEY" : "UNIQUE"),
-            index->idxname, (cxt->relation)->relname);
+            index->idxname, cxt->relation->relname);
    }
 }
 
@@ -1365,6 +1369,7 @@ transformFKConstraints(ParseState *pstate, CreateStmtContext *cxt)
                    IndexElem  *ielem = lfirst(attr);
                    Ident      *pkattr = (Ident *) makeNode(Ident);
 
+                   Assert(ielem->name); /* no func index here */
                    pkattr->name = pstrdup(ielem->name);
                    fkconstraint->pk_attrs = lappend(fkconstraint->pk_attrs,
                                                     pkattr);
@@ -1417,7 +1422,8 @@ transformFKConstraints(ParseState *pstate, CreateStmtContext *cxt)
                        {
                            IndexElem  *indparm = lfirst(indparms);
 
-                           if (strcmp(indparm->name, pkattr->name) == 0)
+                           if (indparm->name &&
+                               strcmp(indparm->name, pkattr->name) == 0)
                            {
                                found = true;
                                break;
@@ -1470,7 +1476,7 @@ transformFKConstraints(ParseState *pstate, CreateStmtContext *cxt)
        fk_trigger = (CreateTrigStmt *) makeNode(CreateTrigStmt);
        fk_trigger->trigname = fkconstraint->constr_name;
        fk_trigger->relation = cxt->relation;
-       fk_trigger->funcname = "RI_FKey_check_ins";
+       fk_trigger->funcname = SystemFuncName("RI_FKey_check_ins");
        fk_trigger->before = false;
        fk_trigger->row = true;
        fk_trigger->actions[0] = 'i';
@@ -1542,21 +1548,21 @@ transformFKConstraints(ParseState *pstate, CreateStmtContext *cxt)
                >> FKCONSTR_ON_DELETE_SHIFT)
        {
            case FKCONSTR_ON_KEY_NOACTION:
-               fk_trigger->funcname = "RI_FKey_noaction_del";
+               fk_trigger->funcname = SystemFuncName("RI_FKey_noaction_del");
                break;
            case FKCONSTR_ON_KEY_RESTRICT:
                fk_trigger->deferrable = false;
                fk_trigger->initdeferred = false;
-               fk_trigger->funcname = "RI_FKey_restrict_del";
+               fk_trigger->funcname = SystemFuncName("RI_FKey_restrict_del");
                break;
            case FKCONSTR_ON_KEY_CASCADE:
-               fk_trigger->funcname = "RI_FKey_cascade_del";
+               fk_trigger->funcname = SystemFuncName("RI_FKey_cascade_del");
                break;
            case FKCONSTR_ON_KEY_SETNULL:
-               fk_trigger->funcname = "RI_FKey_setnull_del";
+               fk_trigger->funcname = SystemFuncName("RI_FKey_setnull_del");
                break;
            case FKCONSTR_ON_KEY_SETDEFAULT:
-               fk_trigger->funcname = "RI_FKey_setdefault_del";
+               fk_trigger->funcname = SystemFuncName("RI_FKey_setdefault_del");
                break;
            default:
                elog(ERROR, "Only one ON DELETE action can be specified for FOREIGN KEY constraint");
@@ -1614,21 +1620,21 @@ transformFKConstraints(ParseState *pstate, CreateStmtContext *cxt)
                >> FKCONSTR_ON_UPDATE_SHIFT)
        {
            case FKCONSTR_ON_KEY_NOACTION:
-               fk_trigger->funcname = "RI_FKey_noaction_upd";
+               fk_trigger->funcname = SystemFuncName("RI_FKey_noaction_upd");
                break;
            case FKCONSTR_ON_KEY_RESTRICT:
                fk_trigger->deferrable = false;
                fk_trigger->initdeferred = false;
-               fk_trigger->funcname = "RI_FKey_restrict_upd";
+               fk_trigger->funcname = SystemFuncName("RI_FKey_restrict_upd");
                break;
            case FKCONSTR_ON_KEY_CASCADE:
-               fk_trigger->funcname = "RI_FKey_cascade_upd";
+               fk_trigger->funcname = SystemFuncName("RI_FKey_cascade_upd");
                break;
            case FKCONSTR_ON_KEY_SETNULL:
-               fk_trigger->funcname = "RI_FKey_setnull_upd";
+               fk_trigger->funcname = SystemFuncName("RI_FKey_setnull_upd");
                break;
            case FKCONSTR_ON_KEY_SETDEFAULT:
-               fk_trigger->funcname = "RI_FKey_setdefault_upd";
+               fk_trigger->funcname = SystemFuncName("RI_FKey_setdefault_upd");
                break;
            default:
                elog(ERROR, "Only one ON UPDATE action can be specified for FOREIGN KEY constraint");
index 6ba8766e1ac173cfe40c5e4c750a7ed3fbdd97e0..3488fb0762ff3a6af8589eddb9f12b727558359f 100644 (file)
@@ -11,7 +11,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.300 2002/04/05 11:56:53 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.301 2002/04/09 20:35:51 tgl Exp $
  *
  * HISTORY
  *   AUTHOR            DATE            MAJOR EVENT
@@ -175,8 +175,9 @@ static bool set_name_needs_quotes(const char *name);
 
 %type         relation_name, copy_file_name, copy_delimiter, copy_null,
        database_name, access_method_clause, access_method, attr_name,
-       class, index_name, name, function_name, file_name,
-       func_name, handler_name
+       class, index_name, name, function_name, file_name
+
+%type    func_name, handler_name
 
 %type   qualified_name, OptConstrFromTable
 
@@ -1859,9 +1860,9 @@ opt_trusted:  TRUSTED         { $$ = TRUE; }
  * Work around by using name and dotted_name separately.
  */
 handler_name: name
-               { $$ = $1; }
+               { $$ = makeList1(makeString($1)); }
            | dotted_name
-               { $$ = strVal(lfirst($1)); /* XXX changing soon */ }
+               { $$ = $1; }
        ;
 
 opt_lancompiler: LANCOMPILER Sconst { $$ = $2; }
@@ -2081,7 +2082,7 @@ DefineStmt:  CREATE AGGREGATE func_name definition
                {
                    DefineStmt *n = makeNode(DefineStmt);
                    n->defType = AGGREGATE;
-                   n->defnames = makeList1(makeString($3)); /* XXX */
+                   n->defnames = $3;
                    n->definition = $4;
                    $$ = (Node *)n;
                }
@@ -2199,54 +2200,21 @@ TruncateStmt:  TRUNCATE opt_table qualified_name
  *
  *****************************************************************************/
  
-CommentStmt:   COMMENT ON comment_type name IS comment_text
+CommentStmt:   COMMENT ON comment_type any_name IS comment_text
            {
                CommentStmt *n = makeNode(CommentStmt);
                n->objtype = $3;
                n->objname = $4;
-               n->objproperty = NULL;
-               n->objlist = NULL;
+               n->objargs = NIL;
                n->comment = $6;
                $$ = (Node *) n;
            }
-       | COMMENT ON COLUMN ColId '.' attr_name IS comment_text
-           {
-               /*
-                * We can't use qualified_name here as the '.' causes a shift/red; 
-                * with ColId we do not test for NEW and OLD as table names, but it is OK
-                * as they would fail anyway as COMMENT cannot appear in a RULE.
-                * ColumnRef is also innapropriate as we don't take subscripts
-                * or '*' and have a very precise number of elements (2 or 3)
-                * so we do it from scratch.
-                */
-               CommentStmt *n = makeNode(CommentStmt);
-               n->objtype = COLUMN;
-               n->objschema = NULL;
-               n->objname = $4;
-               n->objproperty = $6;
-               n->objlist = NULL;
-               n->comment = $8;
-               $$ = (Node *) n;
-           }
-       | COMMENT ON COLUMN ColId '.' ColId '.' attr_name IS comment_text
-           {
-               CommentStmt *n = makeNode(CommentStmt);
-               n->objtype = COLUMN;
-               n->objschema = $4;
-               n->objname = $6;
-               n->objproperty = $8;
-               n->objlist = NULL;
-               n->comment = $10;
-               $$ = (Node *) n;
-           }
        | COMMENT ON AGGREGATE func_name '(' aggr_argtype ')' IS comment_text
            {
                CommentStmt *n = makeNode(CommentStmt);
                n->objtype = AGGREGATE;
-               n->objschema = NULL;
                n->objname = $4;
-               n->objproperty = NULL;
-               n->objlist = makeList1($6);
+               n->objargs = makeList1($6);
                n->comment = $9;
                $$ = (Node *) n;
            }
@@ -2254,10 +2222,8 @@ CommentStmt: COMMENT ON comment_type name IS comment_text
            {
                CommentStmt *n = makeNode(CommentStmt);
                n->objtype = FUNCTION;
-               n->objschema = NULL;
                n->objname = $4;
-               n->objproperty = NULL;
-               n->objlist = $5;
+               n->objargs = $5;
                n->comment = $7;
                $$ = (Node *) n;
            }
@@ -2265,28 +2231,24 @@ CommentStmt:    COMMENT ON comment_type name IS comment_text
            {
                CommentStmt *n = makeNode(CommentStmt);
                n->objtype = OPERATOR;
-               n->objschema = NULL;
-               n->objname = $4;
-               n->objproperty = NULL;
-               n->objlist = $6;
+               n->objname = makeList1(makeString($4)); /* XXX */
+               n->objargs = $6;
                n->comment = $9;
                $$ = (Node *) n;
            }
-       | COMMENT ON TRIGGER name ON qualified_name IS comment_text
+       | COMMENT ON TRIGGER name ON any_name IS comment_text
            {
                CommentStmt *n = makeNode(CommentStmt);
                n->objtype = TRIGGER;
-               /* NOTE: schemaname here refers to the table in objproperty */
-               n->objschema = $6->schemaname;
-               n->objname = $4;
-               n->objproperty = $6->relname;
-               n->objlist = NULL;
+               n->objname = lappend($6, makeString($4));
+               n->objargs = NIL;
                n->comment = $8;
                $$ = (Node *) n;
            }
        ;
 
-comment_type:  DATABASE { $$ = DATABASE; }
+comment_type:  COLUMN { $$ = COLUMN; }
+       | DATABASE { $$ = DATABASE; }
        | INDEX { $$ = INDEX; }
        | RULE { $$ = RULE; }
        | SEQUENCE { $$ = SEQUENCE; }
@@ -2650,7 +2612,8 @@ index_list:  index_list ',' index_elem            { $$ = lappend($1, $3); }
 func_index:  func_name '(' name_list ')' opt_class
                {
                    $$ = makeNode(IndexElem);
-                   $$->name = $1;
+                   $$->name = NULL;
+                   $$->funcname = $1;
                    $$->args = $3;
                    $$->class = $5;
                }
@@ -2660,6 +2623,7 @@ index_elem:  attr_name opt_class
                {
                    $$ = makeNode(IndexElem);
                    $$->name = $1;
+                   $$->funcname = NIL;
                    $$->args = NIL;
                    $$->class = $2;
                }
@@ -2726,7 +2690,7 @@ ProcedureStmt:    CREATE opt_or_replace FUNCTION func_name func_args
                {
                    ProcedureStmt *n = makeNode(ProcedureStmt);
                    n->replace = $2;
-                   n->funcname = makeList1(makeString($4)); /* XXX */
+                   n->funcname = $4;
                    n->argTypes = $5;
                    n->returnType = $7;
                    n->withClause = $12;
@@ -4680,7 +4644,7 @@ row_expr: '(' row_descriptor ')' IN select_with_parens
                    FuncCall *n = makeNode(FuncCall);
                    List *largs = $2;
                    List *rargs = $6;
-                   n->funcname = xlateSqlFunc("overlaps");
+                   n->funcname = SystemFuncName("overlaps");
                    if (length(largs) == 1)
                        largs = lappend(largs, $2);
                    else if (length(largs) != 2)
@@ -4755,7 +4719,7 @@ a_expr:  c_expr
        | a_expr AT TIME ZONE c_expr
                {
                    FuncCall *n = makeNode(FuncCall);
-                   n->funcname = "timezone";
+                   n->funcname = SystemFuncName("timezone");
                    n->args = makeList2($5, $1);
                    n->agg_star = FALSE;
                    n->agg_distinct = FALSE;
@@ -4820,7 +4784,7 @@ a_expr:  c_expr
        | a_expr LIKE a_expr ESCAPE a_expr
                {
                    FuncCall *n = makeNode(FuncCall);
-                   n->funcname = "like_escape";
+                   n->funcname = SystemFuncName("like_escape");
                    n->args = makeList2($3, $5);
                    n->agg_star = FALSE;
                    n->agg_distinct = FALSE;
@@ -4831,7 +4795,7 @@ a_expr:  c_expr
        | a_expr NOT LIKE a_expr ESCAPE a_expr
                {
                    FuncCall *n = makeNode(FuncCall);
-                   n->funcname = "like_escape";
+                   n->funcname = SystemFuncName("like_escape");
                    n->args = makeList2($4, $6);
                    n->agg_star = FALSE;
                    n->agg_distinct = FALSE;
@@ -4842,7 +4806,7 @@ a_expr:  c_expr
        | a_expr ILIKE a_expr ESCAPE a_expr
                {
                    FuncCall *n = makeNode(FuncCall);
-                   n->funcname = "like_escape";
+                   n->funcname = SystemFuncName("like_escape");
                    n->args = makeList2($3, $5);
                    n->agg_star = FALSE;
                    n->agg_distinct = FALSE;
@@ -4853,7 +4817,7 @@ a_expr:  c_expr
        | a_expr NOT ILIKE a_expr ESCAPE a_expr
                {
                    FuncCall *n = makeNode(FuncCall);
-                   n->funcname = "like_escape";
+                   n->funcname = SystemFuncName("like_escape");
                    n->args = makeList2($4, $6);
                    n->agg_star = FALSE;
                    n->agg_distinct = FALSE;
@@ -5300,7 +5264,7 @@ c_expr:  columnref
        | CURRENT_USER opt_empty_parentheses
                {
                    FuncCall *n = makeNode(FuncCall);
-                   n->funcname = "current_user";
+                   n->funcname = SystemFuncName("current_user");
                    n->args = NIL;
                    n->agg_star = FALSE;
                    n->agg_distinct = FALSE;
@@ -5309,7 +5273,7 @@ c_expr:  columnref
        | SESSION_USER opt_empty_parentheses
                {
                    FuncCall *n = makeNode(FuncCall);
-                   n->funcname = "session_user";
+                   n->funcname = SystemFuncName("session_user");
                    n->args = NIL;
                    n->agg_star = FALSE;
                    n->agg_distinct = FALSE;
@@ -5318,7 +5282,7 @@ c_expr:  columnref
        | USER opt_empty_parentheses
                {
                    FuncCall *n = makeNode(FuncCall);
-                   n->funcname = "current_user";
+                   n->funcname = SystemFuncName("current_user");
                    n->args = NIL;
                    n->agg_star = FALSE;
                    n->agg_distinct = FALSE;
@@ -5327,7 +5291,7 @@ c_expr:  columnref
        | EXTRACT '(' extract_list ')'
                {
                    FuncCall *n = makeNode(FuncCall);
-                   n->funcname = "date_part";
+                   n->funcname = SystemFuncName("date_part");
                    n->args = $3;
                    n->agg_star = FALSE;
                    n->agg_distinct = FALSE;
@@ -5337,7 +5301,7 @@ c_expr:  columnref
                {
                    /* position(A in B) is converted to position(B, A) */
                    FuncCall *n = makeNode(FuncCall);
-                   n->funcname = "position";
+                   n->funcname = SystemFuncName("position");
                    n->args = $3;
                    n->agg_star = FALSE;
                    n->agg_distinct = FALSE;
@@ -5349,7 +5313,7 @@ c_expr:  columnref
                     * substring(A, B, C) - thomas 2000-11-28
                     */
                    FuncCall *n = makeNode(FuncCall);
-                   n->funcname = "substring";
+                   n->funcname = SystemFuncName("substring");
                    n->args = $3;
                    n->agg_star = FALSE;
                    n->agg_distinct = FALSE;
@@ -5361,7 +5325,7 @@ c_expr:  columnref
                     * - thomas 1997-07-19
                     */
                    FuncCall *n = makeNode(FuncCall);
-                   n->funcname = "btrim";
+                   n->funcname = SystemFuncName("btrim");
                    n->args = $4;
                    n->agg_star = FALSE;
                    n->agg_distinct = FALSE;
@@ -5370,7 +5334,7 @@ c_expr:  columnref
        | TRIM '(' LEADING trim_list ')'
                {
                    FuncCall *n = makeNode(FuncCall);
-                   n->funcname = "ltrim";
+                   n->funcname = SystemFuncName("ltrim");
                    n->args = $4;
                    n->agg_star = FALSE;
                    n->agg_distinct = FALSE;
@@ -5379,7 +5343,7 @@ c_expr:  columnref
        | TRIM '(' TRAILING trim_list ')'
                {
                    FuncCall *n = makeNode(FuncCall);
-                   n->funcname = "rtrim";
+                   n->funcname = SystemFuncName("rtrim");
                    n->args = $4;
                    n->agg_star = FALSE;
                    n->agg_distinct = FALSE;
@@ -5388,7 +5352,7 @@ c_expr:  columnref
        | TRIM '(' trim_list ')'
                {
                    FuncCall *n = makeNode(FuncCall);
-                   n->funcname = "btrim";
+                   n->funcname = SystemFuncName("btrim");
                    n->args = $3;
                    n->agg_star = FALSE;
                    n->agg_distinct = FALSE;
@@ -5798,19 +5762,11 @@ class:                  ColId           { $$ = $1; };
 index_name:                ColId           { $$ = $1; };
 file_name:             Sconst          { $$ = $1; };
 
-/* func_name will soon return a List ... but not yet */
-/*
 func_name: function_name
-           { $$ = makeList1(makeString($1)); }
+           { $$ = makeList1(makeString(xlateSqlFunc($1))); }
        | dotted_name
            { $$ = $1; }
        ;
-*/
-func_name: function_name
-           { $$ = $1; }
-       | dotted_name
-           { $$ = strVal(lfirst($1)); }
-       ;
 
 
 /* Constants
@@ -5942,9 +5898,9 @@ type_name:  IDENT                     { $$ = $1; }
 
 /* Function identifier --- names that can be function names.
  */
-function_name:  IDENT                  { $$ = xlateSqlFunc($1); }
-       | unreserved_keyword            { $$ = xlateSqlFunc($1); }
-       | func_name_keyword             { $$ = xlateSqlFunc($1); }
+function_name:  IDENT                  { $$ = $1; }
+       | unreserved_keyword            { $$ = $1; }
+       | func_name_keyword             { $$ = $1; }
        ;
 
 /* Column label --- allowed labels in "AS" clauses.
@@ -6459,6 +6415,8 @@ makeSetOp(SetOperation op, bool all, Node *larg, Node *rarg)
 /* xlateSqlFunc()
  * Convert alternate function names to internal Postgres functions.
  *
+ * NOTE: these conversions are only applied to unqualified function names.
+ *
  * Do not convert "float", since that is handled elsewhere
  *  for FLOAT(p) syntax.
  *
@@ -6482,6 +6440,8 @@ xlateSqlFunc(char *name)
 /* xlateSqlType()
  * Convert alternate type names to internal Postgres types.
  *
+ * NOTE: these conversions are only applied to unqualified type names.
+ *
  * NB: do NOT put "char" -> "bpchar" here, because that renders it impossible
  * to refer to our single-byte char type, even with quotes.  (Without quotes,
  * CHAR is a keyword, and the code above produces "bpchar" for it.)
@@ -6521,6 +6481,14 @@ xlateSqlType(char *name)
        return name;
 } /* xlateSqlType() */
 
+/* SystemFuncName()
+ * Build a properly-qualified reference to a built-in function.
+ */
+List *
+SystemFuncName(char *name)
+{
+   return makeList2(makeString("pg_catalog"), makeString(name));
+}
 
 void parser_init(Oid *typev, int nargs)
 {
index dc939a71801e129102ab62bd44bf5dbf35e7fec6..3812579a4dbbc9ec41380c8ad1507d80f04974ac 100644 (file)
@@ -8,12 +8,13 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/parser/parse_agg.c,v 1.47 2002/03/21 16:00:58 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/parser/parse_agg.c,v 1.48 2002/04/09 20:35:52 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
 
 #include "postgres.h"
+#include "catalog/namespace.h"
 #include "catalog/pg_aggregate.h"
 #include "optimizer/clauses.h"
 #include "optimizer/tlist.h"
@@ -187,7 +188,7 @@ parseCheckAggregates(ParseState *pstate, Query *qry, Node *qual)
 
 
 Aggref *
-ParseAgg(ParseState *pstate, char *aggname, Oid basetype,
+ParseAgg(ParseState *pstate, List *aggname, Oid basetype,
         List *args, bool agg_star, bool agg_distinct)
 {
    HeapTuple   aggtuple;
@@ -195,7 +196,7 @@ ParseAgg(ParseState *pstate, char *aggname, Oid basetype,
    Aggref     *aggref;
 
    aggtuple = SearchSysCache(AGGNAME,
-                             PointerGetDatum(aggname),
+                             PointerGetDatum(strVal(llast(aggname))),
                              ObjectIdGetDatum(basetype),
                              0, 0);
    /* shouldn't happen --- caller should have checked already */
@@ -218,7 +219,7 @@ ParseAgg(ParseState *pstate, char *aggname, Oid basetype,
     */
 
    aggref = makeNode(Aggref);
-   aggref->aggname = pstrdup(aggname);
+   aggref->aggname = pstrdup(strVal(llast(aggname)));
    aggref->basetype = aggform->aggbasetype;
    aggref->aggtype = aggform->aggfinaltype;
    aggref->target = lfirst(args);
@@ -237,7 +238,7 @@ ParseAgg(ParseState *pstate, char *aggname, Oid basetype,
  * basetype
  */
 void
-agg_error(char *caller, char *aggname, Oid basetypeID)
+agg_error(const char *caller, List *aggname, Oid basetypeID)
 {
    /*
     * basetypeID that is Invalid (zero) means aggregate over all types.
@@ -246,8 +247,8 @@ agg_error(char *caller, char *aggname, Oid basetypeID)
 
    if (basetypeID == InvalidOid)
        elog(ERROR, "%s: aggregate '%s' for all types does not exist",
-            caller, aggname);
+            caller, NameListToString(aggname));
    else
        elog(ERROR, "%s: aggregate '%s' for type %s does not exist",
-            caller, aggname, format_type_be(basetypeID));
+            caller, NameListToString(aggname), format_type_be(basetypeID));
 }
index 690a047915ac202cfb32e4aabe6fe99cd1c288a5..4dd5777e1e11f6c9b5ddd01f4d0961d258f43dc4 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/parser/parse_coerce.c,v 2.68 2002/03/20 19:44:22 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/parser/parse_coerce.c,v 2.69 2002/04/09 20:35:52 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -657,7 +657,8 @@ PreferredType(CATEGORY category, Oid type)
  *     Look for a coercion function between two types.
  *
  * A coercion function must be named after (the internal name of) its
- * result type, and must accept exactly the specified input type.
+ * result type, and must accept exactly the specified input type.  We
+ * also require it to be defined in the same namespace as its result type.
  *
  * This routine is also used to look for length-coercion functions, which
  * are similar but accept a second argument.  secondArgType is the type
@@ -669,14 +670,19 @@ PreferredType(CATEGORY category, Oid type)
 static Oid
 find_coercion_function(Oid targetTypeId, Oid inputTypeId, Oid secondArgType)
 {
-   char       *funcname;
+   Type        targetType;
+   char       *typname;
+   Oid         typnamespace;
    Oid         oid_array[FUNC_MAX_ARGS];
    int         nargs;
    HeapTuple   ftup;
    Form_pg_proc pform;
    Oid         funcid;
 
-   funcname = typeidTypeName(targetTypeId);
+   targetType = typeidType(targetTypeId);
+   typname = NameStr(((Form_pg_type) GETSTRUCT(targetType))->typname);
+   typnamespace = ((Form_pg_type) GETSTRUCT(targetType))->typnamespace;
+
    MemSet(oid_array, 0, FUNC_MAX_ARGS * sizeof(Oid));
    oid_array[0] = inputTypeId;
    if (OidIsValid(secondArgType))
@@ -687,22 +693,27 @@ find_coercion_function(Oid targetTypeId, Oid inputTypeId, Oid secondArgType)
    else
        nargs = 1;
 
-   ftup = SearchSysCache(PROCNAME,
-                         PointerGetDatum(funcname),
-                         Int32GetDatum(nargs),
+   ftup = SearchSysCache(PROCNAMENSP,
+                         CStringGetDatum(typname),
+                         Int16GetDatum(nargs),
                          PointerGetDatum(oid_array),
-                         0);
+                         ObjectIdGetDatum(typnamespace));
    if (!HeapTupleIsValid(ftup))
+   {
+       ReleaseSysCache(targetType);
        return InvalidOid;
+   }
    /* Make sure the function's result type is as expected, too */
    pform = (Form_pg_proc) GETSTRUCT(ftup);
    if (pform->prorettype != targetTypeId)
    {
        ReleaseSysCache(ftup);
+       ReleaseSysCache(targetType);
        return InvalidOid;
    }
    funcid = ftup->t_data->t_oid;
    ReleaseSysCache(ftup);
+   ReleaseSysCache(targetType);
    return funcid;
 }
 
index 2a5a7698d858fd0c4705785a663870784b2afa6d..f84497160613e6e6bb47cbc92ea951a083f8d507 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.112 2002/03/29 19:06:11 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.113 2002/04/09 20:35:52 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -129,7 +129,8 @@ transformExpr(ParseState *pstate, Node *expr)
                /* handle qualification, if any */
                foreach(fields, pref->fields)
                {
-                   result = ParseFuncOrColumn(pstate, strVal(lfirst(fields)),
+                   result = ParseFuncOrColumn(pstate,
+                                              makeList1(lfirst(fields)),
                                               makeList1(result),
                                               false, false, true);
                }
@@ -158,7 +159,8 @@ transformExpr(ParseState *pstate, Node *expr)
                /* handle qualification, if any */
                foreach(fields, efs->fields)
                {
-                   result = ParseFuncOrColumn(pstate, strVal(lfirst(fields)),
+                   result = ParseFuncOrColumn(pstate,
+                                              makeList1(lfirst(fields)),
                                               makeList1(result),
                                               false, false, true);
                }
@@ -728,7 +730,8 @@ transformColumnRef(ParseState *pstate, ColumnRef *cref)
                rv = makeNode(RangeVar);
                rv->relname = name1;
                rv->inhOpt = INH_DEFAULT;
-               node = ParseFuncOrColumn(pstate, name2,
+               node = ParseFuncOrColumn(pstate,
+                                        makeList1(makeString(name2)),
                                         makeList1(rv),
                                         false, false, true);
            }
@@ -761,7 +764,8 @@ transformColumnRef(ParseState *pstate, ColumnRef *cref)
                rv->schemaname = name1;
                rv->relname = name2;
                rv->inhOpt = INH_DEFAULT;
-               node = ParseFuncOrColumn(pstate, name3,
+               node = ParseFuncOrColumn(pstate,
+                                        makeList1(makeString(name3)),
                                         makeList1(rv),
                                         false, false, true);
            }
@@ -801,7 +805,8 @@ transformColumnRef(ParseState *pstate, ColumnRef *cref)
                rv->schemaname = name2;
                rv->relname = name3;
                rv->inhOpt = INH_DEFAULT;
-               node = ParseFuncOrColumn(pstate, name4,
+               node = ParseFuncOrColumn(pstate,
+                                        makeList1(makeString(name4)),
                                         makeList1(rv),
                                         false, false, true);
            }
index 578402fd255293543a98abaa3275fa5444498b2c..a86195126ffafc29dcb6ab59ebd6c26d8492d8b5 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.124 2002/04/06 06:59:22 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.125 2002/04/09 20:35:53 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -54,7 +54,7 @@ static int match_argtypes(int nargs,
 static FieldSelect *setup_field_select(Node *input, char *attname, Oid relid);
 static FuncCandidateList func_select_candidate(int nargs, Oid *input_typeids,
                                  FuncCandidateList candidates);
-static int agg_get_candidates(char *aggname, Oid typeId,
+static int agg_get_candidates(List *aggname, Oid typeId,
                               FuncCandidateList *candidates);
 static Oid agg_select_candidate(Oid typeid, FuncCandidateList candidates);
 
@@ -64,22 +64,22 @@ static Oid  agg_select_candidate(Oid typeid, FuncCandidateList candidates);
  *
  * For historical reasons, Postgres tries to treat the notations tab.col
  * and col(tab) as equivalent: if a single-argument function call has an
- * argument of complex type and the function name matches any attribute
- * of the type, we take it as a column projection.
+ * argument of complex type and the (unqualified) function name matches
+ * any attribute of the type, we take it as a column projection.
  *
  * Hence, both cases come through here.  The is_column parameter tells us
  * which syntactic construct is actually being dealt with, but this is
  * intended to be used only to deliver an appropriate error message,
  * not to affect the semantics.  When is_column is true, we should have
- * a single argument (the putative table), function name equal to the
- * column name, and no aggregate decoration.
+ * a single argument (the putative table), unqualified function name
+ * equal to the column name, and no aggregate decoration.
  *
  * In the function-call case, the argument expressions have been transformed
  * already.  In the column case, we may get either a transformed expression
  * or a RangeVar node as argument.
  */
 Node *
-ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
+ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs,
                  bool agg_star, bool agg_distinct, bool is_column)
 {
    Oid         rettype;
@@ -113,23 +113,28 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
    {
        first_arg = lfirst(fargs);
        if (first_arg == NULL)  /* should not happen */
-           elog(ERROR, "Function '%s' does not allow NULL input", funcname);
+           elog(ERROR, "Function '%s' does not allow NULL input",
+                NameListToString(funcname));
    }
 
    /*
     * check for column projection: if function has one argument, and that
-    * argument is of complex type, then the function could be a projection.
+    * argument is of complex type, and function name is not qualified,
+    * then the "function call" could be a projection.  We also check
+    * that there wasn't any aggregate decoration.
     */
-   /* We only have one parameter, and it's not got aggregate decoration */
-   if (nargs == 1 && !must_be_agg)
+   if (nargs == 1 && !must_be_agg && length(funcname) == 1)
    {
+       char       *cname = strVal(lfirst(funcname));
+
        /* Is it a not-yet-transformed RangeVar node? */
        if (IsA(first_arg, RangeVar))
        {
            /* First arg is a relation. This could be a projection. */
            refname = ((RangeVar *) first_arg)->relname;
 
-           retval = qualifiedNameToVar(pstate, refname, funcname, true);
+           /* XXX WRONG: ignores possible qualification of argument */
+           retval = qualifiedNameToVar(pstate, refname, cname, true);
            if (retval)
                return retval;
        }
@@ -140,9 +145,7 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
             * ParseComplexProjection can't handle the projection, we have
             * to keep going.
             */
-           retval = ParseComplexProjection(pstate,
-                                           funcname,
-                                           first_arg);
+           retval = ParseComplexProjection(pstate, cname, first_arg);
            if (retval)
                return retval;
        }
@@ -175,7 +178,7 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
 
        /* try for exact match first... */
        if (SearchSysCacheExists(AGGNAME,
-                                PointerGetDatum(funcname),
+                                PointerGetDatum(strVal(llast(funcname))),
                                 ObjectIdGetDatum(basetype),
                                 0, 0))
            return (Node *) ParseAgg(pstate, funcname, basetype,
@@ -183,7 +186,7 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
 
        /* check for aggregate-that-accepts-any-type (eg, COUNT) */
        if (SearchSysCacheExists(AGGNAME,
-                                PointerGetDatum(funcname),
+                                PointerGetDatum(strVal(llast(funcname))),
                                 ObjectIdGetDatum(0),
                                 0, 0))
            return (Node *) ParseAgg(pstate, funcname, 0,
@@ -211,7 +214,7 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
            {
                /* Multiple possible matches --- give up */
                elog(ERROR, "Unable to select an aggregate function %s(%s)",
-                    funcname, format_type_be(basetype));
+                    NameListToString(funcname), format_type_be(basetype));
            }
        }
 
@@ -222,7 +225,7 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
             * function could not have been meant.
             */
            elog(ERROR, "There is no aggregate function %s(%s)",
-                funcname, format_type_be(basetype));
+                NameListToString(funcname), format_type_be(basetype));
        }
    }
 
@@ -275,7 +278,7 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
                 */
                if (is_column)
                    elog(ERROR, "No such attribute %s.%s",
-                        refname, funcname);
+                        refname, strVal(lfirst(funcname)));
                else
                {
                    elog(ERROR, "Cannot pass result of sub-select or join %s to a function",
@@ -329,7 +332,8 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
         * give an error message that is appropriate for that case.
         */
        if (is_column)
-           elog(ERROR, "Attribute \"%s\" not found", funcname);
+           elog(ERROR, "Attribute \"%s\" not found",
+                strVal(lfirst(funcname)));
        /* Else generate a detailed complaint */
        func_error(NULL, funcname, nargs, oid_array,
                   "Unable to identify a function that satisfies the "
@@ -373,7 +377,7 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
 
 
 static int
-agg_get_candidates(char *aggname,
+agg_get_candidates(List *aggname,
                   Oid typeId,
                   FuncCandidateList *candidates)
 {
@@ -388,7 +392,7 @@ agg_get_candidates(char *aggname,
    ScanKeyEntryInitialize(&aggKey[0], 0,
                           Anum_pg_aggregate_aggname,
                           F_NAMEEQ,
-                          NameGetDatum(aggname));
+                          NameGetDatum(strVal(llast(aggname))));
 
    pg_aggregate_desc = heap_openr(AggregateRelationName, AccessShareLock);
    pg_aggregate_scan = systable_beginscan(pg_aggregate_desc,
@@ -862,7 +866,7 @@ func_select_candidate(int nargs,
  *  d) if the answer is zero, try the next array from vector #1
  */
 FuncDetailCode
-func_get_detail(char *funcname,
+func_get_detail(List *funcname,
                List *fargs,
                int nargs,
                Oid *argtypes,
@@ -875,7 +879,7 @@ func_get_detail(char *funcname,
    FuncCandidateList best_candidate;
 
    /* Get list of possible candidates from namespace search */
-   function_typeids = FuncnameGetCandidates(makeList1(makeString(funcname)), nargs);
+   function_typeids = FuncnameGetCandidates(funcname, nargs);
 
    /*
     * See if there is an exact match
@@ -917,15 +921,11 @@ func_get_detail(char *funcname,
        if (nargs == 1)
        {
            Oid         targetType;
+           TypeName   *tn = makeNode(TypeName);
 
-           /* XXX WRONG: need to search searchpath for name; but little
-            * point in fixing before we revise this code for qualified
-            * funcnames too.
-            */
-           targetType = GetSysCacheOid(TYPENAMENSP,
-                                       PointerGetDatum(funcname),
-                                       ObjectIdGetDatum(PG_CATALOG_NAMESPACE),
-                                       0, 0);
+           tn->names = funcname;
+           tn->typmod = -1;
+           targetType = LookupTypeName(tn);
            if (OidIsValid(targetType) &&
                !ISCOMPLEX(targetType))
            {
@@ -1409,7 +1409,7 @@ ParseComplexProjection(ParseState *pstate,
  * argument types
  */
 void
-func_error(const char *caller, const char *funcname,
+func_error(const char *caller, List *funcname,
           int nargs, const Oid *argtypes,
           const char *msg)
 {
@@ -1439,13 +1439,87 @@ func_error(const char *caller, const char *funcname,
    if (caller == NULL)
    {
        elog(ERROR, "Function '%s(%s)' does not exist%s%s",
-            funcname, p,
+            NameListToString(funcname), p,
             ((msg != NULL) ? "\n\t" : ""), ((msg != NULL) ? msg : ""));
    }
    else
    {
        elog(ERROR, "%s: function '%s(%s)' does not exist%s%s",
-            caller, funcname, p,
+            caller, NameListToString(funcname), p,
             ((msg != NULL) ? "\n\t" : ""), ((msg != NULL) ? msg : ""));
    }
 }
+
+/*
+ * LookupFuncName
+ *     Given a possibly-qualified function name and a set of argument types,
+ *     look up the function.  Returns InvalidOid if no such function.
+ *
+ * If the function name is not schema-qualified, it is sought in the current
+ * namespace search path.
+ */
+Oid
+LookupFuncName(List *funcname, int nargs, const Oid *argtypes)
+{
+   FuncCandidateList clist;
+
+   clist = FuncnameGetCandidates(funcname, nargs);
+
+   while (clist)
+   {
+       if (memcmp(argtypes, clist->args, nargs * sizeof(Oid)) == 0)
+           return clist->oid;
+       clist = clist->next;
+   }
+
+   return InvalidOid;
+}
+
+/*
+ * LookupFuncNameTypeNames
+ *     Like LookupFuncName, but the argument types are specified by a
+ *     list of TypeName nodes.  Also, if we fail to find the function
+ *     and caller is not NULL, then an error is reported via func_error.
+ *
+ * "opaque" is accepted as a typename only if opaqueOK is true.
+ */
+Oid
+LookupFuncNameTypeNames(List *funcname, List *argtypes, bool opaqueOK,
+                       const char *caller)
+{
+   Oid     funcoid;
+   Oid     argoids[FUNC_MAX_ARGS];
+   int     argcount;
+   int     i;
+
+   MemSet(argoids, 0, FUNC_MAX_ARGS * sizeof(Oid));
+   argcount = length(argtypes);
+   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(argtypes);
+
+       argoids[i] = LookupTypeName(t);
+       if (!OidIsValid(argoids[i]))
+       {
+           char      *typnam = TypeNameToString(t);
+
+           if (opaqueOK && strcmp(typnam, "opaque") == 0)
+               argoids[i] = InvalidOid;
+           else
+               elog(ERROR, "Type \"%s\" does not exist", typnam);
+       }
+
+       argtypes = lnext(argtypes);
+   }
+
+   funcoid = LookupFuncName(funcname, argcount, argoids);
+
+   if (!OidIsValid(funcoid) && caller != NULL)
+       func_error(caller, funcname, argcount, argoids, NULL);
+
+   return funcoid;
+}
index e8e82a45c3b9d09ee65388eab049546bae5eed50..83c53de5d1d7aeea8c25646fdc4e15dfccb2d8bd 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/parser/parse_target.c,v 1.82 2002/04/05 11:56:53 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/parser/parse_target.c,v 1.83 2002/04/09 20:35:53 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -498,48 +498,34 @@ FigureColnameInternal(Node *node, char **name)
            return 2;
        case T_ColumnRef:
            {
-               List       *fields = ((ColumnRef *) node)->fields;
+               char     *cname = strVal(llast(((ColumnRef *) node)->fields));
 
-               while (lnext(fields) != NIL)
-                   fields = lnext(fields);
-               if (strcmp(strVal(lfirst(fields)), "*") != 0)
+               if (strcmp(cname, "*") != 0)
                {
-                   *name = strVal(lfirst(fields));
+                   *name = cname;
                    return 2;
                }
            }
            break;
        case T_ExprFieldSelect:
            {
-               List       *fields = ((ExprFieldSelect *) node)->fields;
+               char     *fname = strVal(llast(((ExprFieldSelect *) node)->fields));
 
-               if (fields)
+               if (strcmp(fname, "*") != 0)
                {
-                   while (lnext(fields) != NIL)
-                       fields = lnext(fields);
-                   if (strcmp(strVal(lfirst(fields)), "*") != 0)
-                   {
-                       *name = strVal(lfirst(fields));
-                       return 2;
-                   }
+                   *name = fname;
+                   return 2;
                }
            }
            break;
        case T_FuncCall:
-           *name = ((FuncCall *) node)->funcname;
+           *name = strVal(llast(((FuncCall *) node)->funcname));
            return 2;
        case T_A_Const:
            if (((A_Const *) node)->typename != NULL)
            {
-               List       *names = ((A_Const *) node)->typename->names;
-
-               if (names != NIL)
-               {
-                   while (lnext(names) != NIL)
-                       names = lnext(names);
-                   *name = strVal(lfirst(names));
-                   return 1;
-               }
+               *name = strVal(llast(((A_Const *) node)->typename->names));
+               return 1;
            }
            break;
        case T_TypeCast:
@@ -549,15 +535,8 @@ FigureColnameInternal(Node *node, char **name)
            {
                if (((TypeCast *) node)->typename != NULL)
                {
-                   List       *names = ((TypeCast *) node)->typename->names;
-
-                   if (names != NIL)
-                   {
-                       while (lnext(names) != NIL)
-                           names = lnext(names);
-                       *name = strVal(lfirst(names));
-                       return 1;
-                   }
+                   *name = strVal(llast(((TypeCast *) node)->typename->names));
+                   return 1;
                }
            }
            break;
index bd5e31666ca9c70c8489fccbcd2b98303b551d95..ed87b00b75783e2ea5b010783267444164cbc64b 100644 (file)
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.145 2002/04/01 04:35:39 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.146 2002/04/09 20:35:53 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -345,12 +345,7 @@ ProcessUtility(Node *parsetree,
            break;
 
        case T_CommentStmt:
-           {
-               CommentStmt *stmt = (CommentStmt *) parsetree;
-
-               CommentObject(stmt->objtype, stmt->objschema, stmt->objname,
-                             stmt->objproperty, stmt->objlist, stmt->comment);
-           }
+           CommentObject((CommentStmt *) parsetree);
            break;
 
        case T_CopyStmt:
index 7e6a95a324e464a932a7855edec6c0e037057f3d..36535bd7fa92d70764bb0b0e330a12b57c0e73ed 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.74 2002/04/06 06:59:23 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.75 2002/04/09 20:35:54 tgl Exp $
  *
  * NOTES
  *   These routines allow the parser/planner/executor to perform
@@ -303,15 +303,15 @@ static const struct cachedesc cacheinfo[] = {
            0,
            0
    }},
-   {ProcedureRelationName,     /* PROCNAME */
-       ProcedureNameNspIndex,  /* XXX very temporary */
+   {ProcedureRelationName,     /* PROCNAMENSP */
+       ProcedureNameNspIndex,
        0,
-       3,
+       4,
        {
            Anum_pg_proc_proname,
            Anum_pg_proc_pronargs,
            Anum_pg_proc_proargtypes,
-           0
+           Anum_pg_proc_pronamespace
    }},
    {ProcedureRelationName,     /* PROCOID */
        ProcedureOidIndex,
index 4c81e78f3ffbe3699bf638798a7ec84679a46046..15a21e77d5d76b3193526cb3f27bbdaf068bc93e 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: namespace.h,v 1.6 2002/04/06 06:59:24 tgl Exp $
+ * $Id: namespace.h,v 1.7 2002/04/09 20:35:54 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -47,6 +47,8 @@ extern Oid    QualifiedNameGetCreationNamespace(List *names, char **objname_p);
 
 extern RangeVar *makeRangeVarFromNameList(List *names);
 
+extern char *NameListToString(List *names);
+
 extern bool isTempNamespace(Oid namespaceId);
 
 /* stuff for search_path GUC variable */
index 65494e8afe200fe83d7489414196c2069dc1299f..3d44f4c4c0fb6389cddc3891e7a30ecd0bb2093a 100644 (file)
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: pg_aggregate.h,v 1.36 2002/03/29 19:06:18 tgl Exp $
+ * $Id: pg_aggregate.h,v 1.37 2002/04/09 20:35:54 tgl Exp $
  *
  * NOTES
  *   the genbki.sh script reads this file and generates .bki
@@ -157,8 +157,8 @@ DATA(insert OID = 0 ( stddev    PGUID numeric_accum  numeric_stddev     1700 1231 1700
  */
 extern void AggregateCreate(const char *aggName,
                            Oid aggNamespace,
-                           char *aggtransfnName,
-                           char *aggfinalfnName,
+                           List *aggtransfnName,
+                           List *aggfinalfnName,
                            Oid aggBaseType,
                            Oid aggTransType,
                            const char *agginitval);
index f1e9a760b0b08f60f61b9ecb1e0b31acbe01ca34..bf2acfcfa0ed9479f862b2247b0749b179c4a09f 100644 (file)
@@ -12,7 +12,7 @@
 #ifndef COMMENT_H
 #define COMMENT_H
 
-#include "nodes/pg_list.h"
+#include "nodes/parsenodes.h"
 
 /*------------------------------------------------------------------
  * Function Prototypes --
@@ -25,8 +25,7 @@
  *------------------------------------------------------------------
  */
 
-extern void CommentObject(int objtype, char * schemaname, char *objname,
-                           char *objproperty, List *objlist, char *comment);
+extern void CommentObject(CommentStmt *stmt);
 
 extern void DeleteComments(Oid oid, Oid classoid);
 
index 69f180ec1622e9afe80796a77882ec390fcfcd9c..83b8fec6d77cb05cc6e06f9561186fcf7231181d 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: defrem.h,v 1.33 2002/03/29 19:06:22 tgl Exp $
+ * $Id: defrem.h,v 1.34 2002/04/09 20:35:54 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -45,10 +45,10 @@ extern void DefineDomain(CreateDomainStmt *stmt);
  * prototypes in remove.c
  */
 extern void RemoveDomain(List *names, int behavior);
-extern void RemoveFunction(char *functionName, List *argTypes);
+extern void RemoveFunction(List *functionName, List *argTypes);
 extern void RemoveOperator(char *operatorName,
               TypeName *typeName1, TypeName *typeName2);
 extern void RemoveType(List *names);
-extern void RemoveAggregate(char *aggName, TypeName *aggType);
+extern void RemoveAggregate(List *aggName, TypeName *aggType);
 
 #endif   /* DEFREM_H */
index e2b0d9f38f3d43b1d060a16d732e8e1814890a1a..6fc2fec9ad952d677b1edcc36e5f269465eaf1f1 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: parsenodes.h,v 1.168 2002/04/05 11:56:54 momjian Exp $
+ * $Id: parsenodes.h,v 1.169 2002/04/09 20:35:54 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -304,7 +304,7 @@ typedef struct Ident
 typedef struct FuncCall
 {
    NodeTag     type;
-   char       *funcname;       /* name of function */
+   List       *funcname;       /* qualified name of function */
    List       *args;           /* the arguments (list of exprs) */
    bool        agg_star;       /* argument was really '*' */
    bool        agg_distinct;   /* arguments were labeled DISTINCT */
@@ -390,15 +390,16 @@ typedef struct RangeSubselect
 /*
  * IndexElem - index parameters (used in CREATE INDEX)
  *
- * For a plain index, each 'name' is an attribute name in the heap relation,
- * and 'args' is NIL.  For a functional index, only one IndexElem is allowed.
- * It has name = name of function and args = list of attribute names that
- * are the function's arguments.
+ * For a plain index, each 'name' is an attribute name in the heap relation;
+ * 'funcname' and 'args' are NIL.  For a functional index, only one IndexElem
+ * is allowed.  It has name = NULL, funcname = name of function and args =
+ * list of attribute names that are the function's arguments.
  */
 typedef struct IndexElem
 {
    NodeTag     type;
-   char       *name;           /* name of attribute to index, or function */
+   char       *name;           /* name of attribute to index, or NULL */
+   List       *funcname;       /* qualified name of function */
    List       *args;           /* list of names of function arguments */
    char       *class;          /* name of desired opclass; NULL = default */
 } IndexElem;
@@ -780,7 +781,7 @@ typedef struct PrivGrantee
 typedef struct FuncWithArgs
 {
    NodeTag     type;
-   char       *funcname;
+   List       *funcname;       /* qualified name of function */
    List       *funcargs;       /* list of Typename nodes */
 } FuncWithArgs;
 
@@ -919,10 +920,10 @@ typedef struct FkConstraint
 typedef struct CreateTrigStmt
 {
    NodeTag     type;
-   char       *trigname;       /* TRIGGER' name */
-   RangeVar   *relation;       /* triggered relation */
-   char       *funcname;       /* function to call (or NULL) */
-   List       *args;           /* list of (T_String) Values or NULL */
+   char       *trigname;       /* TRIGGER's name */
+   RangeVar   *relation;       /* relation trigger is on */
+   List       *funcname;       /* qual. name of function to call */
+   List       *args;           /* list of (T_String) Values or NIL */
    bool        before;         /* BEFORE/AFTER */
    bool        row;            /* ROW/STATEMENT */
    char        actions[4];     /* Insert, Update, Delete */
@@ -954,7 +955,7 @@ typedef struct CreatePLangStmt
 {
    NodeTag     type;
    char       *plname;         /* PL name */
-   char       *plhandler;      /* PL call handler function */
+   List       *plhandler;      /* PL call handler function (qual. name) */
    char       *plcompiler;     /* lancompiler text */
    bool        pltrusted;      /* PL is trusted */
 } CreatePLangStmt;
@@ -1097,12 +1098,9 @@ typedef struct CommentStmt
 {
    NodeTag     type;
    int         objtype;        /* Object's type */
-   char       *objschema;      /* Schema where object is defined,
-                                * if object is schema specific */
-   char       *objname;        /* Name of the object */
-   char       *objproperty;    /* Property Id (such as column) */
-   List       *objlist;        /* Arguments for VAL objects */
-   char       *comment;        /* The comment to insert */
+   List       *objname;        /* Qualified name of the object */
+   List       *objargs;        /* Arguments if needed (eg, for functions) */
+   char       *comment;        /* Comment to insert, or NULL to remove */
 } CommentStmt;
 
 /* ----------------------
@@ -1154,7 +1152,7 @@ typedef struct ProcedureStmt
 {
    NodeTag     type;
    bool        replace;        /* T => replace if already exists */
-   List       *funcname;       /* name of function to create */
+   List       *funcname;       /* qualified name of function to create */
    List       *argTypes;       /* list of argument types (TypeName nodes) */
    TypeName   *returnType;     /* the return type */
    List       *withClause;     /* a list of DefElem */
@@ -1169,7 +1167,7 @@ typedef struct ProcedureStmt
 typedef struct RemoveAggrStmt
 {
    NodeTag     type;
-   char       *aggname;        /* aggregate to drop */
+   List       *aggname;        /* aggregate to drop */
    TypeName   *aggtype;        /* TypeName for input datatype, or NULL */
 } RemoveAggrStmt;
 
@@ -1180,7 +1178,7 @@ typedef struct RemoveAggrStmt
 typedef struct RemoveFuncStmt
 {
    NodeTag     type;
-   char       *funcname;       /* function to drop */
+   List       *funcname;       /* function to drop */
    List       *args;           /* types of the arguments */
 } RemoveFuncStmt;
 
index 6b224d6c3859b189d8d1af989222a999c09d56b8..722fb772916a404e04c387b908c5930ed8130856 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: pg_list.h,v 1.26 2001/11/05 17:46:34 momjian Exp $
+ * $Id: pg_list.h,v 1.27 2002/04/09 20:35:55 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -109,6 +109,8 @@ typedef struct List
  * function prototypes in nodes/list.c
  */
 extern int length(List *list);
+extern void *llast(List *list);
+extern int llasti(List *list);
 extern List *nconc(List *list1, List *list2);
 extern List *lcons(void *datum, List *list);
 extern List *lconsi(int datum, List *list);
index a9932ab59a041d184f764af8e56dece2b602df5f..42ae42d9e63b084e5d3db3fb6f2821d71d197e3a 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: gramparse.h,v 1.19 2001/11/05 17:46:34 momjian Exp $
+ * $Id: gramparse.h,v 1.20 2002/04/09 20:35:55 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -29,6 +29,7 @@ extern Oid    param_type(int t);
 extern int yyparse(void);
 extern char *xlateSqlFunc(char *name);
 extern char *xlateSqlType(char *name);
+extern List *SystemFuncName(char *name);
 bool       exprIsNullConstant(Node *arg);
 
 #endif   /* GRAMPARSE_H */
index 666e4ede7645706e5b8acc3b434534bba5956b0f..03ac8dc64622e243829dbab8cf41bfadaa2b67db 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: parse_agg.h,v 1.21 2002/03/21 16:01:55 tgl Exp $
+ * $Id: parse_agg.h,v 1.22 2002/04/09 20:35:55 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -18,8 +18,8 @@
 
 extern void AddAggToParseState(ParseState *pstate, Aggref *aggref);
 extern void parseCheckAggregates(ParseState *pstate, Query *qry, Node *qual);
-extern Aggref *ParseAgg(ParseState *pstate, char *aggname, Oid basetype,
+extern Aggref *ParseAgg(ParseState *pstate, List *aggname, Oid basetype,
         List *args, bool agg_star, bool agg_distinct);
-extern void agg_error(char *caller, char *aggname, Oid basetypeID);
+extern void agg_error(const char *caller, List *aggname, Oid basetypeID);
 
 #endif   /* PARSE_AGG_H */
index 01e5b16e2b5d54a88c91a8c44778263559726471..3a7641e1de7a18d4deb127fe8a261145392cc435 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: parse_func.h,v 1.37 2002/03/29 19:06:24 tgl Exp $
+ * $Id: parse_func.h,v 1.38 2002/04/09 20:35:55 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -48,18 +48,22 @@ typedef enum
 
 
 extern Node *ParseFuncOrColumn(ParseState *pstate,
-                 char *funcname, List *fargs,
+                 List *funcname, List *fargs,
                  bool agg_star, bool agg_distinct, bool is_column);
 
-extern FuncDetailCode func_get_detail(char *funcname, List *fargs,
+extern FuncDetailCode func_get_detail(List *funcname, List *fargs,
                int nargs, Oid *argtypes,
                Oid *funcid, Oid *rettype,
                bool *retset, Oid **true_typeids);
 
 extern bool typeInheritsFrom(Oid subclassTypeId, Oid superclassTypeId);
 
-extern void func_error(const char *caller, const char *funcname,
+extern void func_error(const char *caller, List *funcname,
                       int nargs, const Oid *argtypes,
                       const char *msg);
 
+extern Oid LookupFuncName(List *funcname, int nargs, const Oid *argtypes);
+extern Oid LookupFuncNameTypeNames(List *funcname, List *argtypes,
+                                   bool opaqueOK, const char *caller);
+
 #endif   /* PARSE_FUNC_H */
index 1d9ddd9acfd8f37173802ac48e0889947c4f0d08..365d9efdb5d4d92bbdd514b7a85f0ea77e77b0c9 100644 (file)
@@ -9,7 +9,7 @@
  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: syscache.h,v 1.42 2002/04/06 06:59:25 tgl Exp $
+ * $Id: syscache.h,v 1.43 2002/04/09 20:35:55 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -49,7 +49,7 @@
 #define NAMESPACEOID   18
 #define OPERNAME       19
 #define OPEROID            20
-#define PROCNAME       21
+#define PROCNAMENSP        21
 #define PROCOID            22
 #define RELNAMENSP     23
 #define RELOID         24
index 6c9b84dda2b8f56a4d63deec162b66c41300679d..ab4db0d93ef345673bfaaad954b30ce7f6dc0423 100644 (file)
@@ -205,7 +205,7 @@ GRANT USAGE ON FUNCTION testfunc1(int) TO regressuser3; -- semantic error
 ERROR:  invalid privilege type USAGE for function object
 GRANT ALL PRIVILEGES ON FUNCTION testfunc1(int) TO regressuser4;
 GRANT ALL PRIVILEGES ON FUNCTION testfunc_nosuch(int) TO regressuser4;
-ERROR:  Function 'testfunc_nosuch(int4)' does not exist
+ERROR:  GRANT: function 'testfunc_nosuch(int4)' does not exist
 SET SESSION AUTHORIZATION regressuser2;
 SELECT testfunc1(5), testfunc2(5); -- ok
  testfunc1 | testfunc2