Postgresql源码(137)执行器参数传递与使用

参考
《Postgresql源码(127)投影ExecProject的表达式执行分析》

0 总结速查

prepare p_04(int,int) as select b from tbl_01 where a = $1 and b = $2为例。

  • custom计划中,在表达式计算中使用参数的值,因为custom计划会带参数值,所以表达式计算时不需要从参数列表中取值,直接EEO_CASE(EEOP_FUNCEXPR_STRICT)计算即可。
  • generic计划中,在表达式计算中使用参数的值,generic计划不带参数值,所以需要多走一步EEO_CASE(EEOP_PARAM_EXTERN)、EEO_CASE(EEOP_FUNCEXPR_STRICT)。具体调用ExecEvalParamExtern函数拿到参数值。
  • generic计划中,使用参数的节点会放一个Param。

1 执行器如何使用参数?

在下面例子中,execute语句执行时带了两个参数,执行器是在哪里带入参数执行的?下面做一些分析。

prepare p_04(int,int) as select b from tbl_01 where a = $1 and b = $2;
execute p_04(2,200);

带入参数的位置是PortalStart函数。

extern void PortalStart(Portal portal, ParamListInfo params, int eflags, Snapshot snapshot);

PortalStart的第二个参数可以接受参数列表ParamListInfo,从代码上看,PortalStart有三处调用位置:

exec_simple_queryPortalStart(portal, NULL, 0, InvalidSnapshot)exec_bind_messagePortalStart(portal, params, 0, InvalidSnapshot)ExecuteQueryPortalStart(portal, paramLI, eflags, GetActiveSnapshot())SPI_cursor_open_internalPortalStart(portal, paramLI, 0, snapshot)
  1. exec_simple_query:执行简单SQL语句,不需要传参。
  2. exec_bind_message:PEB协议中的B阶段,绑定参数。
  3. ExecuteQuery:SQL语法提供的PBE协议,在execute阶段,绑定参数。
  4. SPI_cursor_open_internal:PL中打开游标时,绑定参数。

下面对3、4两种情况展开分析。

2 execute执行时执行器的传参

栗子:

create table tbl_01(a int, b int);
insert into tbl_01 values (1,100);
insert into tbl_01 values (2,200);
prepare p_04(int,int) as select b from tbl_01 where a = $1 and b = $2;
execute p_04(2,200);

execute p_04(2,200); 执行时,PortalStart会带入ParamListInfo。
在这里插入图片描述

2.1 问题一:ParamListInfo的来源?

ExecuteQueryEvaluateParams// 准备计算参数表达式的值exprstates = ExecPrepareExprList(params, estate)makeParamListretval->parserSetup = paramlist_parser_setup// paramlist_parser_setup//   pstate->p_paramref_hook = paramlist_param_ref//// paramlist_param_ref//   param = makeNode(Param)//   param->paramkind = PARAM_EXTERN//   param->paramid = paramno//   ...//   钩子函数中生成Param,该实例不会走这个钩子,注意Param结构是不带值的,只用于中间过程。// 走表达式计算参数的值// 注意值都在paramLI->params[i]->value中i = 0;foreach(l, exprstates){ExprState  *n = (ExprState *) lfirst(l);ParamExternData *prm = &paramLI->params[i];prm->ptype = param_types[i];prm->pflags = PARAM_FLAG_CONST;prm->value = ExecEvalExprSwitchContext(n,GetPerTupleExprContext(estate),&prm->isnull);i++;}

生成ParamListInfo(包含参数的全部信息,包括值)

paramLI = {paramFetch = 0x0,paramFetchArg = 0x0,paramCompile = 0x0,paramCompileArg = 0x0,parserSetup = 0x8357c1 <paramlist_parser_setup>,parserSetupArg = 0x3238da8,paramValuesStr = 0x0,numParams = 2,params = 0x3238de8}

2.2 问题二:ParamListInfo的使用位置?

custom plan

前五次执行会生成customplan,customplan在GetCachedPlan中生成,customplan计划是带着参数生成的(按参数定制的计划,更准确,但每次参数变了都要重新生成),所以计划中会有参数的具体值,执行时不会使用执行器带入的ParamListInfo。
在这里插入图片描述
构造customplan时,会带入参数生成计划:
在这里插入图片描述

ExecQual调用表达式框架计算where a = $1 and b = $2,ExecQual函数进入表达计算。

ExecScanfor (;;)slot = ExecScanFetch...if (qual == NULL || ExecQual(qual, econtext))...return slot

ExecQual表达式计算流程:

  1. EEO_CASE(EEOP_SCAN_FETCHSOME)
    • 从econtext->ecxt_scantuple读取到scanslot(当前要处理的一行数据)slot_getsomeattrs函数确保这一行数据中,至少有op->d.fetch.last_var个列是可以直接访问的。《Postgresql源码(127)投影ExecProject的表达式执行分析》
  2. EEO_CASE(EEOP_SCAN_VAR)
    • 从行中拿到需要列的值。《Postgresql源码(127)投影ExecProject的表达式执行分析》
  3. EEO_CASE(EEOP_FUNCEXPR_STRICT)
    • 计算where中第一个条件
    • fcinfo : int4eq
    • arg1 : 2
    • arg2 : 2
  4. EEO_CASE(EEOP_QUAL)
  5. EEO_CASE(EEOP_FUNCEXPR_STRICT)
    • 计算where中第二个条件
    • fcinfo : int4eq
    • arg1 : 200
    • arg2 : 200
  6. EEO_CASE(EEOP_QUAL)

generic plan

第六次执行时,choose_custom_plan返回false,BuildCachedPlan时没有传入任何参数构造generic plan(通用执行计划,可以接受任何参数,不用每次都生成计划,但没有customplan精确,毕竟这里没有给参数)
在这里插入图片描述
执行execute p_04(2,200);给的两个参数明显是用于过滤条件的,所以在ExecScan→ExecQual中寻找使用的位置:
在这里插入图片描述

在ExecEvalParamExtern函数中,从econtext->ecxt_param_list_info中拿到参数值,返回给表达式框架:

ExecEvalParamExtern(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
{ParamListInfo paramInfo = econtext->ecxt_param_list_info;int			paramId = op->d.param.paramid;if (likely(paramInfo &&paramId > 0 && paramId <= paramInfo->numParams)){ParamExternData *prm;ParamExternData prmdata;......prm = &paramInfo->params[paramId - 1];......*op->resvalue = prm->value;*op->resnull = prm->isnull;return;}}......
}

最终ExecScan在loop中,拿到的slot经过ExecQual的计算,决定是否保留该元组。

ExecQual调用表达式框架计算where a = $1 and b = $2,通过ExecEvalParamExtern函数拿到$1$2的值,完成计算,放回true OR false。

ExecScanfor (;;)slot = ExecScanFetch...if (qual == NULL || ExecQual(qual, econtext))...return slot

表达式计算流程:

  1. EEO_CASE(EEOP_SCAN_FETCHSOME)
  2. EEO_CASE(EEOP_SCAN_VAR)
  3. EEO_CASE(EEOP_PARAM_EXTERN)
  4. EEO_CASE(EEOP_FUNCEXPR_STRICT)
    • int4eq
    • arg1 : 2
    • arg2 : 2
  5. EEO_CASE(EEOP_QUAL)
  6. EEO_CASE(EEOP_SCAN_VAR)
  7. EEO_CASE(EEOP_PARAM_EXTERN)
  8. EEO_CASE(EEOP_FUNCEXPR_STRICT)
    • int4eq
    • arg1 : 200
    • arg2 : 200

从计划上来看,参数的位置是两个Param。
在这里插入图片描述

3 游标打开时执行器的传参

create table tbl_01(a int, b int);
insert into tbl_01 values (1,100);
insert into tbl_01 values (2,200);do $$
declareres int;c_04 CURSOR (p1 int, p2 int) FOR select b from tbl_01 where a = p1 and b = p2;
beginopen c_04(2,200);fetch c_04 into res;raise notice '%',res;
end; $$;

PL的参数在transform阶段已经转成const了,所以执行类似customplan:
在这里插入图片描述

fetch堆栈:
在这里插入图片描述

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

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

相关文章

SPI通信详解-学习笔记

参考原文地址 SPI&#xff1a;高速、全双工&#xff0c;同步、通信总线 SPI主从模式 SPI分为主、从两种模式&#xff0c;一个SPI通讯系统需要包含一个&#xff08;且只能是一个&#xff09;主设备&#xff0c;一个或多个从设备。提供时钟的为主设备&#xff08;Master&#xff…

Day102漏洞发现-漏扫项目篇Poc开发Yaml语法插件一键生成匹配结果交互提取

知识点&#xff1a; 1、Nuclei-Poc开发-环境配置&编写流程 2、Nuclei-Poc开发-Yaml语法&匹配提取 3、Nuclei-Poc开发-BurpSuite一键生成插件 Nuclei-Poc开发-环境配置&编写流程 1、开发环境&#xff1a;VscodeYaml插件 Visual Studio Code - Code Editing. R…

Node.js 入门指南:从零开始构建全栈应用

​&#x1f308;个人主页&#xff1a;前端青山 &#x1f525;系列专栏&#xff1a;node.js篇 &#x1f516;人终将被年少不可得之物困其一生 依旧青山,本期给大家带来node.js篇专栏内容:node.js-入门指南&#xff1a;从零开始构建全栈应用 前言 大家好&#xff0c;我是青山。作…

WordPress网站添加嵌入B站视频,自适应屏幕大小,取消自动播放

结合bv号 改成以下嵌入式代码&#xff08;自适应屏幕大小,取消自动播放&#xff09; <iframe style"width: 100%; aspect-ratio: 16/9;" src"//player.bilibili.com/player.html?isOutsidetrue&bvidBV13CSVYREpr&p1&autoplay0" scrolling…

大模型应用系列:Query 变换的示例浅析

【引】NLP中的经典组件在大模型应用中还有效么&#xff1f;大模型对自然语言处理中的典型任务有什么影响么&#xff1f; RAG应用通过分割文档、嵌入向量化并检索高语义相似性的块来响应用户问题&#xff0c;但面临文档块不相关、用户用词不当及结构化查询需求等问题。若RAG无法…

【Oracle】空格单字符通配符查询匹配失败

问题 在进行模糊查询的时候&#xff0c;通过全局任意字符串匹配出含有两个字刘姓的人&#xff0c;但是通过刘_不能匹配出结果。 解决 检查后发现&#xff0c;姓名中包含空格 SELECT * FROM student WHERE TRIM(sname) LIKE 刘_;第一种解决方案就是查询的时候进行去空格处理&a…

讲讲⾼并发的原则?

大家好&#xff0c;我是锋哥。今天分享关于【讲讲⾼并发的原则&#xff1f;】面试题。希望对大家有帮助&#xff1b; 讲讲⾼并发的原则&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 高并发是指系统在同一时间内能够处理大量请求的能力。要有效地管理…

鸿蒙进阶-AlphabetIndexer组件

大家好&#xff0c;这里是鸿蒙开天组&#xff0c;今天我们来学习AlphabetIndexer组件&#xff0c;喜欢就点点关注吧&#xff01; 通过 AlphabetIndexer 组件可以与容器组件结合&#xff0c;实现导航联动&#xff0c;以及快速定位的效果 核心用法 AlphabetIndexer不是容器组件…

ubuntu交叉编译expat库给arm平台使用

1.下载expat库源码: https://github.com/libexpat/libexpat/release?page=2 wget https://github.com/libexpat/libexpat/release/download/R_2_3_0/expat-2.3.0.tar.bz2 下载成功: 2.解压expat库,并进入解压后的目录: tar xjf expat-2.3.0.tar.bz2 cd expat-2.3.0 <…

【系统面试篇】进程和线程类(1)(笔记)——区别、通讯方式、同步、互斥、锁分类

目录 一、问题综述 1. 进程和线程的区别&#xff1f; 2. 进程的状态有哪些&#xff1f; 3. 进程之间的通信方式? &#xff08;1&#xff09;管道 &#xff08;2&#xff09;消息队列 &#xff08;3&#xff09;共享内存 &#xff08;4&#xff09;信号量 &#xff08…

nginx(四):如何在 Nginx 中配置以保留真实 IP 地址

如何在 Nginx 中配置以保留真实 IP 地址 1、概述2、nginx配置示例2.1、配置说明2.2、客户端获取真实IP2.2.1、代码说明 3、插曲4、总结 大家好&#xff0c;我是欧阳方超&#xff0c;可以我的公众号“欧阳方超”&#xff0c;后续内容将在公众号首发。 1、概述 当使用nginx作为…

C++《list的模拟实现》

在上一篇C《list》专题当中我们了解了STL当中list类当中的各个成员函数该如何使用&#xff0c;接下来在本篇当中我们将试着模拟实现list&#xff0c;在本篇当中我们将通过模拟实现list过程中深入理解list迭代器和之前学习的vector和string迭代器的不同&#xff0c;接下来就开始…

本篇万字,博客最细,oled多级菜单代码解析,与实现教程,指针实现(含源码)!!!

目录 教程前言 多级菜单基本知识 驱动文件创建 ​编辑 ​编辑 ​编辑 定义菜单数据类型代码解析 按键代码解析 菜单数据赋值代码解析 菜单按键切换显示代码解析 项目工程移植地址 教程前言 前言&#xff1a;编写不易&#xf…

华为HarmonyOS打造开放、合规的广告生态 - 贴片广告

场景介绍 贴片广告是一种在视频播放前、视频播放中或视频播放结束后插入的视频或图片广告。 接口说明 接口名 描述 loadAd(adParam: AdRequestParams, adOptions: AdOptions, listener: AdLoadListener): void 请求单广告位广告&#xff0c;通过AdRequestParams、AdOptions…

Leetcode137只出现一次的数字|| 及其拓展

简述&#xff1a; 虽然标题是这么描述的&#xff0c;但是我们不是一上来就解这道题&#xff0c;先看一下他的子题和扩展 子题&#xff1a;136. 只出现一次的数字 - 力扣&#xff08;LeetCode&#xff09; 扩展题&#xff1a; 所以我们由易到难&#xff0c;先来看第一道&#x…

【解决办法】无法使用右键“通过VSCode打开文件夹”

个人博客&#xff1a;苏三有春的博客 前言 作者的编程环境为VScode&#xff0c;工作时常使用VScode打开整个工程文件夹。如果先打开VScode再从VScode中选择文件夹打开效率太慢&#xff0c;作者一般使用的方式是右键文件夹&#xff0c;直接选择"通过code打开文件夹"…

数据揭秘:掌握K-means聚类算法的精髓与实践

数据揭秘&#xff1a;掌握K-means聚类算法的精髓与实践 在机器学习领域&#xff0c;聚类是一种探索性的数据挖掘技术&#xff0c;用于将数据集中的样本划分成若干个簇&#xff0c;使得同一簇内的样本相似度高&#xff0c;而不同簇之间的样本相似度低。本文将深入探讨聚类分析的…

ADNI蛋白质数据集下载

&#xff08;我发现这个网站最近又更新了界面&#xff0c;现在变得很好看很简洁&#xff0c;但是有一些入口变了&#xff09; 1.官网链接 https://ida.loni.usc.edu/home/projectPage.jsp?projectADNI 2.登录 选择ADNI&#xff08;其实PPMI数据也是这样下的&#xff09;&a…

【数据分享】2024年我国省市县三级的生活服务设施数量(46类设施/Excel/Shp格式)

人才市场、售票处、旅行社等生活服务设施的配置情况是一个城市公共基础设施完善程度的重要体现&#xff0c;一个城市生活服务设施种类越丰富&#xff0c;数量越多&#xff0c;通常能表示这个城市的公共服务水平越高&#xff01; 本次我们为大家带来的是我国各省份、各地级市、…

彻底解决idea不识别java项目

需求背景 下载了一个java swing的项目,通过idea导入后,项目无法识别。打开java文件,也不会报错,也不编译。 无法识别效果图 可以看到左侧的菜单,项目是没有被识别。 打开java文件,可以看到没有识别,java的图标也没有出现。 解决方法 1、打开Project Structure 2、修改…