加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

postgresql查询分析源码分析-流程

发布时间:2020-12-13 17:11:40 所属栏目:百科 来源:网络整理
导读:postgresql version :9.4.4 源码路径:src/backend/parser 所谓查询分析就是把SQL查询语句生成查询树。查询分析是查询编译的第一个模块。主要包括:词法分析,语法分析和语义分析这三个部分。 现在看的源码是9.4.4版本,在9.0词法分析借用了lex,语法分析是yacc

postgresql version :9.4.4

源码路径:src/backend/parser


所谓查询分析就是把SQL查询语句生成查询树。查询分析是查询编译的第一个模块。主要包括:词法分析,语法分析和语义分析这三个部分。


现在看的源码是9.4.4版本,在9.0词法分析借用了lex,语法分析是yacc。现在是升级的flex跟bison。

在postgresql中,对应的是src/backend/parser/gram.y&scan.l,这2个文件在编译的时候会生成gram.c/h,scan.c

关键字是在src/include/parser/kwlist.h,如果我们想添加一个关键字,可以在这个头文件添加。(注意添加顺序哦)


查询分析的基本流程:




我们现在来看看源码:

首先我们创建一张测试表,插入一条数据.

create table sangli(x text,y text,z bigint);
insert into sangli(x,y,z) values('x','y',99);


再gdb到这个进程:


(gdb) b exec_simple_query

Breakpoint 1 at 0x7d35c0: file postgres.c,line 883.

(gdb) c

Continuing.

在exec_simple_query 打个断点。


我们进入了这个函数,可以进行调试跟踪了。

首先,SQL命令为:query_string=select * from sangli;

(gdb) p query_string

$1 = 0x1a22e58 "select * from sangli;"

next......


我们主要是看方法pg_parse_query(const char *query_string)这个就是parse SQL语句函数。这个函数返回个List,这个List是个parsetree.

这个List的返回值类型为:SelectStmt


我们进来函数,raw_parser(query_string),这个函数就是词法的语法分析的入口函数,这个会生成一个未分析的语法解析树。返回值是个yyextra.parsetree;

/*
 29│  * raw_parser
 30│  *              Given a query in string form,do lexical and grammatical analysis.
 31│  *
 32│  * Returns a list of raw (un-analyzed) parse trees.
 33│  */
 34│ List *
 35│ raw_parser(const char *str)



我们看看头文件:
/*
 * The YY_EXTRA data that a flex scanner allows us to pass around.  Private
 * state needed for raw parsing/lexing goes here.
 */
typedef struct base_yy_extra_type
{
	/*
	 * Fields used by the core scanner.
	 */
	core_yy_extra_type core_yy_extra;

	/*
	 * State variables for base_yylex().
	 */
	bool		have_lookahead; /* is lookahead info valid? */
	int			lookahead_token;	/* one-token lookahead */
	core_YYSTYPE lookahead_yylval;		/* yylval for lookahead token */
	YYLTYPE		lookahead_yylloc;		/* yylloc for lookahead token */

	/*
	 * State variables that belong to the grammar.
	 */
	List	   *parsetree;		/* final parse result is delivered here */
} base_yy_extra_type;

上面的yyextra就是base_yy_extra_type。


targetList&fromClause我们来看看是什么东西。


targetList:


上面的gdb内容是:

p *(A_Star*)(*(ColumnRef*)(*(ResTarget*)(*(SelectStmt*)yyextra.parsetree->head->data->ptr_value)->targetList->head->data->ptr_value)->val)->fields->head->data->ptr_value
什么是A_Star?

我们查询语句select * from sangli;

这个*就是A_Star类型。这个应该很直观就能知道的。这样我们就知道什么是targetList.


fromClause:


很清楚,relname="sangli" 这个就是表的名称。别的参数可能在后面会重写的时候会赋值,可能没有.


这样pg_parse_query执行完毕,返回raw_parsetree_list.

其实这里还没有到返回Query,这个具体是在pg_analyze_and_rewrite里面返回的。

而这部分最主要的就是解析SQL文本。后面的analyze&rewrite 都是通过这里返回的parsetree进行操作的。

大概流程就是这样,这个里面最主要的是flex&bison没讲,我下一篇打算讲讲他是如何工作的。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读