summaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
authorPeter Eisentraut2018-02-20 23:03:31 +0000
committerPeter Eisentraut2018-02-23 02:36:48 +0000
commit76b6aa41f41db66004b1c430f17a546d4102fbe7 (patch)
tree3df4add677bd9cc44e9369d2311775a13e76e220 /src/backend
parenta6a80134e3bffa0678a82ed7477d9d46dea07d3a (diff)
Support parameters in CALL
To support parameters in CALL, move the parse analysis of the procedure and arguments into the global transformation phase, so that the parser hooks can be applied. And then at execution time pass the parameters from ProcessUtility on to ExecuteCallStmt.
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/commands/functioncmds.c25
-rw-r--r--src/backend/nodes/copyfuncs.c1
-rw-r--r--src/backend/nodes/equalfuncs.c1
-rw-r--r--src/backend/parser/analyze.c45
-rw-r--r--src/backend/tcop/utility.c2
5 files changed, 52 insertions, 22 deletions
diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c
index a027b19744a..abdfa249c01 100644
--- a/src/backend/commands/functioncmds.c
+++ b/src/backend/commands/functioncmds.c
@@ -2212,11 +2212,9 @@ ExecuteDoStmt(DoStmt *stmt, bool atomic)
* commits that might occur inside the procedure.
*/
void
-ExecuteCallStmt(ParseState *pstate, CallStmt *stmt, bool atomic)
+ExecuteCallStmt(CallStmt *stmt, ParamListInfo params, bool atomic)
{
- List *targs;
ListCell *lc;
- Node *node;
FuncExpr *fexpr;
int nargs;
int i;
@@ -2228,24 +2226,8 @@ ExecuteCallStmt(ParseState *pstate, CallStmt *stmt, bool atomic)
ExprContext *econtext;
HeapTuple tp;
- /* We need to do parse analysis on the procedure call and its arguments */
- targs = NIL;
- foreach(lc, stmt->funccall->args)
- {
- targs = lappend(targs, transformExpr(pstate,
- (Node *) lfirst(lc),
- EXPR_KIND_CALL_ARGUMENT));
- }
-
- node = ParseFuncOrColumn(pstate,
- stmt->funccall->funcname,
- targs,
- pstate->p_last_srf,
- stmt->funccall,
- true,
- stmt->funccall->location);
-
- fexpr = castNode(FuncExpr, node);
+ fexpr = stmt->funcexpr;
+ Assert(fexpr);
aclresult = pg_proc_aclcheck(fexpr->funcid, GetUserId(), ACL_EXECUTE);
if (aclresult != ACLCHECK_OK)
@@ -2289,6 +2271,7 @@ ExecuteCallStmt(ParseState *pstate, CallStmt *stmt, bool atomic)
* we can't free this context till the procedure returns.
*/
estate = CreateExecutorState();
+ estate->es_param_list_info = params;
econtext = CreateExprContext(estate);
i = 0;
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index 82255b0d1da..266a3ef8ef6 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -3231,6 +3231,7 @@ _copyCallStmt(const CallStmt *from)
CallStmt *newnode = makeNode(CallStmt);
COPY_NODE_FIELD(funccall);
+ COPY_NODE_FIELD(funcexpr);
return newnode;
}
diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c
index b9bc8e38d74..bbffc878423 100644
--- a/src/backend/nodes/equalfuncs.c
+++ b/src/backend/nodes/equalfuncs.c
@@ -1206,6 +1206,7 @@ static bool
_equalCallStmt(const CallStmt *a, const CallStmt *b)
{
COMPARE_NODE_FIELD(funccall);
+ COMPARE_NODE_FIELD(funcexpr);
return true;
}
diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c
index 5b3a610cf9f..c3a9617f67f 100644
--- a/src/backend/parser/analyze.c
+++ b/src/backend/parser/analyze.c
@@ -36,6 +36,8 @@
#include "parser/parse_coerce.h"
#include "parser/parse_collate.h"
#include "parser/parse_cte.h"
+#include "parser/parse_expr.h"
+#include "parser/parse_func.h"
#include "parser/parse_oper.h"
#include "parser/parse_param.h"
#include "parser/parse_relation.h"
@@ -74,6 +76,8 @@ static Query *transformExplainStmt(ParseState *pstate,
ExplainStmt *stmt);
static Query *transformCreateTableAsStmt(ParseState *pstate,
CreateTableAsStmt *stmt);
+static Query *transformCallStmt(ParseState *pstate,
+ CallStmt *stmt);
static void transformLockingClause(ParseState *pstate, Query *qry,
LockingClause *lc, bool pushedDown);
#ifdef RAW_EXPRESSION_COVERAGE_TEST
@@ -318,6 +322,10 @@ transformStmt(ParseState *pstate, Node *parseTree)
(CreateTableAsStmt *) parseTree);
break;
+ case T_CallStmt:
+ result = transformCallStmt(pstate,
+ (CallStmt *) parseTree);
+
default:
/*
@@ -2571,6 +2579,43 @@ transformCreateTableAsStmt(ParseState *pstate, CreateTableAsStmt *stmt)
return result;
}
+/*
+ * transform a CallStmt
+ *
+ * We need to do parse analysis on the procedure call and its arguments.
+ */
+static Query *
+transformCallStmt(ParseState *pstate, CallStmt *stmt)
+{
+ List *targs;
+ ListCell *lc;
+ Node *node;
+ Query *result;
+
+ targs = NIL;
+ foreach(lc, stmt->funccall->args)
+ {
+ targs = lappend(targs, transformExpr(pstate,
+ (Node *) lfirst(lc),
+ EXPR_KIND_CALL_ARGUMENT));
+ }
+
+ node = ParseFuncOrColumn(pstate,
+ stmt->funccall->funcname,
+ targs,
+ pstate->p_last_srf,
+ stmt->funccall,
+ true,
+ stmt->funccall->location);
+
+ stmt->funcexpr = castNode(FuncExpr, node);
+
+ result = makeNode(Query);
+ result->commandType = CMD_UTILITY;
+ result->utilityStmt = (Node *) stmt;
+
+ return result;
+}
/*
* Produce a string representation of a LockClauseStrength value.
diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
index 8c23ee53e2b..f78efdf359a 100644
--- a/src/backend/tcop/utility.c
+++ b/src/backend/tcop/utility.c
@@ -660,7 +660,7 @@ standard_ProcessUtility(PlannedStmt *pstmt,
break;
case T_CallStmt:
- ExecuteCallStmt(pstate, castNode(CallStmt, parsetree),
+ ExecuteCallStmt(castNode(CallStmt, parsetree), params,
(context != PROCESS_UTILITY_TOPLEVEL || IsTransactionBlock()));
break;