引言
表达式计算和前几篇文章介绍的算子息息相关,很多个算子里面都需要计算表达式,过滤元组,再返回可行元组,因此,弄懂表达式计算至关重要。接下来的几篇文章里,我将介绍表达式计算的相关内容。
表达式树
和查询语句生成的查询树一样,一个表达式语句在opengauss中也会被生成一个表达式计划树,例如对于以下查询语句
select *
from t
where ( id=100 and x+9<20 ) or (2*y != 10)
其中表达式为( id=100 and x+9<20 ) or (2*y != 10)
,可以生成以下的表达式计划树
注意:本例只是一个特殊情况,使得表达式计划树恰好是一棵二叉树,实际上,表达式计划树只是一个更为普遍的树形结构。
表达式计划树的好处就是能够把表达式计算分成一个个单元运算,和火山模型一样,上层运算调用下层运算,下层运算结果返回给上层运算,最后顶层结果返回给火山模型中的各个算子进行元组过滤。
表达式状态公共根类
表达式状态的公共根类为Exprstate,其结构体定义如下:
//代码清单1
struct ExprState {
NodeTag type; /* 结点类型 */
Expr* expr; /* 关联的表达式结点 */
ExprStateEvalFunc evalfunc; /* 表达式运算的函数指针 */
VectorExprFun vecExprFun; /* 处理向量表达式的函数指针 */
exprFakeCodeGenSig exprCodeGen; /* 运行LLVM汇编函数的指针 */
ScalarVector tmpVector; /* 临时存储数据 */
Oid resultType;
};
相关函数
函数所在代码文件为:src\gausskernel\runtime\executor\execQual.cpp
.
接下来简单介绍一下各个函数的作用,对execQual有一个初步的了解。
函数名称 | 函数作用 |
---|---|
ExecInitExpr | 初始化表达式树 |
ExecMakeFunctionResult | 表达式计算(集合) |
ExecMakeFunctionResultNoSets | 表达式计算(非集合) |
ExecEvalFunc | 调用表达式计算函数 |
ExecEvalxx | 具体的运算函数 |
ExecEvalOper | 调用表达式计算函数 |
ExecQual | 检查条件表达式 |
ExecTargetList | 计算targetlist中的所有表达式 |
ExecProject | 计算投影信息 |
ExecEvalParamExec | 获取Exec类型参数 |
ExecEvalParamExtern | 获取Extern类型参数 |
表达式计算的过程分为3个部分:初始化、执行和清理。初始化使用统一的函数ExecInitExpr,根据表达式的类型不同选择不用的处理方式。执行过程使用统一接口宏ExecEvalExpr,具体情况具体处理。而清理过程没有一个统一的函数,清理操作集成在了执行阶段中。
小结
本篇文章简要介绍了表达式部分的基础知识,下一篇文章我将对相关函数代码以及调用情况简要分析。