diff options
Diffstat (limited to 'src/backend/commands/functioncmds.c')
-rw-r--r-- | src/backend/commands/functioncmds.c | 33 |
1 files changed, 30 insertions, 3 deletions
diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c index 9831692eea0..cb249d9c7d1 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.95 2008/07/12 10:44:56 petere Exp $ + * $PostgreSQL: pgsql/src/backend/commands/functioncmds.c,v 1.96 2008/07/16 01:30:22 tgl Exp $ * * DESCRIPTION * These routines take the parse tree and pick out the @@ -173,6 +173,7 @@ examine_parameter_list(List *parameters, Oid languageOid, Datum *paramModes; Datum *paramNames; int outCount = 0; + int varCount = 0; bool have_names = false; ListCell *x; int i; @@ -228,15 +229,41 @@ examine_parameter_list(List *parameters, Oid languageOid, errmsg("functions cannot accept set arguments"))); if (fp->mode != FUNC_PARAM_OUT) + { + /* only OUT parameters can follow a VARIADIC parameter */ + if (varCount > 0) + ereport(ERROR, + (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), + errmsg("VARIADIC parameter must be the last input parameter"))); inTypes[inCount++] = toid; + } - if (fp->mode != FUNC_PARAM_IN) + if (fp->mode != FUNC_PARAM_IN && fp->mode != FUNC_PARAM_VARIADIC) { if (outCount == 0) /* save first OUT param's type */ *requiredResultType = toid; outCount++; } + if (fp->mode == FUNC_PARAM_VARIADIC) + { + varCount++; + /* validate variadic parameter type */ + switch (toid) + { + case ANYARRAYOID: + case ANYOID: + /* okay */ + break; + default: + if (!OidIsValid(get_element_type(toid))) + ereport(ERROR, + (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), + errmsg("VARIADIC parameter must be an array"))); + break; + } + } + allTypes[i] = ObjectIdGetDatum(toid); paramModes[i] = CharGetDatum(fp->mode); @@ -253,7 +280,7 @@ examine_parameter_list(List *parameters, Oid languageOid, /* Now construct the proper outputs as needed */ *parameterTypes = buildoidvector(inTypes, inCount); - if (outCount > 0) + if (outCount > 0 || varCount > 0) { *allParameterTypes = construct_array(allTypes, parameterCount, OIDOID, sizeof(Oid), true, 'i'); |