Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit76b6aa4

Browse files
committed
Support parameters in CALL
To support parameters in CALL, move the parse analysis of the procedureand arguments into the global transformation phase, so that the parserhooks can be applied. And then at execution time pass the parametersfrom ProcessUtility on to ExecuteCallStmt.
1 parenta6a8013 commit76b6aa4

File tree

11 files changed

+124
-24
lines changed

11 files changed

+124
-24
lines changed

‎src/backend/commands/functioncmds.c

Lines changed: 4 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2212,11 +2212,9 @@ ExecuteDoStmt(DoStmt *stmt, bool atomic)
22122212
* commits that might occur inside the procedure.
22132213
*/
22142214
void
2215-
ExecuteCallStmt(ParseState*pstate,CallStmt*stmt,boolatomic)
2215+
ExecuteCallStmt(CallStmt*stmt,ParamListInfoparams,boolatomic)
22162216
{
2217-
List*targs;
22182217
ListCell*lc;
2219-
Node*node;
22202218
FuncExpr*fexpr;
22212219
intnargs;
22222220
inti;
@@ -2228,24 +2226,8 @@ ExecuteCallStmt(ParseState *pstate, CallStmt *stmt, bool atomic)
22282226
ExprContext*econtext;
22292227
HeapTupletp;
22302228

2231-
/* We need to do parse analysis on the procedure call and its arguments */
2232-
targs=NIL;
2233-
foreach(lc,stmt->funccall->args)
2234-
{
2235-
targs=lappend(targs,transformExpr(pstate,
2236-
(Node*)lfirst(lc),
2237-
EXPR_KIND_CALL_ARGUMENT));
2238-
}
2239-
2240-
node=ParseFuncOrColumn(pstate,
2241-
stmt->funccall->funcname,
2242-
targs,
2243-
pstate->p_last_srf,
2244-
stmt->funccall,
2245-
true,
2246-
stmt->funccall->location);
2247-
2248-
fexpr=castNode(FuncExpr,node);
2229+
fexpr=stmt->funcexpr;
2230+
Assert(fexpr);
22492231

22502232
aclresult=pg_proc_aclcheck(fexpr->funcid,GetUserId(),ACL_EXECUTE);
22512233
if (aclresult!=ACLCHECK_OK)
@@ -2289,6 +2271,7 @@ ExecuteCallStmt(ParseState *pstate, CallStmt *stmt, bool atomic)
22892271
* we can't free this context till the procedure returns.
22902272
*/
22912273
estate=CreateExecutorState();
2274+
estate->es_param_list_info=params;
22922275
econtext=CreateExprContext(estate);
22932276

22942277
i=0;

‎src/backend/nodes/copyfuncs.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3231,6 +3231,7 @@ _copyCallStmt(const CallStmt *from)
32313231
CallStmt*newnode=makeNode(CallStmt);
32323232

32333233
COPY_NODE_FIELD(funccall);
3234+
COPY_NODE_FIELD(funcexpr);
32343235

32353236
returnnewnode;
32363237
}

‎src/backend/nodes/equalfuncs.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1206,6 +1206,7 @@ static bool
12061206
_equalCallStmt(constCallStmt*a,constCallStmt*b)
12071207
{
12081208
COMPARE_NODE_FIELD(funccall);
1209+
COMPARE_NODE_FIELD(funcexpr);
12091210

12101211
return true;
12111212
}

‎src/backend/parser/analyze.c

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636
#include"parser/parse_coerce.h"
3737
#include"parser/parse_collate.h"
3838
#include"parser/parse_cte.h"
39+
#include"parser/parse_expr.h"
40+
#include"parser/parse_func.h"
3941
#include"parser/parse_oper.h"
4042
#include"parser/parse_param.h"
4143
#include"parser/parse_relation.h"
@@ -74,6 +76,8 @@ static Query *transformExplainStmt(ParseState *pstate,
7476
ExplainStmt*stmt);
7577
staticQuery*transformCreateTableAsStmt(ParseState*pstate,
7678
CreateTableAsStmt*stmt);
79+
staticQuery*transformCallStmt(ParseState*pstate,
80+
CallStmt*stmt);
7781
staticvoidtransformLockingClause(ParseState*pstate,Query*qry,
7882
LockingClause*lc,boolpushedDown);
7983
#ifdefRAW_EXPRESSION_COVERAGE_TEST
@@ -318,6 +322,10 @@ transformStmt(ParseState *pstate, Node *parseTree)
318322
(CreateTableAsStmt*)parseTree);
319323
break;
320324

325+
caseT_CallStmt:
326+
result=transformCallStmt(pstate,
327+
(CallStmt*)parseTree);
328+
321329
default:
322330

323331
/*
@@ -2571,6 +2579,43 @@ transformCreateTableAsStmt(ParseState *pstate, CreateTableAsStmt *stmt)
25712579
returnresult;
25722580
}
25732581

2582+
/*
2583+
* transform a CallStmt
2584+
*
2585+
* We need to do parse analysis on the procedure call and its arguments.
2586+
*/
2587+
staticQuery*
2588+
transformCallStmt(ParseState*pstate,CallStmt*stmt)
2589+
{
2590+
List*targs;
2591+
ListCell*lc;
2592+
Node*node;
2593+
Query*result;
2594+
2595+
targs=NIL;
2596+
foreach(lc,stmt->funccall->args)
2597+
{
2598+
targs=lappend(targs,transformExpr(pstate,
2599+
(Node*)lfirst(lc),
2600+
EXPR_KIND_CALL_ARGUMENT));
2601+
}
2602+
2603+
node=ParseFuncOrColumn(pstate,
2604+
stmt->funccall->funcname,
2605+
targs,
2606+
pstate->p_last_srf,
2607+
stmt->funccall,
2608+
true,
2609+
stmt->funccall->location);
2610+
2611+
stmt->funcexpr=castNode(FuncExpr,node);
2612+
2613+
result=makeNode(Query);
2614+
result->commandType=CMD_UTILITY;
2615+
result->utilityStmt= (Node*)stmt;
2616+
2617+
returnresult;
2618+
}
25742619

25752620
/*
25762621
* Produce a string representation of a LockClauseStrength value.

‎src/backend/tcop/utility.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -660,7 +660,7 @@ standard_ProcessUtility(PlannedStmt *pstmt,
660660
break;
661661

662662
caseT_CallStmt:
663-
ExecuteCallStmt(pstate,castNode(CallStmt,parsetree),
663+
ExecuteCallStmt(castNode(CallStmt,parsetree),params,
664664
(context!=PROCESS_UTILITY_TOPLEVEL||IsTransactionBlock()));
665665
break;
666666

‎src/include/commands/defrem.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#defineDEFREM_H
1616

1717
#include"catalog/objectaddress.h"
18+
#include"nodes/params.h"
1819
#include"nodes/parsenodes.h"
1920
#include"utils/array.h"
2021

@@ -61,7 +62,7 @@ extern void DropTransformById(Oid transformOid);
6162
externvoidIsThereFunctionInNamespace(constchar*proname,intpronargs,
6263
oidvector*proargtypes,OidnspOid);
6364
externvoidExecuteDoStmt(DoStmt*stmt,boolatomic);
64-
externvoidExecuteCallStmt(ParseState*pstate,CallStmt*stmt,boolatomic);
65+
externvoidExecuteCallStmt(CallStmt*stmt,ParamListInfoparams,boolatomic);
6566
externOidget_cast_oid(Oidsourcetypeid,Oidtargettypeid,boolmissing_ok);
6667
externOidget_transform_oid(Oidtype_id,Oidlang_id,boolmissing_ok);
6768
externvoidinterpret_function_parameter_list(ParseState*pstate,

‎src/include/nodes/parsenodes.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2814,7 +2814,8 @@ typedef struct InlineCodeBlock
28142814
typedefstructCallStmt
28152815
{
28162816
NodeTagtype;
2817-
FuncCall*funccall;
2817+
FuncCall*funccall;/* from the parser */
2818+
FuncExpr*funcexpr;/* transformed */
28182819
}CallStmt;
28192820

28202821
typedefstructCallContext

‎src/pl/plpgsql/src/expected/plpgsql_call.out

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,26 @@ SELECT * FROM test1;
3535
55
3636
(1 row)
3737

38+
-- nested CALL
39+
TRUNCATE TABLE test1;
40+
CREATE PROCEDURE test_proc4(y int)
41+
LANGUAGE plpgsql
42+
AS $$
43+
BEGIN
44+
CALL test_proc3(y);
45+
CALL test_proc3($1);
46+
END;
47+
$$;
48+
CALL test_proc4(66);
49+
SELECT * FROM test1;
50+
a
51+
----
52+
66
53+
66
54+
(2 rows)
55+
3856
DROP PROCEDURE test_proc1;
3957
DROP PROCEDURE test_proc2;
4058
DROP PROCEDURE test_proc3;
59+
DROP PROCEDURE test_proc4;
4160
DROP TABLE test1;

‎src/pl/plpgsql/src/sql/plpgsql_call.sql

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,26 @@ CALL test_proc3(55);
4040
SELECT*FROM test1;
4141

4242

43+
-- nested CALL
44+
TRUNCATE TABLE test1;
45+
46+
CREATE PROCEDURE test_proc4(yint)
47+
LANGUAGE plpgsql
48+
AS $$
49+
BEGIN
50+
CALL test_proc3(y);
51+
CALL test_proc3($1);
52+
END;
53+
$$;
54+
55+
CALL test_proc4(66);
56+
57+
SELECT*FROM test1;
58+
59+
4360
DROP PROCEDURE test_proc1;
4461
DROP PROCEDURE test_proc2;
4562
DROP PROCEDURE test_proc3;
63+
DROP PROCEDURE test_proc4;
4664

4765
DROPTABLE test1;

‎src/test/regress/expected/create_procedure.out

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,22 @@ AS $$
5555
SELECT 5;
5656
$$;
5757
CALL ptest2();
58+
-- nested CALL
59+
TRUNCATE cp_test;
60+
CREATE PROCEDURE ptest3(y text)
61+
LANGUAGE SQL
62+
AS $$
63+
CALL ptest1(y);
64+
CALL ptest1($1);
65+
$$;
66+
CALL ptest3('b');
67+
SELECT * FROM cp_test;
68+
a | b
69+
---+---
70+
1 | b
71+
1 | b
72+
(2 rows)
73+
5874
-- various error cases
5975
CALL version(); -- error: not a procedure
6076
ERROR: version() is not a procedure

‎src/test/regress/sql/create_procedure.sql

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,21 @@ $$;
3131
CALL ptest2();
3232

3333

34+
-- nested CALL
35+
TRUNCATE cp_test;
36+
37+
CREATE PROCEDURE ptest3(ytext)
38+
LANGUAGE SQL
39+
AS $$
40+
CALL ptest1(y);
41+
CALL ptest1($1);
42+
$$;
43+
44+
CALL ptest3('b');
45+
46+
SELECT*FROM cp_test;
47+
48+
3449
-- various error cases
3550

3651
CALL version();-- error: not a procedure

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp