CloudberryDB(六)SPI拓展功能
SPI(Server Programming Interface)在实现原理主要涉及以下几个方面:
1. **模块化设计**:SPI模块是内核中的一个独立模块,允许内核开发者在C函数中执行SQL语句,并管理事务。这种设计使得开发者可以在不修改核心代码的情况下扩展数据库功能。
2. **接口函数**:SPI提供了一组接口函数,如`SPI_connect`、`SPI_execute`、`SPI_finish`等,这些函数用于建立与SPI管理器的连接、执行SQL命令以及释放连接。通过这些接口,开发者可以在C代码中方便地调用SQL。
3. **事务管理**:SPI模块具备事务管理能力,这意味着在执行的SQL语句中,如果发生错误,事务会自动回滚,确保数据的一致性。
4. **内存管理**:SPI还负责内存管理,确保在执行SQL过程中分配的内存得到正确释放,避免内存泄漏。
5. **扩展性**:SPI的实现使得开发者可以创建自定义的数据库扩展(Extension),通过这些扩展可以在数据库中执行复杂的逻辑和操作。
PostgreSQL中的SPI(Server Programming Interface)即服务器编程接口。
**一、主要功能**
1. **扩展功能**
- 它允许在CloudberryDB服务器内部编写自定义的C函数。例如,可以创建一些复杂的数学计算函数或者特定业务逻辑的函数,这些函数不能仅通过SQL实现时就可以利用SPI。
- 开发者能够利用SPI调用数据库操作相关的函数,像执行查询、插入、更新和删除等操作。比如在一个自定义的存储过程中,使用SPI来执行一个动态生成的SQL查询。
2. **与外部代码交互**
- 便于与其他编程语言编写的代码进行交互。如果有一个用Python或者其他语言编写的应用程序,想要与CloudberryDB数据库深度集成,可以通过SPI相关的机制来实现。
**二、使用要点**
1. **初始化**
- 在使用SPI之前,需要进行初始化操作。这包括设置一些环境变量和分配必要的资源。例如,在C代码中要包含相关的头文件并且调用特定的初始化函数。
2. **错误处理**
- 要妥善处理可能出现的错误。SPI操作可能会因为多种原因失败,如SQL语法错误、权限不足等。需要检查返回值并进行相应的错误处理,比如返回特定的错误码或者向客户端发送合适的错误消息。
3. **资源管理**
- 正确管理SPI使用过程中的资源。在使用完相关资源后,要及时释放,避免内存泄漏等问题。例如,执行完查询后要关闭游标并释放查询占用的内存。
**三、应用场景示例**
1. **复杂数据转换**
- 当需要对从数据库中获取的数据进行复杂的转换,并且这种转换无法简单地用SQL表达式完成时。比如将从数据库中读取的二进制数据按照特定格式解析成业务对象,就可以编写一个SPI函数来完成这个任务。
2. **动态SQL执行**
- 在一些需要根据用户输入或者程序运行时的状态动态生成并执行SQL语句的场景中。例如,一个报表生成工具,根据用户选择的查询条件动态构建SQL查询,然后通过SPI在服务器端执行这个查询。
SPI(Server Programming Interface)实现主要包括以下接口函数:
1. **SPI_connect**:打开一个SPI连接,在通过SPI执行SQL之前,必须先调用此函数。如果成功,返回`SPI_OK_CONNECT`,否则返回`SPI_ERROR_CONNECT`。
2. **SPI_finish**:释放当前程序与SPI的连接。在完成SPI操作后,必须调用此函数关闭连接。如果程序中通过`elog`产生错误,SPI会自动清理自身。
3. **SPI_execute**:用于直接执行一条或多条SQL语句。参数`read_only`指示SQL是否为只读,`count`限制返回结果集的最大个数。
4. **SPI_exec**:与`SPI_execute`类似,但相当于`SPI_execute(command, false, count)`。
5. **SPI_prepare**:创建并返回一个准备好的语句,但不执行它。
6. **SPI_execute_with_args**:执行预定义的SQL语句,使用占位符定义变量。
7. **SPI_tuptable**:用于存储查询结果集的结构体。
8. **SPI_freetuptable**:释放`SPI_tuptable`占用的内存。
在PostgreSQL中,SPI(Server Programming Interface)允许开发者在C语言编写的扩展或函数中执行SQL语句。以下是调用SPI执行SQL的基本步骤和示例代码:
### 1. 包含必要的头文件
首先,确保在C源文件中包含SPI相关的头文件:
```c
#include "postgres.h"
#include "fmgr.h"
#include "utils/builtins.h"
#include "executor/spi.h"
```
### 2. 初始化SPI连接
在执行任何SQL语句之前,需要初始化SPI连接:
```c
int ret;
ret = SPI_connect();
if (ret < 0)
ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR), errmsg("SPI_connect failed")));
```
### 3. 准备并执行SQL语句
使用`SPI_prepare`准备SQL语句,然后使用`SPI_execute`执行它。以下是一个简单的示例:
```c
const char *query = "SELECT * FROM my_table WHERE id = $1";
int nargs = 1; // 参数数量
Oid argtypes[1] = { INT4OID }; // 参数类型,这里假设id是整数
Datum values[1] = { Int32GetDatum(123) }; // 参数值
// 准备SQL语句
SPIPlanPtr plan = SPI_prepare(query, nargs, argtypes);
if (!plan)
ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR), errmsg("SPI_prepare failed")));
// 执行SQL语句
int tuples = SPI_execute_plan(plan, values, NULL, true, 0);
if (tuples < 0)
ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR), errmsg("SPI_execute_plan failed")));
// 处理结果集
SPITupleTable *tuptable = SPI_tuptable;
for (int i = 0; i < tuples; i++) {
Datum *values = tuptable->vals[i];
bool *nulls = tuptable->nulls[i];
// 处理每一行的数据
}
// 释放计划
SPI_freeplan(plan);
```
### 4. 释放SPI连接
在完成所有SPI操作后,释放SPI连接:
```c
SPI_finish();
```
### 5. 错误处理
在整个过程中,需要适当处理可能出现的错误,确保在发生异常时能够正确回滚事务并释放资源。
### 示例:创建一个简单的SPI函数
以下是一个完整的示例,展示如何在PostgreSQL中创建一个使用SPI执行SQL的函数:
```c
#include "postgres.h"
#include "fmgr.h"
#include "utils/builtins.h"
#include "executor/spi.h"
PG_MODULE_MAGIC;
PG_FUNCTION_INFO_V1(spi_example);
Datum spi_example(PG_FUNCTION_ARGS)
{
const char *query = "SELECT name FROM users WHERE id = $1";
int nargs = 1;
Oid argtypes[1] = { INT4OID };
Datum values[1] = { Int32GetDatum(PG_GETARG_INT32(0)) };
SPI_connect();
SPIPlanPtr plan = SPI_prepare(query, nargs, argtypes);
if (!plan)
ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR), errmsg("SPI_prepare failed")));
int tuples = SPI_execute_plan(plan, values, NULL, true, 0);
if (tuples < 0)
ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR), errmsg("SPI_execute_plan failed")));
SPITupleTable *tuptable = SPI_tuptable;
Datum result;
if (tuples > 0) {
HeapTuple tuple = tuptable->vals[0];
result = heap_getattr(tuple, Anum_users_name, tuptable->tupdesc, &isnull);
} else {
result = (Datum)NULL;
}
SPI_freeplan(plan);
SPI_finish();
if (isnull)
PG_RETURN_NULL();
else
PG_RETURN_DATUM(result);
}
```
### 说明
1. **初始化和连接**:使用`SPI_connect()`建立SPI连接。
2. **准备SQL语句**:使用`SPI_prepare()`准备SQL语句,指定参数数量和类型。
3. **执行SQL语句**:使用`SPI_execute_plan()`执行准备好的SQL语句,并传入参数值。
4. **处理结果集**:通过`SPI_tuptable`访问结果集,遍历并处理每一行的数据。
5. **释放资源**:使用`SPI_freeplan()`释放准备好的计划,使用`SPI_finish()`释放SPI连接。
6. **返回结果**:将查询结果返回给调用者。
### 注意事项
- **事务管理**:SPI操作默认在当前事务上下文中执行。如果需要独立的事务,可以使用`SPI_savepoint`和`SPI_release_savepoint`等函数。
- **错误处理**:始终检查SPI函数的返回值,并在必要时使用`ereport`报告错误。
- **内存管理**:确保正确管理内存,避免内存泄漏。使用`SPI_finish()`释放SPI连接时,会自动清理大部分SPI相关的内存。
通过以上步骤,您可以在PostgreSQL的C扩展中有效地使用SPI执行SQL语句,从而实现复杂的数据库操作和扩展功能。
相关文章:
CloudberryDB(六)SPI拓展功能
SPI(Server Programming Interface)在实现原理主要涉及以下几个方面: 1. **模块化设计**:SPI模块是内核中的一个独立模块,允许内核开发者在C函数中执行SQL语句,并管理事务。这种设计使得开发者可以在不修改…...
非谓语动词三驾马车
文章目录 1. 不定式基本结构不定式的由来1.不受主语的人称和数的限制2.没有限定时态3.可以在句子中充当不同的成分 常见句子成分1. 作主语2. 作表语3. 作宾语4. 作定语5. 作状语 不定式 vs 动名词 2. 动名词动名词做成分作主语作主语补语作定语作宾语介词宾语 3. 分词(现在、过…...
环境影响评价(EIA)中,土地利用、植被类型及生态系统图件的制作
在环境影响评价(EIA)中,土地利用、植被类型及生态系统图件的制作需依据科学、法规和技术规范,以确保数据的准确性和图件的规范性。以下是主要的制作依据: 1. 法律法规与政策依据 《中华人民共和国环境影响评价法》 明确…...
Lineageos 22.1(Android 15)更换开机动画
一、原理简介 我们直接用最简单的替换zip的方式来更换开机动画,首先我们要查看系统代码使用的zip包的路径,可能与aosp原生的代码不一定一样。 /frameworks/base/cmds/bootanimation/BootAnimation.cpp bool BootAnimation::threadLoop() {ATRACE_CALL(…...
大语言模型推理中的显存优化 有哪些
大语言模型推理中的显存优化 有哪些 目录 大语言模型推理中的显存优化 有哪些显存优化背景Offloading/Checkpoint原理举例显存优化背景 在大语言模型推理时,显存是显著瓶颈。以开源的BLOOM 176B模型为例,在8张A100计算卡上,通常对话设置下仅能进行批量为10左右的推理。为缓…...
更高效实用 vscode 的常用设置
VSCode 可以说是文本编辑神器, 不止程序员使用, 普通人用其作为文本编辑工具, 更是效率翻倍. 这里分享博主对于 VSCode 的好用设置, 让 VSCode 如虎添翼 进入设置 首先进入设置界面, 后续都在这里进行配置修改 具体设置 每项配置通过搜索关键字, 来快速定位配置项 自动保存…...
【异或数列——博弈论】
题目 思路 异或和为0(即每一位都有偶数个1):平局最高有效位只有唯一的1:先手必胜最高有效位有奇数个1,偶数个0:先手必胜 若先选1产生优势,则剩下偶数个1,偶数个0:对手选…...
阿里云大文件ossutil工具进行上传下载,该工具支持断点续传
ossutil工具进行上传下载,该工具支持断点续传、文件分片、多文件同时上传等 下载和配置 https://help.aliyun.com/zh/oss/developer-reference/install-ossutil 上传操作 https://help.aliyun.com/zh/oss/developer-reference/upload-objects-6 下载操作 https://h…...
草图绘制技巧
1、点击菜单栏文件–》新建–》左下角高级新手切换–》零件; 2、槽口:直槽口,中心点槽口,三点源槽口,中心点圆弧槽口; 3、草图的约束:需要按住ctrl键,选中两个草图,然后…...
Spring Boot中如何自定义Starter
文章目录 Spring Boot中如何自定义Starter概念和作用1. 概念介绍2. 作用和优势2.1 简化依赖管理2.2 提供开箱即用的自动配置2.3 标准化和模块化开发2.4 提高开发效率2.5 提供灵活的配置覆盖3. 应用场景创建核心依赖1. 确定核心依赖的作用2. 创建 starter-core 模块2.1 依赖管理…...
内容中台构建高效数字化内容管理新范式
内容概要 在数字化转型浪潮中,高效的内容管理能力已成为企业构建核心竞争力的关键要素。通过动态发布引擎、元数据智能分类与跨平台协作机制,企业能够实现内容的实时触达与精准分发,同时确保知识资产在多终端环境下的无缝适配与安全共享。这…...
QGIS热力图制作全流程详解
一、热力图的概念与应用 热力图(Heatmap)是一种通过颜色梯度展示空间数据密度的可视化工具,常用于分析点数据的聚集程度。例如,犯罪热点、人口分布、交通流量等场景均可通过热力图直观呈现。QGIS作为开源GIS软件,支持…...
切换镜像源(npm)
常见的npm镜像源 官方源 URL: https://registry.npmjs.org 淘宝镜像源(npmmirror) URL: https://registry.npmmirror.com 其他常用镜像源 URL: https://registry.cnpmjs.org (CNPM) 这里是引用 切换npm镜像源 切换到官方源 npm config set registry http…...
PyQt组态软件 拖拽设计界面测试
PyQt组态软件测试 最近在研究PyQt,尝试写个拖拽设计界面的组态软件,目前实现的功能如下: 支持拖入控件,鼠标拖动控件位置 拖动控件边缘修改控件大小支持属性编辑器,修改当前选中控件的属性 拖动框选控件,点选控件 控…...
深度学习R4周:LSTM-火灾温度预测
🍨 本文为🔗365天深度学习训练营中的学习记录博客🍖 原作者:K同学啊 任务: 数据集中提供了火灾温度(Tem1)、一氧化碳浓度(CO 1)烟雾浓度(Soot 1)…...
Datawhale 数学建模导论二 笔记1
第6章 数据处理与拟合模型 本章主要涉及到的知识点有: 数据与大数据Python数据预处理常见的统计分析模型随机过程与随机模拟数据可视化 本章内容涉及到基础的概率论与数理统计理论,如果对这部分内容不熟悉,可以参考相关概率论与数理统计的…...
Go框架面试突击!30道高频题解析
前言 有粉丝朋友问我能不能整理Go主流框架方面的面试题,安排! 这篇文章分享了gRPC、GoFrame、GoZero、GoMicro、GORM、Gin等主流框架的30道面试题和详解。 需要大厂面经的朋友们也可以直接加我好友,私信我。 gRPC 1.gRPC是什么ÿ…...
从VGG到Transformer:深度神经网络层级演进对模型性能的深度解析与技术实践指南
一、技术原理(数学公式示意图) 1. 层深与模型容量关系 数学表达:根据Universal Approximation Theorem,深度网络可表达复杂函数: f ( x ) f L ( f L − 1 ( ⋯ f 1 ( x ) ) ) f(x) f_L(f_{L-1}(\cdots f_1(x))) f…...
UIView 与 CALayer 的联系和区别
今天说一下UIView 与 CALayer 一、UIView 和 CALayer 的关系 在 iOS 开发中,UIView 是用户界面的基础,它负责处理用户交互和绘制内容,而 CALayer 是 UIView 内部用于显示内容的核心图层(Layer)。每个 UIView 内部都有…...
一键安装教程
Maven 安装 右键 以管理员身份运行点击 下一步安装完成后会同步配置环境变量打开 cmd, 输入 mvn 查看mvn版本修改 maven 本地仓库地址 见图三, 本地新建文件夹,修改为你本地文件夹地址 Redis 安装 右键 以管理员身份运行点击 下一步会安装到选择的文件夹下 JAVA\R…...
【ISO 14229-1:2023 UDS诊断全量测试用例清单系列:第十二节】
ISO 14229-1:2023 UDS诊断服务测试用例全解析(TesterPresent_0x3E服务) 作者:车端域控测试工程师 更新日期:2025年02月14日 关键词:UDS协议、0x3E服务、会话保持、ISO 14229-1:2023、ECU测试 一、服务功能概述 0x3E服…...
李宏毅机器学习笔记:【6.Optimization、Adaptive Learning Rate】
Optimization 1.Adaptive Learning Rate2.不同的参数需要不同的学习率3.Root Mean Square4.RMSProp5.Adam6.learning rate scheduling7.warm up总结 critical point不一定是你在训练一个network时候遇到的最大的障碍。 1.Adaptive Learning Rate 也就是我们要给每个参数不同的…...
vscode使用常见问题处理合集
目录 一、使用vite创建的vue3项目,script和style首行代码不会缩进,且格式化属性字段等会换行问题 首行缩进情况如下: 属性、参数格式化换行情况如下: 解决方式: 一、使用vite创建的vue3项目,script和style首行代码不…...
【技术解析】MultiPatchFormer:多尺度时间序列预测的全新突破
今天给我大家带来一篇最新的时间序列预测论文——MultiPatchFormer。这篇论文提出了一种基于Transformer的创新模型,旨在解决时间序列预测中的关键挑战,特别是在处理多尺度时间依赖性和复杂通道间相关性时的难题。MultiPatchFormer通过引入一维卷积技术&…...
Linux内核 - 非仿生机器人之感知主控系统(协议栈)
Linux内核 - 非仿生机器人之感知主控系统(协议栈) 注:该项目为18年实习期间,参与非仿生六足机器人(Linux方案)的个人理解和积累。时至今日,再看其实仅为一套系统编程相关框架,一直为…...
Node.js 工具模块
Node.js 工具模块 引言 Node.js 是一个开源的、基于 Chrome V8 引擎的 JavaScript 运行时环境。它允许开发者使用 JavaScript 编写服务器端代码,从而构建快速、可扩展的网络应用。在 Node.js 开发过程中,工具模块扮演着至关重要的角色。本文将详细介绍 Node.js 中常用的工具…...
【网络安全 | 漏洞挖掘】价值3133美元的Google IDOR
未经许可,不得转载。 文章目录 正文正文 目标URL:REDACTED.google.com。 为了深入了解其功能,我查阅了 developer.google.com 上的相关文档,并开始进行测试。 在测试过程中,我发现了一个 XSS 漏洞,但它触发的域名是经过正确沙盒化的 *.googleusercontent.com,这符合 …...
大脑网络与智力:基于图神经网络的静息态fMRI数据分析方法|文献速递-医学影像人工智能进展
Title 题目 Brain networks and intelligence: A graph neural network based approach toresting state fMRI data 大脑网络与智力:基于图神经网络的静息态fMRI数据分析方法 01 文献速递介绍 智力是一个复杂的构念,包含了多种认知过程。研究人员通…...
Codeforces Round 1004 (Div. 2)(A-E)
题目链接:Dashboard - Codeforces Round 1004 (Div. 2) - Codeforces A. Adjacent Digit Sums 思路 只有两种情况:n1之后没有进位,y-x1。n1之后进位(y-x-1)%90。 代码 void solve(){int x,y;cin>>x>>y;if(y-x1){cout<<…...
掌握正则表达式_模式匹配的艺术
当然,以下是《掌握正则表达式:模式匹配的艺术》文章内容,使用 Java 正则表达式,并包含丰富的代码示例: 1. 引言 1.1 正则表达式的定义与历史 正则表达式(Regular Expression,简称 regex 或 regexp)是一种用于描述文本模式的强大工具。它最初由数学家 Stephen Kleene…...
