PostgreSQL ECPG ifdef include等预处理用法

本文涉及的产品
云原生数据库 PolarDB MySQL 版,Serverless 5000PCU 100GB
云原生数据库 PolarDB 分布式版,标准版 2核8GB
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介: PostgreSQL 社区版本的ecpg在一些预处理的用法上和Oracle的PROC有一些不一样的地方,使用者需要注意。例如社区版本的ecpg不支持c里面使用的#ifdef或者#ifndef这样的预处理语法,需要用其他写法来替代。所以你如果使用#ifdef这样的写法在.pgc里面,在使用ecpg编.

PostgreSQL 社区版本的ecpg在一些预处理的用法上和Oracle的PROC有一些不一样的地方,使用者需要注意。
例如社区版本的ecpg不支持c里面使用的#ifdef或者#ifndef这样的预处理语法,需要用其他写法来替代。
所以你如果使用#ifdef这样的写法在.pgc里面,在使用ecpg编译时报错,你可能觉得很奇怪。
例子

$ vi t.pgc
#include <stdio.h>
#include <stdlib.h>
#include <pgtypes_numeric.h>

EXEC SQL WHENEVER SQLERROR STOP;

int
main(void)
{
EXEC SQL BEGIN DECLARE SECTION;
    numeric *num;
    numeric *num2;
    decimal *dec;

#ifdef ABC    // ecpg对于这样的代码会整段拷贝输出到.c,同时里面的所有语句都需要被parser过一遍,因此可能报错
    errtype *abc;
#endif

EXEC SQL END DECLARE SECTION;

    EXEC SQL CONNECT TO tcp:postgresql://xxx.xxxcs.com:3433/postgres AS db_digoal USER digoal USING pwd;

    num = PGTYPESnumeric_new();
    dec = PGTYPESdecimal_new();

    EXEC SQL SELECT 12.345::numeric(4,2), 23.456::decimal(4,2) INTO :num, :dec;

    printf("numeric = %s\n", PGTYPESnumeric_to_asc(num, 0));
    printf("numeric = %s\n", PGTYPESnumeric_to_asc(num, 1));
    printf("numeric = %s\n", PGTYPESnumeric_to_asc(num, 2));

    /* Convert decimal to numeric to show a decimal value. */
    num2 = PGTYPESnumeric_new();
    PGTYPESnumeric_from_decimal(dec, num2);

    printf("decimal = %s\n", PGTYPESnumeric_to_asc(num2, 0));
    printf("decimal = %s\n", PGTYPESnumeric_to_asc(num2, 1));
    printf("decimal = %s\n", PGTYPESnumeric_to_asc(num2, 2));

    PGTYPESnumeric_free(num2);
    PGTYPESdecimal_free(dec);
    PGTYPESnumeric_free(num);

    EXEC SQL COMMIT;
    EXEC SQL DISCONNECT ALL;
    return 0;
}

编译报错

ecpg -t -c -I/home/digoal/pgsql9.6/include -o t.c t.pgc
t.pgc:16: ERROR: unrecognized data type name "errtype"

如何修正呢?

#ifdef ABC
    errtype *abc;
#endif

改成

EXEC SQL ifdef ABC;
    errtype *abc;
EXEC SQL endif;

编译通过

digoal@iZ25zysa2jmZ-> ecpg -t -c -I/home/digoal/pgsql9.6/include -o t.c t.pgc

加上ABC宏,里面的这一段才会过parser。

digoal@iZ25zysa2jmZ-> ecpg -t -c -I/home/digoal/pgsql9.6/include -o t.c -D ABC t.pgc
t.pgc:16: ERROR: unrecognized data type name "errtype"

PostgreSQL ecpg还支持include的预处理.
如果include的头文件中包含了ECPG的用法,必须使用以下几种方式来预处理

EXEC SQL INCLUDE filename;
EXEC SQL INCLUDE <filename>;
EXEC SQL INCLUDE "filename";

如果include的文件没有ECPG的语法,则不需要这么做,使用原来的方法即可,ecpg会直接拷贝输出到.c

#include <filename.h>



对于EDB提供的ecpg版本,是支持#ifdef这种写法的,用于兼容ORACLE的PROC。

参考
https://www.postgresql.org/docs/9.5/static/ecpg-preproc.html

EDB ECPG
https://www.enterprisedb.com/docs/en/9.5/ecpg/Postgres_Plus_Advanced_Server_ecpgPlus_Guide.1.24.html#

The ECPGPlus C-preprocessor enforces two behaviors that are dependent on the mode in which you invoke ECPGPlus:
•
PROC mode
•
non-PROC mode

Compiling in PROC mode
In PROC mode, ECPGPlus allows you to:
•
Declare host variables outside of an EXEC SQL BEGIN/END DECLARE SECTION.
•
Use any C variable as a host variable as long as it is of a data type compatible with ECPG.
When you invoke ECPGPlus in PROC mode (by including the -C PROC keywords), the ECPG compiler honors the following C-preprocessor directives:
#include
#if expression
#ifdef symbolName
#ifndef symbolName
#else
#elif expression
#endif
#define symbolName expansion
#define symbolName([macro arguments]) expansion
#undef symbolName
#defined(symbolName)

Pre-processor directives are used to effect or direct the code that is received by the compiler. For example, using the following code sample:
#if HAVE_LONG_LONG == 1
#define BALANCE_TYPE long long
#else
#define BALANCE_TYPE double
#endif
...
BALANCE_TYPE customerBalance;

If you invoke ECPGPlus with the following command-line arguments:
ecpg –C PROC –DHAVE_LONG_LONG=1
ECPGPlus will copy the entire fragment (without change) to the output file, but will only send the following tokens to the ECPG parser:
long long customerBalance;
On the other hand, if you invoke ECPGPlus with the following command-line arguments:
ecpg –C PROC –DHAVE_LONG_LONG=0
The ECPG parser will receive the following tokens:
double customerBalance;

If your code uses preprocessor directives to filter the code that is sent to the compiler, the complete code is retained in the original code, while the ECPG parser sees only the processed token stream.
Compiling in non-PROC mode
If you do not include the -C PROC command-line option:
•
C preprocessor directives are copied to the output file without change.
•
You must declare the type and name of each C variable that you intend to use as a host variable within an EXEC SQL BEGIN/END DECLARE section.
When invoked in non-PROC mode, ECPG implements the behavior described in the PostgreSQL Core documentation
相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
相关文章
|
SQL 关系型数据库 PostgreSQL
PostgreSQL datediff 日期间隔(单位转换)兼容SQL用法
标签 PostgreSQL , datediff 背景 使用datediff,对时间或日期相减,得到的间隔,转换为目标单位(日、月、季度、年、小时、秒。。。等)的数值。 DATEDIFF ( datepart, {date|timestamp}, {date|timestamp} ) 周...
14281 0
|
SQL JSON 关系型数据库
postgresql 高级用法
postgresql 高级用法
|
SQL 存储 移动开发
PostgreSQL psql的使用,SQL语法,数据类型,递归SQL用法(四)|学习笔记
快速学习3 PostgreSQL psql的使用,SQL语法,数据类型,递归SQL用法(四)
380 0
 PostgreSQL psql的使用,SQL语法,数据类型,递归SQL用法(四)|学习笔记
|
SQL 关系型数据库 数据库
3 PostgreSQL psql的使用,SQL语法,数据类型,递归SQL用法(三)|学习笔记
快速学习3 PostgreSQL psql的使用,SQL语法,数据类型,递归SQL用法(三)
304 0
|
SQL 关系型数据库 PostgreSQL
PostgreSQL 数据rotate用法介绍
标签 PostgreSQL , 按时间覆盖历史数据 背景 在某些业务场景中,数据有冷热之分,例如业务只关心最近一天、一周或者一个月的数据。对于历史的数据可以丢弃。 比如某些指标的监控场景,保留一周的监控数据,历史的都可以丢弃。
3156 0
|
SQL XML 移动开发
【学习资料】第14期快速入门PostgreSQL应用开发与管理 - 4 高级SQL用法
大家好,这里是快速入门PostgreSQL应用开发与管理 - 4 高级SQL用法
|
关系型数据库 数据库 PostgreSQL
Postgresql pg_dump&pg_restore用法
PostgreSQL提供的一个工具pg_dump,逻辑导出数据,生成sql文件或其他格式文件,pg_dump是一个客户端工具,可以远程或本地导出逻辑数据,恢复数据至导出时间点。pg_dump 一次只转储一个数据库, 并且不会转储有关角色或表空间的信息 (因为那些是群集范围而不是每个数据库)。
11219 0

相关产品

  • 云原生数据库 PolarDB