控制算子----nodeResult.cpp解析

引言

从本篇文章开始,我将分析几个控制算子的功能和作用。控制算子主要用于执行特殊流程,这类流程通常包含多个输入,例如Union操作,需要把多个子结果合并成一个。接下来介绍Result算子。

代码位置

src\gausskernel\runtime\executor\nodeResult.cpp

功能作用

Result算子用于处理只有一个结果(例如SELECT 3*2或者INSERT语句只包含values子句并不包含列名)或者where表达式中的结果是常量(如 SELECT * FROM t WHERE 2>1,过滤表达式”2>1”是常量)的流程。

ExecResult

算子执行的关键函数为ExecResult,源码如下:

 
  1. //代码清单1
  2. TupleTableSlot* ExecResult(ResultState* node)
  3. {
  4. TupleTableSlot* outer_tuple_slot = NULL;
  5. TupleTableSlot* result_slot = NULL;
  6. PlanState* outer_plan = NULL;
  7. ExprDoneCond is_done;
  8. ExprContext* econtext = node->ps.ps_ExprContext;
  9. /*如果没有做过常量表达式检查,则执行if语句计算常量表达式*/
  10. if (node->rs_checkqual) {
  11. bool qualResult = ExecQual((List*)node->resconstantqual, econtext, false);
  12. node->rs_checkqual = false;
  13. if (!qualResult) {
  14. node->rs_done = true;
  15. u_sess->exec_cxt.exec_result_checkqual_fail = true;
  16. return NULL;
  17. }
  18. }
  19. /*检查是否需要投影*/
  20. if (node->ps.ps_TupFromTlist) {
  21. result_slot = ExecProject(node->ps.ps_ProjInfo, &is_done);
  22. if (is_done == ExprMultipleResult) {
  23. return result_slot;
  24. }
  25. node->ps.ps_TupFromTlist = false;
  26. }
  27. /*重置常量表达式的内存上下文*/
  28. ResetExprContext(econtext);
  29. /*如果rs_done字段为0,则说明结点没有被执行过,进入循环执行*/
  30. while (!node->rs_done) {
  31. outer_plan = outerPlanState(node);
  32. if (outer_plan != NULL) {
  33. /*从外部计划中获取元组*/
  34. outer_tuple_slot = ExecProcNode(outer_plan);
  35. if (TupIsNull(outer_tuple_slot))
  36. return NULL;
  37. econtext->ecxt_outertuple = outer_tuple_slot;
  38. if (node->ps.qual && !ExecQual(node->ps.qual, econtext, false))
  39. continue;
  40. } else {
  41. /*如果没有外部计划,则直接读取target list中的元组*/
  42. node->rs_done = true;
  43. }
  44. /*投影*/
  45. result_slot = ExecProject(node->ps.ps_ProjInfo, &is_done);
  46. if (is_done != ExprEndResult) {
  47. node->ps.ps_TupFromTlist = (is_done == ExprMultipleResult);
  48. return result_slot;
  49. }
  50. }
  51. return NULL;
  52. }

输入参数

ExecResult函数的输入参数是一个ResultState结构体指针,结构体定义如下:

 
  1. typedef struct ResultState {
  2. PlanState ps; /* its first field is NodeTag */
  3. ExprState* resconstantqual;
  4. bool rs_done; /* are we done? */
  5. bool rs_checkqual; /* do we need to check the qual? */
  6. } ResultState;

字段解释:

类型命名含义
PlanStateps父类
ExprState*resconstantqual表达式节点
boolrs_done是否完成了所有的输出
boolrs_checkqual是否需要检查表达式

执行过程

可以画出执行流程图大致如下:

Result算子

  1. 检查是否需要检查常量表达式,如果需要则计算表达式
    • 表达式为假,返回NULL
    • 表达式为真,继续执行后面的代码
  2. 检查是否需要执行投影操作,如果需要则调用ExecProject函数进行投影并返回元组。
  3. 接着进入一个循环,循环检查条件是node结点是否仍需被执行,如果需要则
    • 从左子节点获取一个元组
    • 对元组进行过滤,如果常量表达式为假,则continue,跳过本次循环
    • 对元组进行投影并返回

小结

Result算子主要用来处理一些简单的控制过程,由于opengauss数据库没有投影算子和选择算子,Result算子一定程度上可以代替这两个算子。下一篇文章我将讲解BitmapOR和BitmapAnd算子。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值