我正在尝试将以下 SQL 函数重写为等效的 C 函数(试图使其更快一点):
CREATE OR REPLACE FUNCTION dat2(time_key integer)
RETURNS date AS
$BODY$
BEGIN
RETURN case when time_key > 0 then '2006-12-31'::date + time_key end as result;
END;
$BODY$
LANGUAGE plpgsql IMMUTABLE STRICT
COST 100;
我想我可以修改现有的 date
+int4
运算符并执行如下操作:
#include "postgres.h"
#include "fmgr.h"
#include "utils/date.h"
#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endif
PG_FUNCTION_INFO_V1(dwd);
Datum
dwd(PG_FUNCTION_ARGS)
{
/* DateADT dateVal = PG_GETARG_DATEADT(0); */
DateADT dateVal = PG_GETARG_DATEADT(2006-12-31);
int32 days = PG_GETARG_INT32(0);
PG_RETURN_DATEADT(dateVal + days);
}
如果我编译我的函数并将其转换为 .so
我可以在 PostgreSQL 中创建 dwd
函数:
create or replace function dwd(int) returns date as
'/usr/lib/postgresql/9.3/lib/dwd', 'dwd'
language c
cost 1;
对于 select dwd(0);
,我得到了 2000-01-01
,但我期望的是 2006-12-31
。显然 DateADT dateVal = PG_GETARG_DATEADT(2006-12-31);
有问题。
如何在此 C 函数中定义日期常量?
最佳答案
现在可以了。事实证明,DateADT
是自 2000 年 1 月 1 日以来的天数(整数)。
c函数:
#include "postgres.h"
#include "fmgr.h"
#include "utils/date.h"
#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endif
PG_FUNCTION_INFO_V1(dwd);
Datum
dwd(PG_FUNCTION_ARGS)
{
int32 days = PG_GETARG_INT32(0);
if (days > 0) {
DateADT dateVal = 2556;
PG_RETURN_DATEADT(dateVal + days);
}
else {
PG_RETURN_NULL();
}
}
性能测试:
drop table if exists tmp;
create table tmp as select dat2(gs) from generate_series(1,1000000) gs;
-- Query returned successfully: 1000000 rows affected, 4101 ms execution time.
drop table if exists tmp;
create table tmp as select dwd(gs) from generate_series(1,1000000) gs;
-- Query returned successfully: 1000000 rows affected, 1527 ms execution time.
在搜索过程中,我找到了 this对 PostgreSQL 中的 c 函数非常有用的引用。
关于c - PostgreSQL - 在 C 函数中使用日期常量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22318605/