openGauss源码解析(130)

openGauss源码解析:执行器解析(23)

7.4.2 执行阶段

执行阶段主要是根据宏定义ExecEvalExpr递归调用执行函数。在计算时的核心函数包括ExecMakeFunctionResult和ExecMakeFunctionResultNoSets,通过这两个函数计算出表达式的结果并返回。其他的表达式计算函数还包括ExecEvalFunc、ExecEvalOper、ExecEvalScalarVar、ExecEvalConst、ExecQual、ExecProject等,这些函数分别对应不同的表达式的类型或者参数类型,通过不同的逻辑来处理获取的计算结果。

执行过程就是上层函数调用下层函数。首先下层函数根据参数类型获取相应的数据,然后上层函数通过处理数据得到最后的结果,最后根据表达式逻辑返回结果。

通过一个简单的SQL语句介绍一下表达式计算的函数调用过程,每种SQL语句的执行流程不完全一致,此示例仅供参考。例句:“SELECT * FROM s WHERE s.a<3 or s.b<3;”。具体流程如下。

(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所示。

图7-13 函数调用执行流程

执行阶段所有函数都共享此调用约定,相关代码如下:

输入:

expression:需要计算的表达式状态树。

econtext:评估上下文信息。

输出:

return value:Datum类型的返回值。

*isNull:如果结果为NULL,则设置为TRUE(实际返回值无意义);如果结果非空,则设置为FALSE。

*isDone:设置为set-result状态的指标。

只能接受单例(非集合)结果的调用方应该传递isDone为NULL,如果表达式计算得到集合结果(set-result),则返回错误将通过ereport报告。如果调用者传递的isDone指针不为空,需要将*isDone设置为以下3种状态之一:

(1) ExprSingleResult 单例结果(非集合)。
(2) ExprMultipleResult 返回值是集合的一个元素。
(3) ExprEndResult 集合中没有其他元素。

当返回ExprMultipleResult时,调用者应该重复调用并执行ExecEvalExpr函数,直到返回ExprEndResult。

posted @ 2024-04-30 10:50  openGauss-bot  阅读(4)  评论(0编辑  收藏  举报