openGauss源码解析(122)
openGauss源码解析:执行器解析(15)
2. Sort算子
Sort算子用于执行排序计划节点(即SQL语句中的ORDER BY命令),对应的代码源文件是“nodeSort.cpp”。算子对应的主要函数如表7-25所示。
表7-25 Sort算子主要函数
主要函数 | 说明 |
ExecInitSort | 初始化Sort状态节点 |
ExecSort | 迭代获取元组 |
ExecEndSort | 清理Sort状态节点 |
ExecSortMarkPos | 用于标记排序位置 |
排序算子对应的结构体是SortState,该结构体代码如下:
typedef struct SortState {
ScanState ss; /* 扫描节点 */
bool randomAccess; /* 随机访问标识*/
bool bounded; /* 结果集边界标识 */
int64 bound; /* 结果集中总数 */
bool sort_Done; /* 排序完成标识 */
bool bounded_Done; /* 结果集边界设置标识 */
int64 bound_Done; /* 参与排序的数据集 */
void* tuplesortstate; /* 排序表 */
int32 local_work_mem; /* 内存使用 */
int sortMethodId; /* 所用排序方法(explain) */
int spaceTypeId; /* 空间类型(explain) */
long spaceUsed; /* 所用空间大小(explain) */
int64* space_size; /* 临时表外溢大小 */
} SortState;
ExecInitSort函数用于初始化排序节点,创建排序时的状态信息。主要执行流程如下。
(1) 创建Sort状态结构体,生成排序状态节点(SortState)。
(2) 对结果元组表初始化(分别调用“ExecInitResultTupleSlot(estate,&sortstate->ss.ps)”函数和“ExecInitScanTupleSlot(estate,&sortstate->ss)”函数)。
(3) 初始化子节点。
(4) 初始化元组类型。
ExecSort函数是执行排序的主函数。主要执行流程是:
(1) 判断排序状态节点是否已经做过排序,如果没有做过排序,需要调用tuplesort函数做一次全部排序。
(2) 使用tuplesort函数做排序的流程是先初始化堆排序,然后调用tuplesort_performsort函数执行排序。
(3) 根据排序执行节点的逐一读取元组。
ExecSort函数的执行流程如图7-9所示。
图7-9 ExecSort函数操作流程
ExecEndSort函数用于释放排序过程使用的资源。主要执行流程是:首先释放用于存放中间元组的排序表,然后清理结果表,最后关闭排序执行计划。
ExecSortMarkPos函数用于标记排序位置。ExecSortRestrPos函数用于恢复保存的排序文件。ExecReScanSort函数用于重置排序结果。