aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/functioncmds.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/commands/functioncmds.c')
-rw-r--r--src/backend/commands/functioncmds.c48
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,
&parameterModes,
&parameterNames,
- &requiredResultType);
+ &defaults,
+ &requiredResultType,
+ queryString);
if (stmt->returnType)
{
@@ -836,7 +873,8 @@ CreateFunction(CreateFunctionStmt *stmt)
PointerGetDatum(parameterNames),
PointerGetDatum(proconfig),
procost,
- prorows);
+ prorows,
+ defaults);
}