aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/functioncmds.c
diff options
context:
space:
mode:
authorPeter Eisentraut <peter_e@gmx.net>2018-04-13 17:06:28 -0400
committerPeter Eisentraut <peter_e@gmx.net>2018-04-14 09:13:53 -0400
commita8677e3ff6bb8ef78a9ba676faa647bba237b1c4 (patch)
treec9be62db9de8d2431ad906fbff57da9c0b6d22e7 /src/backend/commands/functioncmds.c
parent7c44c46deb495a2f3861f402d7f2109263e3d50a (diff)
downloadpostgresql-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.c35
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);