postgresql之语法解析 浅析

一、pg语法简介

1.1 语法文件结构

语法.y文件和词法.l文件结构差不多,也是通过 %%分成了三个部分: 声明部分、语法规则部分、C代码部分。

src/backend/parser/gram.y

#### 声明部分

%{
	C代码 头文件,变量声明等(此范围内的内容原样输出到文件中)
	#include "postgres.h"
	...
%}

#变量声明
%union
{
	core_YYSTYPE		core_yystype;
	/* these fields must match core_YYSTYPE: */
	int					ival;
	char				*str;
	const char			*keyword;

	char				chr;
	...
}

#类型声明
%type <node>	stmt toplevel_stmt schema_stmt routine_body_stmt
...

#token 关键字声明
%token <keyword> ABORT_P ABSOLUTE_P ACCESS ACTION ADD_P ADMIN AFTER
...

#优先级声明
%left		UNION EXCEPT
%left		INTERSECT
%left		OR
%left		AND
%right		NOT
...

%%
####语法部分
parse_toplevel:
    stmtmulti
    {
    pg_yyget_extra(yyscanner)->parsetree = $1;
    }
    | ...
    ;
...

%%
#### C 代码 (此段内容原样输出到文件中)
...
static RawStmt *
makeRawStmt(Node *stmt, int stmt_location)
{
	RawStmt    *rs = makeNode(RawStmt);

	rs->stmt = stmt;
	rs->stmt_location = stmt_location;
	rs->stmt_len = 0;			/* might get changed later */
	return rs;
}
...

1.2 语法规则

找一个简单的语法规则,比如CallStmt

在这里插入图片描述

二、 简单语句分析

2.1 语法分析入口

src/backend/tcop/postgres.c

List *
pg_parse_query(const char *query_string)
{
	List	   *raw_parsetree_list;
	...

	raw_parsetree_list = raw_parser(query_string, RAW_PARSE_DEFAULT);
    ...
        
    return raw_parsetree_list;
}

src/backend/parser/parser.c

List *
raw_parser(const char *str, RawParseMode mode)
{
	core_yyscan_t yyscanner;
	base_yy_extra_type yyextra;
	int			yyresult;
    
	...
	/* Parse! */
	yyresult = base_yyparse(yyscanner);

	...

	if (yyresult)				/* error */
		return NIL;

	return yyextra.parsetree;
}

在语法.y文件中指定了name-prefix,

src/backend/parser/gram.y

%name-prefix="base_yy"

所以通过bison生成的语法解析文件src/backend/parser/gram.c中函数都是base_yy开头

/* Substitute the variable and function names.  */
#define yyparse         base_yyparse
#define yylex           base_yylex
#define yyerror         base_yyerror
#define yydebug         base_yydebug
#define yynerrs         base_yynerrs
...
/*----------.
| yyparse.  |
`----------*/

int
yyparse (core_yyscan_t yyscanner)
{
/* The lookahead symbol.  */
int yychar;
...
}

所以yyparse就是base_yyparse。

2.2 简单的Call命令

比如执行如下sql

# call test();

根据语法规则生成的语法树如下

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值