当前位置:网站首页>Postgresql随手记(10)动态执行EXECUTING语法解析过程
Postgresql随手记(10)动态执行EXECUTING语法解析过程
2022-07-01 22:57:00 【mingjie73】
背景
Postgresql中PLPGSQL支持动态拼接SQL并执行:
https://www.postgresql.org/docs/current/plpgsql-statements.html#PLPGSQL-STATEMENTS-EXECUTING-DYN
例如:
EXECUTE 'SELECT count(*) FROM mytable WHERE inserted_by = $1 AND inserted <= $2'
INTO c
USING checked_user, checked_date;
本篇简单分析下EXECUTE执行流程。
测试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解析流程
EXECUTE 'SELECT sum(i) FROM u1tbl WHERE i >= $1 AND i <= $2' INTO id USING i1, i2;
1、第一次read_sql_construct中会调用多次lex把需要的SQL全部提取出来,实际情况是第一次lex后,会把EXECUTE后''内的所有文本拿出来,给出一个SCONST的token。
过程如下:
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、后面在循环体里面的read_sql_construct会把USING后面的所有SQL或变量名读取出来,按,分隔。每一个SQL或变量记为一个expr作为链表挂在PLpgSQL_stmt_dynexecute->param后。
最后返回的PLpgSQL_stmt_dynexecute结构:
{
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相关源码
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’
边栏推荐
- 问题随记 —— file /usr/share/mysql/charsets/README from install of MySQL-server-5.1.73-1.glibc23.x86_64 c
- 内存泄露和内存溢出的区别是什么?
- Win 10 mstsc connect RemoteApp
- ShanDong Multi-University Training #3
- SWT/ANR问题--SWT 导致 low memory killer(LMK)
- YOGA27多维一体电脑,兼具出色外观与高端配置
- Distance measurement - Hamming distance
- Redis data types and application scenarios
- 物联网现状及未来发展趋势
- Detailed explanation of twenty common software testing methods (the most complete in History)
猜你喜欢

Why is PHP called hypertext preprocessor

问题随记 —— file /usr/share/mysql/charsets/README from install of MySQL-server-5.1.73-1.glibc23.x86_64 c

距离度量 —— 汉明距离(Hamming Distance)

Paramètres communs de matplotlib

赵福全:短期解决保供,长期要打造安全、高效有韧性的供应链

【微服务|Sentinel】sentinel整合openfeign

Development trend and future direction of neural network Internet of things

Future trend and development of neural network Internet of things

from pip._ internal. cli. main import main ModuleNotFoundError: No module named ‘pip‘
![Compare the version number [double pointer to intercept the string you want]](/img/19/4f858ffdc1281d6b8b18a996467f10.png)
Compare the version number [double pointer to intercept the string you want]
随机推荐
JS - use of arguments
证券开户选哪个证券公司比较好,哪个更安全
Stm32f030f4 drives tim1637 nixie tube chip
Matplotlib common settings
AirServer最新Win64位个人版投屏软件
Notes on problems - /usr/bin/perl is needed by mysql-server-5.1.73-1 glibc23.x86_ sixty-four
Distance measurement - Hamming distance
CKS CKA CKAD 将终端更改为远程桌面
Jerry's burning of upper version materials requires [chapter]
Convergence and disposal suggestions of some Internet exposure surfaces
MT manager test skiing Adventure
The difference between timer and scheduledthreadpoolexecutor
Rank ranking with MySQL 5.7
The digital summit is popular, and city chain technology has triggered a new round of business transformation
Yoga27 multidimensional all-in-one computer with excellent appearance and high-end configuration
2022安全员-C证考试题模拟考试题库及模拟考试
Compare the version number [double pointer to intercept the string you want]
共享电商的背后: 共创、共生、共享、共富,共赢的共富精神
硅谷产品实战学习感触
YOGA27多维一体电脑,兼具出色外观与高端配置