相关 《Postgresql源码(61)查询执行——最外层Portal模块》 《Postgresql源码(62)查询执行——子模块ProcessUtility》
接上篇 《Postgresql源码(61)查询执行——最外层Portal模块》
1 查询执行整体
PG中的SQL在经过语法解析、查询编译后,进入执行模块,整形模块的分三个子模块:
入口:portal子模块(下图蓝色)
处理DML的Executor子模块(下图绿色)
处理DDL的ProcessUtility子模块(下图橙色)
SQL会在查询编译阶段得到plantree_list,在portal模块启动时(函数PortalStart),根据plantree_list中具体情况(函数ChoosePortalStrategy),来决定PortalStrategy的值,后面执行根据PortalStrategy来决定进入Executor还是ProcessUtility。
本篇重点分析ProcessUtility子模块。
2 分析案例:create table
使用彭老师书中的CASE。
代码语言:javascript复制create table course(
no serial,
name varchar,
credit int,
constraint con1 check(credit >=0 and name <> ''),
primary key(no)
);
2.1 执行前的数据准备
按之前的分析,SQL执行时会先进入portal框架,进入前最主要的数据准备就是查询计划树。
我们看下create table的查询计划树长什么样子:
- plantree_list链表包含唯一节点utilityStmt
plantree_list [List]
(node0) [PlannedStmt]
{ type = T_PlannedStmt, commandType = CMD_UTILITY, ... ,utilityStmt = 0x11bad68, stmt_location = 0, stmt_len = 135}
- utilityStmt保存了CreateStmt类型
utilityStmt [CreateStmt]
{ type = T_CreateStmt, relation = 0x11ba028, tableElts = 0x11ba230, ...}
- CreateStmt类型中,记录了完整表名RangeVar
relation [RangeVar]
{ type = T_RangeVar, catalogname = 0x0, schemaname = 0x0, relname = 0x11ba008 "course", inh = true, relpersistence = 112 'p', alias = 0x0, location = 13}
- CreateStmt类型中,记录了要创建的所有表项,包括三个列和两个约束
tableElts [List]
(node0) [ColumnDef]
{type = T_ColumnDef, colname = 0x11ba080 "no", typeName = 0x11ba140, compression = 0x0, inhcount = 0, is_local = true, is_not_null = false, is_from_type = false, storage = 0 '