diff -uNr intarray/Makefile ../../../SOURCES/intarray/Makefile --- intarray/Makefile Sun Mar 18 18:35:18 2001 +++ ../../../SOURCES/intarray/Makefile Wed May 30 07:51:45 2001 @@ -12,7 +12,7 @@ SO_MAJOR_VERSION= 1 SO_MINOR_VERSION= 0 -override CPPFLAGS := -I$(srcdir) $(CPPFLAGS) -DPGSQL71 +override CPPFLAGS := -I$(srcdir) $(CPPFLAGS) OBJS= _int.o diff -uNr intarray/README.intarray ../../../SOURCES/intarray/README.intarray --- intarray/README.intarray Mon Mar 19 22:08:12 2001 +++ ../../../SOURCES/intarray/README.intarray Fri Jun 1 12:34:45 2001 @@ -10,7 +10,18 @@ (oleg@sai.msu.su). See http://www.sai.msu.su/~megera/postgres/gist for additional information. +ATTENTION: + + This version is only for PostgreSQL v. 7.1.X ! + CHANGES: + +Jun 1, 2001 + 1. Fixed small bug in handling NULL values + +May 31, 2001 + 1. Support for new interface of function calling (7.1 and above) + 2. Optimization for gist__intbig_ops (special treating of degenerated signatures) March 19, 2001 1. Added support for toastable keys diff -uNr intarray/_int.c ../../../SOURCES/intarray/_int.c --- intarray/_int.c Thu Mar 22 10:24:12 2001 +++ ../../../SOURCES/intarray/_int.c Fri Jun 1 11:26:22 2001 @@ -34,24 +34,20 @@ /* useful macros for accessing int4 arrays */ #define ARRPTR(x) ( (int4 *) ARR_DATA_PTR(x) ) -#ifdef PGSQL71 #define ARRNELEMS(x) ArrayGetNItems( ARR_NDIM(x), ARR_DIMS(x)) -#else -#define ARRNELEMS(x) getNitems( ARR_NDIM(x), ARR_DIMS(x)) -#endif #define ARRISNULL(x) ( (x) ? ( ( ARR_NDIM(x) == NDIM ) ? ( ( ARRNELEMS( x ) ) ? 0 : 1 ) : 1 ) : 1 ) #define SORT(x) \ do { \ if ( ARRNELEMS( x ) > 1 ) \ - isort( (void*)ARRPTR( x ), ARRNELEMS( x ) ); \ + isort( ARRPTR( x ), ARRNELEMS( x ) ); \ } while(0) #define PREPAREARR(x) \ do { \ if ( ARRNELEMS( x ) > 1 ) \ - if ( isort( (void*)ARRPTR( x ), ARRNELEMS( x ) ) ) \ + if ( isort( ARRPTR( x ), ARRNELEMS( x ) ) ) \ x = _int_unique( x ); \ } while(0) @@ -130,7 +126,7 @@ /* ** usefull function */ -static bool isort(int *a, const int len); +static bool isort(int4 *a, const int len); static ArrayType *new_intArrayType(int num); static ArrayType *copy_intArrayType(ArrayType *a); static ArrayType *resize_intArrayType(ArrayType *a, int num); @@ -156,48 +152,72 @@ /* ** GiST support methods */ -bool g_int_consistent(GISTENTRY *entry, ArrayType *query, StrategyNumber strategy); -GISTENTRY *g_int_compress(GISTENTRY *entry); -GISTENTRY *g_int_decompress(GISTENTRY *entry); -float *g_int_penalty(GISTENTRY *origentry, GISTENTRY *newentry, float *result); -GIST_SPLITVEC *g_int_picksplit(bytea *entryvec, GIST_SPLITVEC *v); -ArrayType *g_int_union(bytea *entryvec, int *sizep); -bool *g_int_same(ArrayType *b1, ArrayType *b2, bool *result); +PG_FUNCTION_INFO_V1( g_int_consistent ); +PG_FUNCTION_INFO_V1( g_int_compress ); +PG_FUNCTION_INFO_V1( g_int_decompress ); +PG_FUNCTION_INFO_V1( g_int_penalty ); +PG_FUNCTION_INFO_V1( g_int_picksplit ); +PG_FUNCTION_INFO_V1( g_int_union ); +PG_FUNCTION_INFO_V1( g_int_same ); + +Datum g_int_consistent(PG_FUNCTION_ARGS); +Datum g_int_compress(PG_FUNCTION_ARGS); +Datum g_int_decompress(PG_FUNCTION_ARGS); +Datum g_int_penalty(PG_FUNCTION_ARGS); +Datum g_int_picksplit(PG_FUNCTION_ARGS); +Datum g_int_union(PG_FUNCTION_ARGS); +Datum g_int_same(PG_FUNCTION_ARGS); /* ** R-tree support functions */ -bool inner_int_contains(ArrayType *a, ArrayType *b); -bool inner_int_overlap(ArrayType *a, ArrayType *b); -ArrayType *inner_int_union(ArrayType *a, ArrayType *b); -ArrayType *inner_int_inter(ArrayType *a, ArrayType *b); - -bool _int_different(ArrayType *a, ArrayType *b); -bool _int_same(ArrayType *a, ArrayType *b); -bool _int_contains(ArrayType *a, ArrayType *b); -bool _int_contained(ArrayType *a, ArrayType *b); -bool _int_overlap(ArrayType *a, ArrayType *b); -ArrayType *_int_union(ArrayType *a, ArrayType *b); -ArrayType *_int_inter(ArrayType *a, ArrayType *b); -void rt__int_size(ArrayType *a, float *sz); +static bool inner_int_contains(ArrayType *a, ArrayType *b); +static bool inner_int_overlap(ArrayType *a, ArrayType *b); +static ArrayType *inner_int_union(ArrayType *a, ArrayType *b); +static ArrayType *inner_int_inter(ArrayType *a, ArrayType *b); +static void rt__int_size(ArrayType *a, float *sz); + +PG_FUNCTION_INFO_V1( _int_different ); +PG_FUNCTION_INFO_V1( _int_same ); +PG_FUNCTION_INFO_V1( _int_contains ); +PG_FUNCTION_INFO_V1( _int_contained ); +PG_FUNCTION_INFO_V1( _int_overlap ); +PG_FUNCTION_INFO_V1( _int_union ); +PG_FUNCTION_INFO_V1( _int_inter ); + +Datum _int_different(PG_FUNCTION_ARGS); +Datum _int_same(PG_FUNCTION_ARGS); +Datum _int_contains(PG_FUNCTION_ARGS); +Datum _int_contained(PG_FUNCTION_ARGS); +Datum _int_overlap(PG_FUNCTION_ARGS); +Datum _int_union(PG_FUNCTION_ARGS); +Datum _int_inter(PG_FUNCTION_ARGS); /* ** _intbig methods */ -bool g_intbig_consistent(GISTENTRY *entry, ArrayType *query, StrategyNumber strategy); -GISTENTRY *g_intbig_compress(GISTENTRY *entry); -GISTENTRY *g_intbig_decompress(GISTENTRY *entry); -float *g_intbig_penalty(GISTENTRY *origentry, GISTENTRY *newentry, float *result); -GIST_SPLITVEC *g_intbig_picksplit(bytea *entryvec, GIST_SPLITVEC *v); -ArrayType *g_intbig_union(bytea *entryvec, int *sizep); -bool *g_intbig_same(ArrayType *a, ArrayType *b, bool *result); +PG_FUNCTION_INFO_V1( g_intbig_consistent ); +PG_FUNCTION_INFO_V1( g_intbig_compress ); +PG_FUNCTION_INFO_V1( g_intbig_decompress ); +PG_FUNCTION_INFO_V1( g_intbig_penalty ); +PG_FUNCTION_INFO_V1( g_intbig_picksplit ); +PG_FUNCTION_INFO_V1( g_intbig_union ); +PG_FUNCTION_INFO_V1( g_intbig_same ); + +Datum g_intbig_consistent(PG_FUNCTION_ARGS); +Datum g_intbig_compress(PG_FUNCTION_ARGS); +Datum g_intbig_decompress(PG_FUNCTION_ARGS); +Datum g_intbig_penalty(PG_FUNCTION_ARGS); +Datum g_intbig_picksplit(PG_FUNCTION_ARGS); +Datum g_intbig_union(PG_FUNCTION_ARGS); +Datum g_intbig_same(PG_FUNCTION_ARGS); static bool _intbig_contains(ArrayType *a, ArrayType *b); static bool _intbig_overlap(ArrayType *a, ArrayType *b); static ArrayType *_intbig_union(ArrayType *a, ArrayType *b); -/*static ArrayType * _intbig_inter(ArrayType *a, ArrayType *b);*/ +static ArrayType * _intbig_inter(ArrayType *a, ArrayType *b); static void rt__intbig_size(ArrayType *a, float *sz); static void gensign(BITVEC sign, int *a, int len); @@ -211,11 +231,11 @@ ** the predicate x op query == FALSE, where op is the oper ** corresponding to strategy in the pg_amop table. */ -bool -g_int_consistent(GISTENTRY *entry, - ArrayType *query, - StrategyNumber strategy) -{ +Datum +g_int_consistent(PG_FUNCTION_ARGS) { + GISTENTRY *entry = (GISTENTRY *)PG_GETARG_POINTER(0); + ArrayType *query = ( ArrayType * )PG_GETARG_POINTER(1); + StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2); bool retval; /* sort query for fast search, key is already sorted */ @@ -228,33 +248,38 @@ switch (strategy) { case RTOverlapStrategyNumber: - retval = (bool) inner_int_overlap((ArrayType *) (entry->pred), query); + retval = inner_int_overlap((ArrayType *) DatumGetPointer(entry->pred), query); break; case RTSameStrategyNumber: case RTContainsStrategyNumber: - retval = (bool) inner_int_contains((ArrayType *) (entry->pred), query); + retval = inner_int_contains((ArrayType *) DatumGetPointer(entry->pred), query); break; case RTContainedByStrategyNumber: - retval = (bool) inner_int_overlap((ArrayType *) (entry->pred), query); + retval = inner_int_overlap((ArrayType *) DatumGetPointer(entry->pred), query); break; default: retval = FALSE; } - return (retval); + PG_RETURN_BOOL(retval); } -ArrayType * -g_int_union(bytea *entryvec, int *sizep) +Datum +g_int_union(PG_FUNCTION_ARGS) { - return _int_common_union(entryvec, sizep, inner_int_union); + PG_RETURN_POINTER( _int_common_union( + (bytea *) PG_GETARG_POINTER(0), + (int *) PG_GETARG_POINTER(1), + inner_int_union + ) ); } /* ** GiST Compress and Decompress methods */ -GISTENTRY * -g_int_compress(GISTENTRY *entry) +Datum +g_int_compress(PG_FUNCTION_ARGS) { + GISTENTRY *entry = (GISTENTRY *)PG_GETARG_POINTER(0); GISTENTRY *retval; ArrayType *r; int len; @@ -265,14 +290,10 @@ retval = palloc(sizeof(GISTENTRY)); -#ifdef PGSQL71 - if (entry->pred) + if (DatumGetPointer(entry->pred) != NULL) r = (ArrayType *) PG_DETOAST_DATUM_COPY(entry->pred); else r = NULL; -#else - r = copy_intArrayType((ArrayType *) entry->pred); -#endif if (ARRISNULL(r)) { @@ -280,12 +301,12 @@ elog(NOTICE, "COMP IN: NULL"); #endif if (r) - if ((char *) r != (char *) entry->pred) + if ( r != (ArrayType *) DatumGetPointer(entry->pred) ) pfree(r); - gistentryinit(*retval, (char *) NULL, entry->rel, entry->page, entry->offset, + gistentryinit(*retval, NULL, entry->rel, entry->page, entry->offset, 0, FALSE); - return (retval); + PG_RETURN_POINTER(retval); } if (entry->leafkey) @@ -322,14 +343,15 @@ r = resize_intArrayType(r, len); } - gistentryinit(*retval, (char *) r, entry->rel, entry->page, entry->offset, VARSIZE(r), FALSE); + gistentryinit(*retval, (char*)(r), entry->rel, entry->page, entry->offset, VARSIZE(r), FALSE); - return (retval); + PG_RETURN_POINTER(retval); } -GISTENTRY * -g_int_decompress(GISTENTRY *entry) +Datum +g_int_decompress(PG_FUNCTION_ARGS) { + GISTENTRY *entry = (GISTENTRY *)PG_GETARG_POINTER(0); GISTENTRY *retval; ArrayType *r; int *dr, @@ -340,29 +362,23 @@ int i, j; -#ifdef PGSQL71 - if (entry->pred) + if (DatumGetPointer(entry->pred) != NULL) in = (ArrayType *) PG_DETOAST_DATUM(entry->pred); else in = NULL; -#else - in = (ArrayType *) entry->pred; -#endif if (entry->bytes < ARR_OVERHEAD(NDIM) || ARRISNULL(in)) { retval = palloc(sizeof(GISTENTRY)); -#ifdef PGSQL71 if (in) - if ((char *) in != (char *) entry->pred) + if (in != (ArrayType *) DatumGetPointer(entry->pred)) pfree(in); -#endif - gistentryinit(*retval, (char *) NULL, entry->rel, entry->page, entry->offset, 0, FALSE); + gistentryinit(*retval, NULL, entry->rel, entry->page, entry->offset, 0, FALSE); #ifdef GIST_DEBUG elog(NOTICE, "DECOMP IN: NULL"); #endif - return (retval); + PG_RETURN_POINTER(retval); } @@ -372,8 +388,8 @@ if (lenin < 2 * MAXNUMRANGE) { /* not comressed value */ /* sometimes strange bytesize */ - gistentryinit(*entry, (char *) in, entry->rel, entry->page, entry->offset, VARSIZE(in), FALSE); - return (entry); + gistentryinit(*entry, (char*)(in), entry->rel, entry->page, entry->offset, VARSIZE(in), FALSE); + PG_RETURN_POINTER(entry); } #ifdef GIST_DEBUG @@ -390,36 +406,41 @@ if ((!i) || *(dr - 1) != j) *dr++ = j; -#ifdef PGSQL71 - if ((char *) in != (char *) entry->pred) + if (in != (ArrayType *) DatumGetPointer(entry->pred)) pfree(in); -#endif retval = palloc(sizeof(GISTENTRY)); - gistentryinit(*retval, (char *) r, entry->rel, entry->page, entry->offset, VARSIZE(r), FALSE); + gistentryinit(*retval, (char*)(r), entry->rel, entry->page, entry->offset, VARSIZE(r), FALSE); - return (retval); + PG_RETURN_POINTER(retval); } /* ** The GiST Penalty method for _intments */ -float * -g_int_penalty(GISTENTRY *origentry, GISTENTRY *newentry, float *result) +Datum +g_int_penalty(PG_FUNCTION_ARGS) { - return _int_common_penalty(origentry, newentry, result, inner_int_union, rt__int_size); + PG_RETURN_POINTER( _int_common_penalty( + (GISTENTRY *)PG_GETARG_POINTER(0), + (GISTENTRY *)PG_GETARG_POINTER(1), + (float *) PG_GETARG_POINTER(2), + inner_int_union, rt__int_size + ) ); } -GIST_SPLITVEC * -g_int_picksplit(bytea *entryvec, - GIST_SPLITVEC *v) -{ - return _int_common_picksplit(entryvec, v, - inner_int_union, - inner_int_inter, - rt__int_size, - 1e-8); +Datum +g_int_picksplit(PG_FUNCTION_ARGS) +{ + PG_RETURN_POINTER( _int_common_picksplit( + (bytea *)PG_GETARG_POINTER(0), + (GIST_SPLITVEC *)PG_GETARG_POINTER(1), + inner_int_union, + inner_int_inter, + rt__int_size, + 1e-8 + ) ); } /* @@ -427,26 +448,38 @@ */ -bool * -g_int_same(ArrayType *b1, ArrayType *b2, bool *result) +Datum +g_int_same(PG_FUNCTION_ARGS) { - if (_int_same(b1, b2)) - *result = TRUE; - else - *result = FALSE; + bool *result = (bool *)PG_GETARG_POINTER(2); + *result = DatumGetBool( + DirectFunctionCall2( + _int_same, + PointerGetDatum(PG_GETARG_POINTER(0)), + PointerGetDatum(PG_GETARG_POINTER(1)) + ) + ); - return (result); + PG_RETURN_POINTER(result); } -bool -_int_contained(ArrayType *a, ArrayType *b) +Datum +_int_contained(PG_FUNCTION_ARGS) { - return (_int_contains(b, a)); + PG_RETURN_BOOL( DatumGetBool( + DirectFunctionCall2( + _int_contains, + PointerGetDatum(PG_GETARG_POINTER(1)), + PointerGetDatum(PG_GETARG_POINTER(0)) + ) + )); } -bool -_int_contains(ArrayType *a, ArrayType *b) +Datum +_int_contains(PG_FUNCTION_ARGS) { + ArrayType *a = (ArrayType *)PG_GETARG_POINTER(0); + ArrayType *b = (ArrayType *)PG_GETARG_POINTER(1); bool res; ArrayType *an, *bn; @@ -463,10 +496,10 @@ res = inner_int_contains(an, bn); pfree(an); pfree(bn); - return res; + PG_RETURN_BOOL( res ); } -bool +static bool inner_int_contains(ArrayType *a, ArrayType *b) { int na, @@ -509,15 +542,23 @@ * Operator class for R-tree indexing *****************************************************************************/ -bool -_int_different(ArrayType *a, ArrayType *b) +Datum +_int_different(PG_FUNCTION_ARGS) { - return (!_int_same(a, b)); + PG_RETURN_BOOL( ! DatumGetBool( + DirectFunctionCall2( + _int_same, + PointerGetDatum(PG_GETARG_POINTER(0)), + PointerGetDatum(PG_GETARG_POINTER(1)) + ) + )); } -bool -_int_same(ArrayType *a, ArrayType *b) +Datum +_int_same(PG_FUNCTION_ARGS) { + ArrayType *a = (ArrayType *)PG_GETARG_POINTER(0); + ArrayType *b = (ArrayType *)PG_GETARG_POINTER(1); int na, nb; int n; @@ -558,14 +599,16 @@ pfree(an); pfree(bn); - return result; + PG_RETURN_BOOL(result); } /* _int_overlap -- does a overlap b? */ -bool -_int_overlap(ArrayType *a, ArrayType *b) +Datum +_int_overlap(PG_FUNCTION_ARGS) { + ArrayType *a = (ArrayType *)PG_GETARG_POINTER(0); + ArrayType *b = (ArrayType *)PG_GETARG_POINTER(1); bool result; ArrayType *an, *bn; @@ -584,10 +627,10 @@ pfree(an); pfree(bn); - return result; + PG_RETURN_BOOL( result ); } -bool +static bool inner_int_overlap(ArrayType *a, ArrayType *b) { int na, @@ -621,9 +664,11 @@ return FALSE; } -ArrayType * -_int_union(ArrayType *a, ArrayType *b) +Datum +_int_union(PG_FUNCTION_ARGS) { + ArrayType *a = (ArrayType *)PG_GETARG_POINTER(0); + ArrayType *b = (ArrayType *)PG_GETARG_POINTER(1); ArrayType *result; ArrayType *an, *bn; @@ -643,10 +688,10 @@ if (bn) pfree(bn); - return result; + PG_RETURN_POINTER( result ); } -ArrayType * +static ArrayType * inner_int_union(ArrayType *a, ArrayType *b) { ArrayType *r = NULL; @@ -703,15 +748,17 @@ } -ArrayType * -_int_inter(ArrayType *a, ArrayType *b) +Datum +_int_inter(PG_FUNCTION_ARGS) { + ArrayType *a = (ArrayType *)PG_GETARG_POINTER(0); + ArrayType *b = (ArrayType *)PG_GETARG_POINTER(1); ArrayType *result; ArrayType *an, *bn; if (ARRISNULL(a) || ARRISNULL(b)) - return new_intArrayType(0); + PG_RETURN_POINTER(new_intArrayType(0)); an = copy_intArrayType(a); bn = copy_intArrayType(b); @@ -724,10 +771,10 @@ pfree(an); pfree(bn); - return result; + PG_RETURN_POINTER( result ); } -ArrayType * +static ArrayType * inner_int_inter(ArrayType *a, ArrayType *b) { ArrayType *r; @@ -776,7 +823,7 @@ return resize_intArrayType(r, dr - ARRPTR(r)); } -void +static void rt__int_size(ArrayType *a, float *size) { if (ARRISNULL(a)) @@ -794,11 +841,11 @@ /* len >= 2 */ static bool -isort(int *a, int len) +isort(int4 *a, int len) { - int tmp, + int4 tmp, index; - int *cur, + int4 *cur, *end; bool r = FALSE; @@ -835,9 +882,6 @@ MemSet(r, 0, nbytes); r->size = nbytes; r->ndim = NDIM; -#ifndef PGSQL71 - SET_LO_FLAG(false, r); -#endif *((int *) ARR_DIMS(r)) = num; *((int *) ARR_LBOUND(r)) = 1; @@ -1021,9 +1065,12 @@ return r; } -bool * -g_intbig_same(ArrayType *a, ArrayType *b, bool *result) +Datum +g_intbig_same(PG_FUNCTION_ARGS) { + ArrayType *a = (ArrayType *)PG_GETARG_POINTER(0); + ArrayType *b = (ArrayType *)PG_GETARG_POINTER(1); + bool *result = (bool *)PG_GETARG_POINTER(2); BITVECP da, db; int i; @@ -1031,7 +1078,7 @@ if (ARRISNULL(a) || ARRISNULL(b)) { *result = (ARRISNULL(a) && ARRISNULL(b)) ? TRUE : FALSE; - return result; + PG_RETURN_POINTER( result ); } da = SIGPTR(a); @@ -1041,44 +1088,56 @@ if (da[i] != db[i]) { *result = FALSE; - return result; + PG_RETURN_POINTER( result ); } ); *result = TRUE; - return result; + PG_RETURN_POINTER( result ); } -GISTENTRY * -g_intbig_compress(GISTENTRY *entry) +Datum +g_intbig_compress(PG_FUNCTION_ARGS) { + GISTENTRY *entry = (GISTENTRY *)PG_GETARG_POINTER(0); GISTENTRY *retval; ArrayType *r, *in; + bool maycompress = true; + int i; -#ifdef PGSQL71 - if (entry->pred) + if (DatumGetPointer(entry->pred) != NULL) in = (ArrayType *) PG_DETOAST_DATUM(entry->pred); else in = NULL; -#else - in = (ArrayType *) entry->pred; -#endif - if (!entry->leafkey) - return entry; + if (!entry->leafkey) { + if ( ! ARRISNULL(in) ) { + LOOPBYTE( + if ( ( ((char*)ARRPTR(in))[i] & 0xff ) != 0xff ) { + maycompress = false; + break; + } + ); + if ( maycompress ) { + retval = palloc(sizeof(GISTENTRY)); + r = new_intArrayType(1); + gistentryinit(*retval, (char*)(r), entry->rel, entry->page, entry->offset, VARSIZE(r), FALSE); + PG_RETURN_POINTER( retval ); + } + } + PG_RETURN_POINTER( entry ); + } retval = palloc(sizeof(GISTENTRY)); if (ARRISNULL(in)) { -#ifdef PGSQL71 if (in) - if ((char *) in != (char *) entry->pred) + if (in != (ArrayType *) DatumGetPointer(entry->pred)) pfree(in); -#endif - gistentryinit(*retval, (char *) NULL, entry->rel, entry->page, entry->offset, 0, FALSE); - return (retval); + gistentryinit(*retval, NULL, entry->rel, entry->page, entry->offset, 0, FALSE); + PG_RETURN_POINTER (retval); } r = new_intArrayType(SIGLENINT); @@ -1086,64 +1145,101 @@ ARRPTR(in), ARRNELEMS(in)); - gistentryinit(*retval, (char *) r, entry->rel, entry->page, entry->offset, VARSIZE(r), FALSE); + LOOPBYTE( + if( ( ((char*)ARRPTR(in))[i] & 0xff ) != 0xff ) { + maycompress = false; + break; + } + ); + + if ( maycompress ) { + pfree(r); + r = new_intArrayType(1); + } + + gistentryinit(*retval, (char*)(r), entry->rel, entry->page, entry->offset, VARSIZE(r), FALSE); -#ifdef PGSQL71 if (in) - if ((char *) in != (char *) entry->pred) + if ( in != (ArrayType *) DatumGetPointer(entry->pred)) pfree(in); -#endif - return (retval); + PG_RETURN_POINTER (retval); } -GISTENTRY * -g_intbig_decompress(GISTENTRY *entry) +Datum +g_intbig_decompress(PG_FUNCTION_ARGS) { -#ifdef PGSQL71 + GISTENTRY *entry = (GISTENTRY *)PG_GETARG_POINTER(0); ArrayType *key; - key = (ArrayType *) PG_DETOAST_DATUM(entry->pred); - if ((char *) key != (char *) entry->pred) + if ( DatumGetPointer(entry->pred) != NULL ) + key = (ArrayType *) PG_DETOAST_DATUM(entry->pred); + else + key = NULL; + + if ( key != (ArrayType *) DatumGetPointer(entry->pred)) { GISTENTRY *retval; retval = palloc(sizeof(GISTENTRY)); - gistentryinit(*retval, (char *) key, entry->rel, entry->page, entry->offset, VARSIZE(key), FALSE); - return retval; + gistentryinit(*retval, (char*)(key), entry->rel, entry->page, entry->offset, (key) ? VARSIZE(key) : 0, FALSE); + PG_RETURN_POINTER( retval ); } -#endif - return entry; + if ( ! ARRISNULL(key) ) + if ( ARRNELEMS(key) == 1 ) { + GISTENTRY *retval; + ArrayType *newkey; + + retval = palloc(sizeof(GISTENTRY)); + newkey = new_intArrayType(SIGLENINT); + MemSet( (void*)ARRPTR(newkey), 0xff, SIGLEN ); + + gistentryinit(*retval, (char*)(newkey), entry->rel, entry->page, entry->offset, VARSIZE(newkey), FALSE); + PG_RETURN_POINTER( retval ); + } + PG_RETURN_POINTER( entry ); } -GIST_SPLITVEC * -g_intbig_picksplit(bytea *entryvec, GIST_SPLITVEC *v) +Datum +g_intbig_picksplit(PG_FUNCTION_ARGS) { - return _int_common_picksplit(entryvec, v, - _intbig_union, - _intbig_inter, - rt__intbig_size, - 1.0); - + PG_RETURN_POINTER( _int_common_picksplit( + (bytea *)PG_GETARG_POINTER(0), + (GIST_SPLITVEC *)PG_GETARG_POINTER(1), + _intbig_union, + _intbig_inter, + rt__intbig_size, + 1.0 + ) ); } -ArrayType * -g_intbig_union(bytea *entryvec, int *sizep) +Datum +g_intbig_union(PG_FUNCTION_ARGS) { - return _int_common_union(entryvec, sizep, _intbig_union); + PG_RETURN_POINTER( _int_common_union( + (bytea *) PG_GETARG_POINTER(0), + (int *) PG_GETARG_POINTER(1), + _intbig_union + ) ); } -float * -g_intbig_penalty(GISTENTRY *origentry, GISTENTRY *newentry, float *result) +Datum +g_intbig_penalty(PG_FUNCTION_ARGS) { - _int_common_penalty(origentry, newentry, result, _intbig_union, rt__intbig_size); - return result; + PG_RETURN_POINTER( _int_common_penalty( + (GISTENTRY *)PG_GETARG_POINTER(0), + (GISTENTRY *)PG_GETARG_POINTER(1), + (float *) PG_GETARG_POINTER(2), + _intbig_union, rt__intbig_size + ) ); } -bool -g_intbig_consistent(GISTENTRY *entry, ArrayType *query, StrategyNumber strategy) -{ +Datum +g_intbig_consistent(PG_FUNCTION_ARGS) { + GISTENTRY *entry = (GISTENTRY *)PG_GETARG_POINTER(0); + ArrayType *query = ( ArrayType * )PG_GETARG_POINTER(1); + StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2); bool retval; ArrayType *q; @@ -1159,20 +1255,20 @@ switch (strategy) { case RTOverlapStrategyNumber: - retval = (bool) _intbig_overlap((ArrayType *) (entry->pred), q); + retval = _intbig_overlap((ArrayType *) DatumGetPointer(entry->pred), q); break; case RTSameStrategyNumber: case RTContainsStrategyNumber: - retval = (bool) _intbig_contains((ArrayType *) (entry->pred), q); + retval = _intbig_contains((ArrayType *) DatumGetPointer(entry->pred), q); break; case RTContainedByStrategyNumber: - retval = (bool) _intbig_overlap((ArrayType *) (entry->pred), q); + retval = _intbig_overlap((ArrayType *) DatumGetPointer(entry->pred), q); break; default: retval = FALSE; } pfree(q); - return (retval); + PG_RETURN_BOOL(retval); } /***************************************************************** @@ -1183,7 +1279,7 @@ ** The GiST Union method for _intments ** returns the minimal set that encloses all the entries in entryvec */ -ArrayType * +static ArrayType * _int_common_union(bytea *entryvec, int *sizep, formarray unionf) { int numranges, @@ -1196,12 +1292,12 @@ #endif numranges = (VARSIZE(entryvec) - VARHDRSZ) / sizeof(GISTENTRY); - tmp = (ArrayType *) (((GISTENTRY *) (VARDATA(entryvec)))[0]).pred; + tmp = (ArrayType *) DatumGetPointer(((GISTENTRY *) (VARDATA(entryvec)))[0].pred); for (i = 1; i < numranges; i++) { out = (*unionf) (tmp, (ArrayType *) - (((GISTENTRY *) (VARDATA(entryvec)))[i]).pred); + DatumGetPointer(((GISTENTRY *) (VARDATA(entryvec)))[i].pred) ); if (i > 1 && tmp) pfree(tmp); tmp = out; @@ -1227,7 +1323,7 @@ * The GiST Penalty method for _intments * *****************************************/ -float * +static float * _int_common_penalty(GISTENTRY *origentry, GISTENTRY *newentry, float *result, formarray unionf, formfloat sizef) @@ -1239,9 +1335,10 @@ #ifdef GIST_DEBUG elog(NOTICE, "penalty"); #endif - ud = (Datum) (*unionf) ((ArrayType *) (origentry->pred), (ArrayType *) (newentry->pred)); + ud = (Datum) (*unionf) ((ArrayType *) DatumGetPointer(origentry->pred), + (ArrayType *) DatumGetPointer(newentry->pred)); (*sizef) ((ArrayType *) ud, &tmp1); - (*sizef) ((ArrayType *) (origentry->pred), &tmp2); + (*sizef) ((ArrayType *) DatumGetPointer(origentry->pred), &tmp2); *result = tmp1 - tmp2; pfree((char *) ud); @@ -1256,7 +1353,7 @@ ** The GiST PickSplit method for _intments ** We use Guttman's poly time split algorithm */ -GIST_SPLITVEC * +static GIST_SPLITVEC * _int_common_picksplit(bytea *entryvec, GIST_SPLITVEC *v, formarray unionf, @@ -1304,10 +1401,10 @@ for (i = FirstOffsetNumber; i < maxoff; i = OffsetNumberNext(i)) { - datum_alpha = (ArrayType *) (((GISTENTRY *) (VARDATA(entryvec)))[i].pred); + datum_alpha = (ArrayType *) DatumGetPointer(((GISTENTRY *) VARDATA(entryvec))[i].pred); for (j = OffsetNumberNext(i); j <= maxoff; j = OffsetNumberNext(j)) { - datum_beta = (ArrayType *) (((GISTENTRY *) (VARDATA(entryvec)))[j].pred); + datum_beta = (ArrayType *) DatumGetPointer(((GISTENTRY *) VARDATA(entryvec))[j].pred); /* compute the wasted space by unioning these guys */ /* size_waste = size_union - size_inter; */ @@ -1342,10 +1439,10 @@ right = v->spl_right; v->spl_nright = 0; - datum_alpha = (ArrayType *) (((GISTENTRY *) (VARDATA(entryvec)))[seed_1].pred); + datum_alpha = (ArrayType *) DatumGetPointer(((GISTENTRY *) VARDATA(entryvec))[seed_1].pred); datum_l = copy_intArrayType(datum_alpha); (*sizef) ((ArrayType *) datum_l, &size_l); - datum_beta = (ArrayType *) (((GISTENTRY *) (VARDATA(entryvec)))[seed_2].pred); + datum_beta = (ArrayType *) DatumGetPointer(((GISTENTRY *) VARDATA(entryvec))[seed_2].pred); datum_r = copy_intArrayType(datum_beta); (*sizef) ((ArrayType *) datum_r, &size_r); @@ -1386,7 +1483,7 @@ } /* okay, which page needs least enlargement? */ - datum_alpha = (ArrayType *) (((GISTENTRY *) (VARDATA(entryvec)))[i].pred); + datum_alpha = (ArrayType *) DatumGetPointer(((GISTENTRY *) VARDATA(entryvec))[i].pred); union_dl = (ArrayType *) (*unionf) (datum_l, datum_alpha); union_dr = (ArrayType *) (*unionf) (datum_r, datum_alpha); (*sizef) ((ArrayType *) union_dl, &size_alpha); @@ -1428,8 +1525,8 @@ *(right - 1) = InvalidOffsetNumber; } - v->spl_ldatum = (char *) datum_l; - v->spl_rdatum = (char *) datum_r; + v->spl_ldatum = (char*)PointerGetDatum(datum_l); + v->spl_rdatum = (char*)PointerGetDatum(datum_r); #ifdef GIST_DEBUG elog(NOTICE, "--------ENDpicksplit %d %d", v->spl_nleft, v->spl_nright);