PostgreSQL【应用 02】扩展SQL之C语言函数(编写、编译、载入)实例分享

本文涉及的产品
云原生数据库 PolarDB MySQL 版,通用型 2核8GB 50GB
云原生数据库 PolarDB PostgreSQL 版,标准版 2核4GB 50GB
简介: PostgreSQL【应用 02】扩展SQL之C语言函数(编写、编译、载入)实例分享

通过使用 PostgreSQL 的 C 函数接口,我们可以编写用 C 语言实现的函数,并将其集成到数据库中。这些函数可以在 SQL 查询中像其他内置函数一样被调用,从而扩展 PostgreSQL 的功能。

C 函数在某些情况下可以提供比 SQL 函数更高的执行效率,因为它们可以直接访问底层系统资源并进行更高级的优化。通过使用 C 函数,我们可以在函数内部实现复杂的算法和逻辑,利用 C 语言的功能和库来提高执行效率。

1.准备

1.1 开发文档

-- 查询数据库版本
SELECT "version"()
-- PostgreSQL 12.12 (Debian 12.12-1.pgdg110+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 10.2.1-6) 10.2.1 20210110, 64-bit

根据数据库的版本查看文档:

英文:PostgreSQL: Documentation: 12: 37.10. C-Language Functions

中文:37.10. C 语言函数 (postgres.cn)

1.2 工具安装

# 避免报错1
functionNameFile.c:1:10: fatal error: postgres.h: No such file or directory
    1 | #include "postgres.h"
      |          ^~~~~~~~~~~~
compilation terminated.
# 根据版本进行安装【必备】安装的 postgresql12-devel.x86_64 的版本要跟数据库保持一致
yum install postgresql12-devel.x86_64
# 问题
Error: Package: postgresql12-devel-12.15-1PGDG.rhel7.x86_64 (pgdg12)
           Requires: llvm-toolset-7-clang >= 4.0.1
# 解决
yum install centos-release-scl-rh
# 再次进行安装

2.开始

2.1 编写C语言函数

要严格按照文档的说明进行编写,创建一个新的文件,例如 func.c,并添加以下内容:

#include "postgres.h"
#include "fmgr.h"
PG_MODULE_MAGIC;
PG_FUNCTION_INFO_V1(add_one);
Datum
add_one(PG_FUNCTION_ARGS)
{
    int32 arg = PG_GETARG_INT32(0);
    PG_RETURN_INT32(arg + 1);
}
  1. #include "postgres.h":这是一个预处理指令,用于包含 PostgreSQL 的核心头文件,以便在代码中使用 PostgreSQL 的数据类型、宏和函数。
  2. #include "fmgr.h":这是一个预处理指令,用于包含 PostgreSQL 函数管理器的头文件,提供了函数定义和声明所需的宏。
  3. PG_MODULE_MAGIC:这是一个宏,它用于标识模块的版本和兼容性信息。
  4. PG_FUNCTION_INFO_V1(add_one):这是一个宏,用于声明函数的元数据。在这里,它将函数名 add_one 与函数版本号 V1 关联起来。这样 PostgreSQL 就能够正确地识别和处理这个函数。
  5. Datum add_one(PG_FUNCTION_ARGS):这是函数的定义,使用 Datum 作为返回值类型。PG_FUNCTION_ARGS 是一个宏,它展开为一个结构体,包含了函数的参数和返回值信息。
  6. int32 arg = PG_GETARG_INT32(0):这是获取函数参数的值。PG_GETARG_INT32(0) 宏用于从参数列表中获取第一个参数,并将其转换为 int32 类型。这里将获取到的参数值存储在 int32 类型的变量 arg 中。
  7. PG_RETURN_INT32(arg + 1):这是函数的返回语句。它使用 PG_RETURN_INT32 宏将 arg + 1 的结果作为函数的返回值。在这里,函数将输入的整数参数加一后返回。

这段代码的功能很简单:将输入的整数参数加一并作为函数的返回值。

2.2 编译和链接动态载入的函数

Linux环境,其他环境小伙伴儿们自行查看啊:

# 创建PIC的编译器标志是-fpic。创建一个共享库的编译器标志是-shared。
cc -fPIC -c name.c
cc -shared -o name.so name.o

实例使用 C 编译器将源代码编译为共享库,例如 func.so

# 实例
cc -fPIC -I`pg_config --includedir-server` -c funcs.c
cc -shared -o funcs.so funcs.o -I`pg_config --includedir-server` -lm
# pg_config --includedir-server 的地址
[root@tcloud ~]# pg_config --includedir-server
/usr/pgsql-12/include/server
  1. 将共享库文件复制到 PostgreSQL 的共享库目录中:
cp funcs.so `pg_config --libdir`/.
# pg_config --libdir 的地址
[root@tcloud ~]# pg_config --libdir
/usr/pgsql-12/lib
  1. 在 PostgreSQL 中创建函数的定义:
CREATE FUNCTION add_one ( INTEGER ) RETURNS INTEGER AS '/usr/pgsql-12/lib/func',
'add_one' LANGUAGE C STRICT;

现在,已经可以在 SQL 查询中使用 add_one 函数了,例如:

SELECT add_one(11);

注意:在实际应用中,可能需要进行更多的参数校验和错误处理,并支持更复杂的数组类型和维度。

相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
目录
相关文章
|
2月前
|
SQL 关系型数据库 OLAP
云原生数据仓库AnalyticDB PostgreSQL同一个SQL可以实现向量索引、全文索引GIN、普通索引BTREE混合查询,简化业务实现逻辑、提升查询性能
本文档介绍了如何在AnalyticDB for PostgreSQL中创建表、向量索引及混合检索的实现步骤。主要内容包括:创建`articles`表并设置向量存储格式,创建ANN向量索引,为表增加`username`和`time`列,建立BTREE索引和GIN全文检索索引,并展示了查询结果。参考文档提供了详细的SQL语句和配置说明。
77 1
|
7月前
|
关系型数据库 Serverless 定位技术
PostgreSQL GIS函数判断两条线有交点的函数是什么?
PostgreSQL GIS函数判断两条线有交点的函数是什么?
542 60
|
7月前
|
SQL 关系型数据库 C语言
PostgreSQL SQL扩展 ---- C语言函数(三)
可以用C(或者与C兼容,比如C++)语言编写用户自定义函数(User-defined functions)。这些函数被编译到动态可加载目标文件(也称为共享库)中并被守护进程加载到服务中。“C语言函数”与“内部函数”的区别就在于动态加载这个特性,二者的实际编码约定本质上是相同的(因此,标准的内部函数库为用户自定义C语言函数提供了丰富的示例代码)
|
8月前
|
SQL 关系型数据库 MySQL
SQL Server、MySQL、PostgreSQL:主流数据库SQL语法异同比较——深入探讨数据类型、分页查询、表创建与数据插入、函数和索引等关键语法差异,为跨数据库开发提供实用指导
【8月更文挑战第31天】SQL Server、MySQL和PostgreSQL是当今最流行的关系型数据库管理系统,均使用SQL作为查询语言,但在语法和功能实现上存在差异。本文将比较它们在数据类型、分页查询、创建和插入数据以及函数和索引等方面的异同,帮助开发者更好地理解和使用这些数据库。尽管它们共用SQL语言,但每个系统都有独特的语法规则,了解这些差异有助于提升开发效率和项目成功率。
889 0
|
7月前
|
关系型数据库 MySQL 网络安全
5-10Can't connect to MySQL server on 'sh-cynosl-grp-fcs50xoa.sql.tencentcdb.com' (110)")
5-10Can't connect to MySQL server on 'sh-cynosl-grp-fcs50xoa.sql.tencentcdb.com' (110)")
|
9月前
|
SQL 存储 监控
SQL Server的并行实施如何优化?
【7月更文挑战第23天】SQL Server的并行实施如何优化?
257 13
|
9月前
|
SQL
解锁 SQL Server 2022的时间序列数据功能
【7月更文挑战第14天】要解锁SQL Server 2022的时间序列数据功能,可使用`generate_series`函数生成整数序列,例如:`SELECT value FROM generate_series(1, 10)。此外,`date_bucket`函数能按指定间隔(如周)对日期时间值分组,这些工具结合窗口函数和其他时间日期函数,能高效处理和分析时间序列数据。更多信息请参考官方文档和技术资料。
159 9
|
9月前
|
SQL 存储 网络安全
关系数据库SQLserver 安装 SQL Server
【7月更文挑战第26天】
116 6
|
9月前
|
存储 SQL C++
对比 SQL Server中的VARCHAR(max) 与VARCHAR(n) 数据类型
【7月更文挑战7天】SQL Server 中的 VARCHAR(max) vs VARCHAR(n): - VARCHAR(n) 存储最多 n 个字符(1-8000),适合短文本。 - VARCHAR(max) 可存储约 21 亿个字符,适合大量文本。 - VARCHAR(n) 在处理小数据时性能更好,空间固定。 - VARCHAR(max) 对于大文本更合适,但可能影响性能。 - 选择取决于数据长度预期和业务需求。
733 1
下一篇
oss创建bucket