1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-17 17:02:08 +03:00

Default values for function arguments

Pavel Stehule, with some tweaks by Peter Eisentraut
This commit is contained in:
Peter Eisentraut
2008-12-04 17:51:28 +00:00
parent 7b640b0345
commit 455dffbb73
29 changed files with 2848 additions and 2166 deletions

View File

@ -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);
}