PostgreSQL服务端开发学习 --- 常用结构及宏定义1

本文涉及的产品
云原生数据库 PolarDB MySQL 版,通用型 2核4GB 50GB
云原生数据库 PolarDB PostgreSQL 版,标准版 2核4GB 50GB
简介: 本篇主要讲解使用C语言开发PostgreSQL服务端应用(libpq、自定义函数、扩展)常用到的结构及宏定义。

本篇主要讲解使用C语言开发PostgreSQL服务端应用(libpq、自定义函数、扩展)常用到的结构及宏定义。以 pgpool-recovery扩展分析 中的C语言源代码为例,顺序拆解使用到的结构体及宏定义。

PG_MODULE_MAGIC宏

作用:支持验证已加载模块的后端兼容性。

用C语言开发扩展或者自定义函数时要求动态加载的模块包括宏调用PG_MODULE_MAGIC以便检查明显的不兼容性,比如在不同主版本的PostgreSQL下编译。

要在不支持PG_MODULE_MAGIC的PostgreSQL版本进行编译,可以将其包裹在#ifdef/#endif里测试。需要注意的是,在一个有多个源文件的模块中,此宏调用只能出现一次。

magic块中包含的特定项是可自定义配置的,并且如果使用其他值编译动态加载模块,则有可能破坏这些模块。此外,长度字段可用于检测定义更改。

注意:我们会使用memcpy()比较magic块,因此最好不要对其做对齐填充。

注意:更改magic块时,请务必调整dfmgr.c中的incompatible_module_error()函数。

/* magic block structure */typedefstruct{
intlen;            /* sizeof(this struct) */intversion;        /* PostgreSQL major version */intfuncmaxargs;    /* FUNC_MAX_ARGS */intindexmaxkeys;   /* INDEX_MAX_KEYS */intnamedatalen;    /* NAMEDATALEN */intfloat8byval;    /* FLOAT8PASSBYVAL */charabi_extra[32];  /* see pg_config_manual.h */} Pg_magic_struct;
/* * 生成实际的数据块内容 * PG_VERSION_NUM - 在pg_config.h中定义,本例是150002* FUNC_MAX_ARGS - 在pg_config_manual.h中定义,缺省值是100* INDEX_MAX_KEYS - 在pg_config_manual.h中定义,缺省值是32* NAMEDATALEN - 在pg_config_manual.h中定义,缺省值是64* FLOAT8PASSBYVAL - 在c.h中定义,缺省值是true* FMGR_ABI_EXTRA - pg_config_manual.h中定义,缺省值是"PostgreSQL"*/#define PG_MODULE_MAGIC_DATA \{ \sizeof(Pg_magic_struct), \PG_VERSION_NUM / 100, \FUNC_MAX_ARGS, \INDEX_MAX_KEYS, \NAMEDATALEN, \FLOAT8PASSBYVAL, \FMGR_ABI_EXTRA, \}/* FMGR_ABI_EXTRA自义在pg_config_manual.h中* 内容为 "PostgreSQL"*/StaticAssertDecl(sizeof(FMGR_ABI_EXTRA) <=sizeof(((Pg_magic_struct*) 0)->abi_extra),
"FMGR_ABI_EXTRA too long");
/** Declare the module magic function.  It needs to be a function as the dlsym* in the backend is only guaranteed to work on functions, not data*/typedefconstPg_magic_struct*(*PGModuleMagicFunction) (void);
#define PG_MAGIC_FUNCTION_NAME Pg_magic_func#define PG_MAGIC_FUNCTION_NAME_STRING "Pg_magic_func"#define PG_MODULE_MAGIC \extern PGDLLEXPORT const Pg_magic_struct *PG_MAGIC_FUNCTION_NAME(void); \const Pg_magic_struct * \PG_MAGIC_FUNCTION_NAME(void) \{ \static const Pg_magic_struct Pg_magic_data = PG_MODULE_MAGIC_DATA; \return &Pg_magic_data; \} \extern int no_such_variable

根据以上的定义,宏PG_MODULE_MAGIC在翻译时会被展开成如下代码:

externPGDLLEXPORTconstPg_magic_struct*Pg_magic_func(void);
constPg_magic_struct*Pg_magic_func(void) 
{ 
staticconstPg_magic_structPg_magic_data= {
sizeof(Pg_magic_struct),
150002/100,
100,
32,
64,
1,
"PostgreSQL",    
    }; 
return&Pg_magic_data;
} 
externintno_such_variable

PG_FUNCTION_INFO_V1

动态加载函数调用约定检测支持

在fmgr.h中定义。动态加载函数当前仅支持Version-1,不再支持Version-0。

typedefstruct{
intapi_version;    /* 指定调用约定版本 *//* More fields may be added later, for version numbers > 1. */} Pg_finfo_record;
/* info函数的签名 */typedefconstPg_finfo_record*(*PGFInfoFunction) (void);
#define PG_FUNCTION_INFO_V1(funcname) \extern Datum funcname(PG_FUNCTION_ARGS); \extern PGDLLEXPORT const Pg_finfo_record * CppConcat(pg_finfo_,funcname)(void); \const Pg_finfo_record * \CppConcat(pg_finfo_,funcname) (void) \{ \static const Pg_finfo_record my_finfo = { 1 }; \return &my_finfo; \} \extern int no_such_variable

以pgpool-recovery扩展的PG_FUNCTION_INFO_V1(pgpool_recovery)为例,通过宏展开后代码如下:

/** 所有可被fmgr直接调用的函数必须有如下签名,相关struct以后讲*/typedefstructFunctionCallInfoBaseData*FunctionCallInfo;
typedefDatum (*PGFunction) (FunctionCallInfofcinfo);
externDatumpgpool_recovery(FunctionCallInfofcinfo);
externPGDLLEXPORTconstPg_finfo_record*pg_finfo_pgpool_recovery(void)
{
staticconstPg_finfo_recordmy_finfo= { 1 }; 
return&my_finfo;    
}
externintno_such_variable
相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
相关文章
|
关系型数据库 数据库 C语言
PostgreSQL服务端开发学习 -- Datum
在使用C语言开发PostgreSQL后端、客户端应用时,Datum无处不在,所以必须要对Datum有很清楚的了解。
|
6月前
|
存储 SQL 人工智能
01-PostgreSQL 存储过程的基本介绍以及入门(基本结构、声明和赋值、控制结构)(下)
01-PostgreSQL 存储过程的基本介绍以及入门(基本结构、声明和赋值、控制结构)
|
3月前
|
SQL 存储 关系型数据库
新手如何入门学习PostgreSQL?
新手如何入门学习PostgreSQL?
|
3月前
|
SQL 存储 关系型数据库
PostgreSQL核心之SQL基础学习
PostgreSQL核心之SQL基础学习
43 3
|
3月前
|
SQL 关系型数据库 MySQL
SQL Server、MySQL、PostgreSQL:主流数据库SQL语法异同比较——深入探讨数据类型、分页查询、表创建与数据插入、函数和索引等关键语法差异,为跨数据库开发提供实用指导
【8月更文挑战第31天】SQL Server、MySQL和PostgreSQL是当今最流行的关系型数据库管理系统,均使用SQL作为查询语言,但在语法和功能实现上存在差异。本文将比较它们在数据类型、分页查询、创建和插入数据以及函数和索引等方面的异同,帮助开发者更好地理解和使用这些数据库。尽管它们共用SQL语言,但每个系统都有独特的语法规则,了解这些差异有助于提升开发效率和项目成功率。
360 0
|
4月前
|
SQL 存储 关系型数据库
关系型数据库PostgreSQL学习
【7月更文挑战第4天】
456 2
|
5月前
|
存储 关系型数据库 数据库
经验大分享:PostgreSQL学习之【用户权限管理】说明
经验大分享:PostgreSQL学习之【用户权限管理】说明
62 0
|
6月前
|
SQL 人工智能 Oracle
PostgreSQL 递归查询(含层级和结构)
PostgreSQL 递归查询(含层级和结构)
|
关系型数据库 C语言 PostgreSQL
PostgreSQL服务端开发学习 -- fmgr.h
fmgr按官方的解释就是Postgres函数管理器和函数调用接口,在使用C语言开发PostgreSQL后端应用时,所以与backend交互时必须遵循fmgr.h中定义的一些规范。
|
6月前
|
存储 SQL 关系型数据库
01-PostgreSQL 存储过程的基本介绍以及入门(基本结构、声明和赋值、控制结构)(上)
01-PostgreSQL 存储过程的基本介绍以及入门(基本结构、声明和赋值、控制结构)