openGauss源码解析(138)
openGauss源码解析:执行器解析(31)
GsCodeGen提供LLVM环境处理函数和module函数,以及处理IR的函数。另一方面,为了处理算子函数功能,将每个算子涉及的各个操作符封装在ForeigenScanCodeGen类中,接口定义在“codegen/foreignscancodegen.h”中,各个接口功能如表7-32所示:
表7-32 ForeigenScanCodeGen接口汇总
接口名称 |
接口类型 |
职责描述 |
---|---|---|
ScanCodeGen |
API |
生成外表扫描谓词表达式运算对应的IR函数 |
IsJittableExpr |
API |
谓词中的表达式是否支持LLVM化 |
buildConstValue |
API |
获取谓词表达式中的常量 |
目前针对不同的表达式,openGauss实现了4个类:
(1) VecExprCodeGen类主要用于处理查询语句中表达式计算的LLVM动态编译优化。目前主要处理的是过滤条件语法中的表达式,即在ExecVecQual函数中处理的表达式计算。
(2) VecHashAggCodeGen类用于对节点hashagg运算的LLVM动态编译优化。
(3) VecHashJoinCodeGen类用于对节点hash join运算的LLVM动态编译优化。
(4) VecSortCodeGen类用于对节点sort运算的LLVM动态编译优化。
7.5.1 VecExprCode类
VecExprCodeGen类用于支持openGauss设计框架中向量化表达式的动态编译优化,即生成各类向量化表达式计算的IR函数。VecExprCodeGen类主要针对存在qual的查询场景,即表达式在WHERE语法中的查询场景,VecExprCodeGen接口定义在“codegen/vecexprcodegen.h”文件中,VecExprCode类支持的语句场景为:
SELECT targetlist expr FROM table WHERE filter expr…;
其中,对filter expr进行LLVM化处理。
列存储执行引擎每次处理的为一个VectorBatch。在执行过程中,由于采用迭代计算模型,对于每一个qual,会遍历整个qual表达式,然后根据遍历得到的信息去读取VectorBatch中的列向量ScalarVector,这样就会导致需要不停地去替换当前存放在内存或寄存器中的数据。为了更好地减少数据读取,让数据在计算过程中更久地存放在寄存器中,将ExecVecQual与对VectorBatch进行结合处理:只有当前的数据处理完所有的vecqual时再更新寄存器中的数据,即原本的执行流程。相关代码如下:
foreach(cell, qual)
{
DealVecQual(batch->m_arr[var->attno-1]);
}
替换为
for(i = 0; i < batch->m_rows; i++)
{
foreach(cell, qual)
{
DealVecQual(batch->m_arr[var->attno-1]->m_vals[i]);
}
}
DealVecQual代表的就是对当前的数据参数进行qual条件处理。可以看到现有的处理方式实际上已经退化为行存储的形式,即每次只处理batch中的一行数据信息,但是该数据信息会一直存放在寄存器中,直至所有的qual条件处理完成。表7-33列出了VecExprCodeGen的所有接口。
表7-33 VecExprCodeGen接口汇总
接口名称 |
接口类型 |
职责描述 |
ExprJittable |
API |
判断单个表达式是否支持LLVM化 |
QualJittable |
API |
判断整个qual条件是否支持LLVM化 |
QualCodeGen |
API |
ExecVecQual的LLVM化,生成的“machine code”用于替换实际执行时的ExecVecQual |
ExprCodeGen |
API |
ExecInitExpr的LLVM化,目前只支持部分功能和函数的LLVM化 |
OpCodeGen |
API |
操作符表达式(算术表达式,比较表达式等)的LLVM化,目前支持的数据类型包括int、float、numeric、text和bpchar等类型 |
ScalarArrayCodeGen |
API |
ExecEvalScalarArrayOp的LLVM化处理,支持的类型包括text、varchar、bpchar、int和float类型 |
CaseCodeGen |
API |
ExecEvalVecCase的LLVM化处理,其中“case when”中的选项类型包括int类型和text、bpchar类型,对于复杂表达式的暂只支持substr |
VarCodeGen |
API |
ExecEvalVecVar的LLVM化处理 |
EvalConstCodeGen |
API |
ExecEvalConst的LLVM化处理 |