VecGroup算子用于处理SQL语句中的“GROUP BY”子句,对满足条件的元组做分组处理。
VecGroup算子对应的代码源文件是“vecgroup.cpp”。VecGroup算子对应的主要数据结构是VecGroupState,继承于GroupState。相关代码如下:
struct VecGroupState : public GroupState {
void** container;
void* cap;
uint16 idx;
int cellSize;
bool keySimple;
FmgrInfo* buildFunc;
FmgrInfo* buildScanFunc;
VectorBatch* scanBatch;
VarBuf* currentBuf;
VarBuf* bckBuf;
vecqual_func jitted_vecqual;
};
VecGroup算子的相应函数有:ExecInitVecGroup(初始化节点)、ExecVecGroup(执行节点)、ExecEndVecGroup(退出节点)、ExecReScanVecGroup(重置节点)。
ExecInitVecGroup函数用于初始化VecGroup算子,主要执行流程如下。
(1) 创建并初始化VecGroupState执行节点,并为节点创建表达式上下文。
(2) 调用“ExecInitResultTupleSlot(estate,&grp_state->ss.ps);”函数分配存储投影结果的slot。
(3) 调用投影表达式初始化函数ExecInitVecExpr依次对plan.targetlist和plan.qual进行初始化。
(4) 调用ExecInitNode函数初始化子节点。
(5) 调用ExecAssignResultTypeFromTL函数初始化结果扫描描述符和调用ExecAssignVectorForExprEval函数创建投影结构。
ExecVecGroup函数是VecGroup算子的主体函数。主要执行流程如下。
(1) 获取下层元组中符合having子句条件的第1个元组。
(2) 依次获取组内的所有元组,直到获取到分组属性不同的元组,此时表示当前分组获取结束;如果获取到空元组,则表示完成分组操作,设置grp_done字段为true并结束执行。
(3) 扫描下一个符合having条件的元组,将缓存的元组作为分组的开始,并返回新元组。
(4) 重复(2)、(3)直到结束。
ExecEndVecGroup函数用于清理VecGroup算子执行过程中使用的资源。主要执行流程是:首先调用ExecFreeExprContext函数清理表达式上下文,最后调用“ExecEndNode(outerPlanState(node))”函数清理子计划节点。
ExecReScanVecGroup函数用于重新执行扫描计划,通过调用VecExecReScan函数实现重新扫描。




