diff options
Diffstat (limited to 'src/backend')
-rw-r--r-- | src/backend/bootstrap/bootstrap.c | 15 | ||||
-rw-r--r-- | src/backend/catalog/pg_aggregate.c | 5 | ||||
-rw-r--r-- | src/backend/catalog/pg_proc.c | 52 | ||||
-rw-r--r-- | src/backend/commands/functioncmds.c | 29 | ||||
-rw-r--r-- | src/backend/nodes/copyfuncs.c | 18 | ||||
-rw-r--r-- | src/backend/nodes/equalfuncs.c | 16 | ||||
-rw-r--r-- | src/backend/parser/gram.y | 87 | ||||
-rw-r--r-- | src/backend/utils/adt/sets.c | 7 | ||||
-rw-r--r-- | src/backend/utils/fmgr/fmgr.c | 10 |
9 files changed, 192 insertions, 47 deletions
diff --git a/src/backend/bootstrap/bootstrap.c b/src/backend/bootstrap/bootstrap.c index b21f4cc8065..c1105f3b11e 100644 --- a/src/backend/bootstrap/bootstrap.c +++ b/src/backend/bootstrap/bootstrap.c @@ -8,7 +8,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/bootstrap/bootstrap.c,v 1.173 2004/01/06 23:15:22 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/bootstrap/bootstrap.c,v 1.174 2004/01/06 23:55:18 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -130,6 +130,7 @@ static struct typinfo Procid[] = { {"oidvector", OIDVECTOROID, 0, INDEX_MAX_KEYS * 4, F_OIDVECTORIN, F_OIDVECTOROUT}, {"smgr", 210, 0, 2, F_SMGRIN, F_SMGROUT}, {"_int4", 1007, INT4OID, -1, F_ARRAY_IN, F_ARRAY_OUT}, + {"_text", 1009, TEXTOID, -1, F_ARRAY_IN, F_ARRAY_OUT}, {"_aclitem", 1034, 1033, -1, F_ARRAY_IN, F_ARRAY_OUT} }; @@ -690,6 +691,11 @@ DefineAttr(char *name, char *type, int attnum) attrtypes[attnum]->attbyval = Ap->am_typ.typbyval; attrtypes[attnum]->attstorage = Ap->am_typ.typstorage; attrtypes[attnum]->attalign = Ap->am_typ.typalign; + /* if an array type, assume 1-dimensional attribute */ + if (Ap->am_typ.typelem != InvalidOid && Ap->am_typ.typlen < 0) + attrtypes[attnum]->attndims = 1; + else + attrtypes[attnum]->attndims = 0; } else { @@ -729,7 +735,14 @@ DefineAttr(char *name, char *type, int attnum) attrtypes[attnum]->attalign = 'i'; break; } + /* if an array type, assume 1-dimensional attribute */ + if (Procid[typeoid].elem != InvalidOid && attlen < 0) + attrtypes[attnum]->attndims = 1; + else + attrtypes[attnum]->attndims = 0; } + + attrtypes[attnum]->attstattarget = -1; attrtypes[attnum]->attcacheoff = -1; attrtypes[attnum]->atttypmod = -1; attrtypes[attnum]->attislocal = true; diff --git a/src/backend/catalog/pg_aggregate.c b/src/backend/catalog/pg_aggregate.c index 8ed1aecdfe9..d21ecef3606 100644 --- a/src/backend/catalog/pg_aggregate.c +++ b/src/backend/catalog/pg_aggregate.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/catalog/pg_aggregate.c,v 1.65 2003/11/29 19:51:45 pgsql Exp $ + * $PostgreSQL: pgsql/src/backend/catalog/pg_aggregate.c,v 1.66 2004/01/06 23:55:18 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -190,7 +190,8 @@ AggregateCreate(const char *aggName, PROVOLATILE_IMMUTABLE, /* volatility (not * needed for agg) */ 1, /* parameterCount */ - fnArgs); /* parameterTypes */ + fnArgs, /* parameterTypes */ + NULL); /* parameterNames */ /* * Okay to create the pg_aggregate entry. diff --git a/src/backend/catalog/pg_proc.c b/src/backend/catalog/pg_proc.c index bca442ab8c4..b9628734701 100644 --- a/src/backend/catalog/pg_proc.c +++ b/src/backend/catalog/pg_proc.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/catalog/pg_proc.c,v 1.110 2003/11/29 19:51:46 pgsql Exp $ + * $PostgreSQL: pgsql/src/backend/catalog/pg_proc.c,v 1.111 2004/01/06 23:55:18 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -42,6 +42,9 @@ Datum fmgr_internal_validator(PG_FUNCTION_ARGS); Datum fmgr_c_validator(PG_FUNCTION_ARGS); Datum fmgr_sql_validator(PG_FUNCTION_ARGS); +static Datum create_parameternames_array(int parameterCount, + const char *parameterNames[]); + /* ---------------------------------------------------------------- * ProcedureCreate @@ -62,7 +65,8 @@ ProcedureCreate(const char *procedureName, bool isStrict, char volatility, int parameterCount, - const Oid *parameterTypes) + const Oid *parameterTypes, + const char *parameterNames[]) { int i; Relation rel; @@ -72,6 +76,7 @@ ProcedureCreate(const char *procedureName, Datum values[Natts_pg_proc]; char replaces[Natts_pg_proc]; Oid typev[FUNC_MAX_ARGS]; + Datum namesarray; Oid relid; NameData procname; TupleDesc tupDesc; @@ -122,6 +127,9 @@ ProcedureCreate(const char *procedureName, if (parameterCount > 0) memcpy(typev, parameterTypes, parameterCount * sizeof(Oid)); + /* Process param names, if given */ + namesarray = create_parameternames_array(parameterCount, parameterNames); + if (languageObjectId == SQLlanguageId) { /* @@ -197,6 +205,9 @@ ProcedureCreate(const char *procedureName, values[i++] = UInt16GetDatum(parameterCount); /* pronargs */ values[i++] = ObjectIdGetDatum(returnType); /* prorettype */ values[i++] = PointerGetDatum(typev); /* proargtypes */ + values[i++] = namesarray; /* proargnames */ + if (namesarray == PointerGetDatum(NULL)) + nulls[Anum_pg_proc_proargnames - 1] = 'n'; values[i++] = DirectFunctionCall1(textin, /* prosrc */ CStringGetDatum(prosrc)); values[i++] = DirectFunctionCall1(textin, /* probin */ @@ -334,6 +345,43 @@ ProcedureCreate(const char *procedureName, return retval; } + +/* + * create_parameternames_array - build proargnames value from an array + * of C strings. Returns a NULL pointer if no names provided. + */ +static Datum +create_parameternames_array(int parameterCount, const char *parameterNames[]) +{ + Datum elems[FUNC_MAX_ARGS]; + bool found = false; + ArrayType *names; + int i; + + if (!parameterNames) + return PointerGetDatum(NULL); + + for (i=0; i<parameterCount; i++) + { + const char *s = parameterNames[i]; + + if (s && *s) + found = true; + else + s = ""; + + elems[i] = DirectFunctionCall1(textin, CStringGetDatum(s)); + } + + if (!found) + return PointerGetDatum(NULL); + + names = construct_array(elems, parameterCount, TEXTOID, -1, false, 'i'); + + return PointerGetDatum(names); +} + + /* * check_sql_fn_retval() -- check return value of a list of sql parse trees. * diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c index 05bc52d9de5..2eb4c100a2b 100644 --- a/src/backend/commands/functioncmds.c +++ b/src/backend/commands/functioncmds.c @@ -10,7 +10,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/functioncmds.c,v 1.42 2003/11/29 19:51:47 pgsql Exp $ + * $PostgreSQL: pgsql/src/backend/commands/functioncmds.c,v 1.43 2004/01/06 23:55:18 tgl Exp $ * * DESCRIPTION * These routines take the parse tree and pick out the @@ -130,19 +130,22 @@ compute_return_type(TypeName *returnType, Oid languageOid, } /* - * Interpret the argument-types list of the CREATE FUNCTION statement. + * Interpret the parameter list of the CREATE FUNCTION statement. */ static int -compute_parameter_types(List *argTypes, Oid languageOid, - Oid *parameterTypes) +examine_parameter_list(List *parameter, Oid languageOid, + Oid *parameterTypes, const char *parameterNames[]) { int parameterCount = 0; List *x; MemSet(parameterTypes, 0, FUNC_MAX_ARGS * sizeof(Oid)); - foreach(x, argTypes) + MemSet(parameterNames, 0, FUNC_MAX_ARGS * sizeof(char *)); + + foreach(x, parameter) { - TypeName *t = (TypeName *) lfirst(x); + FunctionParameter *fp = (FunctionParameter *) lfirst(x); + TypeName *t = fp->argType; Oid toid; if (parameterCount >= FUNC_MAX_ARGS) @@ -182,7 +185,11 @@ compute_parameter_types(List *argTypes, Oid languageOid, (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), errmsg("functions cannot accept set arguments"))); - parameterTypes[parameterCount++] = toid; + parameterTypes[parameterCount] = toid; + + parameterNames[parameterCount] = fp->name; + + parameterCount++; } return parameterCount; @@ -402,6 +409,7 @@ CreateFunction(CreateFunctionStmt *stmt) AclResult aclresult; int parameterCount; Oid parameterTypes[FUNC_MAX_ARGS]; + const char *parameterNames[FUNC_MAX_ARGS]; bool isStrict, security; char volatility; @@ -480,8 +488,8 @@ CreateFunction(CreateFunctionStmt *stmt) compute_return_type(stmt->returnType, languageOid, &prorettype, &returnsSet); - parameterCount = compute_parameter_types(stmt->argTypes, languageOid, - parameterTypes); + parameterCount = examine_parameter_list(stmt->parameters, languageOid, + parameterTypes, parameterNames); compute_attributes_with_style(stmt->withClause, &isStrict, &volatility); @@ -527,7 +535,8 @@ CreateFunction(CreateFunctionStmt *stmt) isStrict, volatility, parameterCount, - parameterTypes); + parameterTypes, + parameterNames); } diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index 18a8a369e69..b47c51e4621 100644 --- a/src/backend/nodes/copyfuncs.c +++ b/src/backend/nodes/copyfuncs.c @@ -15,7 +15,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.274 2004/01/06 04:31:01 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.275 2004/01/06 23:55:18 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1878,7 +1878,7 @@ _copyCreateFunctionStmt(CreateFunctionStmt *from) COPY_SCALAR_FIELD(replace); COPY_NODE_FIELD(funcname); - COPY_NODE_FIELD(argTypes); + COPY_NODE_FIELD(parameters); COPY_NODE_FIELD(returnType); COPY_NODE_FIELD(options); COPY_NODE_FIELD(withClause); @@ -1886,6 +1886,17 @@ _copyCreateFunctionStmt(CreateFunctionStmt *from) return newnode; } +static FunctionParameter * +_copyFunctionParameter(FunctionParameter *from) +{ + FunctionParameter *newnode = makeNode(FunctionParameter); + + COPY_STRING_FIELD(name); + COPY_NODE_FIELD(argType); + + return newnode; +} + static RemoveAggrStmt * _copyRemoveAggrStmt(RemoveAggrStmt *from) { @@ -2788,6 +2799,9 @@ copyObject(void *from) case T_CreateFunctionStmt: retval = _copyCreateFunctionStmt(from); break; + case T_FunctionParameter: + retval = _copyFunctionParameter(from); + break; case T_RemoveAggrStmt: retval = _copyRemoveAggrStmt(from); break; diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c index 41b292a47cc..61e04b1fbda 100644 --- a/src/backend/nodes/equalfuncs.c +++ b/src/backend/nodes/equalfuncs.c @@ -18,7 +18,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.212 2004/01/05 05:07:35 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.213 2004/01/06 23:55:18 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -884,7 +884,7 @@ _equalCreateFunctionStmt(CreateFunctionStmt *a, CreateFunctionStmt *b) { COMPARE_SCALAR_FIELD(replace); COMPARE_NODE_FIELD(funcname); - COMPARE_NODE_FIELD(argTypes); + COMPARE_NODE_FIELD(parameters); COMPARE_NODE_FIELD(returnType); COMPARE_NODE_FIELD(options); COMPARE_NODE_FIELD(withClause); @@ -893,6 +893,15 @@ _equalCreateFunctionStmt(CreateFunctionStmt *a, CreateFunctionStmt *b) } static bool +_equalFunctionParameter(FunctionParameter *a, FunctionParameter *b) +{ + COMPARE_STRING_FIELD(name); + COMPARE_NODE_FIELD(argType); + + return true; +} + +static bool _equalRemoveAggrStmt(RemoveAggrStmt *a, RemoveAggrStmt *b) { COMPARE_NODE_FIELD(aggname); @@ -1868,6 +1877,9 @@ equal(void *a, void *b) case T_CreateFunctionStmt: retval = _equalCreateFunctionStmt(a, b); break; + case T_FunctionParameter: + retval = _equalFunctionParameter(a, b); + break; case T_RemoveAggrStmt: retval = _equalRemoveAggrStmt(a, b); break; diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 8866200444f..a578e5d3116 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -11,7 +11,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.441 2003/12/01 22:07:58 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.442 2004/01/06 23:55:18 tgl Exp $ * * HISTORY * AUTHOR DATE MAJOR EVENT @@ -87,6 +87,7 @@ static Node *makeRowNullTest(NullTestType test, List *args); static DefElem *makeDefElem(char *name, Node *arg); static A_Const *makeBoolConst(bool state); static FuncCall *makeOverlaps(List *largs, List *rargs); +static List *extractArgTypes(List *parameters); static SelectStmt *findLeftmostSelect(SelectStmt *node); static void insertSelectOptions(SelectStmt *stmt, List *sortClause, List *forUpdate, @@ -116,6 +117,7 @@ static void doNegateFloat(Value *v); ObjectType objtype; TypeName *typnam; + FunctionParameter *fun_param; DefElem *defelt; SortBy *sortby; JoinExpr *jexpr; @@ -230,9 +232,10 @@ static void doNegateFloat(Value *v); %type <range> into_clause OptTempTableName %type <defelt> createfunc_opt_item -%type <typnam> func_arg func_return func_type aggr_argtype +%type <fun_param> func_arg +%type <typnam> func_return func_type aggr_argtype -%type <boolean> opt_arg TriggerForType OptTemp OptWithOids +%type <boolean> arg_class TriggerForType OptTemp OptWithOids %type <oncommit> OnCommitOption %type <list> for_update_clause opt_for_update_clause update_list @@ -303,7 +306,7 @@ static void doNegateFloat(Value *v); %type <str> Sconst comment_text %type <str> UserId opt_boolean ColId_or_Sconst %type <list> var_list var_list_or_default -%type <str> ColId ColLabel type_name +%type <str> ColId ColLabel type_name param_name %type <node> var_value zone_value %type <keyword> unreserved_keyword func_name_keyword @@ -2433,7 +2436,7 @@ opclass_item: CreateOpClassItem *n = makeNode(CreateOpClassItem); n->itemtype = OPCLASS_ITEM_FUNCTION; n->name = $3; - n->args = $4; + n->args = extractArgTypes($4); n->number = $2; $$ = (Node *) n; } @@ -2562,7 +2565,7 @@ CommentStmt: CommentStmt *n = makeNode(CommentStmt); n->objtype = OBJECT_FUNCTION; n->objname = $4; - n->objargs = $5; + n->objargs = extractArgTypes($5); n->comment = $7; $$ = (Node *) n; } @@ -2994,7 +2997,7 @@ function_with_argtypes: { FuncWithArgs *n = makeNode(FuncWithArgs); n->funcname = $1; - n->funcargs = $2; + n->funcargs = extractArgTypes($2); $$ = (Node *)n; } ; @@ -3094,7 +3097,7 @@ CreateFunctionStmt: CreateFunctionStmt *n = makeNode(CreateFunctionStmt); n->replace = $2; n->funcname = $4; - n->argTypes = $5; + n->parameters = $5; n->returnType = $7; n->options = $8; n->withClause = $9; @@ -3116,18 +3119,28 @@ func_args_list: | func_args_list ',' func_arg { $$ = lappend($1, $3); } ; -func_arg: opt_arg func_type +/* We can catch over-specified arguments here if we want to, + * but for now better to silently swallow typmod, etc. + * - thomas 2000-03-22 + */ +func_arg: + arg_class param_name func_type { - /* We can catch over-specified arguments here if we want to, - * but for now better to silently swallow typmod, etc. - * - thomas 2000-03-22 - */ - $$ = $2; + FunctionParameter *n = makeNode(FunctionParameter); + n->name = $2; + n->argType = $3; + $$ = n; + } + | arg_class func_type + { + FunctionParameter *n = makeNode(FunctionParameter); + n->name = NULL; + n->argType = $2; + $$ = n; } - | func_type { $$ = $1; } ; -opt_arg: IN_P { $$ = FALSE; } +arg_class: IN_P { $$ = FALSE; } | OUT_P { ereport(ERROR, @@ -3142,6 +3155,13 @@ opt_arg: IN_P { $$ = FALSE; } errmsg("CREATE FUNCTION / INOUT parameters are not implemented"))); $$ = FALSE; } + | /*EMPTY*/ { $$ = FALSE; } + ; + +/* + * Ideally param_name should be ColId, but that causes too many conflicts. + */ +param_name: function_name ; func_return: @@ -3255,7 +3275,7 @@ RemoveFuncStmt: { RemoveFuncStmt *n = makeNode(RemoveFuncStmt); n->funcname = $3; - n->args = $4; + n->args = extractArgTypes($4); n->behavior = $5; $$ = (Node *)n; } @@ -3433,7 +3453,7 @@ RenameStmt: ALTER AGGREGATE func_name '(' aggr_argtype ')' RENAME TO name RenameStmt *n = makeNode(RenameStmt); n->renameType = OBJECT_FUNCTION; n->object = $3; - n->objarg = $4; + n->objarg = extractArgTypes($4); n->newname = $7; $$ = (Node *)n; } @@ -7402,7 +7422,6 @@ unreserved_keyword: | INCREMENT | INDEX | INHERITS - | INOUT | INPUT_P | INSENSITIVE | INSERT @@ -7428,7 +7447,6 @@ unreserved_keyword: | MONTH_P | MOVE | NAMES - | NATIONAL | NEXT | NO | NOCREATEDB @@ -7440,13 +7458,11 @@ unreserved_keyword: | OIDS | OPERATOR | OPTION - | OUT_P | OWNER | PARTIAL | PASSWORD | PATH_P | PENDANT - | PRECISION | PREPARE | PRESERVE | PRIOR @@ -7543,15 +7559,19 @@ col_name_keyword: | EXISTS | EXTRACT | FLOAT_P + | INOUT | INT_P | INTEGER | INTERVAL + | NATIONAL | NCHAR | NONE | NULLIF | NUMERIC + | OUT_P | OVERLAY | POSITION + | PRECISION | REAL | ROW | SETOF @@ -7582,7 +7602,6 @@ func_name_keyword: | FREEZE | FULL | ILIKE - | IN_P | INNER_P | IS | ISNULL @@ -7640,6 +7659,7 @@ reserved_keyword: | GRANT | GROUP_P | HAVING + | IN_P | INITIALLY | INTERSECT | INTO @@ -7942,6 +7962,27 @@ makeOverlaps(List *largs, List *rargs) return n; } +/* extractArgTypes() + * Given a list of FunctionParameter nodes, extract a list of just the + * argument types (TypeNames). Most of the productions using func_args + * don't currently want the full FunctionParameter data, so we use this + * rather than having two sets of productions. + */ +static List * +extractArgTypes(List *parameters) +{ + List *result = NIL; + List *i; + + foreach(i, parameters) + { + FunctionParameter *p = (FunctionParameter *) lfirst(i); + + result = lappend(result, p->argType); + } + return result; +} + /* findLeftmostSelect() * Find the leftmost component SelectStmt in a set-operation parsetree. */ diff --git a/src/backend/utils/adt/sets.c b/src/backend/utils/adt/sets.c index 45a8b9d5080..33f1ed1a4a8 100644 --- a/src/backend/utils/adt/sets.c +++ b/src/backend/utils/adt/sets.c @@ -10,7 +10,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/adt/sets.c,v 1.61 2003/11/29 19:51:59 pgsql Exp $ + * $PostgreSQL: pgsql/src/backend/utils/adt/sets.c,v 1.62 2004/01/06 23:55:18 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -65,8 +65,9 @@ SetDefine(char *querystr, Oid elemType) false, /* security invoker */ false, /* isStrict (irrelevant, no args) */ PROVOLATILE_VOLATILE, /* assume unsafe */ - 0, /* parameterCount */ - NULL); /* parameterTypes */ + 0, /* parameterCount */ + NULL, /* parameterTypes */ + NULL); /* parameterNames */ /* * Since we're still inside this command of the transaction, we can't diff --git a/src/backend/utils/fmgr/fmgr.c b/src/backend/utils/fmgr/fmgr.c index a6d5246a4aa..c42dfba32b5 100644 --- a/src/backend/utils/fmgr/fmgr.c +++ b/src/backend/utils/fmgr/fmgr.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/fmgr/fmgr.c,v 1.77 2003/11/29 19:52:01 pgsql Exp $ + * $PostgreSQL: pgsql/src/backend/utils/fmgr/fmgr.c,v 1.78 2004/01/06 23:55:19 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -155,6 +155,8 @@ fmgr_info_cxt_security(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt, const FmgrBuiltin *fbp; HeapTuple procedureTuple; Form_pg_proc procedureStruct; + Datum prosrcdatum; + bool isnull; char *prosrc; /* @@ -214,8 +216,12 @@ fmgr_info_cxt_security(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt, * name of the internal function is stored in prosrc (it * doesn't have to be the same as the name of the alias!) */ + prosrcdatum = SysCacheGetAttr(PROCOID, procedureTuple, + Anum_pg_proc_prosrc, &isnull); + if (isnull) + elog(ERROR, "null prosrc"); prosrc = DatumGetCString(DirectFunctionCall1(textout, - PointerGetDatum(&procedureStruct->prosrc))); + prosrcdatum)); fbp = fmgr_lookupByName(prosrc); if (fbp == NULL) ereport(ERROR, |