openGauss内核分析(七):SQL by pass & 经典执行器 (二)
02 经典的执行器
关闭enable_opfusion,简单insert的执行计划是这样的:
在这种执行流程中Portal是执行SQL语句的载体,每一条SQL对应唯一的Portal,不同的查询类型对应的Portal类型也有区别。
typedef enum PortalStrategy {
PORTAL_ONE_SELECT, // SQL语句包含单一的SELECT查询
PORTAL_ONE_RETURNING, // INSERT/UPDATE/DELETE语句包含Returning
PORTAL_ONE_MOD_WITH, // 查询语句包含With
PORTAL_UTIL_SELECT, // 工具类型查询语句,如explain
PORTAL_MULTI_QUERY // 所有其他类型查询语句
} PortalStrategy;
Portal的生命周期管理在exec_simple_query函数中实现,该函数负责Portal创建、执行和清理。Portal执行的主要执行流程包括PortalStart函数、PortalRun函数、PortalDrop函数几个部分。其中PortalStart函数负责进行Portal结构体初始化工作,包括执行算子初始化、内存上下文分配等;PortalRun函数负责真正的执行和运算,它是执行器的核心;PortalDrop函数负责最后的清理工作,主要是数据结构、缓存的清理。
bool PortalRun(
Portal portal, long count, bool isTopLevel, DestReceiver* dest, DestReceiver* altdest, char* completionTag)
{
…
switch (portal->strategy) {
case PORTAL_ONE_SELECT:
…
case PORTAL_MULTI_QUERY: // insert从这里进入
PortalRunMulti(portal, isTopLevel, dest, altdest, completionTag);
/* Prevent portal's commands from being re-executed */
MarkPortalDone(portal);
/* Always complete at end of RunMulti */
result = true;
break;
…
}