openGauss源码解析(133)
openGauss源码解析:执行器解析(26)
ExecQual函数的作用是检查slot结果是否满足表达式中的子表达式,如果子表达式为false,则返回false否则返回true,表示该结果符合预期,需要输出。核心代码如下:
foreach (l, qual) { /* 遍历qual中的子表达式并计算 */
expr_value = ExecEvalExpr(clause, econtext, &isNull, NULL);
if (isNull) { /* 判断计算结果 */
if (resultForNull == false) {
result = false;
break;
}
} else {
if (!DatumGetBool(expr_value)) {
result = false;
……
return result; /* 返回结果是否满足表达式 */
ExecQual函数的主要执行流程如下。
(1) 遍历qual中的子表达式,根据ExecEvalExpr函数计算结果是否满足该子表达式,若满足则expr_value为1,否则为0。
(2) 判断结果是否为空,若为空,则根据resultForNull参数得到返回值信息。若不为空,则根据expr_value判断返回true或者false。
(3) 返回result。
ExecQual函数的执行流程如图7-17所示。
图7-17 ExecQual函数执行流程
ExecEvalOr函数的作用是计算通过or连接的bool表达式(布尔表达式,最终只有true(真)和false(假)两个取值),检查slot结果是否满足表达式中的or表达式。如果结果符合or表达式中的任何一个子表达式,则直接返回true,否则返回false。如果获取的结果为null,则记录isNull为true。核心代码如下:
foreach (clause, clauses) { /* 遍历子表达式 */
ExprState* clausestate = (ExprState*)lfirst(clause);
Datum clause_value;
clause_value = ExecEvalExpr(clausestate, econtext, isNull, NULL); /* 执行表达式 */
/* 如果得到不空且ture的结果,直接返回结果 */
if (*isNull)
/* 记录存在空值 */
AnyNull = true;
else if (DatumGetBool(clause_value))
/* 一次结果为true就返回 */
return clause_value; /* 返回执行结果 */
}
*isNull = AnyNull;
return BoolGetDatum(false);
ExecEvalOr函数主要执行流程如下。
(1) 遍历子表达式clauses。
(2) 通过ExecEvalExpr函数来调用clause中的表达式计算函数,计算出结果。
(3) 对结果进行判断,or表达式中若有一个结果满足条件,就会跳出循环直接返回。
ExecEvalOr函数的执行流程如图7-18所示。
图7-18 ExecEvalOr函数执行流程
ExecTargetList函数的作用是根据给定的表达式上下文计算targetlist中的所有表达式,将计算结果存储到元组中。主要结构体代码如下:
typedef struct GenericExprState {
ExprState xprstate;
ExprState* arg; /*子节点的状态*/
} GenericExprState;
typedef struct TargetEntry {
Expr xpr;
Expr* expr; /*要计算的表达式*/
AttrNumber resno; /*属性号*/
char* resname; /*列的名称*/
Index ressortgroupref; /*如果被sort/group子句引用,则为非零*/
Oid resorigtbl; /*列的源表的OID */
AttrNumber resorigcol; /*源表中的列号*/
bool resjunk; /*设置为true可从最终目标列表中删除该属性*/
} TargetEntry;