c - 在 C 中构建 Postgres 函数时,来自 fmgr.h 的“'return' 之前的预期表达式”错误
问题描述
我正在尝试编译一个用于 Postgres 9.5 的 C 函数。当我尝试运行 makefile 来编译代码时,我收到以下消息/错误:
cc -o int_to_id.o -c int_to_id.c -I /usr/include/postgresql/9.5/server
In file included from int_to_id.c:1:0:
int_to_id.c: In function ‘int_to_id’:
/usr/include/postgresql/9.5/server/postgres.h:613:26: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
#define DatumGetInt64(X) ((int64) GET_8_BYTES(X))
^
/usr/include/postgresql/9.5/server/fmgr.h:238:29: note: in expansion of macro ‘DatumGetInt64’
#define PG_GETARG_INT64(n) DatumGetInt64(PG_GETARG_DATUM(n))
^
int_to_id.c:55:15: note: in expansion of macro ‘PG_GETARG_INT64’
long *x = PG_GETARG_INT64(0);
^
In file included from int_to_id.c:2:0:
/usr/include/postgresql/9.5/server/fmgr.h:305:30: error: expected expression before ‘return’
#define PG_RETURN_POINTER(x) return PointerGetDatum(x)
^
/usr/include/postgresql/9.5/server/fmgr.h:316:32: note: in expansion of macro ‘PG_RETURN_POINTER’
#define PG_RETURN_VARCHAR_P(x) PG_RETURN_POINTER(x)
^
int_to_id.c:60:12: note: in expansion of macro ‘PG_RETURN_VARCHAR_P’
return PG_RETURN_VARCHAR_P(cstring_to_text(result));
^
Makefile:15: recipe for target 'int_to_id.o' failed
make: *** [int_to_id.o] Error 1
看起来这些错误之一来自“fmgr.h”的语法,我不确定如何理解它,因为这是一个包含的库文件。我该如何解决这个错误?
作为参考,我的makefile:
MODULES = int_to_id
PG_CONFIG = pg_config
PGXS = $(shell $(PG_CONFIG) --pgxs)
INCLUDEDIR = $(shell $(PG_CONFIG) --includedir-server)
include $(PGXS)
int_to_id.so: int_to_id.o
cc -shared -o int_to_id.so int_to_id.o
int_to_id.o: int_to_id.c
cc -o int_to_id.o -c int_to_id.c $(CRFLAGS) -I $(INCLUDEDIR)
也供参考,C源文件:
#include "postgres.h"
#include "fmgr.h"
#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endif
const char charmap[36] = {
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'a',
'b',
'c',
'd',
'e',
'f',
'g',
'h',
'i',
'j',
'k',
'l',
'm',
'n',
'o',
'p',
'q',
'r',
's',
't',
'u',
'v',
'w',
'x',
'y',
'z'
};
Datum int_to_id(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(int_to_id);
Datum int_to_id(PG_FUNCTION_ARGS){
char result[10] = {' ',' ',' ',' ',' ',' ',' ',' ',' ',' '};
long base_val = 1L;
long *x = PG_GETARG_INT64(0);
for (int i = 1; i <= 10, i++; ){
result[10 - i] = charmap[ ((*x) / base_val) % 36];
}
base_val = base_val * 36L;
return PG_RETURN_VARCHAR_P(cstring_to_text(result));
}
解决方案
第一个错误
PG_GETARG_INT64(0)
以 . 形式返回一个Datum
值int64
。您正在将值分配给指针 ( long *
),这会使编译器不高兴。
如果您知道自己在做什么,则可以通过强制转换来强制分配:
long *x = (long *)PG_GETARG_INT64(0);
但这对我来说看起来很可疑,并且可能有更好的方法来使用 PostgresQL 类型和宏。
例如,这看起来会更好:
int64 x = PG_GETARG_INT64(0);
for (int i = 1; i++; i <= 10){
result[10 - i] = charmap[(x / 36^i) % 36];
}
第二个错误
return PG_RETURN_VARCHAR_P(cstring_to_text(result));
最终扩展到
return return PointerGetDatum(cstring_to_text(result))
这显然是错误的。删除多余的return
:
PG_RETURN_VARCHAR_P(cstring_to_text(result));
推荐阅读
- python - Pandas 如果多个条件中的一些为真(布尔数学?)
- node.js - 检索与数组中的值匹配的所有对象
- django - 如何通过 ModelChoiceField 选择动态过滤视图
- android - android studio:在调试或构建时创建我的两个应用程序
- mysql - 在一个表的两个表中求和孩子
- java - Android 应用程序不会记住 USB 权限
- php - Fastest return TRUE if all values of a column of a multidimensional array is_numeric
- docker - Jenkins:Jenkins 如何模拟注销和重新登录?
- ios - iOS App starts crashing after a week of installing it to device
- angular - 拥有一个打字稿类的属性取决于另外两个,如何进行?