aboutsummaryrefslogtreecommitdiff
path: root/contrib/btree_gist/btree_utils_num.c
diff options
context:
space:
mode:
authorTeodor Sigaev <teodor@sigaev.ru>2004-05-28 10:43:32 +0000
committerTeodor Sigaev <teodor@sigaev.ru>2004-05-28 10:43:32 +0000
commit42d069886f38687839388c615af608706508b557 (patch)
tree0409615407a17d22e2511ac14745277467853453 /contrib/btree_gist/btree_utils_num.c
parent1a321f26d88e5c64bccba9d36920aede1e201729 (diff)
downloadpostgresql-42d069886f38687839388c615af608706508b557.tar.gz
postgresql-42d069886f38687839388c615af608706508b557.zip
New version. Add support for int2, int8, float4, float8, timestamp with/without time zone, time with/without time zone, date, interval, oid, money and macaddr, char, varchar/text, bytea, numeric, bit, varbit, inet/cidr types for GiST
Diffstat (limited to 'contrib/btree_gist/btree_utils_num.c')
-rw-r--r--contrib/btree_gist/btree_utils_num.c255
1 files changed, 255 insertions, 0 deletions
diff --git a/contrib/btree_gist/btree_utils_num.c b/contrib/btree_gist/btree_utils_num.c
new file mode 100644
index 00000000000..80fccbaef05
--- /dev/null
+++ b/contrib/btree_gist/btree_utils_num.c
@@ -0,0 +1,255 @@
+#include "btree_gist.h"
+#include "btree_utils_num.h"
+#include "utils/date.h"
+
+extern GISTENTRY *
+gbt_num_compress( GISTENTRY *retval , GISTENTRY *entry , const gbtree_ninfo * tinfo )
+{
+
+ if (entry->leafkey)
+ {
+
+ union {
+ int16 i2;
+ int32 i4;
+ TimeADT ts;
+ DateADT dt;
+ } v ;
+
+ GBT_NUMKEY *r = ( GBT_NUMKEY * ) palloc(2 * tinfo->size);
+ void *leaf = NULL;
+
+ switch ( tinfo->t )
+ {
+ case gbt_t_int2 :
+ v.i2 = DatumGetInt16(entry->key);
+ leaf = &v.i2;
+ break;
+ case gbt_t_int4 :
+ v.i4 = DatumGetInt32(entry->key);
+ leaf = &v.i4;
+ break;
+ case gbt_t_oid :
+ v.i4 = DatumGetObjectId(entry->key);
+ leaf = &v.i4;
+ break;
+ case gbt_t_time :
+ v.ts = DatumGetTimeADT(entry->key);
+ leaf = &v.ts;
+ break;
+ case gbt_t_date :
+ v.dt = DatumGetDateADT(entry->key);
+ leaf = &v.dt;
+ break;
+ default :
+ leaf = DatumGetPointer(entry->key);
+ }
+
+ memcpy ( (void*) &r[0] , leaf, tinfo->size );
+ memcpy ( (void*) &r[tinfo->size] , leaf, tinfo->size );
+
+ retval = palloc(sizeof(GISTENTRY));
+ gistentryinit(*retval, PointerGetDatum(r), entry->rel, entry->page,
+ entry->offset,( 2 * tinfo->size), FALSE);
+ } else
+ retval = entry;
+
+ return retval;
+}
+
+
+
+
+/*
+** The GiST union method for numerical values
+*/
+
+extern void *
+gbt_num_union( GBT_NUMKEY * out, const GistEntryVector * entryvec, const gbtree_ninfo * tinfo )
+{
+ int i,
+ numranges;
+ GBT_NUMKEY * cur ;
+ GBT_NUMKEY_R o, c;
+
+ numranges = entryvec->n;
+ cur = (GBT_NUMKEY *) DatumGetPointer((entryvec->vector[0].key));
+
+
+ o.lower = &((GBT_NUMKEY *)out)[0];
+ o.upper = &((GBT_NUMKEY *)out)[tinfo->size];
+
+ memcpy( (void*)out, (void*) cur, 2*tinfo->size );
+
+ for (i = 1; i < numranges; i++)
+ {
+ cur = (GBT_NUMKEY *) DatumGetPointer((entryvec->vector[i].key));
+ c.lower = &cur[0];
+ c.upper = &cur[tinfo->size];
+
+ if ( (*tinfo->f_gt)(o.lower, c.lower) ) /* out->lower > cur->lower */
+ memcpy( (void* ) o.lower, (void*) c.lower, tinfo->size );
+ if ( (*tinfo->f_lt)(o.upper, c.upper) ) /* out->upper < cur->upper */
+ memcpy( (void*) o.upper, (void*) c.upper, tinfo->size );
+ }
+
+ return out;
+}
+
+
+
+/*
+** The GiST same method for numerical values
+*/
+
+extern bool gbt_num_same ( const GBT_NUMKEY * a, const GBT_NUMKEY * b, const gbtree_ninfo * tinfo )
+{
+
+ GBT_NUMKEY_R b1, b2 ;
+
+ b1.lower = &(((GBT_NUMKEY *)a)[0]);
+ b1.upper = &(((GBT_NUMKEY *)a)[tinfo->size]);
+ b2.lower = &(((GBT_NUMKEY *)b)[0]);
+ b2.upper = &(((GBT_NUMKEY *)b)[tinfo->size]);
+
+ if (
+ (*tinfo->f_eq)( b1.lower, b2.lower) &&
+ (*tinfo->f_eq)( b1.upper, b2.upper)
+ )
+ return TRUE;
+ return FALSE;
+
+}
+
+
+extern void
+gbt_num_bin_union(Datum * u , GBT_NUMKEY * e , const gbtree_ninfo * tinfo )
+{
+
+ GBT_NUMKEY_R rd;
+ rd.lower = &e[0];
+ rd.upper = &e[tinfo->size];
+
+ if (!DatumGetPointer(*u))
+ {
+ *u = PointerGetDatum(palloc(2 * tinfo->size));
+ memcpy( (void* ) &( ( (GBT_NUMKEY *) DatumGetPointer(*u) )[0] ) , (void*)rd.lower , tinfo->size );
+ memcpy( (void* ) &( ( (GBT_NUMKEY *) DatumGetPointer(*u) )[tinfo->size]) , (void*)rd.upper , tinfo->size );
+ }
+ else
+ {
+ GBT_NUMKEY_R ur ;
+ ur.lower = &( ( (GBT_NUMKEY *) DatumGetPointer(*u) )[0] ) ;
+ ur.upper = &( ( (GBT_NUMKEY *) DatumGetPointer(*u) )[tinfo->size]) ;
+ if ( (*tinfo->f_gt)((void*)ur.lower, (void*)rd.lower) )
+ memcpy( (void*) ur.lower, (void*) rd.lower, tinfo->size );
+ if ( (*tinfo->f_lt)((void*)ur.upper, (void*)rd.upper) )
+ memcpy( (void*) ur.upper, (void*) rd.upper, tinfo->size );
+ }
+
+}
+
+
+
+/*
+** The GiST consistent method
+*/
+
+extern bool
+gbt_num_consistent(
+ const GBT_NUMKEY_R * key,
+ const void * query,
+ const StrategyNumber * strategy,
+ bool is_leaf,
+ const gbtree_ninfo * tinfo
+)
+{
+
+ bool retval = FALSE;
+
+ switch (*strategy)
+ {
+ case BTLessEqualStrategyNumber:
+ retval = (*tinfo->f_ge)(query, key->lower);
+ break;
+ case BTLessStrategyNumber:
+ if ( is_leaf )
+ retval = (*tinfo->f_gt)(query, key->lower);
+ else
+ retval = (*tinfo->f_ge)(query, key->lower);
+ break;
+ case BTEqualStrategyNumber:
+ if ( is_leaf )
+ retval = (*tinfo->f_eq)(query, key->lower);
+ else
+ retval = (*tinfo->f_le)(key->lower, query) && (*tinfo->f_le)(query, key->upper );
+ break;
+ case BTGreaterStrategyNumber:
+ if ( is_leaf )
+ retval = (*tinfo->f_lt)(query, key->upper);
+ else
+ retval = (*tinfo->f_le)(query, key->upper);
+ break;
+ case BTGreaterEqualStrategyNumber:
+ retval = (*tinfo->f_le)(query, key->upper);
+ break;
+ default:
+ retval = FALSE;
+ }
+
+ return (retval);
+}
+
+
+
+
+GIST_SPLITVEC *
+gbt_num_picksplit( const GistEntryVector *entryvec, GIST_SPLITVEC *v, const gbtree_ninfo * tinfo )
+{
+
+ OffsetNumber i ,
+
+ maxoff = entryvec->n - 1;
+
+ Nsrt arr[maxoff+1] ;
+ int nbytes ;
+
+ nbytes = (maxoff + 2) * sizeof(OffsetNumber);
+ v->spl_left = (OffsetNumber *) palloc(nbytes);
+ v->spl_right = (OffsetNumber *) palloc(nbytes);
+ v->spl_ldatum = PointerGetDatum(0);
+ v->spl_rdatum = PointerGetDatum(0);
+ v->spl_nleft = 0;
+ v->spl_nright = 0;
+
+ /* Sort entries */
+
+ for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i))
+ {
+ arr[i].t = (GBT_NUMKEY *) DatumGetPointer((entryvec->vector[i].key));
+ arr[i].i = i;
+ }
+ qsort ( (void*) &arr[FirstOffsetNumber], maxoff-FirstOffsetNumber+1,sizeof(Nsrt), tinfo->f_cmp );
+
+ /* We do simply create two parts */
+
+ for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i))
+ {
+ if (i <= (maxoff - FirstOffsetNumber + 1) / 2)
+ {
+ gbt_num_bin_union(&v->spl_ldatum, arr[i].t, tinfo);
+ v->spl_left[v->spl_nleft] = arr[i].i;
+ v->spl_nleft++;
+ }
+ else
+ {
+ gbt_num_bin_union(&v->spl_rdatum, arr[i].t, tinfo);
+ v->spl_right[v->spl_nright] = arr[i].i;
+ v->spl_nright++;
+ }
+ }
+
+ return v;
+
+}
+