postgresql查询分析源码分析-流程
2015-12-14 23:23
501 查看
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,如果我们想添加一个关键字,可以在这个头文件添加。(注意添加顺序哦)
查询分析的基本流程:
我们现在来看看源码:
首先我们创建一张测试表,插入一条数据.
再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;
我们看看头文件:
上面的yyextra就是base_yy_extra_type。
targetList&fromClause我们来看看是什么东西。
targetList:
上面的gdb内容是:
我们查询语句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没讲,我下一篇打算讲讲他是如何工作的。
源码路径: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没讲,我下一篇打算讲讲他是如何工作的。
相关文章推荐
- Redis操作命令总结
- MariaDB基础
- [Oracle] sqlplus / as sysdba ora-01031 insufficient privileges
- 使用C#连接ORACLE数据库
- SqlConnection,OleDbConnection,OdbcConnection和OracleConnection
- 1.Benchmark SQL 数据库测试工具使用——安装使用
- mysql自增长id从1000开始
- C# 连接 Oracle 的几种方式
- Redis介绍
- MySQL5.6 GTID新特性实践(转)
- 数据库迁移:MySQL->PostgreSQL注意问题汇总(基于项目并不完整)
- 从头到尾写SQL(三)
- ms sqlserver clr应用(一)
- [MySQL] 实例讲解MYSQL数据库的查询优化技术
- mysql 批量insert
- MySql与SqlServer的一些常用用法的差别
- oracle 删除表空间错误 提示:ora-02429:无法删除用于强制唯一
- 通过bat命令快速启动oracle
- MongoDB介绍与windows下安装
- 总结:数据库连接字符串的使用方法