学习 探索 分享数据库知识和技术 共建数据库技术交流圈
7.4 表达式计算
typedef struct Expr {
NodeTag type; /*表达式节点类型*/
} Expr;
struct ExprState {
NodeTag type;
Expr* expr; /*关联的表达式节点*/
ExprStateEvalFunc evalfunc; /*表达式运算的函数指针*/
VectorExprFun vecExprFun;
exprFakeCodeGenSig exprCodeGen; /*运行LLVM汇编函数的指针*/
ScalarVector tmpVector;
Oid resultType;
};
7.4.1 初始化阶段
if (node == NULL) { /* 判断输入是否为空 */
gstrace_exit(GS_TRC_ID_ExecInitExpr);
return NULL;}
switch (nodeTag(node)) { /* 根据节点类型初始化节点内容 */
case T_Var:
case T_Const:
case T_Param:
……
case T_CaseTestExpr:
case T_Aggref:
……
case T_CurrentOfExpr:
case T_TargetEntry:
case T_List:
case T_Rownum:
default:…… }
return state; /* 返回表达式节点树 */
(1) 判断输入的node节点是否为空,若为空,则直接返回NULL,表示没有表达式限制。
(2) 根据输入的node节点的类型初始化变量evalfunc即node节点对应的执行函数,若节点存在参数或者表达式,则递归调用ExecInitExpr函数,最后生成ExprState tree。
(3) 返回ExprState tree,在执行表达式的时候会根据ExprState tree来递归执行。
图7-12 ExecInitExpr函数执行流程
7.4.2 执行阶段
(1) 根据表达式“s.a<3 or s.b<3”确认第一步调用ExecQual函数。
(2) 由于本次表达式是or语句,所以需要将表达式传入到ExecEvalOr函数计算,在ExecEvalOr函数中采用for循环依次对子表达式“s.a<3”和“s.b<3”计算,将子表达式传入到下一层函数中。
(3) ExecEvalOper函数根据子表达式的返回值是否为set集来调用下一层函数,计算子表达式的结果。
(4) ExecMakeFunctionResultNoSets函数中获取子表达式中的参数的值,“s.a”和“3”分别通过ExecEvalScalarVar函数和ExecEvalConst函数来获取,获取到参数之后计算表达式结果,若s.a<3本次计算返回true,否则返回false,并依次向上层返回结果。
图7-13 函数调用执行流程
执行阶段所有函数都共享此调用约定,相关代码如下:
输入:
expression:需要计算的表达式状态树。
econtext:评估上下文信息。
输出:
return value:Datum类型的返回值。
*isNull:如果结果为NULL,则设置为TRUE(实际返回值无意义);如果结果非空,则设置为FALSE。
*isDone:设置为set-result状态的指标。
……(本节内容未完)
为提升您的阅读体验,完整版内容已运用专业格式发布到CSDN·Gauss松鼠会专栏,请扫码下方二维码,“关注”后进行内容阅读或点击文末“阅读原文”进入博客进行学习~
文章转载自Gauss松鼠会,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。