c - PostgreSQL - 在 C 函数中使用日期常量

标签 c postgresql postgresql-9.3

我正在尝试将以下 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/

相关文章:

Delphi ADO 内存消耗

具有 OR 的 SQL 查询比 2 个单独的查询慢得多

c - fork 进程不是在 C 中调用函数

c - 在 C 中使用递归反转链表

sql - Postgres 数据类型整数和 bool 值

sql - Postgres如何使用子句实现计算列

PostgreSQL 9.3 :Dynamic Cross tab query

无法在c中传递正确的动态结构数组

c - 从 libpcap 捕获的数据包中获取错误的 ip 和端口号

sql - 如果我将 NUMERIC 的列定义太宽泛,是否会牺牲磁盘空间?