PostgreSQL---语义分析1

2021SC@SDUSC

我负责的PostgreSQL代码部分:查询的编译与执行
此篇博客分析内容:语义分析
上篇博客我分析了查询分析的词法分析和语法分析,我们可以知道经过词法分析和语法分析我们可以得到一个用SelectStmt结构体存储的分析树,由流程分析图可以得知我们还需经过语法分析才可以得到查询树。
在这里插入图片描述

语义分析:语义分析阶段会检查命令中是否有不符合语义规定的成分,检查命令是否可以正确执行。
语义分析阶段主要负责语义分析的是analyze.c文件中的parse_analyze函数。parse_analyze函数会根据分析树生成一个对应的查询树,然后再由后面的查询重写模块对这一查询树进行进一步的修改,将查询树改写成查询树链表。在parse_analyze函数中会根据命令类型分成七种情况处理:


在这里插入图片描述

语义分析中涉及的重要结构体:

Query:用于存储查询树,是查询分析的最终输出结果
ParseState:ParseState:用于记录语义分析的中间信息

struct ParseState
{
   
	struct ParseState *parentParseState;	//如果当前是一个子查询的话,这个字段指向其外层查询
	const char *p_sourcetext;	//原始sql命令,只用于报告语法分析出错的位置
	List	   *p_rtable;		//查询涉及的表--范围表
	List	   *p_joinexprs;	//连接表达式
	List	   *p_joinlist;	//连接项	
	List	   *p_namespace;	//表名字集合,用于检查表名冲突
	bool		p_lateral_active;	//是否有关联引用
	List	   *p_ctenamespace;//公共表达式的名字集合
	List	   *p_future_ctes;	//不在p_ctenamespace中的公共表达式
	CommonTableExpr *p_parent_cte;	/* this query's containing CTE */
	Relation	p_target_relation;	//目标表
	RangeTblEntry *p_target_rangetblentry;	/* target rel's RTE */
	bool		p_is_insert;	//是否为insert语句
	List	   *p_windowdefs;	//window子句的原始定义形式
	ParseExprKind p_expr_kind;	//参数的类型
	int			p_next_resno;	
	List	   *p_multiassign_exprs;	
	List	   *p_locking_clause;	//locking子句
	bool		p_locked_from_parent;	
	bool		p_resolve_unknowns; //还未解决的类型
	QueryEnvironment *p_queryEnv;	

	bool		p_hasAggs;//是否有聚集函数
	bool		p_hasWindowFuncs;//是否有窗口函数
	bool		p_hasTargetSRFs;//是否有SRF
	bool		p_hasSubLinks;//是否有子链接
	bool		p_hasModifyingCTE;//是否修改CTE
	Node	   *p_last_srf;		
	/*
	 * Optional hook functions for parser callbacks.  These are null unless
	 * set up by the caller of make_parsestate.
	 */
	PreParseColumnRefHook p_pre_columnref_hook;
	PostParseColumnRefHook p_post_columnref_hook;
	ParseParamRefHook p_paramref_hook;
	CoerceParamHook p_coerce_param_hook;
	void	   *p_ref_hook_state;	/* common passthrough link for above */
};
typedef struct Query
{
   
	NodeTag		type;//节点类型,T_Query

	CmdType		commandType;	//命令类型
	QuerySource querySource;	//是原始查询还是来自规则的查询
	uint64		queryId;		/* query identifier (can be set by plugins) */

	bool		canSetTag;		
	//查询重写时用到,如果该query是由原始查询转换而来则此字段为假;如果query是由查询重写或查询规划时新增加的则此字段为真
	Node	   *utilityStmt;//定义游标或者不可优化的查询语句
	int			resultRelation; //结果关系
	bool		hasAggs;//目标子句或者having子句中是否有聚集函数
	bool		hasWindowFuncs; //目标属性中是否有窗口函数
	bool		hasTargetSRFs;	/* has set-returning functions in tlist *
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

weixin_47373497

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值