Vastbase编程利器:PL/pgSQL原理简介

PL/pgSQL是Vastbase提供的一种过程语言,在普通SQL语句的使用上增加了编程语言的特点,可以用于创建函数、存储过程、触发器过程以及创建匿名块等。

本文介绍Vastbase中PL/pgSQL的执行流程,包括PL/pgSQL的编译运行


1、编译

PL/pgSQL的编译部分核心是解释出可以被内核识别的变量、命名空间和语句节点链表

1.1 编译上下文

typedef struct PLpgSQL_compile_context {struct PLpgSQL_datum** plpgsql_Datums;struct PLpgSQL_function* plpgsql_curr_compile;struct PLpgSQL_nsitem* ns_top;
}

PLpgSQL_compile_context结构用来保存编译期间的上下文信息,其核心成员是plpgsql_Datums、ns_top和plpgsql_curr_compile。

  • plpgsql_Datums:保存识别出的变量,是一个数组
  • ns_top:保存识别出的命名空间,是一个链表
  • plpgsql_curr_compile:保存识别出的语句节点链表

1.2 变量数组

typedef struct PLpgSQL_datum { /* Generic datum array item */int dtype; /* 变量类型 */int dno; /* 变量在变量数组的下标,即变量是变量数组的第几个元素 */
} PLpgSQL_datum;

PL/pgSQL支持多种类型的变量,包括普通的变量、表达式、复合类型和数组类型等。不同的变量类型用相应的结构表示,例如:普通变量使用PLpgSQL_var表示,表达式使用PLpgSQL_expr表示等。

Vastbase使用面向对象的思想,设计PL/pgSQL的变量,PLpgSQL_datum结构表示变量的抽象父类,共有4个结构体成员,PLpgSQL_var和PLpgSQL_expr等表示子类,子类结构的前4个成员与PLpgSQL_datum结构保持一致。

PL/pgSQL变量的来源主要有:

  • 函数的入参
  • 声明部分声明的变量
  • 内置变量,例如found变量和游标变量等

1.3 命名空间链表

typedef struct PLpgSQL_nsitem { /* Item in the compilers namespace tree */int itemtype; /* 命名空间类型 */int itemno; /* 命名空间关联的变量在变量数组的下标 */struct PLpgSQL_nsitem* prev; /* 指向上一个命名空间 */char name[FLEXIBLE_ARRAY_MEMBER]; /* 命名空间字符串 */
} PLpgSQL_nsitem;

PL/pgSQL里,命名空间(namespace)表示变量或标签的名称。主要有以下类型的命名空间:

PL/pgSQL在运行语句时,通过标识符查找命名空间链表,若查找到命名空间,则根据命名空间的itemno在变量数组里获取变量,进行相应的操作。

1.4 语法解析

Vastbase的PL/pgSQL有独立的词法分析和语法分析器。PL/pgSQL主要有两种大类的块:声明块语句块

声明块

声明块是以DECLARE关键字作为开始标记以BEGIN关键字作为结束标记的语句块

在声明块内可以声明变量和定义类型。新定义的类型会被记录到系统表元信息中。声明的变量会被记录到变量数组和命名空间链表里,对于复合类型的变量,PL/pgSQL会对其进行展开,即会创建${变量名}.${属性}这样的变量和命名空间。

语句块

语句块是指以BEGIN关键字作为开始标记,以END关键字作为结束标记的语句块

语句块内可以嵌套新的声明块和语句块。内层语句块可以访问外层声明块的类型和变量,反之不允许。

语句块以分号作为语句分隔符,每个语句都会被解析为不同类型的语句节点。

typedef struct { /* One EXCEPTION ... WHEN clause */PLpgSQL_condition* conditions;List* action; /* List of statements */
} PLpgSQL_exception;typedef struct PLpgSQL_stmt_block {List* body; /* List of statements */PLpgSQL_exception_block* exceptions;
} PLpgSQL_stmt_block;

PL/pgSQL使用PLpgSQL_stmt_block结构表示经过语法解析后的PL/pgSQL语句块,PLpgSQL_stmt_block结构有两个核心的成员,分别是body和exceptions。

body是语句块内正常运行的语句节点链表。

exceptions是PLpgSQL_exception类型变量链表。

当语句节点链表内的语句发生异常时,进入exceptions成员表示的异常处理流程。PLpgSQL_exception结构里,conditions成员表示该异常处理块的异常类型,action成员就是该类型异常的处理语句节点链表,当运行时发生了匹配conditions的异常,则执行该异常的action进行异常处理。

PL/pgSQL支持的语句类型比较丰富,以下是一些常用的语句类型归类:

  • 嵌套语句块:PLPGSQL_STMT_BLOCK
  • 赋值语句:PLPGSQL_STMT_ASSIGN
  • 条件分支:PLPGSQL_STMT_IF/PLPGSQL_STMT_GOTO/PLPGSQL_STMT_CASE
  • 循环控制:PLPGSQL_STMT_LOOP/PLPGSQL_STMT_WHILE/PLPGSQL_STMT_FORI/PLPGSQL_STMT_FORS/PLPGSQL_STMT_FORC/PLPGSQL_STMT_FOREACH_A/PLPGSQL_STMT_EXIT
  • 返回语句:PLPGSQL_STMT_RETURN/PLPGSQL_STMT_RETURN_NEXT/PLPGSQL_STMT_RETURN_QUERY
  • 打印输出:PLPGSQL_STMT_RAISE
  • 执行语句:PLPGSQL_STMT_EXECSQL/PLPGSQL_STMT_DYNEXECUTE/PLPGSQL_STMT_DYNFORS/PLPGSQL_STMT_PERFORM
  • 游标相关:PLPGSQL_STMT_OPEN/PLPGSQL_STMT_FETCH/PLPGSQL_STMT_CLOSE
  • 事务控制:PLPGSQL_STMT_COMMIT/PLPGSQL_STMT_ROLLBACK/PLPGSQL_STMT_SAVEPOINT
  • 其他:PLPGSQL_STMT_GETDIAG/PLPGSQL_STMT_NULL/PLPGSQL_STMT_SIGNAL/PLPGSQL_STMT_RESIGNAL

1.5 编译缓存

PL/pgSQL的编译是一个耗时操作,每次运行前都重新编译对性能来说影响非常大。为解决这个问题,对于使用PL/pgSQL定义的函数/存储过程,Vastbase 把编译结果缓存在会话的内存中。在会话运行期间,如果函数/存储过程的定义没有发生变化,则只需要编译一次,后续函数/存储过程的运行会从缓存获取编译结果。

2、运行

PL/pgSQL运行依赖SPI(Server Programming Interface)机制,把需要运行的SQL语句发送到内核模块中,内核模块通过预定义的钩子函数对语句中引用的变量进行解析处理。

2.1 SPI机制

SPI机制提供了一系列接口连接并访问数据库内核,

PLPGSQL_STMT_EXECSQL语句节点的工作流程大致如下图:

  • 流程说明
  • SPI_connect:PL/pgSQL语句块执行前,连接到内核服务端,整个语句块的执行只需要连接一次
  • SPI_prepare_params:发送待执行的sql语句到服务端,获取执行计划
  • setup_param_list:设置语句的参数
  • SPI_execute_plan_with_paramlist:发送参数到服务的,执行语句
  • SPI_finish:断开与内核服务端的连接,释放资源

2.2 执行语句块

PL/pgSQL经过编译后,编译上下文保存了变量数组、命名空间链表和语句节点链表。如下图,执行语句实际上就是遍历语句节点链表,根据不同的语句节点类型,调用不同的处理函数。

2.3 异常处理

如下图所示,异常处理块实际上是通过PG_TRY/PG_CATCH/PG_END_TRY实现

当调用exec_stmt_block执行的语句块时,如果PLpgSQL_stmt_block的exceptions成员不为空,即定义了异常处理块,则使用PG_TRY/PG_CATCH/PG_END_TRY异常处理工具进行exec_stmts(block→body)的调动,捕获异常后,调用exec_stmts(exception→action)进行异常处理。

2.4 参数处理

PL/pgSQL内允许语句内引用声明块内声明的变量或函数入参,代码如下:

CREATE TABLE t_test(id INT);
DECLARE id INT;
BEGINid := 1;INSERT INTO t_test values (id);
END;
/

第6行的INSERT语句会被语法解析器解析成PLPGSQL_STMT_EXECSQL语句节点,PL/pgSQL会把整个语句原封不动发送到内核服务端中并生成计划,那么内核的语义分析模块就需要识别出括号内的id标识符是一个参数。

Vastbase通过钩子函数实现参数识别和值替换,代码如下:

struct ParseState {PreParseColumnRefHook p_pre_columnref_hook;PostParseColumnRefHook p_post_columnref_hook;ParseParamRefHook p_paramref_hook;
}
typedef struct ParamListInfoData {ParamFetchHook paramFetch; /* parameter fetch hook */
} ParamListInfoData;

通过设置ParseState结构p_post_columnref_hook钩子,内核在进行对写入字段进行语义分析时,会调用钩子函数,该钩子函数对命名空间链表进行查找,如果查找到则构造Param节点记录变量在PL/pgSQL变量里数组中的位置和类型,并挂载Query树上。

通过设置ParamListInfoData结构paramFetch钩子,内核在生成执行计划的预处理表达式阶段,调用该钩子,根据Param结构信息拿到该参数的在变量值,并把该Param结构替换为Const结构。

通过两个钩子函数,使得PL/pgSQL执行sql语句时,可以引用声明块内声明的变量或函数入参。

3、总结

通过上述介绍可以看出,Vastbase的PL/pgSQL模块与常规的编程语言类似,均支持赋值、条件分支、循环等多种语句类型,通过PL/pgSQL模块,可以在Vastbase服务端编写较为复杂的逻辑。其生命周期分为编译和运行两个阶段,使用PL/pgSQL编写函数/存储过程时,还通过缓存编译结果,使得函数调用变得更加高效。

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

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

相关文章

基于深度学习的心律异常分类算法

基于深度学习的心律异常分类系统——算法设计 第一章 研究背景算法流程本文研究内容 第二章 心电信号分类理论基础心电信号产生机理MIT-BIH 心律失常数据库 第三章 心电信号预处理心电信号噪声来源与特点基线漂移工频干扰肌电干扰 心电信号读取与加噪基于小波阈值去噪技术的应用…

金三银四-探秘银行科技部:稳定职业背后的挑战 | 不敢跳槽啦 | 好慌

小伙伴们好,我是「 行走的程序喵」,感谢您阅读本文,欢迎三连~ 😻 【Java基础】专栏,Java基础知识全面详解:👉点击直达 🐱 【Mybatis框架】专栏,入门到基于XML的配置、以…

数据结构——二叉搜索树详解

一、二叉搜索树定义 二叉搜索树又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树: 1.非空左子树上所有节点的值都小于根节点的值。 2.非空右子树上所有节点的值都大于根节点的值。 3.左右子树也都为二叉搜索树。 如下图所示&#xff1a…

浏览器扩展程序增加 vue_dev_tools 调试工具

1、引言 在做 Vue 项目的开发时,我们经常需要在页面上调试,接下来介绍如何在浏览器扩展程序增加 vue_dev_tools 调试工具。 Download the Vue Devtools extension for a better development experience 翻译:下载Vue Devtools扩展以获得更好…

1.6.1 变换

我们要想改变物体的位置,现有解决办法是,每一帧改变物体的顶点并且重配置缓冲区从而使物体移动,但是这样太繁琐,更好的解决方式是使用矩阵(Matrix)来更好的变换(Transform)一个物体。…

数据结构——快速排序的三种方法和非递归实现快速排序

数据结构——快速排序的三种方法和非递归实现快速排序(升序) 快速排序的单趟排序hoare法挖坑法前后指针法 快速排序的实现key基准值的选取快速排序代码快速排序的优化 快速排序(非递归) 快速排序的单趟排序 hoare法 思路:从给定…

后端前行Vue之路(二):模版语法之插值与指令

1.概述 Vue.js的模板语法是一种将Vue实例的数据绑定到HTML文档的方法。Vue的模板语法是一种基于HTML的扩展,允许开发者将Vue实例中的数据绑定到HTML元素,以及在HTML中使用一些简单的逻辑和指令。Vue.js 基于 HTML 的模板语法允许开发者声明式地将 DOM 绑…

Windows11系统缺少解决办法

一.缺少msvcp120.dll 下载Mircrosoft Visual C 2015等系统关键组件 Microsoft Visual C 2015-2022 Redistributable (x86) - 14.34.31931 Installation Error etc.. - Microsoft Q&A 二.缺少python27.dll 重新下载python2.7进行安装(选择Windows x86-64 MSI installer)…

三级等保建设技术方案-Word

1信息系统详细设计方案 1.1安全建设需求分析 1.1.1网络结构安全 1.1.2边界安全风险与需求分析 1.1.3运维风险需求分析 1.1.4关键服务器管理风险分析 1.1.5关键服务器用户操作管理风险分析 1.1.6数据库敏感数据运维风险分析 1.1.7“人机”运维操作行为风险综合分析 1.2…

IP如何异地共享文件?

【天联】 组网由于操作简单、跨平台应用、无网络要求、独创的安全加速方案等原因,被几十万用户广泛应用,解决了各行业客户的远程连接需求。采用穿透技术,简单易用,不需要在硬件设备中端口映射即可实现远程访问。 异地共享文件 在…

腾讯云2核2G服务器CVM S5和轻量应用服务器优惠价格

腾讯云2核2G服务器多少钱一年?轻量服务器61元一年,CVM 2核2G S5服务器313.2元15个月,腾讯云2核2G服务器优惠活动 txyfwq.com/go/txy 链接打开如下图: 腾讯云2核2G服务器价格 轻量61元一年:轻量2核2G3M、3M带宽、200GB月…

AXI Memory Mapped to PCI Express 学习笔记(五)—— Test Bench

本文包含有关Vivado Design Suite环境中提供的测试平台(Test Bench)的信息。 一、Endpoint的Root Port模型测试平台 PCI Express Root Port Model是一个强大的测试平台环境,它提供了一个测试程序接口,可以与提供的PIO设计&#…

洛谷_P4995 跳跳!_python写法

P4995 跳跳&#xff01; - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) n int(input()) data list(map(int,input().split())) data.append(0) data.sort()sum 0 l 0 r len(data)-1 flag 1 while l<r:sum (data[l]-data[r])**2if flag:l 1flag 0else:r - 1flag 1…

LinkedList讲解指南

咦咦咦&#xff0c;各位小可爱&#xff0c;我是你们的好伙伴——bug菌&#xff0c;今天又来给大家普及Java SE相关知识点了&#xff0c;别躲起来啊&#xff0c;听我讲干货还不快点赞&#xff0c;赞多了我就有动力讲得更嗨啦&#xff01;所以呀&#xff0c;养成先点赞后阅读的好…

教育数字化调研团走进锐捷,共议职业教育数字化转型新思路

为贯彻落实国家教育数字化战略行动部署和2024年全国教育工作会议精神,加快推进职业教育数字化转型与发展,梳理职业教育数字化转型的现状、问题及发展趋势,并总结展示职业教育数字化转型的好经验、好做法,培育职业教育数字化创新成果,推动数字技术与职业教育深度融合、提高数字化…

ensp的PPP实验报告

实验要求&#xff1a; 1、R1和R2使用PPP链路直连&#xff0c;R2和R3把2条PPP链路捆绑为PPP MP直连 2、按照图示配置IP地址 3、R2对R1的PPP进行单向chap验证 4、R2和R3的PPP进行双向chap验证 1、配置ip地址 R1&#xff1a; [R1] int Serial 3/0/0 [Rl-Seria13/0/0] ip add 192…

机器学习——聚类算法-DBSCAN

机器学习——聚类算法-DBSCAN DBSCAN&#xff08;Density-Based Spatial Clustering of Applications with Noise&#xff09;是一种基于密度的聚类算法&#xff0c;可以发现任意形状的簇&#xff0c;并能有效处理噪声数据。本文将介绍DBSCAN算法的核心概念、算法流程、优缺点…

Kali远程操纵win7

一.准备 1.介绍 攻击方&#xff1a;kali IPV4:192.168.92.133 被攻击方&#xff1a;win7 IPV4:192.168.92.130 2.使用永恒之蓝漏洞 (1.使用root权限 (2.进入msfconsole (3.添加rhosts (4.run进行一下 二.进行远程操作 1.获取用户名和密码 在cmd5查询 2.获取syste…

抓包工具charles修改请求和返回数据

数据篡改的主要使用场景&#xff1a; &#xff08;1&#xff09;mock场景&#xff0c;mock入参和返回值参数&#xff0c;实现mock测试 &#xff08;2&#xff09;安全测试&#xff0c;对于支付金额等比较重要的字段&#xff0c;可以修改请求参数来进行安全测试 1.首先选择要…

Qt中QIcon图标设置(标题、菜单栏、工具栏、状态栏图标)

1 exe程序图标概述 在 Windows 操作系统中&#xff0c;程序图标一般会涉及三个地方&#xff1b; &#xff08;1&#xff09; 可执行程序&#xff08;以及对应的快捷方式&#xff09;的图标 &#xff08;2&#xff09; 程序界面标题栏图标 &#xff08;3&#xff09;程序在任务…