当前位置:网站首页>PostgreSQL notes (10) dynamically execute syntax parsing process
PostgreSQL notes (10) dynamically execute syntax parsing process
2022-07-01 23:28:00 【mingjie73】
background
Postgresql in PLPGSQL Support dynamic splicing SQL And implement :
https://www.postgresql.org/docs/current/plpgsql-statements.html#PLPGSQL-STATEMENTS-EXECUTING-DYN
for example :
EXECUTE 'SELECT count(*) FROM mytable WHERE inserted_by = $1 AND inserted <= $2'
INTO c
USING checked_user, checked_date;
This article briefly analyzes EXECUTE Execute the process .
test case
drop table u1tbl;
create table u1tbl(i int);
insert into u1tbl values (1);
insert into u1tbl values (2);
insert into u1tbl values (3);
drop function f1();
CREATE OR REPLACE FUNCTION f1() RETURNS int AS $$
DECLARE
id int;
i1 int := 1;
i2 int := 2;
BEGIN
EXECUTE 'SELECT sum(i) FROM u1tbl WHERE i >= $1 AND i <= $2'
INTO id
USING i1, i2;
return id;
END;
$$ LANGUAGE plpgsql;
select f1();
postgres=# select f1();
f1
----
3
(1 row)
EXECUTE Analytical process
EXECUTE 'SELECT sum(i) FROM u1tbl WHERE i >= $1 AND i <= $2' INTO id USING i1, i2;
1、 for the first time read_sql_construct Will be called many times lex Put what you need SQL Extract it all , The actual situation is for the first time lex after , Will be able to EXECUTE after '' Take out all the text in , Give a SCONST Of token.
The process is as follows :
EXECUTE 'SELECT sum(i) FROM u1tbl WHERE i >= $1 AND i <= $2' INTO id USING i1, i2;
|--------------- SCONST -----------------| K_INTO K_USING
[pl_gram.y] stmt_dynexecute : K_EXECUTE read_sql_construct
[ scan.l] {xqstart} BEGIN(xq);
[ scan.l] <xq,xus>{xqinside} addlit(yytext, yyleng, yyscanner);
[ scan.l] <xb,xh,xq,xe,xus>{quote} BEGIN(xqs);
[ scan.l] <xqs><<EOF>> BEGIN(INITIAL); return SCONST;
[pl_gram.y]
2、 Later in the circulation body read_sql_construct Will be able to USING Everything in the back SQL Or read the variable name , Press , Separate . every last SQL Or the variable is recorded as a expr Hang it as a linked list PLpgSQL_stmt_dynexecute->param after .
Last returned PLpgSQL_stmt_dynexecute structure :
{
cmd_type = PLPGSQL_STMT_DYNEXECUTE,
lineno = 7,
stmtid = 1,
query = 0x1a3a328, <PLpgSQL_expr> 'SELECT sum(i) FROM u1tbl WHERE i >= $1 AND i <= $2'
into = true,
strict = false,
target = 0x1a3a490, <PLpgSQL_variable> dno=4 --> ((PLpgSQL_row*)plpgsql_Datums[4])
params = 0x1a3a600 List: <PLpgSQL_expr> <PLpgSQL_expr>
}
pl_gram.y Related to the source code
stmt_dynexecute : K_EXECUTE
{
PLpgSQL_stmt_dynexecute *new;
PLpgSQL_expr *expr;
int endtoken;
expr = read_sql_construct(K_INTO, K_USING, ';',
"INTO or USING or ;",
RAW_PARSE_PLPGSQL_EXPR,
true, true, true,
NULL, &endtoken);
new = palloc(sizeof(PLpgSQL_stmt_dynexecute));
new->cmd_type = PLPGSQL_STMT_DYNEXECUTE;
new->lineno = plpgsql_location_to_lineno(@1);
new->stmtid = ++plpgsql_curr_compile->nstatements;
new->query = expr;
new->into = false;
new->strict = false;
new->target = NULL;
new->params = NIL;
/*
* We loop to allow the INTO and USING clauses to
* appear in either order, since people easily get
* that wrong. This coding also prevents "INTO foo"
* from getting absorbed into a USING expression,
* which is *really* confusing.
*/
for (;;)
{
if (endtoken == K_INTO)
{
if (new->into) /* multiple INTO */
yyerror("syntax error");
new->into = true;
read_into_target(&new->target, &new->strict);
endtoken = yylex();
}
else if (endtoken == K_USING)
{
if (new->params) /* multiple USING */
yyerror("syntax error");
do
{
expr = read_sql_construct(',', ';', K_INTO,
", or ; or INTO",
RAW_PARSE_PLPGSQL_EXPR,
true, true, true,
NULL, &endtoken);
new->params = lappend(new->params, expr);
} while (endtoken == ',');
}
else if (endtoken == ';')
break;
else
yyerror("syntax error");
}
$$ = (PLpgSQL_stmt *)new;
}
;
SELECT sum(i) FROM u1tbl WHERE i >= $1 AND i <= $2’
边栏推荐
- [micro service sentinel] sentinelresourceaspect details
- What are the common types of points mall games?
- flutter Unable to load asset: assets/images/888. png
- What category does the Internet of things application technology major belong to
- 【小程序】通过scroll-view组件实现左右【滑动】列表
- 【微服务|Sentinel】@SentinelResource详解
- RPA: Bank digitalization, business process automation "a small step", and loan review efficiency "a big step"
- The online beggar function of Japanese shopping websites
- Matplotlib常用設置
- 常见的积分商城游戏类型有哪些?
猜你喜欢

软件架构的本质

2022年起重机司机(限桥式起重机)考试试题及模拟考试

notBlank 和 notEmpty

RPA: Bank digitalization, business process automation "a small step", and loan review efficiency "a big step"

mt管理器测试滑雪大冒险

2022年R1快开门式压力容器操作考题及答案

Linux基础 —— CentOS7 离线安装 MySQL

Zhao Fuquan: to ensure supply in the short term, we should build a safe, efficient and resilient supply chain in the long term

神经网络物联网的发展趋势和未来方向

2022 safety officer-c certificate examination question simulation examination question bank and simulation examination
随机推荐
【小程序】通过scroll-view组件实现左右【滑动】列表
ShanDong Multi-University Training #3
Some thoughts on game performance optimization
Paramètres communs de matplotlib
建模和影视后期有什么关联?
typescript枚举
plain framework的实际应用和扩展
y53.第三章 Kubernetes从入门到精通 -- ingress(二六)
2022-07-01:某公司年会上,大家要玩一食发奖金游戏,一共有n个员工, 每个员工都有建设积分和捣乱积分, 他们需要排成一队,在队伍最前面的一定是老板
【微服务|Sentinel】SentinelResourceAspect详解
SWT/ANR问题--SWT 导致 low memory killer(LMK)
Redis RDB快照
Wechat personal small store one click opening assistant applet development
每日三题 6.29
Three development trends of enterprise application from the perspective of the third technological revolution
notBlank 和 notEmpty
[micro service sentinel] sentinelresourceaspect details
2022年起重机司机(限桥式起重机)考试试题及模拟考试
What is the relationship between modeling and later film and television?
[applet] realize the left and right [sliding] list through the scroll view component