PG源码之parser(2)
上文大概描述了pgsql处理查询的第一步,下面我将分析parser部分的原代码,(src/backend/parser里的源代码),可能需要写的东西要比较多一点。
1 scan.l
这个文件包含了几个头文件,其中postgres.h主要是一些在后台进程中经常用到的常量以及自定义变量(这个以后再说);gramparse.h用于避免使用bison做语法分析时的缺省模式(bison使用行列号来标示单词);keywords.h主要是跟关键字相关的内容(要区分开非关键字0,列名关键字1,类型/函数名关键字2,保留关键字3,ScanKeyword结构体就是用于区分关键字的,实际上是一个关键字符号表);scanup.h是与扫描相关的代码(还没弄的太懂);pg_wchar则引入对多字节字符的支持(比如汉语)。
以下是对一些成员变量的解释:
fprintf用于打印出错误。
backslash_quote好像是用于处理跟GNU工具相关的内容。(但是我不明白具体是做什么的)
literalbuf用于在满足多个规则时聚合相应的字面量。
使用startlit重置buffer,使用addlit来添加字符。buffer用palloc来分配,随着每次解析循环重新开始和刷新buffer。
接下来的这部分主要是处理各种情况,比如双引号,单引号(字符串中的),美元符号等等。
从331(8.3.1版本中)行开始就是对各种情况的处理。
从764行开始是几个函数,lexer_errposition用于确定错误的单词位置,yyerror用于报错,scanner_init在实际的解析开始之间做用于分配内存,scanner_finish用于释放内存,addlit来添加字符,addlitchar用于给传入的字符串的长度加1,litbufdup用于对缓冲区重写,unescape_single_char用于检测escape表达式中的特殊字符(like语句的正则表达式部分),check_string_escape_warning和check_escape_warning与escape语句表达式的错误相关(具体是处理什么我没太看明白。)。
2 gram.y
第81行的指针变量parsetree实际上就是gram的返回结果,这个变量在parser.c中定义,这样就可以返回一个解析好的语法树。从151到358行是声明针对各种情况的解析函数。从369行到453行是SQL关键字。从465行到503行是操作符的优先级定义。从514开始到9433行是各种语法定义,包括create/alter/drop role,create/alter/drop user,create/alter/drop group,create schema等等。
makeColumnRef函数的作用不明,欢迎高手指教。
makeTypeCast函数用于SQL数据类型转换。
make...Const这几个函数似乎是用于生成常量节点。
makeOverlaps生成函数调用节点。
check_qualified_name和check_func_name函数的作用不是很清楚。
extractArgTypes函数用于在给定一系列函数参数名的情况下,提取参数的类型。(好像是这样子,不是很确定)
findLeftmostSelect是获取最左端的select语句。
insertSelectOptions是用于处理如下语句:insert into tablename select * from another_tablename。
makeSetOp的作用也不是很明白,似乎是和SET语句的选项有关系。
SystemFuncName用于返回系统函数名(pg_catalog里定义)。SystemTypeName用于返回系统type名。
parser_init用于初始化。
doNegate和doNegateFloat用于处理负数的情况。
makeXmlExpr是用于处理XML表达式和XML函数。
痛风
4 天前
没有评论:
发表评论