blob: e7713226791e8d340d78168664eb01f30c4be62b [file] [log] [blame]
#include "vtype_ext.h"
#include "utils/builtins.h"
#define MAX_NUM_LEN 64
extern int BATCHSIZE;
/* vdateadtin()
* Given text string, convert to internal format date.
*/
PG_FUNCTION_INFO_V1(vdateadtin);
Datum
vdateadtin(PG_FUNCTION_ARGS)
{
char *intString = PG_GETARG_CSTRING(0);
vtype *res = NULL;
char tempstr[MAX_NUM_LEN] = {0};
int n = 0;
res = buildvtype(DATEOID,BATCHSIZE,NULL);
for (n = 0; *intString && n < BATCHSIZE; n++)
{
char *start = NULL;
while (*intString && isspace((unsigned char) *intString))
intString++;
if (*intString == '\0')
break;
start = intString;
while ((*intString && !isspace((unsigned char) *intString)) && *intString != '\0')
intString++;
Assert(intString - start < MAX_NUM_LEN);
strncpy(tempstr, start, intString - start);
tempstr[intString - start] = 0;
res->values[n] = DirectFunctionCall1(date_in, CStringGetDatum(tempstr));
while (*intString && !isspace((unsigned char) *intString))
intString++;
}
while (*intString && isspace((unsigned char) *intString))
intString++;
if (*intString)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("int2vector has too many elements")));
res->elemtype = DATEOID;
res->dim = n;
SET_VARSIZE(res, VTYPESIZE(n));
PG_RETURN_POINTER(res);
}
/* vdateadtout()
* Given internal format date, convert to text string.
*/
PG_FUNCTION_INFO_V1(vdateadtout);
Datum
vdateadtout(PG_FUNCTION_ARGS)
{
vtype * arg1 = (vtype *) PG_GETARG_POINTER(0);
int len = arg1->dim;
int i = 0;
char *rp;
char *result;
rp = result = (char *) palloc0(len * MAX_NUM_LEN + 1);
for (i = 0; i < len; i++)
{
if (i != 0)
*rp++ = ' ';
strcat(rp, DatumGetCString(DirectFunctionCall1(date_out, arg1->values[i])));
while (*++rp != '\0');
}
*rp = '\0';
PG_RETURN_CSTRING(result);
}
#define EXT_TYPE_CMP(TYPE,TYPEEXPR,cmpsym,cmpstr) \
PG_FUNCTION_INFO_V1(v##TYPE##_##cmpstr); \
Datum v##TYPE##_##cmpstr(PG_FUNCTION_ARGS) \
{ \
int size = 0; \
int i = 0; \
v##TYPE* arg1 = PG_GETARG_POINTER(0); \
v##TYPE* arg2 = PG_GETARG_POINTER(1); \
Assert(arg1->dim == arg2->dim); \
vbool *res = buildvtype(BOOLOID, BATCHSIZE, NULL); \
size = arg1->dim; \
while(i < size) \
{ \
res->isnull[i] = arg1->isnull[i] || arg2->isnull[i]; \
if(!res->isnull[i]) \
res->values[i] = BoolGetDatum(DatumGet##TYPEEXPR(arg1->values[i]) cmpsym (DatumGet##TYPEEXPR(arg2->values[i]))); \
i++; \
} \
res->dim = arg1->dim; \
PG_RETURN_POINTER(res);\
}; \
#define EXT_TYPE_CMP_RCONST(type, XTYPE, const_type, CONST_ARG_MACRO, cmpsym, cmpstr) \
PG_FUNCTION_INFO_V1(v##type##_##cmpstr##_##type); \
Datum \
v##type##_##cmpstr##_##type(PG_FUNCTION_ARGS) \
{ \
int size = 0; \
int i = 0; \
v##type *arg1 = PG_GETARG_POINTER(0); \
const_type arg2 = CONST_ARG_MACRO(1); \
vbool *res = buildvtype(BOOLOID, BATCHSIZE, NULL); \
size = arg1->dim; \
while(i < size) \
{ \
res->isnull[i] = arg1->isnull[i]; \
if(!res->isnull[i]) \
res->values[i] = BoolGetDatum((DatumGet##XTYPE(arg1->values[i])) cmpsym arg2); \
i++; \
} \
res->dim = arg1->dim; \
PG_RETURN_POINTER(res); \
}
EXT_TYPE_CMP(dateadt,DateADT,==,eq)
EXT_TYPE_CMP(dateadt,DateADT,!=,ne)
EXT_TYPE_CMP(dateadt,DateADT,<,lt)
EXT_TYPE_CMP(dateadt,DateADT,<=,le)
EXT_TYPE_CMP(dateadt,DateADT,>,gt)
EXT_TYPE_CMP(dateadt,DateADT,>=,ge)
EXT_TYPE_CMP_RCONST(dateadt, DateADT, DateADT , PG_GETARG_DATEADT, ==, eq)
EXT_TYPE_CMP_RCONST(dateadt, DateADT, DateADT, PG_GETARG_DATEADT, !=, ne)
EXT_TYPE_CMP_RCONST(dateadt, DateADT, DateADT, PG_GETARG_DATEADT, <, lt)
EXT_TYPE_CMP_RCONST(dateadt, DateADT, DateADT, PG_GETARG_DATEADT, <=, le)
EXT_TYPE_CMP_RCONST(dateadt, DateADT, DateADT, PG_GETARG_DATEADT, >, gt)
EXT_TYPE_CMP_RCONST(dateadt, DateADT, DateADT, PG_GETARG_DATEADT, >=, ge)
PG_FUNCTION_INFO_V1(vdateadt_mi_dateadt);
Datum vdateadt_mi_dateadt(PG_FUNCTION_ARGS)
{
int size = 0;
int i = 0;
vdateadt* arg1 = PG_GETARG_POINTER(0);
DateADT arg2 = PG_GETARG_INT32(1);
vint4 *res = buildvint4(BATCHSIZE, NULL);
size = arg1->dim;
while(i < size)
{
res->isnull[i] = arg1->isnull[i];
if(!res->isnull[i])
res->values[i] = Int32GetDatum((DatumGetDateADT(arg1->values[i])) - (DatumGetDateADT(arg2)));
i++;
}
res->dim = arg1->dim;
PG_RETURN_POINTER(res);
}
/* vdateadt_mii_int4
* vdateadt - int4
* */
PG_FUNCTION_INFO_V1(vdateadt_mii_int4);
Datum vdateadt_mii_int4(PG_FUNCTION_ARGS)
{
int size = 0;
int i = 0;
vdateadt* arg1 = PG_GETARG_POINTER(0);
int arg2 = PG_GETARG_INT32(1);
vdateadt* res = buildvint4(BATCHSIZE, NULL);
size = arg1->dim;
while(i < size)
{
res->isnull[i] = arg1->isnull[i] ;
if(!res->isnull[i])
res->values[i] = DateADTGetDatum((DatumGetDateADT(arg1->values[i])) - arg2);
i++;
}
res->dim = arg1->dim;
PG_RETURN_POINTER(res);
}
/* vdateadt_pli_int4
* vdateadt + int4
* */
PG_FUNCTION_INFO_V1(vdateadt_pli_int4);
Datum vdateadt_pli_int4(PG_FUNCTION_ARGS)
{
int size = 0;
int i = 0;
vdateadt* arg1 = PG_GETARG_POINTER(0);
int arg2 = PG_GETARG_INT32(1);
vdateadt* res = buildvint4(BATCHSIZE, NULL);
size = arg1->dim;
while(i < size)
{
res->isnull[i] = arg1->isnull[i] ;
if(!res->isnull[i])
res->values[i] = Int32GetDatum((DatumGetDateADT(arg1->values[i])) + arg2);
i++;
}
res->dim = arg1->dim;
PG_RETURN_POINTER(res);
}
/* vdateadt_mi
* vdateadt - vdateadt
* */
PG_FUNCTION_INFO_V1(vdateadt_mi);
Datum vdateadt_mi(PG_FUNCTION_ARGS)
{
int size = 0;
int i = 0;
vdateadt* arg1 = PG_GETARG_POINTER(0);
vdateadt* arg2 = PG_GETARG_POINTER(1);
vint4 *res = buildvint4(BATCHSIZE, NULL);
Assert(arg1->dim == arg2->dim);
size = arg1->dim;
while(i < size)
{
res->isnull[i] = arg1->isnull[i] || arg2->isnull[i];
if(!res->isnull[i])
res->values[i] = Int32GetDatum((DatumGetDateADT(arg1->values[i])) - (DatumGetDateADT(arg2->values[i])));
i++;
}
res->dim = arg1->dim;
PG_RETURN_POINTER(res);
}
/* vdateadt_mii
* vdateadt - vint4
* */
PG_FUNCTION_INFO_V1(vdateadt_mii);
Datum vdateadt_mii(PG_FUNCTION_ARGS)
{
int size = 0;
int i = 0;
vdateadt* arg1 = PG_GETARG_POINTER(0);
vint4* arg2 = PG_GETARG_POINTER(1);
vdateadt* res = buildvint4(BATCHSIZE, NULL);
Assert(arg1->dim == arg2->dim);
size = arg1->dim;
while(i < size)
{
res->isnull[i] = arg1->isnull[i] || arg2->isnull[i];
if(!res->isnull[i])
res->values[i] = DateADTGetDatum((DatumGetDateADT(arg1->values[i])) - (DatumGetInt32(arg2->values[i])));
i++;
}
res->dim = arg1->dim;
PG_RETURN_POINTER(res);
}
/* vdateadt_pli
* vdateadt + vint4
* */
PG_FUNCTION_INFO_V1(vdateadt_pli);
Datum vdateadt_pli(PG_FUNCTION_ARGS)
{
int size = 0;
int i = 0;
vdateadt* arg1 = PG_GETARG_POINTER(0);
vint4* arg2 = PG_GETARG_POINTER(1);
vdateadt* res = buildvint4(BATCHSIZE, NULL);
Assert(arg1->dim == arg2->dim);
size = arg1->dim;
while(i < size)
{
res->isnull[i] = arg1->isnull[i] || arg2->isnull[i];
if(!res->isnull[i])
res->values[i] = Int32GetDatum((DatumGetDateADT(arg1->values[i])) + (DatumGetDateADT(arg2->values[i])));
i++;
}
res->dim = arg1->dim;
PG_RETURN_POINTER(res);
}