diff options
author | Peter Eisentraut <peter_e@gmx.net> | 2018-04-13 17:06:28 -0400 |
---|---|---|
committer | Peter Eisentraut <peter_e@gmx.net> | 2018-04-14 09:13:53 -0400 |
commit | a8677e3ff6bb8ef78a9ba676faa647bba237b1c4 (patch) | |
tree | c9be62db9de8d2431ad906fbff57da9c0b6d22e7 /src/backend/commands/functioncmds.c | |
parent | 7c44c46deb495a2f3861f402d7f2109263e3d50a (diff) | |
download | postgresql-a8677e3ff6bb8ef78a9ba676faa647bba237b1c4.tar.gz postgresql-a8677e3ff6bb8ef78a9ba676faa647bba237b1c4.zip |
Support named and default arguments in CALL
We need to call expand_function_arguments() to expand named and default
arguments.
In PL/pgSQL, we also need to deal with named and default INOUT arguments
when receiving the output values into variables.
Author: Pavel Stehule <pavel.stehule@gmail.com>
Diffstat (limited to 'src/backend/commands/functioncmds.c')
-rw-r--r-- | src/backend/commands/functioncmds.c | 35 |
1 files changed, 21 insertions, 14 deletions
diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c index 80cbbf94b47..3c74873eeb6 100644 --- a/src/backend/commands/functioncmds.c +++ b/src/backend/commands/functioncmds.c @@ -52,6 +52,7 @@ #include "executor/execdesc.h" #include "executor/executor.h" #include "miscadmin.h" +#include "optimizer/clauses.h" #include "optimizer/var.h" #include "parser/parse_coerce.h" #include "parser/parse_collate.h" @@ -2226,34 +2227,40 @@ ExecuteCallStmt(CallStmt *stmt, ParamListInfo params, bool atomic, DestReceiver if (aclresult != ACLCHECK_OK) aclcheck_error(aclresult, OBJECT_PROCEDURE, get_func_name(fexpr->funcid)); - nargs = list_length(fexpr->args); - - /* safety check; see ExecInitFunc() */ - if (nargs > FUNC_MAX_ARGS) - ereport(ERROR, - (errcode(ERRCODE_TOO_MANY_ARGUMENTS), - errmsg_plural("cannot pass more than %d argument to a procedure", - "cannot pass more than %d arguments to a procedure", - FUNC_MAX_ARGS, - FUNC_MAX_ARGS))); - /* Prep the context object we'll pass to the procedure */ callcontext = makeNode(CallContext); callcontext->atomic = atomic; + tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(fexpr->funcid)); + if (!HeapTupleIsValid(tp)) + elog(ERROR, "cache lookup failed for function %u", fexpr->funcid); + /* * If proconfig is set we can't allow transaction commands because of the * way the GUC stacking works: The transaction boundary would have to pop * the proconfig setting off the stack. That restriction could be lifted * by redesigning the GUC nesting mechanism a bit. */ - tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(fexpr->funcid)); - if (!HeapTupleIsValid(tp)) - elog(ERROR, "cache lookup failed for function %u", fexpr->funcid); if (!heap_attisnull(tp, Anum_pg_proc_proconfig, NULL)) callcontext->atomic = true; + + /* + * Expand named arguments, defaults, etc. + */ + fexpr->args = expand_function_arguments(fexpr->args, fexpr->funcresulttype, tp); + nargs = list_length(fexpr->args); + ReleaseSysCache(tp); + /* safety check; see ExecInitFunc() */ + if (nargs > FUNC_MAX_ARGS) + ereport(ERROR, + (errcode(ERRCODE_TOO_MANY_ARGUMENTS), + errmsg_plural("cannot pass more than %d argument to a procedure", + "cannot pass more than %d arguments to a procedure", + FUNC_MAX_ARGS, + FUNC_MAX_ARGS))); + /* Initialize function call structure */ InvokeFunctionExecuteHook(fexpr->funcid); fmgr_info(fexpr->funcid, &flinfo); |