Postgresql动态执行EXECUTING语法解析过程
背景
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 cUSING 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 $$
DECLAREid int;i1 int := 1;i2 int := 2;
BEGINEXECUTE 'SELECT sum(i) FROM u1tbl WHERE i >= $1 AND i <= $2'INTO idUSING 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;elseyyerror("syntax error");}$$ = (PLpgSQL_stmt *)new;};
SELECT sum(i) FROM u1tbl WHERE i >= $1 AND i <= $2’
Postgresql动态执行EXECUTING语法解析过程相关推荐
- 「三」浏览器中CSS 语法解析过程
CSS 语法解析过程 1.在浏览器系列文章中,今天终点讲下CSS解析这块内容.我们已知浏览器的渲染流程中HTML Parser会生成 DOM树,而 CSS Parser会将解析结果附加到 DOM 树上 ...
- oracle 动态执行ddl语句,Oracle过程中执行动态SQL或DDL语句
如果你用的是 Oracle 8i 及以上的版本,那简单,在过程中用 execute immediate sql_str 就行, sql_str 是一个拼凑的 SQL 语句, 如果你用的是 Oracle ...
- 内核级python:编译器的词法和语法解析基本原理
python在收到代码内容后,首先要启动两个流程,分别为词法解析和语法解析.看过我编译原理课程的同学对这两个流程应该不陌生.词法解析其实就是把代码里面不同的元素分别归类,例如234,1.35,1e3等 ...
- mysql查询解析过程_MySQL查询执行过程详解
查询是用户通过设置某些查询条件,从表或其他查询中选取全部或者部分数据,以表的形式显示数据供用户浏览.查询是一个独立的.功能强大的.具有计算功能和条件检索功能的数据库对象.MySQL数据库中,MySQL ...
- 【原创】大数据基础之Hive(2)Hive SQL执行过程之SQL解析过程
Hive SQL解析过程 SQL->AST(Abstract Syntax Tree)->Task(MapRedTask,FetchTask)->QueryPlan(Task集合)- ...
- Android 8.0 学习(12)---init.rc语法及解析过程总结
Android 8.0 init.rc语法及解析过程总结 Android O高通默认使用QMMI取代了fastmmi,但是由于QMMI是一个APK,属于Android应用层面,所以必须等到 ...
- mysql ddl 语法解析工具_sharding-sphere之语法解析器
语法解析器,根据不同类型的语句有不同的语法解析器去解析成成SQLStatement,SQL解析器的类图我用脑图画出来如下: SQLParser.png 可以看到,不同的sql有不同的处理解析器去解析, ...
- python动态运行py代码_Python 动态执行
Python 动态执行 2015-06-16 Tuesday 在 Python 中,允许通过 exec 和 eval 执行以字符串形式表示的代码片段,这体现了动态语言的特性,可以让代码变得更灵活.实际 ...
- sqlparser mysql_SQL语法解析器JSQLParser | IT瘾
相关 [sql 语法 解析器] 推荐: SQL 语法解释器jsqlparser. 是用java 开发的解析器, 可以生成java类层次结构.. 可以完美解析 表的 增删查改等操作.. 展开它的源码你会 ...
- oracle 测试sql执行时间_通过错误的SQL来测试推理SQL的解析过程
这是学习笔记的第 1977 篇文章 如果抛出一个问题,你是如何理解MySQL解析器的,它和Oracle解析器有什么差别?相信大多数同学都会比较迷茫,因为这个问题很难验证,要不是看源码,要不就是查看书上 ...
最新文章
- Unix shell 编程相关命令
- Makefile文件生成
- python定义函数计算斐波那契公式前20的项_Python3算法之二:斐波那契函数
- PHP学习笔记六【方法-递归】
- mfc 改变tab快捷键对控件的顺序
- php写简单的随机验证码
- No field gDefault in class Landroid/app/ActivityManagerNative
- kindeditor图片上传
- Ubuntu18.04创建新的系统用户
- freebsd mount linprocfs
- 设计模式(3)——装饰者模式
- redux-saga源码解析
- 汇编:1位16进制数到ASCII码转换
- 无标度网络的C++代码实现
- 微信小程序uniapp实现小图标转成SVN代码
- oracle分析函数结构,oracle之分析函数解析及其应用场景
- Nucleus SE RTOS 初始化和启动
- 中国计算机展望未来,作文:展望未来中国的2025
- 计算机网络 如何算 子网号,计算机网络的划分以及主机号子网号的计算方法
- 华为 Python:初级能力测评
热门文章
- 语音识别 卷积神经网络,卷积神经网络字符识别
- python除法运算定律有哪些_小学数学最重要的7个运算定律,都在这里了
- 计算机硬件 系统安装维护教程 02安装基础篇-02:MBR与GPT、分区、活动分区
- 2021牛客多校9.F.Train Wreck 构造
- 创新电影院意在传播中华民族优秀传统文化
- 博观约取,厚积薄发,聊一聊最近读完的几本书,太上头了~
- 任正非:不要在微信里消耗你的人生和青春
- 如何破解域管理员密码
- tas5424_TAS5424 Datasheet(数据表) 16 Page - Texas Instruments
- ubuntu16如何开wifi