前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Postgresql随手记(7)使用plpgsql解析stmt_execsql子树过程

Postgresql随手记(7)使用plpgsql解析stmt_execsql子树过程

作者头像
mingjie
发布2022-07-14 13:51:42
1710
发布2022-07-14 13:51:42
举报

stmt_execsql语法树

stmt_execsql是pl_block->proc_stmt大语法树中的一个分支

代码语言:javascript
复制
proc_stmt		: pl_block ';'
						{ $$ = $1; }
				| stmt_assign
						{ $$ = $1; }
				| stmt_if
						{ $$ = $1; }
				| stmt_case
						{ $$ = $1; }
				| stmt_loop
						{ $$ = $1; }
				| stmt_while
						{ $$ = $1; }
				| stmt_for
						{ $$ = $1; }
				| stmt_foreach_a
						{ $$ = $1; }
				| stmt_exit
						{ $$ = $1; }
				| stmt_return
						{ $$ = $1; }
				| stmt_raise
						{ $$ = $1; }
				| stmt_assert
						{ $$ = $1; }
				| stmt_execsql
						{ $$ = $1; }

stmt_execsql

代码语言:javascript
复制
stmt_execsql	: K_IMPORT
					{
						$$ = make_execsql_stmt(K_IMPORT, @1);
					}
				| K_INSERT
					{
						$$ = make_execsql_stmt(K_INSERT, @1);
					}
				| T_WORD
					{
						int			tok;

						tok = yylex();
						plpgsql_push_back_token(tok);
						if (tok == '=' || tok == COLON_EQUALS || tok == '[')
							word_is_not_variable(&($1), @1);
						$$ = make_execsql_stmt(T_WORD, @1);
					}
				| T_CWORD
					{
						int			tok;

						tok = yylex();
						plpgsql_push_back_token(tok);
						if (tok == '=' || tok == COLON_EQUALS || tok == '[')
							cword_is_not_variable(&($1), @1);
						$$ = make_execsql_stmt(T_CWORD, @1);
					}
				;

用于解析形如:

代码语言:javascript
复制
$$
begin
    select (3+1) into vvv;      
    select 100 into v_int;
end;
$$;

解析过程

select (3+1) into vvv;

代码语言:javascript
复制
stmt_execsql	: opt_stmt_label K_IMPORT
				...
				...
				| opt_stmt_label T_WORD
					{
						int			tok;

						tok = yylex();
						plpgsql_push_back_token(tok);
						if (tok == '=' || tok == COLON_EQUALS ||
							tok == '[' || tok == '.')
							word_is_not_variable(&($2), @2);
						$$ = make_execsql_stmt($1, T_WORD, @2);
					}
					...
					...

make_execsql_stmt

代码语言:javascript
复制
tok = 275                         T_WORD
for (;;)
	prev_tok = 275   tok = 40     (
	prev_tok = 40    tok = 266    ICONST
	prev_tok = 266   tok = 43     +
	prev_tok = 43    tok = 266    ICONST
	prev_tok = 266   tok = 41     )
	prev_tok = 41    tok = 334    K_INTO
	prev_tok = 334   tok = 59     ;

make_execsql_stmt

代码语言:javascript
复制
tok = 275                       T_WORD
for (;;)
	prev_tok = 275   tok = 40     (
	prev_tok = 40    tok = 266    ICONST            --> 3
	prev_tok = 266   tok = 43     +                 --> +
	prev_tok = 43    tok = 266    ICONST            --> 1
	prev_tok = 266   tok = 41     )
	prev_tok = 41    tok = 334    K_INTO            --> INTO
	  if (tok == K_INTO)
	    read_into_target(&target, &have_strict)
	      ...
	      tok = yylex() // 277    T_DATUM           --> vvv
	      read_into_scalar_list(NameOfDatum(&(yylval.wdatum)),yylval.wdatum.datum, yylloc);
	      
	prev_tok = 334   tok = 59     ;                 --> ;

select 100 into v_int;

make_execsql_stmt

代码语言:javascript
复制
tok = 275                      T_WORD
for (;;)
	prev_tok = 275   tok = 266   ICONST
	prev_tok = 266   tok = 334   K_INTO
	prev_tok = 334   tok = 59    ;
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-07-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • stmt_execsql语法树
  • 解析过程
    • select (3+1) into vvv;
      • select 100 into v_int;
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档