Greenplum is_date C Language Interface

Source: Internet
Author: User

In greenplum/PostgreSQL, it is convenient to convert a string to a time. In many formats, GP can automatically identify whether the time character is used. If the time is not correct or the time is incorrect, the SQL statement reports an error.

aligputf8=# select'2011-13-10 10:10:10'::date;ERROR:  date/time field value out of range:"2011-13-10 10:10:10"LINE 1: select'2011-13-10 10:10:10'::date;               ^HINT:  Perhaps you need a different"datestyle" setting. aligputf8=# select'df'::date;                   ERROR:  invalid input syntax for type date:"df"LINE 1: select'df'::date;

One requirement is to identify whether a string is valid at a time. Many PostgreSQL documents have not found such a function. However, during the type conversion, the database did perform this verification, but it did not implement this function call. So let's take a look at the source code of postgresql, extract this function, and recreate a function to implement this function.

In the src/backend/utils/ADT/date. C code, this function is available:

/* date_in() * Given date text string, convert to internaldate format. */Datumdate_in(PG_FUNCTION_ARGS){        char       *str = PG_GETARG_CSTRING(0);        DateADT         date;        fsec_t          fsec;        struct pg_tm tt,                          *tm = &tt;        int                     tzp;        int                     dtype;        int                     nf;        int                     dterr;        char       *field[MAXDATEFIELDS];        int                     ftype[MAXDATEFIELDS];        char            workbuf[MAXDATELEN + 1];         dterr = ParseDateTime(str, workbuf,sizeof(workbuf),                                                 field, ftype, MAXDATEFIELDS, &nf);        if (dterr == 0)                dterr = DecodeDateTime(field,ftype, nf, &dtype, tm, &fsec, &tzp);        if (dterr != 0)                DateTimeParseError(dterr, str,"date");

 

This function calls the parsedatetime and decodedatetime functions to identify whether the string is a time character. h, so we need to include this header file. So I wrote the following C language function to implement this function:

 

//is_date.c#include"postgres.h"#include"funcapi.h"#include"utils/datetime.h"#include"fmgr.h"#ifdefPG_MODULE_MAGICPG_MODULE_MAGIC;#endifDatumis_date(PG_FUNCTION_ARGS);PG_FUNCTION_INFO_V1(is_date);Datumis_date(PG_FUNCTION_ARGS){      VarChar *arg1 = PG_GETARG_VARCHAR_P(0);      struct pg_tm tt,                           *tm = &tt;      fsec_t          fsec;      char      *str = (char *)palloc(VARSIZE(arg1) - VARHDRSZ +1);      memcpy(str, VARDATA(arg1), VARSIZE(arg1)- VARHDRSZ);      str[VARSIZE(arg1) - VARHDRSZ]=0;      int                     nf;      int                     dtype;      int                     dterr;      int                     tzp;      char            workbuf[MAXDATELEN + 1];      char      *field[MAXDATEFIELDS];      int                     ftype[MAXDATEFIELDS];      elog(INFO, str);      //elog(INFO, arg1->vl_len_);      dterr = ParseDateTime(str, workbuf,sizeof(workbuf),field, ftype, MAXDATEFIELDS, &nf);      if (dterr == 0)                dterr = DecodeDateTime(field,ftype, nf, &dtype, tm, &fsec, &tzp);      if (dterr == 0){      //   elog(INFO, "true");          PG_RETURN_BOOL(true);       }      else      {       //  elog(INFO, "false");          PG_RETURN_BOOL(false);      }}

 

 

Compile:

gcc -m64-I$GPHOME/include -I$GPHOME/include/postgresql -I$GPHOME/include/libpq-I$GPHOME/include/postgresql/server -I$GPHOME/include/postgresql/internal -O2-Wall -Wmissing-prototypes -Wpointer-arith -Winline-Wdeclaration-after-statement -Wendif-labels -fno-strict-aliasing -fwrapv -fPIC-I. -c -o is_date.o is_date.c gcc -m64 -sharedis_date.o  -L$GPHOME/lib-L$GPHOME/lib/postgresql -o is_date.so

Put the is_date.so library file SCP in the/home/gpadmin1/cxf/is_date directory of each GP machine:

Create a function:

CREATE or replaceFUNCTION is_date(varchar)RETURNS bool AS'/home/gpadmin1/cxf/is_date'LANGUAGE C IMMUTABLE  ;

Verification:

aligputf8=# selectis_date('2011-12-10 10:10:10'); is_date --------- t(1 row) aligputf8=# selectis_date('2011-13-10 10:10:10');  is_date --------- f(1 row) aligputf8=# selectis_date('sfd'); is_date --------- f(1 row)

PS: If the string is in time format and the time is correct, true is returned; otherwise, false is returned.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.