postgresql之语法解析 浅析

news/2024/7/9 23:16:23 标签: 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();

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

在这里插入图片描述


http://www.niftyadmin.cn/n/1829975.html

相关文章

传统MySQL+ Memcached架构遇到的问题

实际MySQL是适合进行海量数据存储的&#xff0c;通过Memcached将热点数据加载到cache&#xff0c;加速访问&#xff0c;很多公司都曾经使用过这样的架构&#xff0c;但随着业务数据量的不断增加&#xff0c;和访问量的持续增长&#xff0c;我们遇到了很多问题&#xff1a; MySQ…

PHPcms怎么调用二级栏目

{pc:content action"category" catid"0" num"25" siteid"$siteid" order"listorder ASC"}<a href"{siteurl($siteid)}" title"首页">首 页</a>{loop $data $k $r}<a href"{$r[url]…

协议抓包分析软件

wireshark sudo apt-get install wireshark 运行的时候使用sudo权限转载于:https://www.cnblogs.com/codeAB/p/4938873.html

docker中调试失败

一、背景 在docker环境下使用gdb调试pg源码&#xff0c; gdb附加不上进程。 1.1 环境 $ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 18.04.6 LTS Release: 18.04 Codename: bionic$ docker --version Docker version 20.10.…

微信网页静默授权(scope=snsapi_base),这种方式不需要用户手动同意

1&#xff0c;是 prepay_id 不是 prepayid。2&#xff0c;prepay_id 是通过统一下单接口才能拿到&#xff0c;至于 openid&#xff0c;只有 trade_type 为 JSAPI 时对需要&#xff0c;NATIVE 是不需要 openid 的。3&#xff0c;京东的微信支付&#xff0c;是 JSAPI 方式的&…

EF框架学习手记

转载: [ASP.NET MVC]&#xff1a; - EF框架学习手记 1、EF(Entity Framework)实体框架EF是ADO.NET中的一组支持开发面向数据的软件应用程序的技术&#xff0c;是微软的一个ORM框架。2、什么是ORM?ORM指的是面向对象的对象模型和关系型数据库的数据结构之间的互相转换。(表实体…

经方膏方

入冬以来&#xff0c;传统的膏滋药受到各方热捧&#xff0c;这是百姓对中医养生功效的期待&#xff0c;也是中医走向大众的机遇。中医界需要珍惜&#xff0c;切不可当作谋利的时机&#xff0c;见利而忘学。膏方也是方&#xff0c;是方均离不开经方&#xff0c;经方中就有许多制…

postgresql之page分配管理(一)

一、简介 postgresql是多进程架构&#xff0c;同时也是一个庞大的共享内存系统&#xff0c;大部分的数据都是在共享内存中&#xff0c;供多进程进行协作处理&#xff0c;今天主要是buffer&#xff08;page&#xff09;。 二、page 大小 page默认大小是8kB,可以在编译时进行调…