【PostgreSQL内核学习(二十九)—— 执行器(ExecProcNode)】

执行器(ExecProcNode)

  • 概述
  • ExecProcNode 函数
    • ExecProcNodeFirst 函数
    • PlanState 结构体

声明:本文的部分内容参考了他人的文章。在编写过程中,我们尊重他人的知识产权和学术成果,力求遵循合理使用原则,并在适用的情况下注明引用来源。
本文主要参考了 postgresql-10.1 的开源代码和《OpenGauss数据库源码解析》和《PostgresSQL数据库内核分析》一书

概述

  在文章【PostgreSQL内核学习(二十二)—— 执行器(ExecutePlan)】中详细介绍了 PostgreSQL 数据库中 ExecutePlan 函数的原理和实现细节,强调了它在数据库查询执行机制中的核心作用。文章分析了 ExecutePlan 函数的执行流程,包括初始化变量处理并行执行模式循环执行查询计划节点直到满足退出条件等步骤。此外,还介绍了 ExecProcNode 函数的作用,即执行给定计划节点并返回元组
  本文将深入了解 ExecProcNode原理实现细节ExecProcNode 函数是 ExecutePlan 函数流程中的关键部分,负责实际执行查询计划树中的各个节点并返回结果元组ExecutePlan 通过循环调用 ExecProcNode处理查询计划中的每一个节点,直到获取到空元组,表示没有更多的数据需要处理,或者达到了预定的元组处理数量。简而言之,ExecProcNode 是连接执行器逻辑与具体计划节点执行结果的桥梁。

ExecProcNode 函数

  下面是 ExecProcNode 函数的定义,其作用是执行给定的查询计划节点并返回一个新的元组。如果节点的 chgParam 非空,表示有些参数改变了,这时会先调用 ExecReScan 函数来处理这些变化。然后,通过调用节点自身的 ExecProcNode 方法来执行节点并获取元组。这个过程是 PostgreSQL 执行计划操作的核心,它确保了在查询执行过程中,每个节点根据当前的状态和数据动态地生成结果。函数源码如下所示:(路径:postgresql-10.1\src\include\executor\executor.h

/* ----------------------------------------------------------------*		ExecProcNode**		Execute the given node to return a(nother) tuple.* ----------------------------------------------------------------*/
#ifndef FRONTEND
static inline TupleTableSlot *
ExecProcNode(PlanState *node) // 执行给定的查询计划节点,返回一个元组。
{if (node->chgParam != NULL) /* something changed? */ExecReScan(node);		/* 如果节点的参数有变化,重新扫描节点以应对这些变化。*/return node->ExecProcNode(node); // 调用节点自身的ExecProcNode方法执行该节点,并返回结果元组。
}
#endif

  在 PostgreSQL 中,node->ExecProcNode 通过函数指针指向具体的执行函数。当一个 PlanState 结构体被初始化时,根据不同的节点类型(如 SeqScanJoin 等),ExecProcNode 指针会被设置为指向相应节点特定的执行函数。这样,当调用 node->ExecProcNode(node); 时,实际上是调用了与节点类型相匹配的具体执行函数。这种设计允许多态行为,即同一接口可以根据不同的节点类型执行不同的操作,从而实现了查询计划的灵活执行。

ExecProcNodeFirst 函数

  ExecProcNodeFirst 函数是 ExecProcNode 的一个封装器,用于在第一次调用具体节点的执行函数之前执行一些一次性的检查。这包括执行栈深度检查,以确保不会因为递归调用或深层嵌套查询而超出系统栈空间。此外,如果需要,它还会将节点的执行函数指针从 ExecProcNode 更改为 ExecProcNodeInstr,用于收集执行过程中的性能数据。如果不需要性能数据收集,它会直接将执行函数指针指向实际的执行函数 ExecProcNodeReal。这样,ExecProcNodeFirst 确保在查询执行过程中,相关的性能检查和调整只在第一次执行时发生,优化了之后的执行效率。函数源码如下所示:(路径:postgresql-10.1\src\backend\executor\execProcnode.c

static TupleTableSlot *ExecProcNodeFirst(PlanState *node)
{// 在节点第一次执行前,执行栈深度检查。因为在某些架构上(如x86),这并不是一个低成本的操作。// 这个假设是基于ExecProcNode对给定计划节点的调用总是在大致相同的栈深度上进行。check_stack_depth();// 如果需要收集执行信息(instrumentation),则将执行函数指针改为ExecProcNodeInstr,只做性能收集。// 否则,我们可以去掉所有的封装器,并直接从现在开始让ExecProcNode()调用相应的函数。if (node->instrument)node->ExecProcNode = ExecProcNodeInstr;elsenode->ExecProcNode = node->ExecProcNodeReal;// 调用当前节点设置的执行函数,返回处理的元组。return node->ExecProcNode(node);
}

PlanState 结构体

  其中,PlanState 结构体是 PostgreSQL 查询执行计划中各种节点共享的基础数据结构。在 PostgreSQL 的执行引擎中,查询计划被编译成一个由多种类型的节点组成的树结构,每个节点类型都有自己特定的作用,如处理数据连接、过滤、聚合等操作PlanState结构体作为所有具体节点类型(如 SeqScanStateJoinState 等)的公共基础,包含了执行查询计划时所需的公共状态信息和控制逻辑。结构体源码如下所示:(路径:postgresql-10.1\src\include\nodes\execnodes.h

typedef struct PlanState
{NodeTag     type; // 节点类型标识符,用于区分不同的计划节点类型Plan        *plan;            /* 与此状态关联的Plan节点 */EState      *state;           /* 执行时,各个节点的状态指向整个顶层计划的一个EState实例 */ExecProcNodeMtd ExecProcNode; /* 函数指针,用于返回下一个结果元组 */ExecProcNodeMtd ExecProcNodeReal; /* 实际的函数,如果ExecProcNode是一个包装函数的话 */Instrumentation *instrument;  /* 可选的,为此节点提供运行时统计信息 */WorkerInstrumentation *worker_instrument; /* 每个工作器的性能监测数据 *//** 所有Plan类型的公共结构数据。这些到子状态树的链接在相关的计划树中也有对应的链接* (除了subPlan列表,在计划树中不存在)*/ExprState  *qual;           /* 布尔条件表达式 */struct PlanState *lefttree; /* 输入计划树(可能有多个) */struct PlanState *righttree;List       *initPlan;       /* 初始化的SubPlanState节点(非相关表达式子选择) */List       *subPlan;        /* 表达式中的SubPlanState节点 *//** 管理参数变化驱动的重新扫描的状态*/Bitmapset  *chgParam;       /* 已变更参数的ID集合 *//** 大多数节点类型所需的其他运行时状态*/TupleTableSlot *ps_ResultTupleSlot; /* 结果元组的槽 */ExprContext *ps_ExprContext;    /* 节点的表达式评估上下文 */ProjectionInfo *ps_ProjInfo;    /* 进行元组投影的信息 */
} PlanState;

  其中,ExecProcNodeMtdPostgreSQL 查询执行框架中的一个关键组成部分。这个类型的函数指针用于指向实现了特定逻辑的函数,这些函数负责从执行计划的某个节点中获取下一个元组(tuple。如果没有更多的元组可供获取,这些函数将返回 NULL 或一个空的 TupleTableSlot。这个定义允许不同类型的执行节点(如顺序扫描连接操作等)实现各自的元组获取逻辑,而这些逻辑可以通过相同的接口被执行器调用。

/* 定义一个函数指针类型ExecProcNodeMtd */
typedef TupleTableSlot *(*ExecProcNodeMtd) (struct PlanState *pstate);
  • TupleTableSlot *(*ExecProcNodeMtd) (struct PlanState *pstate);:这是一个函数指针的定义,它指向的函数接受一个指向 PlanState 结构体的指针作为参数,返回一个指向 TupleTableSlot 的指针。这里的 PlanState 代表查询执行树中的一个节点的状态,而 TupleTableSlot 是用于存储和传递元组的数据结构。
  • struct PlanState *pstate:函数的参数是一个指向 PlanState 结构的指针,表示当前执行节点的状态。PlanState 包含了执行该节点所需要的所有上下文信息,如节点的执行计划子节点的状态当前节点产生的结果等。
  • TupleTableSlot *:函数的返回类型是一个指向 TupleTableSlo t的指针。TupleTableSlotPostgreSQL 中用于表示一个元组(数据库行)的结构,可以看作是查询结果的一个容器。如果函数返回一个非空的 TupleTableSlot,则表示获取到了一个元组;如果返回 NULL 或一个空的 TupleTableSlot,则表示没有更多的元组可供处理。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/790458.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring Boot中前端通过请求接口下载后端存放的Excel模板

导出工具类 package com.yutu.garden.utils;import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import org.apache.commons.io.IOUtils; import org.apache.poi.hssf.util.HSSFColor; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.slf4j.Logger;…

云计算的安全需求

目录 一、概述 二、云安全服务基本能力要求 三、信息安全服务(云计算安全类)资质要求 3.1 概述 3.2 资质要求内容 3.2.1 组织与管理要求 3.2.2 技术能力要求 四、云安全主要合规要求 4.1 安全管理机构部门的建立 4.2 安全管理规范计划的编制 4…

C++ //练习 11.3 编写你自己的单词计数程序。

C Primer(第5版) 练习 11.3 练习 11.3 编写你自己的单词计数程序。 环境:Linux Ubuntu(云服务器) 工具:vim 代码块 /*************************************************************************> …

Vue 学习随笔系列十二 -- 表格内容渲染方法

表格内容渲染方法 文章目录 表格内容渲染方法1、使用 formatter 函数2、 使用 render 函数3、使用 template 自定义4、使用 slot 插槽5、注意 1、使用 formatter 函数 示例代码1 <el-table-column prop"status" label"状态" align"center" …

2024最新AI创作系统ChatGPT源码+Ai绘画网站源码,GPTs应用、AI换脸、插件系统、GPT文档分析、GPT语音对话一站式解决方案

一、前言 SparkAi创作系统是基于ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统&#xff0c;支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;那么如何搭建部署AI创作ChatGPT&#xff1f;小编这里写一个详细图文教程吧。已支持GPT…

记 log4j-over-slf4j.jar AND bound slf4j-log4j12.jar jar包冲突问题

报错信息如下 SLF4J: Detected both log4j-over-slf4j.jar AND bound slf4j-log4j12.jar on the class path, preempting StackOverflowError. SLF4J: See also http://www.slf4j.org/codes.html#log4jDelegationLoop for more details. Exception in thread “main” java.lan…

NineData云原生智能数据管理平台新功能发布|2024年3月版

数据库 DevOps - 大功能升级 SQL 开发早期主要提供 SQL 窗口&#xff08;IDE&#xff09;功能&#xff0c;在产品经过将近两年时间的打磨&#xff0c;新增了大量的企业级功能&#xff0c;已经服务了上万开发者&#xff0c;覆盖了数据库设计、开发、测试、变更等生命周期的功能…

神经网络与深度学习(二)

一、深度学习平台 张量&#xff08;Tensor&#xff09; 是一个物理量&#xff0c;对高维(维数 ≥ 2) 的物理量进行“量纲分析” 的一种工具。简单的可以理解为&#xff1a;一维数组称为矢量&#xff0c;二维数组为二阶张量&#xff0c;三维数组为三阶张量 计算图 用“结点”…

调用飞书获取用户Id接口成功,但是没有返回相应数据

原因&#xff1a; 该自建应用没有开放相应的数据权限。 解决办法&#xff1a; 在此处配置即可。

单片机学习笔记——ESP32

ESP32 引言ESP32的一些基本知识ESP32 的通信能量消耗ESP的休眠模式中断程序定时器 Timers脉宽调制频 pulse-width modulation数模转换器SAR ADC 逐次逼近型ADC应用——停车占用探测HCSR-04引脚器件参数工作原理

DETR【Transformer+目标检测】

End-to-End Object Detection with Transformers 2024 NVIDIA GTC&#xff0c;发布了地表最强的GPU B200&#xff0c;同时&#xff0c;黄仁勋对谈《Attention is All You Need》论文其中的7位作者&#xff0c;座谈的目的无非就是诉说&#xff0c;Transformer才是今天人工智能成…

【环境变量】命令行参数 | 概念 | 理解 | 命令行参数表 | bash进程

目录 四组概念 命令行参数概念&理解 查看命令函参数 命令行字符串&命令行参数表 命令行参数存在的意义 谁形成的命令行参数 父进程&子进程&数据段 bash进程 最近有点小忙&#xff0c;可能更新比较慢。 四组概念 竞争性: 系统进程数目众多&#xff0c…

构建企业级微服务平台:实现可扩展性、弹性和高效性

在软件开发的快速发展领域中&#xff0c;企业不断努力构建健壮、可扩展和高效的系统。随着微服务架构的出现&#xff0c;再加上云原生技术的应用&#xff0c;创建敏捷且具有弹性的平台的可能性是无限的。在本指南中&#xff0c;我们将深入探讨使用强大的工具和技术组合&#xf…

Python基于深度学习的人脸识别项目源码+演示视频,利用OpenCV进行人脸检测与识别 preview

​ 一、原理介绍 该人脸识别实例是一个基于深度学习和计算机视觉技术的应用&#xff0c;主要利用OpenCV和Python作为开发工具。系统采用了一系列算法和技术&#xff0c;其中包括以下几个关键步骤&#xff1a; 图像预处理&#xff1a;首先&#xff0c;对输入图像进行预处理&am…

.Net Core/.Net6/.Net8 ,启动配置/Program.cs 配置

.Net Core/.Net6/.Net8 &#xff0c;启动配置/Program.cs 配置 没有废话&#xff0c;直接上代码调用 没有废话&#xff0c;直接上代码 /// <summary>/// 启动类/// </summary>public static class Mains{static IServiceCollection _services;static IMvcBuilder _…

ViT模型实现-数据处理

目录 ViT模型实现 将PIL图像或NumPy ndarray转换为torch.Tensor torchvision是什么 img.con

flutter中的ListView单元测试

在 Flutter 中&#xff0c;你可能会希望测试 ListView 内容是否如预期那样显示&#xff0c;是否能够正确滚动&#xff0c;以及是否处理用户输入。以下是测试 ListView 的一些基本步骤&#xff1a; 测试 ListView 的内容 这涉及到确认 ListView 是否显示了正确数量的项&#x…

Debian linux版本下运行的openmediavault网盘 千兆网卡升级万兆

一、适用场景 1、使用vmware ESXi虚拟化平台运行多种不同应用服务器时&#xff0c;其中网盘服务器采用开源的openmediavault搭建&#xff1b; 2、将老专业服务器升级千兆网为万兆网&#xff1b; 3、需要转移的数据量大的企业或用户&#xff1b; 4、从服务器到服务器的数据转移…

【群晖】NASTOOL-自动化处理影音视频工具

【群晖】NASTOOL-自动化处理影音视频 本文主要从获取、部署、使用、配置等方面进行手把手教学如何使用nastool工具进行影音视频自动化处理。从此靠别繁琐的网上各个网址找资源-下载-复制-改名-刮削等操作。 准备 DSM 7.1 &#xff08;我使用的是群晖 7.1 系统&#xff0c;不管…

uniapp/设置桌面角标/发送系统通知/动态修改桌面应用图标/展示3d模型/仿淘宝二楼

uniapp的安卓apk图标角标设置消息数量 1、主要方法&#xff1a; 设置角标&#xff1a; plus.runtime.setBadgeNumber(999) 清除角标&#xff1a; //plus.runtime.setBadgeNumber(0)//没有效果 plus.runtime.setBadgeNumber(-1) //有效果 2、使用在具体的生命周期 1、打开app获取…