aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/commands')
-rw-r--r--src/backend/commands/comment.c68
-rw-r--r--src/backend/commands/define.c226
-rw-r--r--src/backend/commands/remove.c38
3 files changed, 174 insertions, 158 deletions
diff --git a/src/backend/commands/comment.c b/src/backend/commands/comment.c
index 51832bc2c7b..e7b13a80788 100644
--- a/src/backend/commands/comment.c
+++ b/src/backend/commands/comment.c
@@ -25,6 +25,8 @@
#include "commands/comment.h"
#include "miscadmin.h"
#include "parser/parse.h"
+#include "parser/parse_expr.h"
+#include "parser/parse_func.h"
#include "rewrite/rewriteRemove.h"
#include "utils/acl.h"
#include "utils/fmgroids.h"
@@ -46,7 +48,7 @@ static void CommentAttribute(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, char *aggtype, 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 *relation, char *comments);
@@ -92,7 +94,7 @@ CommentObject(int objtype, char *objname, char *objproperty,
CommentType(objname, comment);
break;
case (AGGREGATE):
- CommentAggregate(objname, objproperty, comment);
+ CommentAggregate(objname, objlist, comment);
break;
case (FUNCTION):
CommentProc(objname, objlist, comment);
@@ -544,9 +546,10 @@ CommentType(char *type, char *comment)
*/
static void
-CommentAggregate(char *aggregate, char *argument, char *comment)
+CommentAggregate(char *aggregate, List *arguments, char *comment)
{
-
+ TypeName *aggtype = (TypeName *) lfirst(arguments);
+ char *aggtypename = NULL;
HeapTuple aggtuple;
Oid baseoid,
oid;
@@ -554,11 +557,12 @@ CommentAggregate(char *aggregate, char *argument, char *comment)
/*** First, attempt to determine the base aggregate oid ***/
- if (argument)
+ if (aggtype)
{
- baseoid = TypeGet(argument, &defined);
+ aggtypename = TypeNameToInternalName(aggtype);
+ baseoid = TypeGet(aggtypename, &defined);
if (!OidIsValid(baseoid))
- elog(ERROR, "aggregate type '%s' does not exist", argument);
+ elog(ERROR, "type '%s' does not exist", aggtypename);
}
else
baseoid = 0;
@@ -568,10 +572,10 @@ CommentAggregate(char *aggregate, char *argument, char *comment)
#ifndef NO_SECURITY
if (!pg_aggr_ownercheck(GetUserId(), aggregate, baseoid))
{
- if (argument)
+ if (aggtypename)
{
elog(ERROR, "you are not permitted to comment on aggregate '%s' %s '%s'",
- aggregate, "with type", argument);
+ aggregate, "with type", aggtypename);
}
else
{
@@ -587,10 +591,10 @@ CommentAggregate(char *aggregate, char *argument, char *comment)
ObjectIdGetDatum(baseoid), 0, 0);
if (!HeapTupleIsValid(aggtuple))
{
- if (argument)
+ if (aggtypename)
{
elog(ERROR, "aggregate type '%s' does not exist for aggregate '%s'",
- argument, aggregate);
+ aggtypename, aggregate);
}
else
elog(ERROR, "aggregate '%s' does not exist", aggregate);
@@ -622,7 +626,6 @@ CommentProc(char *function, List *arguments, char *comment)
functuple;
Oid oid,
argoids[FUNC_MAX_ARGS];
- char *argument;
int i,
argcount;
@@ -635,18 +638,20 @@ CommentProc(char *function, List *arguments, char *comment)
FUNC_MAX_ARGS);
for (i = 0; i < argcount; i++)
{
- argument = strVal(lfirst(arguments));
+ TypeName *t = (TypeName *) lfirst(arguments);
+ char *typnam = TypeNameToInternalName(t);
+
arguments = lnext(arguments);
- if (strcmp(argument, "opaque") == 0)
- argoids[i] = 0;
+
+ if (strcmp(typnam, "opaque") == 0)
+ argoids[i] = InvalidOid;
else
{
argtuple = SearchSysCacheTuple(TYPENAME,
- PointerGetDatum(argument),
+ PointerGetDatum(typnam),
0, 0, 0);
if (!HeapTupleIsValid(argtuple))
- elog(ERROR, "function argument type '%s' does not exist",
- argument);
+ elog(ERROR, "CommentProc: type '%s' not found", typnam);
argoids[i] = argtuple->t_data->t_oid;
}
}
@@ -664,10 +669,9 @@ CommentProc(char *function, List *arguments, char *comment)
functuple = SearchSysCacheTuple(PROCNAME, PointerGetDatum(function),
Int32GetDatum(argcount),
PointerGetDatum(argoids), 0);
-
if (!HeapTupleIsValid(functuple))
- elog(ERROR, "function '%s' with the supplied %s does not exist",
- function, "argument list");
+ func_error("CommentProc", function, argcount, argoids, NULL);
+
oid = functuple->t_data->t_oid;
/*** Call CreateComments() to create/drop the comments ***/
@@ -691,23 +695,24 @@ CommentProc(char *function, List *arguments, char *comment)
static void
CommentOperator(char *opername, List *arguments, char *comment)
{
-
+ TypeName *typenode1 = (TypeName *) lfirst(arguments);
+ TypeName *typenode2 = (TypeName *) lsecond(arguments);
+ char oprtype = 0,
+ *lefttype = NULL,
+ *righttype = NULL;
Form_pg_operator data;
HeapTuple optuple;
Oid oid,
leftoid = InvalidOid,
rightoid = InvalidOid;
bool defined;
- char oprtype = 0,
- *lefttype = NULL,
- *righttype = NULL;
/*** Initialize our left and right argument types ***/
- if (lfirst(arguments) != NULL)
- lefttype = strVal(lfirst(arguments));
- if (lsecond(arguments) != NULL)
- righttype = strVal(lsecond(arguments));
+ if (typenode1 != NULL)
+ lefttype = TypeNameToInternalName(typenode1);
+ if (typenode2 != NULL)
+ righttype = TypeNameToInternalName(typenode2);
/*** Attempt to fetch the left oid, if specified ***/
@@ -732,9 +737,9 @@ CommentOperator(char *opername, List *arguments, char *comment)
if (OidIsValid(leftoid) && (OidIsValid(rightoid)))
oprtype = 'b';
else if (OidIsValid(leftoid))
- oprtype = 'l';
- else if (OidIsValid(rightoid))
oprtype = 'r';
+ else if (OidIsValid(rightoid))
+ oprtype = 'l';
else
elog(ERROR, "operator '%s' is of an illegal type'", opername);
@@ -769,7 +774,6 @@ CommentOperator(char *opername, List *arguments, char *comment)
/*** Call CreateComments() to create/drop the comments ***/
CreateComments(oid, comment);
-
}
/*------------------------------------------------------------------
diff --git a/src/backend/commands/define.c b/src/backend/commands/define.c
index cf31e5edb1f..a33d155db9f 100644
--- a/src/backend/commands/define.c
+++ b/src/backend/commands/define.c
@@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/define.c,v 1.46 2000/07/22 03:34:26 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/define.c,v 1.47 2000/10/07 00:58:16 tgl Exp $
*
* DESCRIPTION
* The "DefineFoo" routines take the parse tree and pick out the
@@ -49,6 +49,7 @@
#include "commands/defrem.h"
#include "fmgr.h"
#include "optimizer/cost.h"
+#include "parser/parse_expr.h"
#include "tcop/dest.h"
#include "utils/builtins.h"
#include "utils/syscache.h"
@@ -83,27 +84,15 @@ case_translate_language_name(const char *input, char *output)
static void
-compute_return_type(const Node *returnType,
+compute_return_type(TypeName *returnType,
char **prorettype_p, bool *returnsSet_p)
{
/*---------------------------------------------------------------------------
Examine the "returns" clause returnType of the CREATE FUNCTION statement
- and return information about it as **prorettype_p and **returnsSet.
+ and return information about it as *prorettype_p and *returnsSet.
----------------------------------------------------------------------------*/
- if (nodeTag(returnType) == T_TypeName)
- {
- /* a set of values */
- TypeName *setType = (TypeName *) returnType;
-
- *prorettype_p = setType->name;
- *returnsSet_p = setType->setof;
- }
- else
- {
- /* singleton */
- *prorettype_p = strVal(returnType);
- *returnsSet_p = false;
- }
+ *prorettype_p = TypeNameToInternalName(returnType);
+ *returnsSet_p = returnType->setof;
}
@@ -214,7 +203,7 @@ interpret_AS_clause(const char *languageName, const List *as,
*prosrc_str_p = strVal(lfirst(as));
*probin_str_p = "-";
- if (lnext(as) != NULL)
+ if (lnext(as) != NIL)
elog(ERROR, "CREATE FUNCTION: only one AS item needed for %s language",
languageName);
}
@@ -231,27 +220,23 @@ void
CreateFunction(ProcedureStmt *stmt, CommandDest dest)
{
char *probin_str;
-
/* pathname of executable file that executes this function, if any */
- char *prosrc_str;
+ char *prosrc_str;
/* SQL that executes this function, if any */
- char *prorettype;
+ char *prorettype;
/* Type of return value (or member of set of values) from function */
- char languageName[NAMEDATALEN];
+ char languageName[NAMEDATALEN];
/*
* name of language of function, with case adjusted: "C", "newC",
* "internal", "newinternal", "sql", etc.
*/
bool returnsSet;
-
/* The function returns a set of values, as opposed to a singleton. */
- bool lanisPL = false;
-
/*
* The following are optional user-supplied attributes of the
* function.
@@ -263,8 +248,12 @@ CreateFunction(ProcedureStmt *stmt, CommandDest dest)
bool canCache,
isStrict;
+ /* Convert language name to canonical case */
case_translate_language_name(stmt->language, languageName);
+ /*
+ * Apply appropriate security checks depending on language.
+ */
if (strcmp(languageName, "C") == 0 ||
strcmp(languageName, "newC") == 0 ||
strcmp(languageName, "internal") == 0 ||
@@ -301,7 +290,7 @@ CreateFunction(ProcedureStmt *stmt, CommandDest dest)
/* Check that this language is a PL */
languageStruct = (Form_pg_language) GETSTRUCT(languageTuple);
- if (!(languageStruct->lanispl))
+ if (!languageStruct->lanispl)
elog(ERROR,
"Language '%s' isn't defined as PL", languageName);
@@ -316,11 +305,15 @@ CreateFunction(ProcedureStmt *stmt, CommandDest dest)
"language.",
languageName);
}
-
- lanisPL = true;
}
- compute_return_type(stmt->returnType, &prorettype, &returnsSet);
+ /*
+ * Convert remaining parameters of CREATE to form wanted by
+ * ProcedureCreate.
+ */
+ Assert(IsA(stmt->returnType, TypeName));
+ compute_return_type((TypeName *) stmt->returnType,
+ &prorettype, &returnsSet);
compute_full_attributes(stmt->withClause,
&byte_pct, &perbyte_cpu, &percall_cpu,
@@ -345,7 +338,7 @@ CreateFunction(ProcedureStmt *stmt, CommandDest dest)
perbyte_cpu,
percall_cpu,
outin_ratio,
- stmt->defArgs,
+ stmt->argTypes,
dest);
}
@@ -389,49 +382,43 @@ DefineOperator(char *oprName,
{
DefElem *defel = (DefElem *) lfirst(pl);
- if (!strcasecmp(defel->defname, "leftarg"))
+ if (strcasecmp(defel->defname, "leftarg") == 0)
{
- if ((nodeTag(defel->arg) == T_TypeName)
- && (((TypeName *) defel->arg)->setof))
- elog(ERROR, "setof type not implemented for leftarg");
-
typeName1 = defGetString(defel);
- if (typeName1 == NULL)
- elog(ERROR, "type for leftarg is malformed.");
+ if (IsA(defel->arg, TypeName)
+ && ((TypeName *) defel->arg)->setof)
+ elog(ERROR, "setof type not implemented for leftarg");
}
- else if (!strcasecmp(defel->defname, "rightarg"))
+ else if (strcasecmp(defel->defname, "rightarg") == 0)
{
- if ((nodeTag(defel->arg) == T_TypeName)
- && (((TypeName *) defel->arg)->setof))
- elog(ERROR, "setof type not implemented for rightarg");
-
typeName2 = defGetString(defel);
- if (typeName2 == NULL)
- elog(ERROR, "type for rightarg is malformed.");
+ if (IsA(defel->arg, TypeName)
+ && ((TypeName *) defel->arg)->setof)
+ elog(ERROR, "setof type not implemented for rightarg");
}
- else if (!strcasecmp(defel->defname, "procedure"))
+ else if (strcasecmp(defel->defname, "procedure") == 0)
functionName = defGetString(defel);
- else if (!strcasecmp(defel->defname, "precedence"))
+ else if (strcasecmp(defel->defname, "precedence") == 0)
{
/* NOT IMPLEMENTED (never worked in v4.2) */
elog(NOTICE, "CREATE OPERATOR: precedence not implemented");
}
- else if (!strcasecmp(defel->defname, "associativity"))
+ else if (strcasecmp(defel->defname, "associativity") == 0)
{
/* NOT IMPLEMENTED (never worked in v4.2) */
elog(NOTICE, "CREATE OPERATOR: associativity not implemented");
}
- else if (!strcasecmp(defel->defname, "commutator"))
+ else if (strcasecmp(defel->defname, "commutator") == 0)
commutatorName = defGetString(defel);
- else if (!strcasecmp(defel->defname, "negator"))
+ else if (strcasecmp(defel->defname, "negator") == 0)
negatorName = defGetString(defel);
- else if (!strcasecmp(defel->defname, "restrict"))
+ else if (strcasecmp(defel->defname, "restrict") == 0)
restrictionName = defGetString(defel);
- else if (!strcasecmp(defel->defname, "join"))
+ else if (strcasecmp(defel->defname, "join") == 0)
joinName = defGetString(defel);
- else if (!strcasecmp(defel->defname, "hashes"))
+ else if (strcasecmp(defel->defname, "hashes") == 0)
canHash = TRUE;
- else if (!strcasecmp(defel->defname, "sort1"))
+ else if (strcasecmp(defel->defname, "sort1") == 0)
{
/* ----------------
* XXX ( ... [ , sort1 = oprname ] [ , sort2 = oprname ] ... )
@@ -441,7 +428,7 @@ DefineOperator(char *oprName,
*/
sortName1 = defGetString(defel);
}
- else if (!strcasecmp(defel->defname, "sort2"))
+ else if (strcasecmp(defel->defname, "sort2") == 0)
sortName2 = defGetString(defel);
else
{
@@ -562,72 +549,73 @@ DefineType(char *typeName, List *parameters)
char delimiter = DEFAULT_TYPDELIM;
char *shadow_type;
List *pl;
- char alignment = 'i';/* default alignment */
- char storage = 'p'; /* default storage in TOAST */
+ char alignment = 'i'; /* default alignment */
+ char storage = 'p'; /* default storage in TOAST */
/*
- * Type names can only be 15 characters long, so that the shadow type
- * can be created using the 16th character as necessary.
+ * Type names must be one character shorter than other names,
+ * allowing room to create the corresponding array type name with
+ * prepended "_".
*/
- if (strlen(typeName) >= (NAMEDATALEN - 1))
+ if (strlen(typeName) > (NAMEDATALEN - 2))
{
elog(ERROR, "DefineType: type names must be %d characters or less",
- NAMEDATALEN - 1);
+ NAMEDATALEN - 2);
}
foreach(pl, parameters)
{
DefElem *defel = (DefElem *) lfirst(pl);
- if (!strcasecmp(defel->defname, "internallength"))
+ if (strcasecmp(defel->defname, "internallength") == 0)
internalLength = defGetTypeLength(defel);
- else if (!strcasecmp(defel->defname, "externallength"))
+ else if (strcasecmp(defel->defname, "externallength") == 0)
externalLength = defGetTypeLength(defel);
- else if (!strcasecmp(defel->defname, "input"))
+ else if (strcasecmp(defel->defname, "input") == 0)
inputName = defGetString(defel);
- else if (!strcasecmp(defel->defname, "output"))
+ else if (strcasecmp(defel->defname, "output") == 0)
outputName = defGetString(defel);
- else if (!strcasecmp(defel->defname, "send"))
+ else if (strcasecmp(defel->defname, "send") == 0)
sendName = defGetString(defel);
- else if (!strcasecmp(defel->defname, "delimiter"))
+ else if (strcasecmp(defel->defname, "delimiter") == 0)
{
char *p = defGetString(defel);
delimiter = p[0];
}
- else if (!strcasecmp(defel->defname, "receive"))
+ else if (strcasecmp(defel->defname, "receive") == 0)
receiveName = defGetString(defel);
- else if (!strcasecmp(defel->defname, "element"))
+ else if (strcasecmp(defel->defname, "element") == 0)
elemName = defGetString(defel);
- else if (!strcasecmp(defel->defname, "default"))
+ else if (strcasecmp(defel->defname, "default") == 0)
defaultValue = defGetString(defel);
- else if (!strcasecmp(defel->defname, "passedbyvalue"))
+ else if (strcasecmp(defel->defname, "passedbyvalue") == 0)
byValue = true;
- else if (!strcasecmp(defel->defname, "alignment"))
+ else if (strcasecmp(defel->defname, "alignment") == 0)
{
char *a = defGetString(defel);
- if (!strcasecmp(a, "double"))
+ if (strcasecmp(a, "double") == 0)
alignment = 'd';
- else if (!strcasecmp(a, "int4"))
+ else if (strcasecmp(a, "int4") == 0)
alignment = 'i';
else
{
- elog(ERROR, "DefineType: \"%s\" alignment not recognized",
+ elog(ERROR, "DefineType: \"%s\" alignment not recognized",
a);
}
}
- else if (!strcasecmp(defel->defname, "storage"))
+ else if (strcasecmp(defel->defname, "storage") == 0)
{
char *a = defGetString(defel);
- if (!strcasecmp(a, "plain"))
+ if (strcasecmp(a, "plain") == 0)
storage = 'p';
- else if (!strcasecmp(a, "external"))
+ else if (strcasecmp(a, "external") == 0)
storage = 'e';
- else if (!strcasecmp(a, "extended"))
+ else if (strcasecmp(a, "extended") == 0)
storage = 'x';
- else if (!strcasecmp(a, "main"))
+ else if (strcasecmp(a, "main") == 0)
storage = 'm';
else
{
@@ -674,8 +662,8 @@ DefineType(char *typeName, List *parameters)
storage); /* TOAST strategy */
/* ----------------
- * When we create a true type (as opposed to a complex type)
- * we need to have an shadow array entry for it in pg_type as well.
+ * When we create a base type (as opposed to a complex type)
+ * we need to have an array entry for it in pg_type as well.
* ----------------
*/
shadow_type = makeArrayTypeName(typeName);
@@ -702,19 +690,32 @@ DefineType(char *typeName, List *parameters)
static char *
defGetString(DefElem *def)
{
- char *string;
-
- if (nodeTag(def->arg) == T_String)
- string = strVal(def->arg);
- else if (nodeTag(def->arg) == T_TypeName)
- string = ((TypeName *) def->arg)->name;
- else
- string = NULL;
-#if 0
- elog(ERROR, "Define: \"%s\" = what?", def->defname);
-#endif
+ if (def->arg == NULL)
+ elog(ERROR, "Define: \"%s\" requires a parameter",
+ def->defname);
+ switch (nodeTag(def->arg))
+ {
+ case T_Integer:
+ {
+ char *str = palloc(32);
- return string;
+ snprintf(str, 32, "%ld", (long) intVal(def->arg));
+ return str;
+ }
+ case T_Float:
+ /* T_Float values are kept in string form, so this type cheat
+ * works (and doesn't risk losing precision)
+ */
+ return strVal(def->arg);
+ case T_String:
+ return strVal(def->arg);
+ case T_TypeName:
+ return TypeNameToInternalName((TypeName *) def->arg);
+ default:
+ elog(ERROR, "Define: cannot interpret argument of \"%s\"",
+ def->defname);
+ }
+ return NULL; /* keep compiler quiet */
}
static double
@@ -739,15 +740,32 @@ defGetNumeric(DefElem *def)
static int
defGetTypeLength(DefElem *def)
{
- if (nodeTag(def->arg) == T_Integer)
- return intVal(def->arg);
- else if (nodeTag(def->arg) == T_String &&
- !strcasecmp(strVal(def->arg), "variable"))
- return -1; /* variable length */
- else if (nodeTag(def->arg) == T_TypeName &&
- !strcasecmp(((TypeName *)(def->arg))->name, "variable"))
- return -1;
-
- elog(ERROR, "Define: \"%s\" = what?", def->defname);
- return -1;
+ if (def->arg == NULL)
+ elog(ERROR, "Define: \"%s\" requires a parameter",
+ def->defname);
+ switch (nodeTag(def->arg))
+ {
+ case T_Integer:
+ return intVal(def->arg);
+ case T_Float:
+ elog(ERROR, "Define: \"%s\" requires an integral value",
+ def->defname);
+ break;
+ case T_String:
+ if (strcasecmp(strVal(def->arg), "variable") == 0)
+ return -1; /* variable length */
+ break;
+ case T_TypeName:
+ /* cope if grammar chooses to believe "variable" is a typename */
+ if (strcasecmp(TypeNameToInternalName((TypeName *) def->arg),
+ "variable") == 0)
+ return -1; /* variable length */
+ break;
+ default:
+ elog(ERROR, "Define: cannot interpret argument of \"%s\"",
+ def->defname);
+ }
+ elog(ERROR, "Define: invalid argument for \"%s\"",
+ def->defname);
+ return 0; /* keep compiler quiet */
}
diff --git a/src/backend/commands/remove.c b/src/backend/commands/remove.c
index c5b7968e5fd..6da32297f61 100644
--- a/src/backend/commands/remove.c
+++ b/src/backend/commands/remove.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/Attic/remove.c,v 1.52 2000/09/12 16:48:55 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/Attic/remove.c,v 1.53 2000/10/07 00:58:16 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -22,6 +22,7 @@
#include "commands/comment.h"
#include "commands/defrem.h"
#include "miscadmin.h"
+#include "parser/parse_expr.h"
#include "parser/parse_func.h"
#include "utils/acl.h"
#include "utils/syscache.h"
@@ -39,8 +40,8 @@
*/
void
RemoveOperator(char *operatorName, /* operator name */
- char *typeName1, /* first type name */
- char *typeName2) /* optional second type name */
+ char *typeName1, /* left argument type name */
+ char *typeName2) /* right argument type name */
{
Relation relation;
HeapTuple tup;
@@ -53,28 +54,22 @@ RemoveOperator(char *operatorName, /* operator name */
{
typeId1 = TypeGet(typeName1, &defined);
if (!OidIsValid(typeId1))
- {
elog(ERROR, "RemoveOperator: type '%s' does not exist", typeName1);
- return;
- }
}
if (typeName2)
{
typeId2 = TypeGet(typeName2, &defined);
if (!OidIsValid(typeId2))
- {
elog(ERROR, "RemoveOperator: type '%s' does not exist", typeName2);
- return;
- }
}
if (OidIsValid(typeId1) && OidIsValid(typeId2))
oprtype = 'b';
else if (OidIsValid(typeId1))
- oprtype = 'l';
- else
oprtype = 'r';
+ else
+ oprtype = 'l';
relation = heap_openr(OperatorRelationName, RowExclusiveLock);
@@ -94,7 +89,6 @@ RemoveOperator(char *operatorName, /* operator name */
operatorName);
#endif
-
/*** Delete any comments associated with this operator ***/
DeleteComments(tup->t_data->t_oid);
@@ -308,13 +302,12 @@ RemoveType(char *typeName) /* type name to be removed */
*/
void
RemoveFunction(char *functionName, /* function name to be removed */
- int nargs,
- List *argNameList /* list of TypeNames */ )
+ List *argTypes) /* list of TypeName nodes */
{
+ int nargs = length(argTypes);
Relation relation;
HeapTuple tup;
Oid argList[FUNC_MAX_ARGS];
- char *typename;
int i;
if (nargs > FUNC_MAX_ARGS)
@@ -323,19 +316,20 @@ RemoveFunction(char *functionName, /* function name to be removed */
MemSet(argList, 0, FUNC_MAX_ARGS * sizeof(Oid));
for (i = 0; i < nargs; i++)
{
- typename = strVal(lfirst(argNameList));
- argNameList = lnext(argNameList);
+ TypeName *t = (TypeName *) lfirst(argTypes);
+ char *typnam = TypeNameToInternalName(t);
- if (strcmp(typename, "opaque") == 0)
- argList[i] = 0;
+ argTypes = lnext(argTypes);
+
+ if (strcmp(typnam, "opaque") == 0)
+ argList[i] = InvalidOid;
else
{
tup = SearchSysCacheTuple(TYPENAME,
- PointerGetDatum(typename),
+ PointerGetDatum(typnam),
0, 0, 0);
-
if (!HeapTupleIsValid(tup))
- elog(ERROR, "RemoveFunction: type '%s' not found", typename);
+ elog(ERROR, "RemoveFunction: type '%s' not found", typnam);
argList[i] = tup->t_data->t_oid;
}
}