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

本文涉及的产品
云原生数据库 PolarDB MySQL 版,通用型 2核4GB 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数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
目录
相关文章
|
6天前
|
C语言
c语言调用的函数的声明
被调用的函数的声明: 一个函数调用另一个函数需具备的条件: 首先被调用的函数必须是已经存在的函数,即头文件中存在或已经定义过; 如果使用库函数,一般应该在本文件开头用#include命令将调用有关库函数时在所需要用到的信息“包含”到本文件中。.h文件是头文件所用的后缀。 如果使用用户自己定义的函数,而且该函数与使用它的函数在同一个文件中,一般还应该在主调函数中对被调用的函数做声明。 如果被调用的函数定义出现在主调函数之前可以不必声明。 如果已在所有函数定义之前,在函数的外部已做了函数声明,则在各个主调函数中不必多所调用的函数在做声明
21 6
|
19天前
|
存储 算法 程序员
C语言:库函数
C语言的库函数是预定义的函数,用于执行常见的编程任务,如输入输出、字符串处理、数学运算等。使用库函数可以简化编程工作,提高开发效率。C标准库提供了丰富的函数,满足各种需求。
|
24天前
|
机器学习/深度学习 C语言
【c语言】一篇文章搞懂函数递归
本文详细介绍了函数递归的概念、思想及其限制条件,并通过求阶乘、打印整数每一位和求斐波那契数等实例,展示了递归的应用。递归的核心在于将大问题分解为小问题,但需注意递归可能导致效率低下和栈溢出的问题。文章最后总结了递归的优缺点,提醒读者在实际编程中合理使用递归。
53 7
|
24天前
|
存储 编译器 程序员
【c语言】函数
本文介绍了C语言中函数的基本概念,包括库函数和自定义函数的定义、使用及示例。库函数如`printf`和`scanf`,通过包含相应的头文件即可使用。自定义函数需指定返回类型、函数名、形式参数等。文中还探讨了函数的调用、形参与实参的区别、return语句的用法、函数嵌套调用、链式访问以及static关键字对变量和函数的影响,强调了static如何改变变量的生命周期和作用域,以及函数的可见性。
29 4
|
22天前
|
存储 C语言
【c语言】字符串函数和内存函数
本文介绍了C语言中常用的字符串函数和内存函数,包括`strlen`、`strcpy`、`strcat`、`strcmp`、`strstr`、`strncpy`、`strncat`、`strncmp`、`strtok`、`memcpy`、`memmove`和`memset`等函数的使用方法及模拟实现。文章详细讲解了每个函数的功能、参数、返回值,并提供了具体的代码示例,帮助读者更好地理解和掌握这些函数的应用。
19 0
|
22天前
|
C语言
【c语言】qsort函数及泛型冒泡排序的模拟实现
本文介绍了C语言中的`qsort`函数及其背后的回调函数概念。`qsort`函数用于对任意类型的数据进行排序,其核心在于通过函数指针调用用户自定义的比较函数。文章还详细讲解了如何实现一个泛型冒泡排序,包括比较函数、交换函数和排序函数的编写,并展示了完整的代码示例。最后,通过实际运行验证了排序的正确性,展示了泛型编程的优势。
18 0
|
25天前
|
算法 C语言
factorial函数c语言
C语言中实现阶乘函数提供了直接循环和递归两种思路,各有优劣。循环实现更适用于大规模数值,避免了栈溢出风险;而递归实现则在代码简洁度上占优,但需警惕深度递归带来的潜在问题。在实际开发中,根据具体需求与环境选择合适的实现方式至关重要。
22 0
|
关系型数据库 分布式数据库 PolarDB
《阿里云产品手册2022-2023 版》——PolarDB for PostgreSQL
《阿里云产品手册2022-2023 版》——PolarDB for PostgreSQL
363 0
|
存储 缓存 关系型数据库
|
存储 SQL 并行计算
PolarDB for PostgreSQL 开源必读手册-开源PolarDB for PostgreSQL架构介绍(中)
PolarDB for PostgreSQL 开源必读手册-开源PolarDB for PostgreSQL架构介绍
419 0