当前位置:网站首页>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’
边栏推荐
- [understanding of opportunity-35]: Guiguzi - flying clamp - the art of remote connection, remote control and remote testing
- 2022 crane driver (limited to bridge crane) examination questions and simulation examination
- [LeetCode] 最后一个单词的长度【58】
- The difference between timer and scheduledthreadpoolexecutor
- Notes on problems - /usr/bin/perl is needed by mysql-server-5.1.73-1 glibc23.x86_ sixty-four
- 转行软件测试,知道这四点就够了!
- 内存泄露和内存溢出的区别是什么?
- Linux foundation - centos7 offline installation of MySQL
- 从第三次技术革命看企业应用三大开发趋势
- SWT/ANR问题--SWT 导致 low memory killer(LMK)
猜你喜欢
[micro service sentinel] sentinel integrates openfeign
Zhao Fuquan: to ensure supply in the short term, we should build a safe, efficient and resilient supply chain in the long term
AirServer最新Win64位个人版投屏软件
Why is PHP called hypertext preprocessor
CADD课程学习(3)-- 靶点药物相互作用
2021 RoboCom 世界机器人开发者大赛-高职组初赛
2022年最佳智能家居开源系统:Alexa、Home Assistant、HomeKit生态系统介绍
2021 RoboCom 世界机器人开发者大赛-高职组复赛
2021 RoboCom 世界机器人开发者大赛-本科组初赛
2022 examination questions and online simulation examination for safety management personnel of hazardous chemical business units
随机推荐
想请教股票开户要认识谁?在线开户是安全么?
y53.第三章 Kubernetes从入门到精通 -- ingress(二六)
Three development trends of enterprise application from the perspective of the third technological revolution
What are the common types of points mall games?
13 MySQL-约束
MySQL binlog cleanup
Wechat personal small store one click opening assistant applet development
Redis数据类型和应用场景
Redis 主从同步
【微服务|Sentinel】sentinel整合openfeign
[must] bm41 output the right view of the binary tree [medium +]
会声会影2022智能、快速、简单的视频剪辑软件
Typescript enumeration
【必会】BM41 输出二叉树的右视图【中等+】
物联网技术应用属于什么专业分类
认识--Matplotlib
Daily three questions 6.28
Redis~02 cache: how to ensure data consistency in MySQL and redis when updating data?
[micro service sentinel] @sentinelresource details
Win 10 mstsc connect RemoteApp