Commit f2d70d32 authored by Tom Lane's avatar Tom Lane

Functions live in namespaces. Qualified function names work, eg

SELECT schema1.func2(...).  Aggregate names can be qualified at the
syntactic level, but the qualification is ignored for the moment.
parent c419c224
......@@ -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;
}
......
......@@ -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))
......
......@@ -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?
*/
......
......@@ -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);
......
......@@ -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);
......
......@@ -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))
{
......
This diff is collapsed.
......@@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/define.c,v 1.73 2002/04/05 00:31:25 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/define.c,v 1.74 2002/04/09 20:35:47 tgl Exp $
*
* DESCRIPTION
* The "DefineFoo" routines take the parse tree and pick out the
......@@ -60,9 +60,10 @@
#include "utils/syscache.h"
static Oid findTypeIOFunction(const char *procname, bool isOutput);
static Oid findTypeIOFunction(List *procname, bool isOutput);
static char *defGetString(DefElem *def);
static double defGetNumeric(DefElem *def);
static List *defGetQualifiedName(DefElem *def);
static TypeName *defGetTypeName(DefElem *def);
static int defGetTypeLength(DefElem *def);
......@@ -474,8 +475,8 @@ DefineAggregate(List *names, List *parameters)
{
char *aggName;
Oid aggNamespace;
char *transfuncName = NULL;
char *finalfuncName = NULL;
List *transfuncName = NIL;
List *finalfuncName = NIL;
TypeName *baseType = NULL;
TypeName *transType = NULL;
char *initval = NULL;
......@@ -495,11 +496,11 @@ DefineAggregate(List *names, List *parameters)
* spellings for sfunc, stype, initcond.
*/
if (strcasecmp(defel->defname, "sfunc") == 0)
transfuncName = defGetString(defel);
transfuncName = defGetQualifiedName(defel);
else if (strcasecmp(defel->defname, "sfunc1") == 0)
transfuncName = defGetString(defel);
transfuncName = defGetQualifiedName(defel);
else if (strcasecmp(defel->defname, "finalfunc") == 0)
finalfuncName = defGetString(defel);
finalfuncName = defGetQualifiedName(defel);
else if (strcasecmp(defel->defname, "basetype") == 0)
baseType = defGetTypeName(defel);
else if (strcasecmp(defel->defname, "stype") == 0)
......@@ -522,7 +523,7 @@ DefineAggregate(List *names, List *parameters)
elog(ERROR, "Define: \"basetype\" unspecified");
if (transType == NULL)
elog(ERROR, "Define: \"stype\" unspecified");
if (transfuncName == NULL)
if (transfuncName == NIL)
elog(ERROR, "Define: \"sfunc\" unspecified");
/*
......@@ -800,10 +801,10 @@ DefineType(List *names, List *parameters)
int16 internalLength = -1; /* int2 */
int16 externalLength = -1; /* int2 */
Oid elemType = InvalidOid;
char *inputName = NULL;
char *outputName = NULL;
char *sendName = NULL;
char *receiveName = NULL;
List *inputName = NIL;
List *outputName = NIL;
List *sendName = NIL;
List *receiveName = NIL;
char *defaultValue = NULL;
bool byValue = false;
char delimiter = DEFAULT_TYPDELIM;
......@@ -838,13 +839,13 @@ DefineType(List *names, List *parameters)
else if (strcasecmp(defel->defname, "externallength") == 0)
externalLength = defGetTypeLength(defel);
else if (strcasecmp(defel->defname, "input") == 0)
inputName = defGetString(defel);
inputName = defGetQualifiedName(defel);
else if (strcasecmp(defel->defname, "output") == 0)
outputName = defGetString(defel);
outputName = defGetQualifiedName(defel);
else if (strcasecmp(defel->defname, "send") == 0)
sendName = defGetString(defel);
sendName = defGetQualifiedName(defel);
else if (strcasecmp(defel->defname, "receive") == 0)
receiveName = defGetString(defel);
receiveName = defGetQualifiedName(defel);
else if (strcasecmp(defel->defname, "delimiter") == 0)
{
char *p = defGetString(defel);
......@@ -909,9 +910,9 @@ DefineType(List *names, List *parameters)
/*
* make sure we have our required definitions
*/
if (inputName == NULL)
if (inputName == NIL)
elog(ERROR, "Define: \"input\" unspecified");
if (outputName == NULL)
if (outputName == NIL)
elog(ERROR, "Define: \"output\" unspecified");
/* Convert I/O proc names to OIDs */
......@@ -989,7 +990,7 @@ DefineType(List *names, List *parameters)
}
static Oid
findTypeIOFunction(const char *procname, bool isOutput)
findTypeIOFunction(List *procname, bool isOutput)
{
Oid argList[FUNC_MAX_ARGS];
int nargs;
......@@ -1001,11 +1002,7 @@ findTypeIOFunction(const char *procname, bool isOutput)
*/
MemSet(argList, 0, FUNC_MAX_ARGS * sizeof(Oid));
procOid = GetSysCacheOid(PROCNAME,
PointerGetDatum(procname),
Int32GetDatum(1),
PointerGetDatum(argList),
0);
procOid = LookupFuncName(procname, 1, argList);
if (!OidIsValid(procOid))
{
......@@ -1028,11 +1025,7 @@ findTypeIOFunction(const char *procname, bool isOutput)
argList[1] = OIDOID;
argList[2] = INT4OID;
}
procOid = GetSysCacheOid(PROCNAME,
PointerGetDatum(procname),
Int32GetDatum(nargs),
PointerGetDatum(argList),
0);
procOid = LookupFuncName(procname, nargs, argList);
if (!OidIsValid(procOid))
func_error("TypeCreate", procname, 1, argList, NULL);
......@@ -1094,6 +1087,26 @@ defGetNumeric(DefElem *def)
return 0; /* keep compiler quiet */
}
static List *
defGetQualifiedName(DefElem *def)
{
if (def->arg == NULL)
elog(ERROR, "Define: \"%s\" requires a parameter",
def->defname);
switch (nodeTag(def->arg))
{
case T_TypeName:
return ((TypeName *) def->arg)->names;
case T_String:
/* Allow quoted name for backwards compatibility */
return makeList1(def->arg);
default:
elog(ERROR, "Define: argument of \"%s\" must be a name",
def->defname);
}
return NIL; /* keep compiler quiet */
}
static TypeName *
defGetTypeName(DefElem *def)
{
......
......@@ -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");
}
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/proclang.c,v 1.29 2002/02/18 23:11:11 petere Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/proclang.c,v 1.30 2002/04/09 20:35:48 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -18,12 +18,15 @@
#include "access/heapam.h"
#include "catalog/catname.h"
#include "catalog/indexing.h"
#include "catalog/namespace.h"
#include "catalog/pg_language.h"
#include "catalog/pg_proc.h"
#include "commands/proclang.h"
#include "fmgr.h"
#include "miscadmin.h"
#include "parser/parse_func.h"
#include "utils/builtins.h"
#include "utils/lsyscache.h"
#include "utils/syscache.h"
......@@ -50,15 +53,13 @@ void
CreateProceduralLanguage(CreatePLangStmt *stmt)
{
char languageName[NAMEDATALEN];
HeapTuple procTup;
Oid procOid;
Oid typev[FUNC_MAX_ARGS];
char nulls[Natts_pg_language];
Datum values[Natts_pg_language];
Relation rel;
HeapTuple tup;
TupleDesc tupDesc;
int i;
/*
......@@ -83,18 +84,14 @@ CreateProceduralLanguage(CreatePLangStmt *stmt)
* Lookup the PL handler function and check that it is of return type
* Opaque
*/
memset(typev, 0, sizeof(typev));
procTup = SearchSysCache(PROCNAME,
PointerGetDatum(stmt->plhandler),
Int32GetDatum(0),
PointerGetDatum(typev),
0);
if (!HeapTupleIsValid(procTup))
MemSet(typev, 0, sizeof(typev));
procOid = LookupFuncName(stmt->plhandler, 0, typev);
if (!OidIsValid(procOid))
elog(ERROR, "PL handler function %s() doesn't exist",
stmt->plhandler);
if (((Form_pg_proc) GETSTRUCT(procTup))->prorettype != InvalidOid)
NameListToString(stmt->plhandler));
if (get_func_rettype(procOid) != InvalidOid)
elog(ERROR, "PL handler function %s() isn't of return type Opaque",
stmt->plhandler);
NameListToString(stmt->plhandler));
/*
* Insert the new language into pg_language
......@@ -109,13 +106,11 @@ CreateProceduralLanguage(CreatePLangStmt *stmt)
values[i++] = PointerGetDatum(languageName);
values[i++] = BoolGetDatum(true); /* lanispl */
values[i++] = BoolGetDatum(stmt->pltrusted);
values[i++] = ObjectIdGetDatum(procTup->t_data->t_oid);
values[i++] = ObjectIdGetDatum(procOid);
values[i++] = DirectFunctionCall1(textin,
CStringGetDatum(stmt->plcompiler));
nulls[i] = 'n'; /* lanacl */
ReleaseSysCache(procTup);
rel = heap_openr(LanguageRelationName, RowExclusiveLock);
tupDesc = rel->rd_att;
......
......@@ -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 */
......
......@@ -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);
......
......@@ -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,12 +2051,9 @@ _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);
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;
......
......@@ -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))
......
......@@ -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
*
......
......@@ -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 ");
......
......@@ -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");
......
This diff is collapsed.
......@@ -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));
}
......@@ -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;
}
......
......@@ -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);
}
......
This diff is collapsed.
......@@ -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,49 +498,35 @@ 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));
*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));
*name = strVal(llast(((A_Const *) node)->typename->names));
return 1;
}
}
break;
case T_TypeCast:
strength = FigureColnameInternal(((TypeCast *) node)->arg,
......@@ -549,17 +535,10 @@ 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));
*name = strVal(llast(((TypeCast *) node)->typename->names));
return 1;
}
}
}
break;
case T_CaseExpr:
strength = FigureColnameInternal(((CaseExpr *) node)->defresult,
......
......@@ -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:
......
......@@ -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,
......
......@@ -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 */
......
......@@ -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);
......
......@@ -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);
......
......@@ -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 */
......@@ -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;
......
......@@ -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);
......
......@@ -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 */
......@@ -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 */
......@@ -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 */
......@@ -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
......
......@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment