From 5320c6cf6b21811eda1910a7df6f05b992fe2aea Mon Sep 17 00:00:00 2001 From: Teodor Sigaev Date: Wed, 3 May 2006 16:31:07 +0000 Subject: Make GIN opclass worked with intarray extensions --- contrib/intarray/_int_gin.c | 100 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 contrib/intarray/_int_gin.c (limited to 'contrib/intarray/_int_gin.c') diff --git a/contrib/intarray/_int_gin.c b/contrib/intarray/_int_gin.c new file mode 100644 index 00000000000..dfbb6e2ff1d --- /dev/null +++ b/contrib/intarray/_int_gin.c @@ -0,0 +1,100 @@ +#include "_int.h" + +PG_FUNCTION_INFO_V1(ginint4_queryextract); +Datum ginint4_queryextract(PG_FUNCTION_ARGS); + +Datum +ginint4_queryextract(PG_FUNCTION_ARGS) { + uint32 *nentries = (uint32*)PG_GETARG_POINTER(1); + StrategyNumber strategy = PG_GETARG_UINT16(2); + Datum *res = NULL; + + *nentries = 0; + + if ( strategy == BooleanSearchStrategy ) { + QUERYTYPE *query = (QUERYTYPE*)PG_DETOAST_DATUM_COPY(PG_GETARG_POINTER(0)); + ITEM *items = GETQUERY(query); + int i; + + if (query->size == 0) + PG_RETURN_POINTER(NULL); + + if ( shorterquery(items, query->size) == 0 ) + elog(ERROR,"Query requires full scan, GIN doesn't support it"); + + pfree( query ); + + query = (QUERYTYPE*)PG_DETOAST_DATUM(PG_GETARG_POINTER(0)); + items = GETQUERY(query); + + res = (Datum*)palloc(sizeof(Datum) * query->size); + *nentries = 0; + + for(i=0;isize;i++) + if ( items[i].type == VAL ) { + res[*nentries] = Int32GetDatum( items[i].val ); + (*nentries)++; + } + } else { + ArrayType *query = PG_GETARG_ARRAYTYPE_P(0); + int4 *arr; + uint32 i; + + CHECKARRVALID(query); + *nentries=ARRNELEMS(query); + if ( *nentries > 0 ) { + res = (Datum*)palloc(sizeof(Datum) * (*nentries)); + + arr=ARRPTR(query); + for(i=0;i<*nentries;i++) + res[i] = Int32GetDatum( arr[i] ); + } + } + + PG_RETURN_POINTER( res ); +} + +PG_FUNCTION_INFO_V1(ginint4_consistent); +Datum ginint4_consistent(PG_FUNCTION_ARGS); + +Datum +ginint4_consistent(PG_FUNCTION_ARGS) { + bool *check = (bool*)PG_GETARG_POINTER(0); + StrategyNumber strategy = PG_GETARG_UINT16(1); + int res=FALSE; + + /* we can do not check array carefully, it's done by previous ginarrayextract call */ + + switch( strategy ) { + case RTOverlapStrategyNumber: + case RTContainedByStrategyNumber: + /* at least one element in check[] is true, so result = true */ + + res = TRUE; + break; + case RTSameStrategyNumber: + case RTContainsStrategyNumber: + res = TRUE; + do { + ArrayType *query = PG_GETARG_ARRAYTYPE_P(2); + int i, nentries=ARRNELEMS(query); + + for(i=0;i