【PostgreSQL内核学习(九)—— 查询执行(数据定义语句执行)】

数据定义语句执行

  • 概述
    • 数据定义语句执行流程
    • 执行示例

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

概述

  数据定义语言(DDL,Data Definition Language) 是一类用于定义数据模式、函数等的功能性语句。不同于元组增删查改的操作,其处理方式是为每一种类型的描述语句调用相应的处理函数。
  数据定义语句的处理过程比较简单,其执行流程最终会进入到ProcessUtility处理器,然后执行语句对应的不同处理过程。由于数据定义语句的种类很多,因此整个处理过程中的数据结构和方式种类繁冗、复杂,但流程相对简单、固定。

数据定义语句执行流程

  由于ProcessUtility需要处理所有类型的数据定义语句,因此其输人数据结构的类型也是各种各样,每种类型的数据结构表示不同的操作类型。ProcessUtility将通过判断数据结构中NodeTag字段的值来区分各种不同节点并引导执行流程进人相应的处理函数。图6-7展示了ProcessUtility的总体流程。
在这里插入图片描述
  ProcessUtility函数源码如下:(路径:src/backend/tcop/utility.c

/** ProcessUtility*		general utility function invoker**	pstmt: PlannedStmt wrapper for the utility statement*	queryString: original source text of command*	context: identifies source of statement (toplevel client command,*		non-toplevel client command, subcommand of a larger utility command)*	params: parameters to use during execution*	queryEnv: environment for parse through execution (e.g., ephemeral named*		tables like trigger transition tables).  May be NULL.*	dest: where to send results*	completionTag: points to a buffer of size COMPLETION_TAG_BUFSIZE*		in which to store a command completion status string.** Caller MUST supply a queryString; it is not allowed (anymore) to pass NULL.* If you really don't have source text, you can pass a constant string,* perhaps "(query not available)".** completionTag is only set nonempty if we want to return a nondefault status.** completionTag may be NULL if caller doesn't want a status string.** Note for users of ProcessUtility_hook: the same queryString may be passed* to multiple invocations of ProcessUtility when processing a query string* containing multiple semicolon-separated statements.  One should use* pstmt->stmt_location and pstmt->stmt_len to identify the substring* containing the current statement.  Keep in mind also that some utility* statements (e.g., CREATE SCHEMA) will recurse to ProcessUtility to process* sub-statements, often passing down the same queryString, stmt_location,* and stmt_len that were given for the whole statement.*/
void
ProcessUtility(PlannedStmt *pstmt,const char *queryString,ProcessUtilityContext context,ParamListInfo params,QueryEnvironment *queryEnv,DestReceiver *dest,char *completionTag)
{Assert(IsA(pstmt, PlannedStmt));Assert(pstmt->commandType == CMD_UTILITY);Assert(queryString != NULL);	/* required as of 8.4 *//** We provide a function hook variable that lets loadable plugins get* control when ProcessUtility is called.  Such a plugin would normally* call standard_ProcessUtility().*/if (ProcessUtility_hook)(*ProcessUtility_hook) (pstmt, queryString,context, params, queryEnv,dest, completionTag);elsestandard_ProcessUtility(pstmt, queryString,context, params, queryEnv,dest, completionTag);
}

  函数参数解释:

  • pstmt:是包装了 utility 语句的 PlannedStmt 结构体,其中存储了 utility 语句的执行计划信息。
  • queryString:是原始的 SQL 查询文本,即用户输入的 utility 语句。
  • context:标识 utility 语句的来源,可以是顶层客户端命令、非顶层客户端命令,或者是其他更大的 utility 命令的子命令。
  • params:是在执行过程中可能需要用到的参数。
  • queryEnv:是用于解析到执行期间的环境信息,比如在触发器中使用的过渡表等。可以为NULL。
  • dest:指定了执行结果的输出位置。
  • completionTag:是一个指向存储命令完成状态字符串的缓冲区,用于返回一些执行结果的状态信息,例如影响的行数等。可以为NULL,表示不需要这些状态信息。

  函数执行流程解释:

  1. 首先,函数会进行一系列断言(Assert)的检查,确保传入的参数是符合要求的,例如 pstmt 必须是 PlannedStmt 类型,queryString 不为空,commandTypeCMD_UTILITY 等。
  2. 接着,函数检查是否有外部插件定义了 ProcessUtility_hook 钩子函数。如果有插件定义了该钩子函数,那么数据库会调用这个插件的处理函数来处理 utility 语句,而不是继续执行下面的标准处理流程。
  3. 如果没有插件定义 ProcessUtility_hook 钩子函数,那么数据库会调用 standard_ProcessUtility 函数,来处理 utility 语句。standard_ProcessUtility 函数会根据不同的 utility 类型(比如创建表、创建索引等)调用相应的处理函数来执行 utility 语句,并且根据情况将执行结果返回给客户端。

  针对各种不同的查询树,查询编译器在执行处理前会做一些额外的处理对查询树进行分析、处理与转换。例如,创建表的语句会用函数transformCreateStmt进行查询树的处理。这些处理过程可能会在当前操作之前和之后增加一些新的操作(例如在创建表的操作之前增加创建serial序列表操作、之后增加创建触发器用于外键约束操作等),也可能会执行对数据结构的处理操作(例如将CreateStmt节点tableElts字段中CONST_CHECK类型的Constraint节点转存到CreateStmtconstraints链表中等)。由于这些处理过程会产生一些新的操作,因此最终会生成一个由多个操作构成的链表。因此,执行过程需要依次扫描该链表,为每一个原子操作调用相应的处理函数。
  以创建表create table t_a (id int, name char(20));为例进行调试。

函数调用顺序:exec_simple_query —> PortalRun —> PortalRunMulti —> PortalRunUtility —>
ProcessUtility —> standard_ProcessUtility

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
  相同类别的语句处理过程涉及内容相近,实现思想和主要过程相似。例如,事务类处理主要是对于当前事务的状态的判断和转换;游标类处理的主要思想是首次将执行一个查询计划树(Plantree),将结果缓存在Portal指向的特殊结构中,然后按照要求获取元组数据;表、属性管理类主要涉及权限管理、修改相应系统表以及关系表的存储类别操作等。由于数据定义语句的种类多达上百种,我们下面将以一个创建表的例子来介绍数据定义语句的执行流程。

执行示例

  来看一看书中给出的案例吧:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

  我们根据书中的描述来实际的调试一下代码吧:
  由先前的查询树可视化工具可以打印出例6.1中经过查询重写的Query结构:
在这里插入图片描述
  可以看到ChoosePortalStrategy函数的确选择了PORTAL_MULTI_QUERY字段。
在这里插入图片描述
  此外,PortalRun函数调用PortalRunMulti来执行PORTAL_MULTI_QUERY策略。
在这里插入图片描述
  执行PortalDrop函数后Portal结构体如下所示:
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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

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

相关文章

ES6 模块编程(新思路方便复习笔记)

文章目录 ES6 模块编程(新思路方便复习笔记)介绍需求说明思路分析/图解代码实现创建common.js创建use_common.js 其它导出形式--直接导出创建common2.js创建use_common2.js 其它导出形式--默认导出创建common3.js创建use_common3.js--导入默认导出模块/数据注意事项和使用细节导…

【应用】Asible自动化运维工具的应用与常用命令

ansible自动化运维工具 一、ansible 的概述1. ansible 的概念2. ansible 的特性 二、ansible 的部署与命令1. ansible 的部署1.1 服务器ip地址设置1.2 ansible 服务器部署 2. ansible 命令行模块2.1 command 模块2.2 shell 模块2.3 cron 模块2.4 user 模块2.5 group 模块2.6 co…

中国农业大学计算机考研分析

关注我们的微信公众号 姚哥计算机考研 更多详情欢迎咨询 中国农业大学(B-)考研难度(☆☆☆) 中国农业大学计算机考研招生学院是信息与电气工程学院。目前均已出拟录取名单。 中国农业大学信息与电气工程学院,起源于…

使用EasyPoi实现Excel的按模板样式导出

1,横向遍历 #fe 使用#fe命令可以实现集合数据的横向拓展,比如模板代码是 {{#fe:maths t.score}}导出的excel里面就会显示会自当前列,向右拓展,效果可参见下面的导出文件截图 2,横向遍历值 v_fe 使用v_fe命令可以实现…

ROS前驱前转小车仿真(2D)项目

文章目录 一.官方网址1.ROS官网2.urdf-模型3.rviz-数据可视化4.gazebo-仿真环境5.gmapping-建图6.navigation-导航 二.文件框架三.启动顺序0.依赖包的安装1.手动控制的启动顺序2.建图的启动顺序3.导航的启动顺序 四.urdf-模型文件1.ackermann.xacro-轮子传动的配置2.common_pro…

MAC 推送证书不受信任

配置推送证书的时候,一打开就变成不受信任,搜了很多解决版本。 由于苹果修改相关规定,推送证书 打开Apple PKI - Apple 下载AppleWWDRCA文件,选择G4,双击安装之后,证书已经变为受信任。 AppleWWDRCA(Apple Worldwid…

仿VScode MDK背景配色方案

效果如果所示 操作方法:备份后修改~/UV4文件夹下的global.prop,用以下的代码代替。 # properties for all file types indent.automatic1 virtual.space0 view.whitespace0 view.endofline0 code.page936 caretline.visible1 highlight.matchingbraces1…

【数据结构】链表是否有环相关问题

文章目录 快指针走3、4、5步甚至更多可以吗为什么快慢指针一定在入口点相遇![在这里插入图片描述](https://img-blog.csdnimg.cn/ba346dbc9fee425dbb895ae2962e99ce.png) 快指针走3、4、5步甚至更多可以吗 部分情况下可以。 如果这样,相对(追及&#xf…

tauri在github上进行自动更新打包并发版过程,实战操作避坑

从网上找了很多很多的文章,结果还是入坑了,一个问题找了一天才解决: Error A public key has been found, but no private key. Make sure to set TAURI_PRIVATE_KEY environment variable. 596 ELIFECYCLE  Command failed with exit code…

智慧消防:如何基于视频与智能分析技术搭建可视化风险预警平台?

一、背景分析 消防安全是一个重要的话题,涉及到每个人的生活和安全。每年都会发生大量的火灾,给人们带来极大的危害,摧毁了大量的财产,甚至造成了可怕的人员伤亡。而消防安全监督管理部门人员有限,消防安全监管缺乏有…

SVN - 记录一下无法提交代码 提示:被锁定(locked)

今天遇到一个问题,svn 在提交代码的时候出现了svn is already locked,导致代码无法提交(commit)和更新(update) 主要报错如下: 解决方法: 然后点击 Clean up 选中一下选项&#xff…

Linux centos7.x系统 下没有ens33 网卡的解决方案

一、背景 安装完windows11 Centos7.9 版本的双系统之后 , 启动Centos7.9时发现没有网卡信息 , 只有ifcfg-lo网卡的信息 , 这个时候就证明没有网卡信息,或者网卡驱动不匹配(我这里是没有网卡),所以我们要重新安装 , 安装步骤如下 : 二、安装步骤 1.查…

PHP 药店管理系统mysql数据库web结构apache计算机软件工程网页wamp

一、源码特点 PHP 药品管理系统 是一套完善的web设计系统,系统采用smarty框架进行开发设计,对理解php编程开发语言有帮助,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。 PHP 药店管理系统mysql数据库web结构apache计 下载地址…

开发一个简单的数据库路由进行分库分表

今天我们来看看一个简单的数据库路由组件要怎么开发出来,这篇文章分为几个步骤进行介绍,分别为: 什么是数据库路由 路由组件的作用为什么要自研组件需要用到什么技术 整体的业务流程主要代码 介绍 数据库路由的作用 使用数据库路由是在业…

产品解读|有了JMeter,为什么还需要MeterSphere?

提起JMeter,相信大部分的测试人员应该都很熟悉。JMeter因其小巧轻量、开源,加上支持多种协议的接口和性能测试,在测试领域拥有广泛的用户群体。一方面,测试人员会将其安装在个人的PC上,用以满足日常测试工作的需要&…

【SpringCloud Alibaba】(一)微服务介绍

此专栏内容皆来自于【冰河】的《SpringCloud Alibaba 实战》文档。 1. 专栏介绍 我们先来看看《SpringCloud Alibaba实战》专栏的整体结构吧,先上图 从上图,大家可以看到,专栏从整体上分为十个大的篇章,分别为 专栏设计、微服务…

【Git】

学习来自于: 女朋友乱用Git,差点把我代码删了。。。 一些常用的Git 知识点整理 关于Git这一篇就够了 Git基本命令大全 30分钟精通Git,学不会来找我 Git 版本管理 | 莫烦PYTHON Git 代码版本管理教程 文章目录 【前言】集中式与分布式的…

Jmeter配置起来太繁琐?试试RunnerGo

在用jmeter做性能测试时想看完整一点的测试报告,想配置阶梯模式来压测,想配置不同的接口并发这些都需要安装插件并且影响机器性能,想做自动化测试还得放到jenkins,这些配置起来太繁琐。今天给大家推荐一款测试平台RunnerGo&#x…

【Redis】高级篇: 一篇文章讲清楚Redis的单线程和多线程

目录 面试题 Redis到底是多线程还是单线程? 简单回答 详解 Redis的“单线程” Redis为什么选择单线程? 后来Redis为什么又逐渐加入了多线程特性? Redis为什么快? 回答 IO多路复用 Unix网络编程的5种IO模型 主线程和IO…

【100天精通python】Day9:数据结构_字典、集合

目录 目录 1 字典 1.1 字典的基本操作示例 1.2 字典推导式 2 集合 2.1 集合的常用操作示例 3 列表、元组、字典、集合的区别 1 字典 在Python中,字典(Dictionary)是一种无序的数据结构,用于存储键值对的集合。每个…