[PostgreSQL的 SPI_接口函数]

news/2024/5/18 12:45:40/文章来源:https://blog.csdn.net/weixin_47308871/article/details/126651946

Server Programming Interface(SPI)是PostgreSQL内核中的一个模块,这个模块让内核开发者可以在C函数中执行SQL语句,并具备管理事务的能力。通过它我们可以用C语言去调用数据库里的各种SQL。

这个SPI_比较便利的一点在于,我们可以在自定义的Extension中也可以使用它,去用C调用SQL执行,也就是说,如果我们想的话,我们可以在Extension里用C语言定义一个函数,在函数里拼接出我们想要执行的SQL,并调用SPI_的相关接口函数,在数据库里实际执行该SQL。因为是以Extension的形式去做的,所以,不想使用了,直接drop extension就可以了。

在spi.h里我们可以看到有很多的SPI_的函数。具体的可以参考官方文档PostgreSQL: Documentation: 14: Chapter 47. Server Programming Interface

因为此前发过自定义PostgreSQL的extension的文章,在此就不做赘述了,直接放链接:如何为PostgreSQL创建自定义Extension

下面,我将举个小例子,在Extension里使用这些SPI_接口函数,来实现一个数据库里的函数,在PostgreSQL里执行SQL。关键的部分如下,通过逻辑,其实可以看出来,我这里做了一个巨鸡肋的功能————通过函数输入一个表名和一个路径文件,函数拼接了一个COPY的SQL来实现copy to拷贝表的功能,但是为了演示SPI_的接口函数已经足够了。

PG_FUNCTION_INFO_V1(pg_copy_plugin_out);Datum pg_copy_plugin_out(PG_FUNCTION_ARGS)
{int SPI_connect(void);int SPI_exec(const char * command, long count);int SPI_finish(void);char *plugintableName = text_to_cstring(PG_GETARG_TEXT_PP(0));char *filepath = text_to_cstring(PG_GETARG_TEXT_PP(1));char command[128];sprintf(command,"copy  %s to  \'%s\';", plugintableName,filepath);SPI_connect();SPI_exec(command, 0); SPI_finish();

SPI_connect的主要作用是连接一个C函数到 SPI 管理器 。
SPI_exec的作用是执行一个读/写命令。
SPI_finish的作用是将一个C函数从 SPI 管理器断开。

我这里是拼接后直接执行了,因此只用到这几个,如果想获取prepare语句,但不执行等,可以去使用其他类型的SPI_接口函数,具体可以参考手册。

其实在后边返回值那里,我遇到了点障碍,所以,我加了一个 ereport(ERROR,去抛出一个报错,但却能让我的功能正常完成。

[postgres@localhost pg_copy_plugin]$ ll
total 16
-rw-r--r-- 1 postgres dba  217 Jun 15 05:13 Makefile
-rw-r--r-- 1 postgres dba  642 Aug  1 15:26 pg_copy_plugin--1.0.sql
-rw-r--r-- 1 postgres dba 1013 Aug  1 17:29 pg_copy_plugin.c
-rw-r--r-- 1 postgres dba  137 Jun 15 05:12 pg_copy_plugin.control[postgres@localhost pg_copy_plugin]$ make
gcc -std=gnu99 -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Werror=vla -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -O2 -fPIC -I. -I./ -I/home/postgres/soft/include/server -I/home/postgres/soft/include/internal  -D_GNU_SOURCE   -c -o pg_copy_plugin.o pg_copy_plugin.c
gcc -std=gnu99 -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Werror=vla -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -O2 -fPIC pg_copy_plugin.o -L/home/postgres/soft/lib   -Wl,--as-needed -Wl,-rpath,'/home/postgres/soft/lib',--enable-new-dtags  -shared -o pg_copy_plugin.so[postgres@localhost pg_copy_plugin]$ make install
/bin/mkdir -p '/home/postgres/soft/share/extension'
/bin/mkdir -p '/home/postgres/soft/share/extension'
/bin/mkdir -p '/home/postgres/soft/lib'
/bin/install -c -m 644 .//pg_copy_plugin.control '/home/postgres/soft/share/extension/'
/bin/install -c -m 644 .//pg_copy_plugin--1.0.sql  '/home/postgres/soft/share/extension/'
/bin/install -c -m 755  pg_copy_plugin.so '/home/postgres/soft/lib/'

依次的编译安装,make阶段产生了.so的文件,make install阶段,把.control和.sql文件拷贝到share路径下,将.so文件拷贝到lib路径下。

我们到数据库里去安装这个自定义的插件,下边的这个pg_copy_plugin_out 就是我们刚才定义的那个函数。

[postgres@localhost pg_copy_plugin]$ psql
psql (15beta1)
Type "help" for help.postgres=# \dfList of functionsSchema | Name | Result data type | Argument data types | Type 
--------+------+------------------+---------------------+------
(0 rows)postgres=# create extension pg_copy_plugin;
CREATE EXTENSION
postgres=# \dfList of functionsSchema |        Name        | Result data type |            Argument data types             | Type 
--------+--------------------+------------------+--------------------------------------------+------public | pg_bak_tab         | text             | ta character varying, fa character varying | funcpublic | pg_copy_plugin_out | text             | plugintablename text, filename text        | func
(2 rows)

来验证一下这个函数的功能,可以看到,他是使用c实现的,输入的两个参数是两个text类型,返回值也是text。

可以看到,这个函数通过使用SPI_的接口函数,实现了在C语言层面根据输入值拼接SQL并在数据库执行的功能。(…其实在数据库里用plpgsql写一个函数就可以达到同样的效果,所以我说很鸡肋。但是本文主要就是展示SPI_接口函数在Extension里的一个大致使用)

postgres=# \! ls -l /home/postgres/ysl.sql
ls: cannot access /home/postgres/ysl.sql: No such file or directory
postgres=# select pg_copy_plugin_out('t1','/home/postgres/ysl.sql');
ERROR:  copy  t1 to  '/home/postgres/ysl.sql';
postgres=# \! ls -l /home/postgres/ysl.sql
-rw-r--r-- 1 postgres dba 11679 Aug  1 17:55 /home/postgres/ysl.sql
postgres=# \! head -10 /home/postgres/ysl.sql
1
2
3
4
5
6
7
8
9
10

到此,这个演示结束了。感兴趣的也可以去尝试使用这些SPI_的接口函数,去实现一些功能。

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

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

相关文章

如何使用 Bootstrap 处理 CSS

如何使用 Bootstrap 处理 CSS 大家好!如果您像我一样开始使用 CSS 编码并使用它进行任何大型项目,那么您肯定会因为响应式布局、溢出和选择器特异性而感到数不清的头痛。这就是几周前我决定学习 Bootstrap 的原因,这里是它的文档和主要功能的简短描述,所以你也可以。引导程…

一、Azkaban简明笔记

1、azkaban部署 主要是集群部署安装。 1.1 准备安装包Downloads (azkaban.github.io)1.2 配置MySQL启动mysql mysql -uroot -proot创建azkaban数据库 create database azkaban;创建azkaban用户并赋予权限(可以不设置账号,继续使用root账号) -- 显示相关变量 SHOW VARIABLES …

实体店主最爱的中秋活动方案,直接照搬就能轻松爆单!

中秋将至,传统佳节和营销好时机一起到了!利用氛围浓厚的节日进行营销活动,是吸引客户、增粉卖货的最佳手段之一,商户老板们可千万不能错过! 但是,活动人人都能做,如何在一片节日促销中脱颖而出&…

JVM详解

1. 源文件 源文件就是我们编写Java代码的文件。文件扩展名为.java 2. 字节码文件 字节码文件是源文件编译后的文件。字节码文件是二进制文件,需要通过特定的工具才能查看。里面存放了源文件编译后的字节码指令。 3. 类加载器 Class Loader Java 程序运行时会由…

USB转GPIO应用方案

概述 沁恒提供的多款USB转接系列芯片均提供GPIO引脚功能,各引脚支持独立的输出输入,GPIO功能的使用需要与计算机端厂商驱动程序和应用软件配合使用。各芯片的默认GPIO引脚状态有所区别,可查阅芯片技术手册或参考方案中附表。 型号 CH344Q …

基于神经网络的图像识别,人工神经网络图像识别

如何通过人工神经网络实现图像识别 。 人工神经网络(ArtificialNeuralNetworks)(简称ANN)系统从20世纪40年代末诞生至今仅短短半个多世纪,但由于他具有信息的分布存储、并行处理以及自学习能力等优点,已经…

Jmeter(五) - 从入门到精通 - 测试计划(Test Plan)的元件(详解教程)

一.测试计划(Test Plan)要素 1.JMeter中一个脚本就是一个测试计划(Test Plan),也是一个管理单元。JMeter 的请求模拟与并发数(设置线程数,一个线程代表一个虚拟用户)设置都在脚本文件中一起设置。JMeter 不…

雨夜赶长路,房企必经的三场“价值战事”

今年上半年,地产行业一直在高压下运行。市场周期震荡叠加疫情等因素,为房企的销售、土拍、融资带来不确定性。 下半年以来,虽然不确定性和高压仍在,但市场有望恢复,下行趋势似乎已到拐点。 面对高压,不同…

安装 ZooKeeper 并配置服务

官网 访问官方下载页面安装 # 注意替换一下新的链接 curl -sSLO https://dlcdn.apache.org/zookeeper/zookeeper-3.8.0/apache-zookeeper-3.8.0-bin.tar.gz tar -zxvf apache-zookeeper-3.8.0-bin.tar.gz -C /opt/ cd /opt ln -s zookeeper-3.4.10 ./zookeepercd zookeeper m…

微服务项目:尚融宝(8)(后端接口:积分等级CRUD)

认清现实,放弃幻想,准备斗争 一、积分等级列表接口 1、编写积分等级管理接口 在controller中添加admin包,添加AdminIntegralGradeController类CrossOrigin RestController RequestMapping("/admin/core/integralGrade") public cl…

Mac中无法运行旧版本印象笔记:版本太旧 你的本地印象笔记数据是由新版印象笔记管理

📢📢📢📣📣📣 哈喽!大家好,我是「奇点」,江湖人称 singularity。刚工作几年,想和大家一同进步🤝🤝 一位上进心十足的【Java ToB端大厂…

算法设计与分析作业——递归循环

用循环实现&#xff1a; 1、 求级数 求&#xff1a;1/1!-1/3!1/5!-1/7!…(-1)n1/(2n-1)! #include <bits/stdc.h> using namespace std; int main( ) {int i,n,j,sign1; float s,t1; cin>>n; s1; for(i2;i<n;ii1){t1; /*求阶乘*/for(j1;j<2*i-1;…

(11)工业界推荐系统-小红书推荐场景及内部实践【粗排三塔模型】

&#xff08;1&#xff09;工业界推荐系统-小红书推荐场景及内部实践【业务指标、链路、ItemCF】 &#xff08;2&#xff09;工业界推荐系统-小红书推荐场景及内部实践【UserCF、离线特征处理】 &#xff08;3&#xff09;工业界推荐系统-小红书推荐场景及内部实践【矩阵补充、…

推荐10款好用的数据可视化工具,赶紧收藏

写在前面的话&#xff1a;没有十全十美的工具&#xff0c;但是如果确立&#xff08;可视化&#xff09;目标&#xff0c;就能找到合适的工具去实现。 数据分析过程可以分为&#xff1a;确定目标数据、数据采集、数据清洗、数据存储、数据分析、结果可视化及结果支持和决策等步骤…

文字转音频软件哪个好用?这几个方法你值得拥有

不知道你有没有发现一个现象&#xff0c;现在越来越多的人会把自己制作好的视频发布到各个社交平台上&#xff0c;分享自己的日常。有的人还会用自己的声音来做配音旁白&#xff0c;而有的人因为自己声音和视频不搭&#xff0c;会使用配音软件&#xff0c;把文字转换成语音。可…

FRED应用:真实玻片设置

简介 FRED具备通过光学系统模拟光线偏振的能力。光源可以是随机偏振、圆偏振或线偏振。过滤或控制偏振的光学元件&#xff0c;如双折射波片和偏振片&#xff0c;可以准确的模拟。FRED偏振模型中一些简单例子包括吸收二向色性和线栅偏振片&#xff0c;方解石半波片&#xff0…

最近在学日语

对比了一些B站的日语教学视频,觉得这个挺不错: 视频在这里昨天开始学的,50音图平假名全记住了,片假名还有点磕巴。 现在开始学语法了。 【动力这种东西,真是来得莫名奇妙。】手打一遍50音图,练习~ (键盘手打刻意练习了一下,熟练多了。) a i u e o あ ア い イ う…

Magisk如何针对性隐藏Root避免被检测

如果这篇文章对你有帮助,欢迎点赞关注收藏三联,这对我有帮助,谢谢小伙伴们,你们的支持是我认真分享的动力。 关于Magisk有一个有趣的故事,Magisk的作者老吴,国内人,妥妥的大牛,主攻Root领域,目前在Google里卖弄当工程师,在去Google之前,老吴还去苹果公司实习过,就在…

HTML5新特性 day_05(8.11)上传头像、webSocket

一、文件上传经典业务流程 -- 上传头像 在注册业务&#xff0c;填写表单的过程中&#xff0c;需要选择头像&#xff0c;上传头像&#xff0c;填写基本信息&#xff08;用户名、密码等&#xff09;后&#xff0c;点击注册按钮&#xff0c;完成用户注册。当下次登录时需要看到以…

janus videoroom之媒体录制

janus videoroom为音视频会议&#xff0c;内部自创建一个房间号为1234的会议&#xff0c;读者可以配置会议召开时&#xff0c;录制会议的视频和语音&#xff0c;录制文件的后缀名为mjr&#xff0c;此为janus自定义的一种媒体封装格式&#xff0c;个人理解全称是meetecho janus …