diff options
Diffstat (limited to 'src/backend/commands/functioncmds.c')
-rw-r--r-- | src/backend/commands/functioncmds.c | 48 |
1 files changed, 43 insertions, 5 deletions
diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c index 97cde6419d1..1509da73124 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.101 2008/11/02 01:45:27 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/commands/functioncmds.c,v 1.102 2008/12/04 17:51:26 petere Exp $ * * DESCRIPTION * These routines take the parse tree and pick out the @@ -49,8 +49,10 @@ #include "commands/proclang.h" #include "miscadmin.h" #include "parser/parse_coerce.h" +#include "parser/parse_expr.h" #include "parser/parse_func.h" #include "parser/parse_type.h" +#include "parser/parse_utilcmd.h" #include "utils/acl.h" #include "utils/builtins.h" #include "utils/fmgroids.h" @@ -164,7 +166,9 @@ examine_parameter_list(List *parameters, Oid languageOid, ArrayType **allParameterTypes, ArrayType **parameterModes, ArrayType **parameterNames, - Oid *requiredResultType) + List **parameterDefaults, + Oid *requiredResultType, + const char *queryString) { int parameterCount = list_length(parameters); Oid *inTypes; @@ -177,6 +181,8 @@ examine_parameter_list(List *parameters, Oid languageOid, bool have_names = false; ListCell *x; int i; + bool have_defaults = false; + ParseState *pstate; *requiredResultType = InvalidOid; /* default result */ @@ -184,6 +190,10 @@ examine_parameter_list(List *parameters, Oid languageOid, allTypes = (Datum *) palloc(parameterCount * sizeof(Datum)); paramModes = (Datum *) palloc(parameterCount * sizeof(Datum)); paramNames = (Datum *) palloc0(parameterCount * sizeof(Datum)); + *parameterDefaults = NIL; + + pstate = make_parsestate(NULL); + pstate->p_sourcetext = queryString; /* Scan the list and extract data into work arrays */ i = 0; @@ -276,9 +286,33 @@ examine_parameter_list(List *parameters, Oid languageOid, have_names = true; } + if (fp->defexpr) + { + if (fp->mode != FUNC_PARAM_IN && fp->mode != FUNC_PARAM_INOUT) + ereport(ERROR, + (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), + errmsg("only IN and INOUT parameters can have default values"))); + + *parameterDefaults = lappend(*parameterDefaults, + coerce_to_specific_type(NULL, + transformExpr(pstate, fp->defexpr), + toid, + "DEFAULT")); + have_defaults = true; + } + else + { + if (have_defaults) + ereport(ERROR, + (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), + errmsg("parameter without default value specified after parameter with default value"))); + } + i++; } + free_parsestate(pstate); + /* Now construct the proper outputs as needed */ *parameterTypes = buildoidvector(inTypes, inCount); @@ -653,7 +687,7 @@ interpret_AS_clause(Oid languageOid, const char *languageName, * Execute a CREATE FUNCTION utility statement. */ void -CreateFunction(CreateFunctionStmt *stmt) +CreateFunction(CreateFunctionStmt *stmt, const char *queryString) { char *probin_str; char *prosrc_str; @@ -680,6 +714,7 @@ CreateFunction(CreateFunctionStmt *stmt) HeapTuple languageTuple; Form_pg_language languageStruct; List *as_clause; + List *defaults = NULL; /* Convert list of names to a name and namespace */ namespaceId = QualifiedNameGetCreationNamespace(stmt->funcname, @@ -753,7 +788,9 @@ CreateFunction(CreateFunctionStmt *stmt) &allParameterTypes, ¶meterModes, ¶meterNames, - &requiredResultType); + &defaults, + &requiredResultType, + queryString); if (stmt->returnType) { @@ -836,7 +873,8 @@ CreateFunction(CreateFunctionStmt *stmt) PointerGetDatum(parameterNames), PointerGetDatum(proconfig), procost, - prorows); + prorows, + defaults); } |