Commit 42d06988 authored by Teodor Sigaev's avatar Teodor Sigaev

New version. Add support for int2, int8, float4, float8, timestamp...

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
parent 1a321f26
......@@ -3,27 +3,17 @@ subdir = contrib/btree_gist
top_builddir = ../..
include $(top_builddir)/src/Makefile.global
MODULE_big = btree_gist
OBJS= btree_common.o btree_int2.o btree_int4.o btree_int8.o btree_float4.o btree_float8.o btree_ts.o
DATA_built = btree_gist.sql
DOCS = README.btree_gist
REGRESS = btree_gist
MODULE_big = btree_gist
EXTRA_CLEAN = btree_int2.c btree_int4.c btree_int8.c btree_float4.c btree_float8.c
OBJS = btree_gist.o btree_utils_num.o btree_utils_var.o btree_int2.o btree_int4.o btree_int8.o \
btree_float4.o btree_float8.o btree_cash.o btree_oid.o btree_ts.o btree_time.o \
btree_date.o btree_interval.o btree_macaddr.o btree_inet.o btree_text.o \
btree_bytea.o btree_bit.o btree_numeric.o
include $(top_srcdir)/contrib/contrib-global.mk
btree_int2.c: btree_num.c.in
sed 's,__DEFINE_BTREE_TYPE_HERE__,BTREE_GIST_INT2,g;s,__BTREE_GIST_TYPE__,int16,g;s,__BTREE_GIST_TYPE2__,int2,g' < $< > $@
btree_int4.c: btree_num.c.in
sed 's,__DEFINE_BTREE_TYPE_HERE__,BTREE_GIST_INT4,g;s,__BTREE_GIST_TYPE__,int32,g;s,__BTREE_GIST_TYPE2__,int4,g' < $< > $@
DATA_built = btree_gist.sql
DOCS = README.btree_gist
btree_int8.c: btree_num.c.in
sed 's,__DEFINE_BTREE_TYPE_HERE__,BTREE_GIST_INT8,g;s,__BTREE_GIST_TYPE__,int64,g;s,__BTREE_GIST_TYPE2__,int8,g' < $< > $@
REGRESS = init int2 int4 int8 float4 float8 cash oid timestamp timestamptz time timetz \
date interval macaddr inet cidr text varchar char bytea bit varbit numeric
btree_float4.c: btree_num.c.in
sed 's,__DEFINE_BTREE_TYPE_HERE__,BTREE_GIST_FLOAT4,g;s,__BTREE_GIST_TYPE__,float4,g;s,__BTREE_GIST_TYPE2__,float4,g' < $< > $@
btree_float8.c: btree_num.c.in
sed 's,__DEFINE_BTREE_TYPE_HERE__,BTREE_GIST_FLOAT8,g;s,__BTREE_GIST_TYPE__,float8,g;s,__BTREE_GIST_TYPE2__,float8,g' < $< > $@
include $(top_srcdir)/contrib/contrib-global.mk
This is B-Tree implementation using GiST for int2, int4, int8, float4, float8
timestamp types.
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.
All work was done by Teodor Sigaev (teodor@stack.net) and Oleg Bartunov
(oleg@sai.msu.su). See http://www.sai.msu.su/~megera/postgres/gist
for additional information.
All work was done by Teodor Sigaev (teodor@stack.net) , Oleg Bartunov
(oleg@sai.msu.su), Janko Richter (jankorichter@yahoo.de).
See http://www.sai.msu.su/~megera/postgres/gist for additional
information.
NEWS:
Feb 5, 2003 - btree_gist now support int2, int8, float4, float8 !
Thank Janko Richter <jankorichter@yahoo.de> for
contribution.
Apr 17, 2004 - Performance optimizing
Jan 21, 2004 - add support for bytea, numeric, bit, varbit, inet/cidr
Jan 17, 2004 - Reorganizing code and add support for char, varchar/text
Jan 10, 2004 - btree_gist now support oid , timestamp with time zone ,
time with and without time zone, date , interval
money, macaddr
Feb 5, 2003 - btree_gist now support int2, int8, float4, float8
NOTICE:
This version will works only with postgresql version 7.3 and above
This version will works only with postgresql version 7.4 and above
because of changes in interface of function calling and in system
tables.
If you want to index varchar attributes, you have to index using
the function text(<varchar>):
Example:
CREATE TABLE test ( a varchar(23) );
CREATE INDEX testidx ON test USING GIST ( text(a) );
INSTALLATION:
......
#include "btree_gist.h"
#include "btree_utils_var.h"
#include "utils/builtins.h"
#include "utils/varbit.h"
/*
** Bit ops
*/
PG_FUNCTION_INFO_V1(gbt_bit_compress);
PG_FUNCTION_INFO_V1(gbt_bit_union);
PG_FUNCTION_INFO_V1(gbt_bit_picksplit);
PG_FUNCTION_INFO_V1(gbt_bit_consistent);
PG_FUNCTION_INFO_V1(gbt_bit_penalty);
PG_FUNCTION_INFO_V1(gbt_bit_same);
Datum gbt_bit_compress(PG_FUNCTION_ARGS);
Datum gbt_bit_union(PG_FUNCTION_ARGS);
Datum gbt_bit_picksplit(PG_FUNCTION_ARGS);
Datum gbt_bit_consistent(PG_FUNCTION_ARGS);
Datum gbt_bit_penalty(PG_FUNCTION_ARGS);
Datum gbt_bit_same(PG_FUNCTION_ARGS);
/* define for comparison */
static bool gbt_bitgt (const void *a, const void *b)
{
return ( DatumGetBool(DirectFunctionCall2( bitgt ,PointerGetDatum( a ),PointerGetDatum( b ) ) ) );
}
static bool gbt_bitge (const void *a, const void *b)
{
return ( DatumGetBool(DirectFunctionCall2( bitge ,PointerGetDatum( a ),PointerGetDatum( b ) ) ) );
}
static bool gbt_biteq (const void *a, const void *b)
{
return ( DatumGetBool(DirectFunctionCall2( biteq ,PointerGetDatum( a ),PointerGetDatum( b ) ) ) );
}
static bool gbt_bitle (const void *a, const void *b)
{
return ( DatumGetBool(DirectFunctionCall2( bitle ,PointerGetDatum( a ),PointerGetDatum( b ) ) ) );
}
static bool gbt_bitlt (const void *a, const void *b)
{
return ( DatumGetBool(DirectFunctionCall2( bitlt ,PointerGetDatum( a ),PointerGetDatum( b ) ) ) );
}
static int32 gbt_bitcmp ( const bytea * a , const bytea * b )
{
return
( DatumGetInt32(DirectFunctionCall2(byteacmp,PointerGetDatum(a),PointerGetDatum(b) ) ) );
}
static bytea *
gbt_bit_xfrm ( bytea * leaf )
{
bytea * out = leaf;
int s = VARBITBYTES(leaf) + VARHDRSZ;
out = palloc ( s );
VARATT_SIZEP(out) = s;
memcpy ( (void*)VARDATA(out), (void*)VARBITS(leaf), VARBITBYTES(leaf) );
return out;
}
static GBT_VARKEY * gbt_bit_l2n ( GBT_VARKEY * leaf )
{
GBT_VARKEY *out = leaf ;
GBT_VARKEY_R r = gbt_var_key_readable ( leaf );
bytea *o ;
o = gbt_bit_xfrm (r.lower);
r.upper = r.lower = o;
out = gbt_var_key_copy( &r, TRUE );
pfree(o);
return out;
}
static const gbtree_vinfo tinfo =
{
gbt_t_bit,
FALSE,
TRUE,
gbt_bitgt,
gbt_bitge,
gbt_biteq,
gbt_bitle,
gbt_bitlt,
gbt_bitcmp,
gbt_bit_l2n
};
/**************************************************
* Bit ops
**************************************************/
Datum
gbt_bit_compress (PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
PG_RETURN_POINTER ( gbt_var_compress( entry, &tinfo ) );
}
Datum
gbt_bit_consistent(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
GBT_VARKEY *ktst = (GBT_VARKEY *) DatumGetPointer ( entry->key ) ;
GBT_VARKEY *key = (GBT_VARKEY *) DatumGetPointer ( PG_DETOAST_DATUM( entry->key ) );
void *qtst = ( void * ) DatumGetPointer( PG_GETARG_DATUM(1) );
void *query = ( void * ) DatumGetByteaP ( PG_GETARG_DATUM(1) );
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
bool retval = FALSE;
GBT_VARKEY_R r = gbt_var_key_readable ( key );
if ( GIST_LEAF(entry) )
{
retval = gbt_var_consistent( &r, query, &strategy, TRUE, &tinfo );
} else {
bytea * q = gbt_bit_xfrm ( ( bytea * ) query );
retval = gbt_var_consistent( &r, (void*)q, &strategy, FALSE, &tinfo );
pfree(q);
}
if ( ktst != key ){
pfree ( key );
}
if ( qtst != query ){
pfree ( query );
}
PG_RETURN_BOOL(retval);
}
Datum
gbt_bit_union(PG_FUNCTION_ARGS)
{
GistEntryVector * entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
int32 * size = (int *) PG_GETARG_POINTER(1);
PG_RETURN_POINTER( gbt_var_union ( entryvec , size , &tinfo ) );
}
Datum
gbt_bit_picksplit(PG_FUNCTION_ARGS)
{
GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1);
gbt_var_picksplit ( entryvec, v, &tinfo );
PG_RETURN_POINTER(v);
}
Datum
gbt_bit_same(PG_FUNCTION_ARGS)
{
Datum d1 = PG_GETARG_DATUM(0);
Datum d2 = PG_GETARG_DATUM(1);
bool *result = (bool *) PG_GETARG_POINTER(2);
PG_RETURN_POINTER( gbt_var_same ( result, d1 , d2 , &tinfo ));
}
Datum
gbt_bit_penalty(PG_FUNCTION_ARGS)
{
float *result = (float *) PG_GETARG_POINTER(2);
GISTENTRY * o = (GISTENTRY *) PG_GETARG_POINTER(0);
GISTENTRY * n = (GISTENTRY *) PG_GETARG_POINTER(1);
PG_RETURN_POINTER( gbt_var_penalty ( result ,o , n, &tinfo ) );
}
#include "btree_gist.h"
#include "btree_utils_var.h"
#include "utils/builtins.h"
/*
** Bytea ops
*/
PG_FUNCTION_INFO_V1(gbt_bytea_compress);
PG_FUNCTION_INFO_V1(gbt_bytea_union);
PG_FUNCTION_INFO_V1(gbt_bytea_picksplit);
PG_FUNCTION_INFO_V1(gbt_bytea_consistent);
PG_FUNCTION_INFO_V1(gbt_bytea_penalty);
PG_FUNCTION_INFO_V1(gbt_bytea_same);
Datum gbt_bytea_compress(PG_FUNCTION_ARGS);
Datum gbt_bytea_union(PG_FUNCTION_ARGS);
Datum gbt_bytea_picksplit(PG_FUNCTION_ARGS);
Datum gbt_bytea_consistent(PG_FUNCTION_ARGS);
Datum gbt_bytea_penalty(PG_FUNCTION_ARGS);
Datum gbt_bytea_same(PG_FUNCTION_ARGS);
/* define for comparison */
static bool gbt_byteagt (const void *a, const void *b)
{
return ( DatumGetBool(DirectFunctionCall2( byteagt ,PointerGetDatum( a ),PointerGetDatum( b ) ) ) );
}
static bool gbt_byteage (const void *a, const void *b)
{
return ( DatumGetBool(DirectFunctionCall2( byteage ,PointerGetDatum( a ),PointerGetDatum( b ) ) ) );
}
static bool gbt_byteaeq (const void *a, const void *b)
{
return ( DatumGetBool(DirectFunctionCall2( byteaeq ,PointerGetDatum( a ),PointerGetDatum( b ) ) ) );
}
static bool gbt_byteale (const void *a, const void *b)
{
return ( DatumGetBool(DirectFunctionCall2( byteale ,PointerGetDatum( a ),PointerGetDatum( b ) ) ) );
}
static bool gbt_bytealt (const void *a, const void *b)
{
return ( DatumGetBool(DirectFunctionCall2( bytealt ,PointerGetDatum( a ),PointerGetDatum( b ) ) ) );
}
static int32 gbt_byteacmp ( const bytea * a , const bytea * b )
{
return
( DatumGetInt32(DirectFunctionCall2(byteacmp,PointerGetDatum(a),PointerGetDatum(b) ) ) );
}
static const gbtree_vinfo tinfo =
{
gbt_t_bytea,
FALSE,
TRUE,
gbt_byteagt,
gbt_byteage,
gbt_byteaeq,
gbt_byteale,
gbt_bytealt,
gbt_byteacmp,
NULL
};
/**************************************************
* Text ops
**************************************************/
Datum
gbt_bytea_compress (PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
PG_RETURN_POINTER ( gbt_var_compress( entry, &tinfo ) );
}
Datum
gbt_bytea_consistent(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
GBT_VARKEY *ktst = (GBT_VARKEY *) DatumGetPointer ( entry->key ) ;
GBT_VARKEY *key = (GBT_VARKEY *) DatumGetPointer ( PG_DETOAST_DATUM( entry->key ) );
void *qtst = ( void * ) DatumGetPointer( PG_GETARG_DATUM(1) );
void *query = ( void * ) DatumGetByteaP ( PG_GETARG_DATUM(1) );
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
bool retval = FALSE;
GBT_VARKEY_R r = gbt_var_key_readable ( key );
retval = gbt_var_consistent( &r, query, &strategy, GIST_LEAF(entry), &tinfo );
if ( ktst != key ){
pfree ( key );
}
if ( qtst != query ){
pfree ( query );
}
PG_RETURN_BOOL(retval);
}
Datum
gbt_bytea_union(PG_FUNCTION_ARGS)
{
GistEntryVector * entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
int32 * size = (int *) PG_GETARG_POINTER(1);
PG_RETURN_POINTER( gbt_var_union ( entryvec , size , &tinfo ) );
}
Datum
gbt_bytea_picksplit(PG_FUNCTION_ARGS)
{
GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1);
gbt_var_picksplit ( entryvec, v, &tinfo );
PG_RETURN_POINTER(v);
}
Datum
gbt_bytea_same(PG_FUNCTION_ARGS)
{
Datum d1 = PG_GETARG_DATUM(0);
Datum d2 = PG_GETARG_DATUM(1);
bool *result = (bool *) PG_GETARG_POINTER(2);
PG_RETURN_POINTER( gbt_var_same ( result, d1 , d2 , &tinfo ));
}
Datum
gbt_bytea_penalty(PG_FUNCTION_ARGS)
{
float *result = (float *) PG_GETARG_POINTER(2);
GISTENTRY * o = (GISTENTRY *) PG_GETARG_POINTER(0);
GISTENTRY * n = (GISTENTRY *) PG_GETARG_POINTER(1);
PG_RETURN_POINTER( gbt_var_penalty ( result ,o , n, &tinfo ) );
}
#include "btree_gist.h"
#include "btree_utils_num.h"
#include "utils/cash.h"
typedef struct
{
Cash lower;
Cash upper;
} cashKEY;
/*
** Cash ops
*/
PG_FUNCTION_INFO_V1(gbt_cash_compress);
PG_FUNCTION_INFO_V1(gbt_cash_union);
PG_FUNCTION_INFO_V1(gbt_cash_picksplit);
PG_FUNCTION_INFO_V1(gbt_cash_consistent);
PG_FUNCTION_INFO_V1(gbt_cash_penalty);
PG_FUNCTION_INFO_V1(gbt_cash_same);
Datum gbt_cash_compress(PG_FUNCTION_ARGS);
Datum gbt_cash_union(PG_FUNCTION_ARGS);
Datum gbt_cash_picksplit(PG_FUNCTION_ARGS);
Datum gbt_cash_consistent(PG_FUNCTION_ARGS);
Datum gbt_cash_penalty(PG_FUNCTION_ARGS);
Datum gbt_cash_same(PG_FUNCTION_ARGS);
static bool gbt_cashgt (const void *a, const void *b)
{
return ( *((Cash*)a) > *((Cash*)b) );
}
static bool gbt_cashge (const void *a, const void *b)
{
return ( *((Cash*)a) >= *((Cash*)b) );
}
static bool gbt_casheq (const void *a, const void *b)
{
return ( *((Cash*)a) == *((Cash*)b) );
}
static bool gbt_cashle (const void *a, const void *b)
{
return ( *((Cash*)a) <= *((Cash*)b) );
}
static bool gbt_cashlt (const void *a, const void *b)
{
return ( *((Cash*)a) < *((Cash*)b) );
}
static int
gbt_cashkey_cmp(const void *a, const void *b)
{
if ( *(Cash*)&(((Nsrt *) a)->t[0]) > *(Cash*)&(((Nsrt *) b)->t[0]) ){
return 1;
} else
if ( *(Cash*)&(((Nsrt *) a)->t[0]) < *(Cash*)&(((Nsrt *) b)->t[0]) ){
return -1;
}
return 0;
}
static const gbtree_ninfo tinfo =
{
gbt_t_cash,
sizeof(Cash),
gbt_cashgt,
gbt_cashge,
gbt_casheq,
gbt_cashle,
gbt_cashlt,
gbt_cashkey_cmp
};
/**************************************************
* Cash ops
**************************************************/
Datum
gbt_cash_compress(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
GISTENTRY *retval = NULL;
PG_RETURN_POINTER( gbt_num_compress( retval , entry , &tinfo ));
}
Datum
gbt_cash_consistent(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
Cash query = (*((Cash *) PG_GETARG_POINTER(1)));
cashKEY *kkk = (cashKEY *) DatumGetPointer(entry->key);
GBT_NUMKEY_R key ;
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
key.lower = (GBT_NUMKEY*) &kkk->lower ;
key.upper = (GBT_NUMKEY*) &kkk->upper ;
PG_RETURN_BOOL(
gbt_num_consistent( &key, (void*)&query,&strategy,GIST_LEAF(entry),&tinfo)
);
}
Datum
gbt_cash_union(PG_FUNCTION_ARGS)
{
GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
void *out = palloc(sizeof(cashKEY));
*(int *) PG_GETARG_POINTER(1) = sizeof(cashKEY);
PG_RETURN_POINTER( gbt_num_union ( (void*)out, entryvec, &tinfo ) );
}
Datum
gbt_cash_penalty(PG_FUNCTION_ARGS)
{
cashKEY *origentry = (cashKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
cashKEY *newentry = (cashKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
float *result = (float *) PG_GETARG_POINTER(2);
Cash res ;
*result = 0.0;
res = Max(newentry->upper - origentry->upper, 0) +
Max(origentry->lower - newentry->lower, 0);
if ( res > 0 ){
*result += FLT_MIN ;
*result += (float) ( res / ( (double) ( res + origentry->upper - origentry->lower ) ) );
*result *= ( FLT_MAX / ( ( (GISTENTRY *) PG_GETARG_POINTER(0))->rel->rd_att->natts + 1 ) );
}
PG_RETURN_POINTER(result);
}
Datum
gbt_cash_picksplit(PG_FUNCTION_ARGS)
{
PG_RETURN_POINTER(gbt_num_picksplit(
(GistEntryVector *) PG_GETARG_POINTER(0),
(GIST_SPLITVEC *) PG_GETARG_POINTER(1),
&tinfo
));
}
Datum
gbt_cash_same(PG_FUNCTION_ARGS)
{
cashKEY *b1 = (cashKEY *) PG_GETARG_POINTER(0);
cashKEY *b2 = (cashKEY *) PG_GETARG_POINTER(1);
bool *result = (bool *) PG_GETARG_POINTER(2);
*result = gbt_num_same ( (void*)b1, (void*)b2, &tinfo );
PG_RETURN_POINTER(result);
}
#include "btree_gist.h"
PG_FUNCTION_INFO_V1(btree_decompress);
Datum btree_decompress(PG_FUNCTION_ARGS);
/*
** GiST DeCompress methods
** do not do anything.
*/
Datum
btree_decompress(PG_FUNCTION_ARGS)
{
PG_RETURN_POINTER(PG_GETARG_POINTER(0));
}
/**************************************************
* Common btree-function (for all ops)
**************************************************/
/*
** The GiST PickSplit method
*/
extern GIST_SPLITVEC *
btree_picksplit(GistEntryVector *entryvec, GIST_SPLITVEC *v, BINARY_UNION bu, CMPFUNC cmp)
{
OffsetNumber i;
RIX *array;
OffsetNumber maxoff;
int nbytes;
maxoff = entryvec->n - 1;
nbytes = (maxoff + 2) * sizeof(OffsetNumber);
v->spl_left = (OffsetNumber *) palloc(nbytes);
v->spl_right = (OffsetNumber *) palloc(nbytes);
v->spl_nleft = 0;
v->spl_nright = 0;
v->spl_ldatum = PointerGetDatum(0);
v->spl_rdatum = PointerGetDatum(0);
array = (RIX *) palloc(sizeof(RIX) * (maxoff + 1));
/* copy the data into RIXes, and sort the RIXes */
for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i))
{
array[i].index = i;
array[i].r = (char *) DatumGetPointer((entryvec->vector[i].key));
}
qsort((void *) &array[FirstOffsetNumber], maxoff - FirstOffsetNumber + 1,
sizeof(RIX), cmp);
for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i))
{
if (i <= (maxoff - FirstOffsetNumber + 1) / 2)
{
v->spl_left[v->spl_nleft] = array[i].index;
v->spl_nleft++;
(*bu) (&v->spl_ldatum, array[i].r);
}
else
{
v->spl_right[v->spl_nright] = array[i].index;
v->spl_nright++;
(*bu) (&v->spl_rdatum, array[i].r);
}
}
pfree(array);
return (v);
}
#include "btree_gist.h"
#include "btree_utils_num.h"
#include "utils/date.h"
typedef struct
{
DateADT lower;
DateADT upper;
} dateKEY;
/*
** date ops
*/
PG_FUNCTION_INFO_V1(gbt_date_compress);
PG_FUNCTION_INFO_V1(gbt_date_union);
PG_FUNCTION_INFO_V1(gbt_date_picksplit);
PG_FUNCTION_INFO_V1(gbt_date_consistent);
PG_FUNCTION_INFO_V1(gbt_date_penalty);
PG_FUNCTION_INFO_V1(gbt_date_same);
Datum gbt_date_compress(PG_FUNCTION_ARGS);
Datum gbt_date_union(PG_FUNCTION_ARGS);
Datum gbt_date_picksplit(PG_FUNCTION_ARGS);
Datum gbt_date_consistent(PG_FUNCTION_ARGS);
Datum gbt_date_penalty(PG_FUNCTION_ARGS);
Datum gbt_date_same(PG_FUNCTION_ARGS);
static bool gbt_dategt (const void *a, const void *b)
{
return DatumGetBool(
DirectFunctionCall2(date_gt,DateADTGetDatum( *((DateADT*)a) ), DateADTGetDatum( *((DateADT*)b) ) )
);
}
static bool gbt_datege (const void *a, const void *b)
{
return DatumGetBool(
DirectFunctionCall2(date_ge,DateADTGetDatum( *((DateADT*)a) ), DateADTGetDatum( *((DateADT*)b) ) )
);
}
static bool gbt_dateeq (const void *a, const void *b)
{
return DatumGetBool(
DirectFunctionCall2(date_eq,DateADTGetDatum( *((DateADT*)a) ), DateADTGetDatum( *((DateADT*)b) ) )
);
}
static bool gbt_datele (const void *a, const void *b)
{
return DatumGetBool(
DirectFunctionCall2(date_le,DateADTGetDatum( *((DateADT*)a) ), DateADTGetDatum( *((DateADT*)b) ) )
);
}
static bool gbt_datelt (const void *a, const void *b)
{
return DatumGetBool(
DirectFunctionCall2(date_lt,DateADTGetDatum( *((DateADT*)a) ), DateADTGetDatum( *((DateADT*)b) ) )
);
}
static int
gbt_datekey_cmp(const void *a, const void *b)
{
if ( gbt_dategt( (void*)&(((Nsrt *) a)->t[0]) , (void*)&(((Nsrt *) b)->t[0]) ) ){
return 1;
} else
if ( gbt_datelt( (void*)&(((Nsrt *) a)->t[0]) , (void*)&(((Nsrt *) b)->t[0]) ) ){
return -1;
}
return 0;
}
static const gbtree_ninfo tinfo =
{
gbt_t_date,
sizeof(DateADT),
gbt_dategt,
gbt_datege,
gbt_dateeq,
gbt_datele,
gbt_datelt,
gbt_datekey_cmp
};
/**************************************************
* date ops
**************************************************/
Datum
gbt_date_compress(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
GISTENTRY *retval = NULL;
PG_RETURN_POINTER( gbt_num_compress( retval , entry , &tinfo ));
}
Datum
gbt_date_consistent(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
DateADT query = PG_GETARG_DATEADT( 1 );
dateKEY *kkk = (dateKEY *) DatumGetPointer(entry->key);
GBT_NUMKEY_R key ;
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
key.lower = (GBT_NUMKEY*) &kkk->lower ;
key.upper = (GBT_NUMKEY*) &kkk->upper ;
PG_RETURN_BOOL(
gbt_num_consistent( &key, (void*)&query,&strategy,GIST_LEAF(entry),&tinfo)
);
}
Datum
gbt_date_union(PG_FUNCTION_ARGS)
{
GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
void *out = palloc(sizeof(dateKEY));
*(int *) PG_GETARG_POINTER(1) = sizeof(dateKEY);
PG_RETURN_POINTER( gbt_num_union ( (void*)out, entryvec, &tinfo ) );
}
Datum
gbt_date_penalty(PG_FUNCTION_ARGS)
{
dateKEY *origentry = (dateKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
dateKEY *newentry = (dateKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
float *result = (float *) PG_GETARG_POINTER(2);
int32 diff, res ;
diff = DatumGetInt32(DirectFunctionCall2(
date_mi,
DateADTGetDatum(newentry->upper),
DateADTGetDatum(origentry->upper)));
res = Max(diff, 0);
diff = DatumGetInt32(DirectFunctionCall2(
date_mi,
DateADTGetDatum(origentry->lower),
DateADTGetDatum(newentry->lower)));
res += Max(diff, 0);
*result = 0.0;
if ( res > 0 ){
diff = DatumGetInt32(DirectFunctionCall2(
date_mi,
DateADTGetDatum(origentry->upper),
DateADTGetDatum(origentry->lower)));
*result += FLT_MIN ;
*result += (float) ( res / ( (double) ( res + diff ) ) );
*result *= ( FLT_MAX / ( ( (GISTENTRY *) PG_GETARG_POINTER(0))->rel->rd_att->natts + 1 ) );
}
PG_RETURN_POINTER(result);
}
Datum
gbt_date_picksplit(PG_FUNCTION_ARGS)
{
PG_RETURN_POINTER(gbt_num_picksplit(
(GistEntryVector *) PG_GETARG_POINTER(0),
(GIST_SPLITVEC *) PG_GETARG_POINTER(1),
&tinfo
));
}
Datum
gbt_date_same(PG_FUNCTION_ARGS)
{
dateKEY *b1 = (dateKEY *) PG_GETARG_POINTER(0);
dateKEY *b2 = (dateKEY *) PG_GETARG_POINTER(1);
bool *result = (bool *) PG_GETARG_POINTER(2);
*result = gbt_num_same ( (void*)b1, (void*)b2, &tinfo );
PG_RETURN_POINTER(result);
}
#include "btree_gist.h"
#include "btree_utils_num.h"
typedef struct float4key
{
float4 lower;
float4 upper;
} float4KEY;
/*
** float4 ops
*/
PG_FUNCTION_INFO_V1(gbt_float4_compress);
PG_FUNCTION_INFO_V1(gbt_float4_union);
PG_FUNCTION_INFO_V1(gbt_float4_picksplit);
PG_FUNCTION_INFO_V1(gbt_float4_consistent);
PG_FUNCTION_INFO_V1(gbt_float4_penalty);
PG_FUNCTION_INFO_V1(gbt_float4_same);
Datum gbt_float4_compress(PG_FUNCTION_ARGS);
Datum gbt_float4_union(PG_FUNCTION_ARGS);
Datum gbt_float4_picksplit(PG_FUNCTION_ARGS);
Datum gbt_float4_consistent(PG_FUNCTION_ARGS);
Datum gbt_float4_penalty(PG_FUNCTION_ARGS);
Datum gbt_float4_same(PG_FUNCTION_ARGS);
static bool gbt_float4gt (const void *a, const void *b)
{
return ( *((float4*)a) > *((float4*)b) );
}
static bool gbt_float4ge (const void *a, const void *b)
{
return ( *((float4*)a) >= *((float4*)b) );
}
static bool gbt_float4eq (const void *a, const void *b)
{
return ( *((float4*)a) == *((float4*)b) );
}
static bool gbt_float4le (const void *a, const void *b)
{
return ( *((float4*)a) <= *((float4*)b) );
}
static bool gbt_float4lt (const void *a, const void *b)
{
return ( *((float4*)a) < *((float4*)b) );
}
static int
gbt_float4key_cmp(const void *a, const void *b)
{
if ( *(float4*)&(((Nsrt *) a)->t[0]) > *(float4*)&(((Nsrt *) b)->t[0]) ){
return 1;
} else
if ( *(float4*)&(((Nsrt *) a)->t[0]) < *(float4*)&(((Nsrt *) b)->t[0]) ){
return -1;
}
return 0;
}
static const gbtree_ninfo tinfo =
{
gbt_t_float4,
sizeof(float4),
gbt_float4gt,
gbt_float4ge,
gbt_float4eq,
gbt_float4le,
gbt_float4lt,
gbt_float4key_cmp
};
/**************************************************
* float4 ops
**************************************************/
Datum
gbt_float4_compress(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
GISTENTRY *retval = NULL;
PG_RETURN_POINTER( gbt_num_compress( retval , entry , &tinfo ));
}
Datum
gbt_float4_consistent(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
float4 query = PG_GETARG_FLOAT4(1);
float4KEY *kkk = (float4KEY *) DatumGetPointer(entry->key);
GBT_NUMKEY_R key ;
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
key.lower = (GBT_NUMKEY*) &kkk->lower ;
key.upper = (GBT_NUMKEY*) &kkk->upper ;
PG_RETURN_BOOL(
gbt_num_consistent( &key, (void*)&query,&strategy,GIST_LEAF(entry),&tinfo)
);
}
Datum
gbt_float4_union(PG_FUNCTION_ARGS)
{
GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
void *out = palloc(sizeof(float4KEY));
*(int *) PG_GETARG_POINTER(1) = sizeof(float4KEY);
PG_RETURN_POINTER( gbt_num_union ( (void*)out, entryvec, &tinfo ) );
}
Datum
gbt_float4_penalty(PG_FUNCTION_ARGS)
{
float4KEY *origentry = (float4KEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
float4KEY *newentry = (float4KEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
float *result = (float *) PG_GETARG_POINTER(2);
float4 res ;
*result = 0.0;
res = Max(newentry->upper - origentry->upper, 0) +
Max(origentry->lower - newentry->lower, 0);
if ( res > 0 ){
*result += FLT_MIN ;
*result += (float) ( res / ( (double) ( res + origentry->upper - origentry->lower ) ) );
*result *= ( FLT_MAX / ( ( (GISTENTRY *) PG_GETARG_POINTER(0))->rel->rd_att->natts + 1 ) );
}
PG_RETURN_POINTER(result);
}
Datum
gbt_float4_picksplit(PG_FUNCTION_ARGS)
{
PG_RETURN_POINTER(gbt_num_picksplit(
(GistEntryVector *) PG_GETARG_POINTER(0),
(GIST_SPLITVEC *) PG_GETARG_POINTER(1),
&tinfo
));
}
Datum
gbt_float4_same(PG_FUNCTION_ARGS)
{
float4KEY *b1 = (float4KEY *) PG_GETARG_POINTER(0);
float4KEY *b2 = (float4KEY *) PG_GETARG_POINTER(1);
bool *result = (bool *) PG_GETARG_POINTER(2);
*result = gbt_num_same ( (void*)b1, (void*)b2, &tinfo );
PG_RETURN_POINTER(result);
}
#include "btree_gist.h"
#include "btree_utils_num.h"
typedef struct float8key
{
float8 lower;
float8 upper;
} float8KEY;
/*
** float8 ops
*/
PG_FUNCTION_INFO_V1(gbt_float8_compress);
PG_FUNCTION_INFO_V1(gbt_float8_union);
PG_FUNCTION_INFO_V1(gbt_float8_picksplit);
PG_FUNCTION_INFO_V1(gbt_float8_consistent);
PG_FUNCTION_INFO_V1(gbt_float8_penalty);
PG_FUNCTION_INFO_V1(gbt_float8_same);
Datum gbt_float8_compress(PG_FUNCTION_ARGS);
Datum gbt_float8_union(PG_FUNCTION_ARGS);
Datum gbt_float8_picksplit(PG_FUNCTION_ARGS);
Datum gbt_float8_consistent(PG_FUNCTION_ARGS);
Datum gbt_float8_penalty(PG_FUNCTION_ARGS);
Datum gbt_float8_same(PG_FUNCTION_ARGS);
static bool gbt_float8gt (const void *a, const void *b)
{
return ( *((float8*)a) > *((float8*)b) );
}
static bool gbt_float8ge (const void *a, const void *b)
{
return ( *((float8*)a) >= *((float8*)b) );
}
static bool gbt_float8eq (const void *a, const void *b)
{
return ( *((float8*)a) == *((float8*)b) );
}
static bool gbt_float8le (const void *a, const void *b)
{
return ( *((float8*)a) <= *((float8*)b) );
}
static bool gbt_float8lt (const void *a, const void *b)
{
return ( *((float8*)a) < *((float8*)b) );
}
static int
gbt_float8key_cmp(const void *a, const void *b)
{
if ( *(float8*)&(((Nsrt *) a)->t[0]) > *(float8*)&(((Nsrt *) b)->t[0]) ){
return 1;
} else
if ( *(float8*)&(((Nsrt *) a)->t[0]) < *(float8*)&(((Nsrt *) b)->t[0]) ){
return -1;
}
return 0;
}
static const gbtree_ninfo tinfo =
{
gbt_t_float8,
sizeof(float8),
gbt_float8gt,
gbt_float8ge,
gbt_float8eq,
gbt_float8le,
gbt_float8lt,
gbt_float8key_cmp
};
/**************************************************
* float8 ops
**************************************************/
Datum
gbt_float8_compress(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
GISTENTRY *retval = NULL;
PG_RETURN_POINTER( gbt_num_compress( retval , entry , &tinfo ));
}
Datum
gbt_float8_consistent(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
float8 query = PG_GETARG_FLOAT8(1);
float8KEY *kkk = (float8KEY *) DatumGetPointer(entry->key);
GBT_NUMKEY_R key ;
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
key.lower = (GBT_NUMKEY*) &kkk->lower ;
key.upper = (GBT_NUMKEY*) &kkk->upper ;
PG_RETURN_BOOL(
gbt_num_consistent( &key, (void*)&query,&strategy,GIST_LEAF(entry),&tinfo)
);
}
Datum
gbt_float8_union(PG_FUNCTION_ARGS)
{
GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
void *out = palloc(sizeof(float8KEY));
*(int *) PG_GETARG_POINTER(1) = sizeof(float8KEY);
PG_RETURN_POINTER( gbt_num_union ( (void*)out, entryvec, &tinfo ) );
}
Datum
gbt_float8_penalty(PG_FUNCTION_ARGS)
{
float8KEY *origentry = (float8KEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
float8KEY *newentry = (float8KEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
float *result = (float *) PG_GETARG_POINTER(2);
float8 res ;
*result = 0.0;
res = Max(newentry->upper - origentry->upper, 0) +
Max(origentry->lower - newentry->lower, 0);
if ( res > 0 ){
*result += FLT_MIN ;
*result += (float) ( res / ( (double) ( res + origentry->upper - origentry->lower ) ) );
*result *= ( FLT_MAX / ( ( (GISTENTRY *) PG_GETARG_POINTER(0))->rel->rd_att->natts + 1 ) );
}
PG_RETURN_POINTER(result);
}
Datum
gbt_float8_picksplit(PG_FUNCTION_ARGS)
{
PG_RETURN_POINTER(gbt_num_picksplit(
(GistEntryVector *) PG_GETARG_POINTER(0),
(GIST_SPLITVEC *) PG_GETARG_POINTER(1),
&tinfo
));
}
Datum
gbt_float8_same(PG_FUNCTION_ARGS)
{
float8KEY *b1 = (float8KEY *) PG_GETARG_POINTER(0);
float8KEY *b2 = (float8KEY *) PG_GETARG_POINTER(1);
bool *result = (bool *) PG_GETARG_POINTER(2);
*result = gbt_num_same ( (void*)b1, (void*)b2, &tinfo );
PG_RETURN_POINTER(result);
}
#include "btree_gist.h"
PG_FUNCTION_INFO_V1(gbt_decompress);
PG_FUNCTION_INFO_V1(gbtreekey_in);
PG_FUNCTION_INFO_V1(gbtreekey_out);
Datum gbt_decompress(PG_FUNCTION_ARGS);
/**************************************************
* In/Out for keys
**************************************************/
Datum
gbtreekey_in(PG_FUNCTION_ARGS)
{
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("<datatype>key_in() not implemented")));
PG_RETURN_POINTER(NULL);
}
#include "btree_utils_var.h"
#include "utils/builtins.h"
Datum
gbtreekey_out(PG_FUNCTION_ARGS)
{
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("<datatype>key_out() not implemented")));
PG_RETURN_POINTER(NULL);
}
/*
** GiST DeCompress methods
** do not do anything.
*/
Datum
gbt_decompress(PG_FUNCTION_ARGS)
{
PG_RETURN_POINTER(PG_GETARG_POINTER(0));
}
#include "postgres.h"
#include "access/gist.h"
#include "access/itup.h"
#include "access/nbtree.h"
#include "utils/geo_decls.h"
typedef int (*CMPFUNC) (const void *a, const void *b);
typedef void (*BINARY_UNION) (Datum *, char *);
/* indexed types */
enum gbtree_type
{
gbt_t_var ,
gbt_t_int2 ,
gbt_t_int4 ,
gbt_t_int8 ,
gbt_t_float4 ,
gbt_t_float8 ,
gbt_t_numeric,
gbt_t_ts,
gbt_t_cash,
gbt_t_oid,
gbt_t_time,
gbt_t_date,
gbt_t_intv,
gbt_t_macad,
gbt_t_text,
gbt_t_bpchar,
gbt_t_bytea,
gbt_t_bit,
gbt_t_inet
};
/* used for sorting */
typedef struct rix
{
int index;
char *r;
} RIX;
/*
** Common btree-function (for all ops)
*/
* Generic btree functions
*/
Datum gbtreekey_in (PG_FUNCTION_ARGS);
extern GIST_SPLITVEC *btree_picksplit(GistEntryVector *entryvec, GIST_SPLITVEC *v,
BINARY_UNION bu, CMPFUNC cmp);
Datum gbtreekey_out(PG_FUNCTION_ARGS);
This diff is collapsed.
#include "btree_gist.h"
#include "btree_utils_num.h"
#include "utils/builtins.h"
#include "utils/inet.h"
#include "catalog/pg_type.h"
typedef struct inetkey
{
double lower;
double upper;
} inetKEY;
/*
** inet ops
*/
PG_FUNCTION_INFO_V1(gbt_inet_compress);
PG_FUNCTION_INFO_V1(gbt_cidr_compress);
PG_FUNCTION_INFO_V1(gbt_inet_union);
PG_FUNCTION_INFO_V1(gbt_inet_picksplit);
PG_FUNCTION_INFO_V1(gbt_inet_consistent);
PG_FUNCTION_INFO_V1(gbt_cidr_consistent);
PG_FUNCTION_INFO_V1(gbt_inet_penalty);
PG_FUNCTION_INFO_V1(gbt_inet_same);
Datum gbt_inet_compress(PG_FUNCTION_ARGS);
Datum gbt_cidr_compress(PG_FUNCTION_ARGS);
Datum gbt_inet_union(PG_FUNCTION_ARGS);
Datum gbt_inet_picksplit(PG_FUNCTION_ARGS);
Datum gbt_inet_consistent(PG_FUNCTION_ARGS);
Datum gbt_cidr_consistent(PG_FUNCTION_ARGS);
Datum gbt_inet_penalty(PG_FUNCTION_ARGS);
Datum gbt_inet_same(PG_FUNCTION_ARGS);
static bool gbt_inetgt (const void *a, const void *b)
{
return ( *((double*)a) > *((double*)b) );
}
static bool gbt_inetge (const void *a, const void *b)
{
return ( *((double*)a) >= *((double*)b) );
}
static bool gbt_ineteq (const void *a, const void *b)
{
return ( *((double*)a) == *((double*)b) );
}
static bool gbt_inetle (const void *a, const void *b)
{
return ( *((double*)a) <= *((double*)b) );
}
static bool gbt_inetlt (const void *a, const void *b)
{
return ( *((double*)a) < *((double*)b) );
}
static int
gbt_inetkey_cmp(const void *a, const void *b)
{
if ( *(double*)(&((Nsrt *) a)->t[0]) > *(double*)(&((Nsrt *) b)->t[0]) ){
return 1;
} else
if ( *(double*)(&((Nsrt *) a)->t[0]) < *(double*)(&((Nsrt *) b)->t[0]) ){
return -1;
}
return 0;
}
static const gbtree_ninfo tinfo =
{
gbt_t_inet,
sizeof(double),
gbt_inetgt,
gbt_inetge,
gbt_ineteq,
gbt_inetle,
gbt_inetlt,
gbt_inetkey_cmp
};
/**************************************************
* inet ops
**************************************************/
static GISTENTRY *
gbt_inet_compress_inetrnal(GISTENTRY *retval , GISTENTRY *entry , Oid typid)
{
if (entry->leafkey)
{
inetKEY *r = (inetKEY *) palloc(sizeof(inetKEY));
retval = palloc(sizeof(GISTENTRY));
r->lower = convert_network_to_scalar(entry->key, typid );
r->upper = r->lower ;
gistentryinit(*retval, PointerGetDatum(r),
entry->rel, entry->page,
entry->offset, sizeof(inetKEY), FALSE);
}
else
retval = entry;
return ( retval );
}
Datum
gbt_inet_compress(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
GISTENTRY *retval = NULL;
PG_RETURN_POINTER( gbt_inet_compress_inetrnal(retval ,entry ,INETOID ) );
}
Datum
gbt_cidr_compress(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
GISTENTRY *retval = NULL;
PG_RETURN_POINTER( gbt_inet_compress_inetrnal(retval ,entry ,CIDROID ) );
}
static bool
gbt_inet_consistent_internal (
const GISTENTRY * entry,
const double * query,
const StrategyNumber * strategy
){
inetKEY *kkk = (inetKEY *) DatumGetPointer(entry->key);
GBT_NUMKEY_R key ;
key.lower = (GBT_NUMKEY*) &kkk->lower ;
key.upper = (GBT_NUMKEY*) &kkk->upper ;
return (
gbt_num_consistent( &key, (void*)query,strategy,GIST_LEAF(entry),&tinfo)
);
}
Datum
gbt_inet_consistent(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
double query = convert_network_to_scalar( PG_GETARG_DATUM(1) ,INETOID );
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
PG_RETURN_BOOL(
gbt_inet_consistent_internal ( entry, &query, &strategy )
);
}
Datum
gbt_cidr_consistent(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
double query = convert_network_to_scalar( PG_GETARG_DATUM(1) ,CIDROID );
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
PG_RETURN_BOOL(
gbt_inet_consistent_internal ( entry, &query, &strategy )
);
}
Datum
gbt_inet_union(PG_FUNCTION_ARGS)
{
GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
void *out = palloc(sizeof(inetKEY));
*(int *) PG_GETARG_POINTER(1) = sizeof(inetKEY);
PG_RETURN_POINTER( gbt_num_union ( (void*)out, entryvec, &tinfo ) );
}
Datum
gbt_inet_penalty(PG_FUNCTION_ARGS)
{
inetKEY *origentry = (inetKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
inetKEY *newentry = (inetKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
float *result = (float *) PG_GETARG_POINTER(2);
double res ;
*result = 0.0;
res = Max(newentry->upper - origentry->upper, 0) +
Max(origentry->lower - newentry->lower, 0);
if ( res > 0 ){
*result += FLT_MIN ;
*result += (float) ( res / ( (double) ( res + origentry->upper - origentry->lower ) ) );
*result *= ( FLT_MAX / ( ( (GISTENTRY *) PG_GETARG_POINTER(0))->rel->rd_att->natts + 1 ) );
}
PG_RETURN_POINTER(result);
}
Datum
gbt_inet_picksplit(PG_FUNCTION_ARGS)
{
PG_RETURN_POINTER(gbt_num_picksplit(
(GistEntryVector *) PG_GETARG_POINTER(0),
(GIST_SPLITVEC *) PG_GETARG_POINTER(1),
&tinfo
));
}
Datum
gbt_inet_same(PG_FUNCTION_ARGS)
{
inetKEY *b1 = (inetKEY *) PG_GETARG_POINTER(0);
inetKEY *b2 = (inetKEY *) PG_GETARG_POINTER(1);
bool *result = (bool *) PG_GETARG_POINTER(2);
*result = gbt_num_same ( (void*)b1, (void*)b2, &tinfo );
PG_RETURN_POINTER(result);
}
#include "btree_gist.h"
#include "btree_utils_num.h"
typedef struct int16key
{
int16 lower;
int16 upper;
} int16KEY;
/*
** int16 ops
*/
PG_FUNCTION_INFO_V1(gbt_int2_compress);
PG_FUNCTION_INFO_V1(gbt_int2_union);
PG_FUNCTION_INFO_V1(gbt_int2_picksplit);
PG_FUNCTION_INFO_V1(gbt_int2_consistent);
PG_FUNCTION_INFO_V1(gbt_int2_penalty);
PG_FUNCTION_INFO_V1(gbt_int2_same);
Datum gbt_int2_compress(PG_FUNCTION_ARGS);
Datum gbt_int2_union(PG_FUNCTION_ARGS);
Datum gbt_int2_picksplit(PG_FUNCTION_ARGS);
Datum gbt_int2_consistent(PG_FUNCTION_ARGS);
Datum gbt_int2_penalty(PG_FUNCTION_ARGS);
Datum gbt_int2_same(PG_FUNCTION_ARGS);
static bool gbt_int2gt (const void *a, const void *b)
{
return ( *((int16*)a) > *((int16*)b) );
}
static bool gbt_int2ge (const void *a, const void *b)
{
return ( *((int16*)a) >= *((int16*)b) );
}
static bool gbt_int2eq (const void *a, const void *b)
{
return ( *((int16*)a) == *((int16*)b) );
}
static bool gbt_int2le (const void *a, const void *b)
{
return ( *((int16*)a) <= *((int16*)b) );
}
static bool gbt_int2lt (const void *a, const void *b)
{
return ( *((int16*)a) < *((int16*)b) );
}
static int
gbt_int2key_cmp(const void *a, const void *b)
{
if ( *(int16*)(&((Nsrt *) a)->t[0]) > *(int16*)&(((Nsrt *) b)->t[0]) ){
return 1;
} else
if ( *(int16*)&(((Nsrt *) a)->t[0]) < *(int16*)&(((Nsrt *) b)->t[0]) ){
return -1;
}
return 0;
}
static const gbtree_ninfo tinfo =
{
gbt_t_int2,
sizeof(int16),
gbt_int2gt,
gbt_int2ge,
gbt_int2eq,
gbt_int2le,
gbt_int2lt,
gbt_int2key_cmp
};
/**************************************************
* int16 ops
**************************************************/
Datum
gbt_int2_compress(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
GISTENTRY *retval = NULL;
PG_RETURN_POINTER( gbt_num_compress( retval , entry , &tinfo ));
}
Datum
gbt_int2_consistent(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
int16 query = PG_GETARG_INT16(1);
int16KEY *kkk = (int16KEY *) DatumGetPointer(entry->key);
GBT_NUMKEY_R key ;
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
key.lower = (GBT_NUMKEY*) &kkk->lower ;
key.upper = (GBT_NUMKEY*) &kkk->upper ;
PG_RETURN_BOOL(
gbt_num_consistent( &key, (void*)&query,&strategy,GIST_LEAF(entry),&tinfo)
);
}
Datum
gbt_int2_union(PG_FUNCTION_ARGS)
{
GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
void *out = palloc(sizeof(int16KEY));
*(int *) PG_GETARG_POINTER(1) = sizeof(int16KEY);
PG_RETURN_POINTER( gbt_num_union ( (void*)out, entryvec, &tinfo ) );
}
Datum
gbt_int2_penalty(PG_FUNCTION_ARGS)
{
int16KEY *origentry = (int16KEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
int16KEY *newentry = (int16KEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
float *result = (float *) PG_GETARG_POINTER(2);
int2 res ;
*result = 0.0;
res = Max(newentry->upper - origentry->upper, 0) +
Max(origentry->lower - newentry->lower, 0);
if ( res > 0 ){
*result += FLT_MIN ;
*result += (float) ( res / ( (double) ( res + origentry->upper - origentry->lower ) ) );
*result *= ( FLT_MAX / ( ( (GISTENTRY *) PG_GETARG_POINTER(0))->rel->rd_att->natts + 1 ) );
}
PG_RETURN_POINTER(result);
}
Datum
gbt_int2_picksplit(PG_FUNCTION_ARGS)
{
PG_RETURN_POINTER(gbt_num_picksplit(
(GistEntryVector *) PG_GETARG_POINTER(0),
(GIST_SPLITVEC *) PG_GETARG_POINTER(1),
&tinfo
));
}
Datum
gbt_int2_same(PG_FUNCTION_ARGS)
{
int16KEY *b1 = (int16KEY *) PG_GETARG_POINTER(0);
int16KEY *b2 = (int16KEY *) PG_GETARG_POINTER(1);
bool *result = (bool *) PG_GETARG_POINTER(2);
*result = gbt_num_same ( (void*)b1, (void*)b2, &tinfo );
PG_RETURN_POINTER(result);
}
#include "btree_gist.h"
#include "btree_utils_num.h"
typedef struct int32key
{
int32 lower;
int32 upper;
} int32KEY;
/*
** int32 ops
*/
PG_FUNCTION_INFO_V1(gbt_int4_compress);
PG_FUNCTION_INFO_V1(gbt_int4_union);
PG_FUNCTION_INFO_V1(gbt_int4_picksplit);
PG_FUNCTION_INFO_V1(gbt_int4_consistent);
PG_FUNCTION_INFO_V1(gbt_int4_penalty);
PG_FUNCTION_INFO_V1(gbt_int4_same);
Datum gbt_int4_compress(PG_FUNCTION_ARGS);
Datum gbt_int4_union(PG_FUNCTION_ARGS);
Datum gbt_int4_picksplit(PG_FUNCTION_ARGS);
Datum gbt_int4_consistent(PG_FUNCTION_ARGS);
Datum gbt_int4_penalty(PG_FUNCTION_ARGS);
Datum gbt_int4_same(PG_FUNCTION_ARGS);
static bool gbt_int4gt (const void *a, const void *b)
{
return ( *((int32*)a) > *((int32*)b) );
}
static bool gbt_int4ge (const void *a, const void *b)
{
return ( *((int32*)a) >= *((int32*)b) );
}
static bool gbt_int4eq (const void *a, const void *b)
{
return ( *((int32*)a) == *((int32*)b) );
}
static bool gbt_int4le (const void *a, const void *b)
{
return ( *((int32*)a) <= *((int32*)b) );
}
static bool gbt_int4lt (const void *a, const void *b)
{
return ( *((int32*)a) < *((int32*)b) );
}
static int
gbt_int4key_cmp(const void *a, const void *b)
{
if ( *(int32*)&(((Nsrt *) a)->t[0]) > *(int32*)&(((Nsrt *) b)->t[0]) ){
return 1;
} else
if ( *(int32*)&(((Nsrt *) a)->t[0]) < *(int32*)&(((Nsrt *) b)->t[0]) ){
return -1;
}
return 0;
}
static const gbtree_ninfo tinfo =
{
gbt_t_int4,
sizeof(int32),
gbt_int4gt,
gbt_int4ge,
gbt_int4eq,
gbt_int4le,
gbt_int4lt,
gbt_int4key_cmp
};
/**************************************************
* int32 ops
**************************************************/
Datum
gbt_int4_compress(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
GISTENTRY *retval = NULL;
PG_RETURN_POINTER( gbt_num_compress( retval , entry , &tinfo ));
}
Datum
gbt_int4_consistent(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
int32 query = PG_GETARG_INT32(1);
int32KEY *kkk = (int32KEY *) DatumGetPointer(entry->key);
GBT_NUMKEY_R key ;
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
key.lower = (GBT_NUMKEY*) &kkk->lower ;
key.upper = (GBT_NUMKEY*) &kkk->upper ;
PG_RETURN_BOOL(
gbt_num_consistent( &key, (void*)&query,&strategy,GIST_LEAF(entry),&tinfo)
);
}
Datum
gbt_int4_union(PG_FUNCTION_ARGS)
{
GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
void *out = palloc( sizeof(int32KEY) );
*(int *) PG_GETARG_POINTER(1) = sizeof(int32KEY);
PG_RETURN_POINTER( gbt_num_union ( (void*)out, entryvec, &tinfo ) );
}
Datum
gbt_int4_penalty(PG_FUNCTION_ARGS)
{
int32KEY *origentry = (int32KEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
int32KEY *newentry = (int32KEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
float *result = (float *) PG_GETARG_POINTER(2);
int4 res ;
*result = 0.0;
res = Max(newentry->upper - origentry->upper, 0) +
Max(origentry->lower - newentry->lower, 0);
if ( res > 0 ){
*result += FLT_MIN ;
*result += (float) ( res / ( (double) ( res + origentry->upper - origentry->lower ) ) );
*result *= ( FLT_MAX / ( ( (GISTENTRY *) PG_GETARG_POINTER(0))->rel->rd_att->natts + 1 ) );
}
PG_RETURN_POINTER(result);
}
Datum
gbt_int4_picksplit(PG_FUNCTION_ARGS)
{
PG_RETURN_POINTER(gbt_num_picksplit(
(GistEntryVector *) PG_GETARG_POINTER(0),
(GIST_SPLITVEC *) PG_GETARG_POINTER(1),
&tinfo
));
}
Datum
gbt_int4_same(PG_FUNCTION_ARGS)
{
int32KEY *b1 = (int32KEY *) PG_GETARG_POINTER(0);
int32KEY *b2 = (int32KEY *) PG_GETARG_POINTER(1);
bool *result = (bool *) PG_GETARG_POINTER(2);
*result = gbt_num_same ( (void*)b1, (void*)b2, &tinfo );
PG_RETURN_POINTER(result);
}
#include "btree_gist.h"
#include "btree_utils_num.h"
typedef struct int64key
{
int64 lower;
int64 upper;
} int64KEY;
/*
** int64 ops
*/
PG_FUNCTION_INFO_V1(gbt_int8_compress);
PG_FUNCTION_INFO_V1(gbt_int8_union);
PG_FUNCTION_INFO_V1(gbt_int8_picksplit);
PG_FUNCTION_INFO_V1(gbt_int8_consistent);
PG_FUNCTION_INFO_V1(gbt_int8_penalty);
PG_FUNCTION_INFO_V1(gbt_int8_same);
Datum gbt_int8_compress(PG_FUNCTION_ARGS);
Datum gbt_int8_union(PG_FUNCTION_ARGS);
Datum gbt_int8_picksplit(PG_FUNCTION_ARGS);
Datum gbt_int8_consistent(PG_FUNCTION_ARGS);
Datum gbt_int8_penalty(PG_FUNCTION_ARGS);
Datum gbt_int8_same(PG_FUNCTION_ARGS);
static bool gbt_int8gt (const void *a, const void *b)
{
return ( *((int64*)a) > *((int64*)b) );
}
static bool gbt_int8ge (const void *a, const void *b)
{
return ( *((int64*)a) >= *((int64*)b) );
}
static bool gbt_int8eq (const void *a, const void *b)
{
return ( *((int64*)a) == *((int64*)b) );
}
static bool gbt_int8le (const void *a, const void *b)
{
return ( *((int64*)a) <= *((int64*)b) );
}
static bool gbt_int8lt (const void *a, const void *b)
{
return ( *((int64*)a) < *((int64*)b) );
}
static int
gbt_int8key_cmp(const void *a, const void *b)
{
if ( *(int64*)&(((Nsrt *) a)->t[0]) > *(int64*)&(((Nsrt *) b)->t[0]) ){
return 1;
} else
if ( *(int64*)&(((Nsrt *) a)->t[0]) < *(int64*)&(((Nsrt *) b)->t[0]) ){
return -1;
}
return 0;
}
static const gbtree_ninfo tinfo =
{
gbt_t_int8,
sizeof(int64),
gbt_int8gt,
gbt_int8ge,
gbt_int8eq,
gbt_int8le,
gbt_int8lt,
gbt_int8key_cmp
};
/**************************************************
* int64 ops
**************************************************/
Datum
gbt_int8_compress(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
GISTENTRY *retval = NULL;
PG_RETURN_POINTER( gbt_num_compress( retval , entry , &tinfo ));
}
Datum
gbt_int8_consistent(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
int64 query = PG_GETARG_INT64(1);
int64KEY *kkk = (int64KEY *) DatumGetPointer(entry->key);
GBT_NUMKEY_R key ;
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
key.lower = (GBT_NUMKEY*) &kkk->lower ;
key.upper = (GBT_NUMKEY*) &kkk->upper ;
PG_RETURN_BOOL(
gbt_num_consistent( &key, (void*)&query,&strategy,GIST_LEAF(entry),&tinfo)
);
}
Datum
gbt_int8_union(PG_FUNCTION_ARGS)
{
GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
void *out = palloc(sizeof(int64KEY));
*(int *) PG_GETARG_POINTER(1) = sizeof(int64KEY);
PG_RETURN_POINTER( gbt_num_union ( (void*)out, entryvec, &tinfo ) );
}
Datum
gbt_int8_penalty(PG_FUNCTION_ARGS)
{
int64KEY *origentry = (int64KEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
int64KEY *newentry = (int64KEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
float *result = (float *) PG_GETARG_POINTER(2);
int64 res ;
*result = 0.0;
res = Max(newentry->upper - origentry->upper, 0) +
Max(origentry->lower - newentry->lower, 0);
if ( res > 0 ){
*result += FLT_MIN ;
*result += (float) ( res / ( (double) ( res + origentry->upper - origentry->lower ) ) );
*result *= ( FLT_MAX / ( ( (GISTENTRY *) PG_GETARG_POINTER(0))->rel->rd_att->natts + 1 ) );
}
PG_RETURN_POINTER(result);
}
Datum
gbt_int8_picksplit(PG_FUNCTION_ARGS)
{
PG_RETURN_POINTER(gbt_num_picksplit(
(GistEntryVector *) PG_GETARG_POINTER(0),
(GIST_SPLITVEC *) PG_GETARG_POINTER(1),
&tinfo
));
}
Datum
gbt_int8_same(PG_FUNCTION_ARGS)
{
int64KEY *b1 = (int64KEY *) PG_GETARG_POINTER(0);
int64KEY *b2 = (int64KEY *) PG_GETARG_POINTER(1);
bool *result = (bool *) PG_GETARG_POINTER(2);
*result = gbt_num_same ( (void*)b1, (void*)b2, &tinfo );
PG_RETURN_POINTER(result);
}
#include "btree_gist.h"
#include "btree_utils_num.h"
typedef struct
{
Interval lower,
upper;
} intvKEY;
/*
** Interval ops
*/
PG_FUNCTION_INFO_V1(gbt_intv_compress);
PG_FUNCTION_INFO_V1(gbt_intv_union);
PG_FUNCTION_INFO_V1(gbt_intv_picksplit);
PG_FUNCTION_INFO_V1(gbt_intv_consistent);
PG_FUNCTION_INFO_V1(gbt_intv_penalty);
PG_FUNCTION_INFO_V1(gbt_intv_same);
Datum gbt_intv_compress(PG_FUNCTION_ARGS);
Datum gbt_intv_union(PG_FUNCTION_ARGS);
Datum gbt_intv_picksplit(PG_FUNCTION_ARGS);
Datum gbt_intv_consistent(PG_FUNCTION_ARGS);
Datum gbt_intv_penalty(PG_FUNCTION_ARGS);
Datum gbt_intv_same(PG_FUNCTION_ARGS);
static bool gbt_intvgt (const void *a, const void *b)
{
return DirectFunctionCall2 ( interval_gt , IntervalPGetDatum ( a ) , IntervalPGetDatum ( b ) );
}
static bool gbt_intvge (const void *a, const void *b)
{
return DirectFunctionCall2 ( interval_ge , IntervalPGetDatum ( a ) , IntervalPGetDatum ( b ) );
}
static bool gbt_intveq (const void *a, const void *b)
{
return DirectFunctionCall2 ( interval_eq , IntervalPGetDatum ( a ) , IntervalPGetDatum ( b ) );
}
static bool gbt_intvle (const void *a, const void *b)
{
return DirectFunctionCall2 ( interval_le , IntervalPGetDatum ( a ) , IntervalPGetDatum ( b ) );
}
static bool gbt_intvlt (const void *a, const void *b)
{
return DirectFunctionCall2 ( interval_lt , IntervalPGetDatum ( a ) , IntervalPGetDatum ( b ) );
}
static int
gbt_intvkey_cmp(const void *a, const void *b)
{
return DatumGetInt32 (
DirectFunctionCall2 ( interval_cmp ,
IntervalPGetDatum(&((Nsrt *) a)->t[0]) ,
IntervalPGetDatum(&((Nsrt *) b)->t[0])
)
);
}
static const gbtree_ninfo tinfo =
{
gbt_t_intv,
sizeof(Interval),
gbt_intvgt,
gbt_intvge,
gbt_intveq,
gbt_intvle,
gbt_intvlt,
gbt_intvkey_cmp
};
/**************************************************
* interval ops
**************************************************/
Datum
gbt_intv_compress(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
GISTENTRY *retval = NULL;
PG_RETURN_POINTER( gbt_num_compress( retval , entry , &tinfo ));
}
Datum
gbt_intv_consistent(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
Interval *query = PG_GETARG_INTERVAL_P(1);
intvKEY *kkk = (intvKEY *) DatumGetPointer(entry->key);
GBT_NUMKEY_R key ;
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
key.lower = (GBT_NUMKEY*) &kkk->lower ;
key.upper = (GBT_NUMKEY*) &kkk->upper ;
PG_RETURN_BOOL(
gbt_num_consistent( &key, (void*)query ,&strategy,GIST_LEAF(entry),&tinfo)
);
}
Datum
gbt_intv_union(PG_FUNCTION_ARGS)
{
GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
void *out = palloc(sizeof(intvKEY));
*(int *) PG_GETARG_POINTER(1) = sizeof(intvKEY);
PG_RETURN_POINTER( gbt_num_union ( (void*)out, entryvec, &tinfo ) );
}
Datum
gbt_intv_penalty(PG_FUNCTION_ARGS)
{
intvKEY *origentry = (intvKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
intvKEY *newentry = (intvKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
float *result = (float *) PG_GETARG_POINTER(2);
Interval *intr;
#ifdef HAVE_INT64_TIMESTAMP
int64 res;
#else
double res;
#endif
intr = DatumGetIntervalP(DirectFunctionCall2(
interval_mi,
IntervalPGetDatum(&newentry->upper),
IntervalPGetDatum(&origentry->upper)
));
/* see interval_larger */
res = Max(intr->time + intr->month * (30 * 86400), 0);
pfree(intr);
intr = DatumGetIntervalP(DirectFunctionCall2(
interval_mi,
IntervalPGetDatum(&origentry->lower),
IntervalPGetDatum(&newentry->lower)
));
/* see interval_larger */
res += Max(intr->time + intr->month * (30 * 86400), 0);
pfree(intr);
*result = 0.0;
if ( res > 0 ){
intr = DatumGetIntervalP(DirectFunctionCall2(
interval_mi,
IntervalPGetDatum(&origentry->upper),
IntervalPGetDatum(&origentry->lower)
));
*result += FLT_MIN ;
*result += (float) ( res / ( (double) ( res + intr->time + intr->month * (30 * 86400) ) ) );
*result *= ( FLT_MAX / ( ( (GISTENTRY *) PG_GETARG_POINTER(0))->rel->rd_att->natts + 1 ) );
pfree ( intr );
}
PG_RETURN_POINTER(result);
}
Datum
gbt_intv_picksplit(PG_FUNCTION_ARGS)
{
PG_RETURN_POINTER(gbt_num_picksplit(
(GistEntryVector *) PG_GETARG_POINTER(0),
(GIST_SPLITVEC *) PG_GETARG_POINTER(1),
&tinfo
));
}
Datum
gbt_intv_same(PG_FUNCTION_ARGS)
{
intvKEY *b1 = (intvKEY *) PG_GETARG_POINTER(0);
intvKEY *b2 = (intvKEY *) PG_GETARG_POINTER(1);
bool *result = (bool *) PG_GETARG_POINTER(2);
*result = gbt_num_same ( (void*)b1, (void*)b2, &tinfo );
PG_RETURN_POINTER(result);
}
#include "btree_gist.h"
#include "btree_utils_num.h"
#include "utils/builtins.h"
#include "utils/inet.h"
typedef struct
{
macaddr lower;
macaddr upper;
} macKEY;
/*
** OID ops
*/
PG_FUNCTION_INFO_V1(gbt_macad_compress);
PG_FUNCTION_INFO_V1(gbt_macad_union);
PG_FUNCTION_INFO_V1(gbt_macad_picksplit);
PG_FUNCTION_INFO_V1(gbt_macad_consistent);
PG_FUNCTION_INFO_V1(gbt_macad_penalty);
PG_FUNCTION_INFO_V1(gbt_macad_same);
Datum gbt_macad_compress(PG_FUNCTION_ARGS);
Datum gbt_macad_union(PG_FUNCTION_ARGS);
Datum gbt_macad_picksplit(PG_FUNCTION_ARGS);
Datum gbt_macad_consistent(PG_FUNCTION_ARGS);
Datum gbt_macad_penalty(PG_FUNCTION_ARGS);
Datum gbt_macad_same(PG_FUNCTION_ARGS);
static bool gbt_macadgt (const void *a, const void *b)
{
return DatumGetBool(DirectFunctionCall2(macaddr_gt,PointerGetDatum(a),PointerGetDatum(b)));
}
static bool gbt_macadge (const void *a, const void *b)
{
return DatumGetBool(DirectFunctionCall2(macaddr_ge,PointerGetDatum(a),PointerGetDatum(b)));
}
static bool gbt_macadeq (const void *a, const void *b)
{
return DatumGetBool(DirectFunctionCall2(macaddr_eq,PointerGetDatum(a),PointerGetDatum(b)));
}
static bool gbt_macadle (const void *a, const void *b)
{
return DatumGetBool(DirectFunctionCall2(macaddr_le,PointerGetDatum(a),PointerGetDatum(b)));
}
static bool gbt_macadlt (const void *a, const void *b)
{
return DatumGetBool(DirectFunctionCall2(macaddr_lt,PointerGetDatum(a),PointerGetDatum(b)));
}
static int
gbt_macadkey_cmp(const void *a, const void *b)
{
return DatumGetInt32(
DirectFunctionCall2(
macaddr_cmp ,
PointerGetDatum (&((Nsrt *) a)->t[0]),
PointerGetDatum (&((Nsrt *) b)->t[0])
)
);
}
static const gbtree_ninfo tinfo =
{
gbt_t_macad,
sizeof(macaddr),
gbt_macadgt,
gbt_macadge,
gbt_macadeq,
gbt_macadle,
gbt_macadlt,
gbt_macadkey_cmp
};
/**************************************************
* macaddr ops
**************************************************/
static int64 mac_2_int64 ( macaddr * m ){
unsigned char * mi = ( unsigned char * ) m;
int64 res = 0;
int i;
for (i=0; i<6; i++ ){
res += mi[i] << ( (5-i)*8 );
}
return res;
}
Datum
gbt_macad_compress(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
GISTENTRY *retval = NULL;
PG_RETURN_POINTER( gbt_num_compress( retval , entry , &tinfo ));
}
Datum
gbt_macad_consistent(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
macaddr *query = (macaddr *) PG_GETARG_POINTER(1);
macKEY *kkk = (macKEY *) DatumGetPointer(entry->key);
GBT_NUMKEY_R key ;
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
key.lower = (GBT_NUMKEY*) &kkk->lower ;
key.upper = (GBT_NUMKEY*) &kkk->upper ;
PG_RETURN_BOOL(
gbt_num_consistent( &key, (void*)query,&strategy,GIST_LEAF(entry),&tinfo)
);
}
Datum
gbt_macad_union(PG_FUNCTION_ARGS)
{
GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
void *out = palloc(sizeof(macKEY));
*(int *) PG_GETARG_POINTER(1) = sizeof(macKEY);
PG_RETURN_POINTER( gbt_num_union ( (void*)out, entryvec, &tinfo ) );
}
Datum
gbt_macad_penalty(PG_FUNCTION_ARGS)
{
macKEY *origentry = (macKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
macKEY *newentry = (macKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
float *result = (float *) PG_GETARG_POINTER(2);
int64 iorg[2], inew[2], res ;
iorg[0] = mac_2_int64 ( &origentry->lower );
iorg[1] = mac_2_int64 ( &origentry->upper );
inew[0] = mac_2_int64 ( &newentry->lower );
inew[1] = mac_2_int64 ( &newentry->upper );
res = Max(inew[1] - iorg[1], 0) +
Max(iorg[0] - inew[0] , 0);
*result = 0.0;
if ( res > 0 ){
*result += FLT_MIN ;
*result += (float) ( res / ( (double) ( res + iorg[1] - iorg[0] ) ) );
*result *= ( FLT_MAX / ( ( (GISTENTRY *) PG_GETARG_POINTER(0))->rel->rd_att->natts + 1 ) );
}
PG_RETURN_POINTER(result);
}
Datum
gbt_macad_picksplit(PG_FUNCTION_ARGS)
{
PG_RETURN_POINTER(gbt_num_picksplit(
(GistEntryVector *) PG_GETARG_POINTER(0),
(GIST_SPLITVEC *) PG_GETARG_POINTER(1),
&tinfo
));
}
Datum
gbt_macad_same(PG_FUNCTION_ARGS)
{
macKEY *b1 = (macKEY *) PG_GETARG_POINTER(0);
macKEY *b2 = (macKEY *) PG_GETARG_POINTER(1);
bool *result = (bool *) PG_GETARG_POINTER(2);
*result = gbt_num_same ( (void*)b1, (void*)b2, &tinfo );
PG_RETURN_POINTER(result);
}
#include "btree_gist.h"
#define __DEFINE_BTREE_TYPE_HERE__ 1
typedef struct __BTREE_GIST_TYPE__key
{
__BTREE_GIST_TYPE__ lower;
__BTREE_GIST_TYPE__ upper;
} __BTREE_GIST_TYPE__KEY;
/*
** __BTREE_GIST_TYPE__key in/out
*/
PG_FUNCTION_INFO_V1(__BTREE_GIST_TYPE2__key_in);
PG_FUNCTION_INFO_V1(__BTREE_GIST_TYPE2__key_out);
Datum __BTREE_GIST_TYPE2__key_in(PG_FUNCTION_ARGS);
Datum __BTREE_GIST_TYPE2__key_out(PG_FUNCTION_ARGS);
/*
** __BTREE_GIST_TYPE__ ops
*/
PG_FUNCTION_INFO_V1(g__BTREE_GIST_TYPE2___compress);
PG_FUNCTION_INFO_V1(g__BTREE_GIST_TYPE2___union);
PG_FUNCTION_INFO_V1(g__BTREE_GIST_TYPE2___picksplit);
PG_FUNCTION_INFO_V1(g__BTREE_GIST_TYPE2___consistent);
PG_FUNCTION_INFO_V1(g__BTREE_GIST_TYPE2___penalty);
PG_FUNCTION_INFO_V1(g__BTREE_GIST_TYPE2___same);
Datum g__BTREE_GIST_TYPE2___compress(PG_FUNCTION_ARGS);
Datum g__BTREE_GIST_TYPE2___union(PG_FUNCTION_ARGS);
Datum g__BTREE_GIST_TYPE2___picksplit(PG_FUNCTION_ARGS);
Datum g__BTREE_GIST_TYPE2___consistent(PG_FUNCTION_ARGS);
Datum g__BTREE_GIST_TYPE2___penalty(PG_FUNCTION_ARGS);
Datum g__BTREE_GIST_TYPE2___same(PG_FUNCTION_ARGS);
static void g__BTREE_GIST_TYPE2___binary_union(Datum *r1, char *r2);
static int __BTREE_GIST_TYPE2__key_cmp(const void *a, const void *b);
/**************************************************
* __BTREE_GIST_TYPE__ ops
**************************************************/
Datum
g__BTREE_GIST_TYPE2___compress(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
GISTENTRY *retval;
if (entry->leafkey)
{
__BTREE_GIST_TYPE__KEY *r = ( __BTREE_GIST_TYPE__KEY * ) palloc(sizeof(__BTREE_GIST_TYPE__KEY));
#ifdef BTREE_GIST_INT2
int16 leaf = DatumGetInt16(entry->key);
#endif
#ifdef BTREE_GIST_INT4
int32 leaf = DatumGetInt32(entry->key);
#endif
#ifdef BTREE_GIST_INT8
int64 leaf = DatumGetInt64(entry->key);
#endif
#ifdef BTREE_GIST_FLOAT4
float4 leaf = DatumGetFloat4(entry->key);
#endif
#ifdef BTREE_GIST_FLOAT8
float8 leaf = DatumGetFloat8(entry->key);
#endif
retval = palloc(sizeof(GISTENTRY));
r->lower = r->upper = leaf ;
gistentryinit(*retval, PointerGetDatum(r), entry->rel, entry->page,
entry->offset, sizeof(__BTREE_GIST_TYPE__KEY), FALSE);
}
else
retval = entry;
PG_RETURN_POINTER(retval);
}
Datum
g__BTREE_GIST_TYPE2___consistent(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
#ifdef BTREE_GIST_INT2
int16 query = PG_GETARG_INT16(1);
#endif
#ifdef BTREE_GIST_INT4
int32 query = PG_GETARG_INT32(1);
#endif
#ifdef BTREE_GIST_INT8
int64 query = PG_GETARG_INT64(1);
#endif
#ifdef BTREE_GIST_FLOAT4
float4 query = PG_GETARG_FLOAT4(1);
#endif
#ifdef BTREE_GIST_FLOAT8
float8 query = PG_GETARG_FLOAT8(1);
#endif
__BTREE_GIST_TYPE__KEY *kkk = (__BTREE_GIST_TYPE__KEY *) DatumGetPointer(entry->key);
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
bool retval;
switch (strategy)
{
case BTLessEqualStrategyNumber:
retval = (query >= kkk->lower);
break;
case BTLessStrategyNumber:
if (GIST_LEAF(entry))
retval = (query > kkk->lower);
else
retval = (query >= kkk->lower);
break;
case BTEqualStrategyNumber:
/* in leaf page kkk->lower always = kkk->upper */
if (GIST_LEAF(entry))
retval = (query == kkk->lower);
else
retval = (kkk->lower <= query && query <= kkk->upper);
break;
case BTGreaterStrategyNumber:
if (GIST_LEAF(entry))
retval = (query < kkk->upper);
else
retval = (query <= kkk->upper);
break;
case BTGreaterEqualStrategyNumber:
retval = (query <= kkk->upper);
break;
default:
retval = FALSE;
}
PG_RETURN_BOOL(retval);
}
Datum
g__BTREE_GIST_TYPE2___union(PG_FUNCTION_ARGS)
{
GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
int i,
numranges;
__BTREE_GIST_TYPE__KEY *cur,
*out = palloc(sizeof(__BTREE_GIST_TYPE__KEY));
numranges = entryvec->n;
*(int *) PG_GETARG_POINTER(1) = sizeof(__BTREE_GIST_TYPE__KEY);
cur = (__BTREE_GIST_TYPE__KEY *) DatumGetPointer((entryvec->vector[0].key));
out->lower = cur->lower;
out->upper = cur->upper;
for (i = 1; i < numranges; i++)
{
cur = (__BTREE_GIST_TYPE__KEY *) DatumGetPointer((entryvec->vector[i].key));
if (out->lower > cur->lower)
out->lower = cur->lower;
if (out->upper < cur->upper)
out->upper = cur->upper;
}
PG_RETURN_POINTER(out);
}
Datum
g__BTREE_GIST_TYPE2___penalty(PG_FUNCTION_ARGS)
{
__BTREE_GIST_TYPE__KEY *origentry = (__BTREE_GIST_TYPE__KEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
__BTREE_GIST_TYPE__KEY *newentry = (__BTREE_GIST_TYPE__KEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
float *result = (float *) PG_GETARG_POINTER(2);
*result = Max(newentry->upper - origentry->upper, 0) +
Max(origentry->lower - newentry->lower, 0);
PG_RETURN_POINTER(result);
}
Datum
g__BTREE_GIST_TYPE2___picksplit(PG_FUNCTION_ARGS)
{
PG_RETURN_POINTER(btree_picksplit(
(GistEntryVector *) PG_GETARG_POINTER(0),
(GIST_SPLITVEC *) PG_GETARG_POINTER(1),
g__BTREE_GIST_TYPE2___binary_union,
__BTREE_GIST_TYPE2__key_cmp
));
}
Datum
g__BTREE_GIST_TYPE2___same(PG_FUNCTION_ARGS)
{
__BTREE_GIST_TYPE__KEY *b1 = (__BTREE_GIST_TYPE__KEY *) PG_GETARG_POINTER(0);
__BTREE_GIST_TYPE__KEY *b2 = (__BTREE_GIST_TYPE__KEY *) PG_GETARG_POINTER(1);
bool *result = (bool *) PG_GETARG_POINTER(2);
*result = (b1->lower == b2->lower && b1->upper == b2->upper) ? TRUE : FALSE;
PG_RETURN_POINTER(result);
}
static void
g__BTREE_GIST_TYPE2___binary_union(Datum *r1, char *r2)
{
__BTREE_GIST_TYPE__KEY *b1;
__BTREE_GIST_TYPE__KEY *b2 = (__BTREE_GIST_TYPE__KEY *) r2;
if (!DatumGetPointer(*r1))
{
*r1 = PointerGetDatum(palloc(sizeof(__BTREE_GIST_TYPE__KEY)));
b1 = (__BTREE_GIST_TYPE__KEY *) DatumGetPointer(*r1);
b1->upper = b2->upper;
b1->lower = b2->lower;
}
else
{
b1 = (__BTREE_GIST_TYPE__KEY *) DatumGetPointer(*r1);
b1->lower = (b1->lower > b2->lower) ?
b2->lower : b1->lower;
b1->upper = (b1->upper > b2->upper) ?
b1->upper : b2->upper;
}
}
static int
__BTREE_GIST_TYPE2__key_cmp(const void *a, const void *b)
{
if (((__BTREE_GIST_TYPE__KEY *) (((RIX *) a)->r))->lower > ((__BTREE_GIST_TYPE__KEY *) (((RIX *) b)->r))->lower){
return 1;
} else if (((__BTREE_GIST_TYPE__KEY *) (((RIX *) a)->r))->lower < ((__BTREE_GIST_TYPE__KEY *) (((RIX *) b)->r))->lower){
return -1;
} else {
return 0;
}
}
/**************************************************
* In/Out for keys
**************************************************/
Datum
__BTREE_GIST_TYPE2__key_in(PG_FUNCTION_ARGS)
{
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("<datatype>key_in() not implemented")));
PG_RETURN_POINTER(NULL);
}
Datum
__BTREE_GIST_TYPE2__key_out(PG_FUNCTION_ARGS)
{
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("<datatype>key_out() not implemented")));
PG_RETURN_POINTER(NULL);
}
#include "btree_gist.h"
#include "btree_utils_var.h"
#include "utils/builtins.h"
#include "utils/numeric.h"
/*
** Bytea ops
*/
PG_FUNCTION_INFO_V1(gbt_numeric_compress);
PG_FUNCTION_INFO_V1(gbt_numeric_union);
PG_FUNCTION_INFO_V1(gbt_numeric_picksplit);
PG_FUNCTION_INFO_V1(gbt_numeric_consistent);
PG_FUNCTION_INFO_V1(gbt_numeric_penalty);
PG_FUNCTION_INFO_V1(gbt_numeric_same);
Datum gbt_numeric_compress(PG_FUNCTION_ARGS);
Datum gbt_numeric_union(PG_FUNCTION_ARGS);
Datum gbt_numeric_picksplit(PG_FUNCTION_ARGS);
Datum gbt_numeric_consistent(PG_FUNCTION_ARGS);
Datum gbt_numeric_penalty(PG_FUNCTION_ARGS);
Datum gbt_numeric_same(PG_FUNCTION_ARGS);
/* define for comparison */
static bool gbt_numeric_gt (const void *a, const void *b)
{
return ( DatumGetBool(DirectFunctionCall2( numeric_gt ,PointerGetDatum( a ),PointerGetDatum( b ) ) ) );
}
static bool gbt_numeric_ge (const void *a, const void *b)
{
return ( DatumGetBool(DirectFunctionCall2( numeric_ge ,PointerGetDatum( a ),PointerGetDatum( b ) ) ) );
}
static bool gbt_numeric_eq (const void *a, const void *b)
{
return ( DatumGetBool(DirectFunctionCall2( numeric_eq ,PointerGetDatum( a ),PointerGetDatum( b ) ) ) );
}
static bool gbt_numeric_le (const void *a, const void *b)
{
return ( DatumGetBool(DirectFunctionCall2( numeric_le ,PointerGetDatum( a ),PointerGetDatum( b ) ) ) );
}
static bool gbt_numeric_lt (const void *a, const void *b)
{
return ( DatumGetBool(DirectFunctionCall2( numeric_lt ,PointerGetDatum( a ),PointerGetDatum( b ) ) ) );
}
static int32 gbt_numeric_cmp ( const bytea * a , const bytea * b )
{
return
( DatumGetInt32(DirectFunctionCall2(numeric_cmp,PointerGetDatum(a),PointerGetDatum(b) ) ) );
}
static const gbtree_vinfo tinfo =
{
gbt_t_numeric,
FALSE,
FALSE,
gbt_numeric_gt,
gbt_numeric_ge,
gbt_numeric_eq,
gbt_numeric_le,
gbt_numeric_lt,
gbt_numeric_cmp,
NULL
};
/**************************************************
* Text ops
**************************************************/
Datum
gbt_numeric_compress (PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
PG_RETURN_POINTER ( gbt_var_compress( entry, &tinfo ) );
}
Datum
gbt_numeric_consistent(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
GBT_VARKEY *ktst = (GBT_VARKEY *) DatumGetPointer ( entry->key ) ;
GBT_VARKEY *key = (GBT_VARKEY *) DatumGetPointer ( PG_DETOAST_DATUM( entry->key ) );
void *qtst = ( void * ) DatumGetPointer ( PG_GETARG_DATUM(1) );
void *query = ( void * ) DatumGetNumeric ( PG_GETARG_DATUM(1) );
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
bool retval = FALSE;
GBT_VARKEY_R r = gbt_var_key_readable ( key );
retval = gbt_var_consistent( &r, query, &strategy, GIST_LEAF(entry), &tinfo );
if ( ktst != key ){
pfree ( key );
}
if ( qtst != query ){
pfree ( query );
}
PG_RETURN_BOOL(retval);
}
Datum
gbt_numeric_union(PG_FUNCTION_ARGS)
{
GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
int32 * size = (int *) PG_GETARG_POINTER(1);
PG_RETURN_POINTER( gbt_var_union ( entryvec , size , &tinfo ) );
}
Datum
gbt_numeric_same(PG_FUNCTION_ARGS)
{
Datum d1 = PG_GETARG_DATUM(0);
Datum d2 = PG_GETARG_DATUM(1);
bool *result = (bool *) PG_GETARG_POINTER(2);
PG_RETURN_POINTER( gbt_var_same ( result, d1 , d2 , &tinfo ));
}
Datum
gbt_numeric_penalty (PG_FUNCTION_ARGS)
{
GISTENTRY * o = (GISTENTRY *) PG_GETARG_POINTER(0);
GISTENTRY * n = (GISTENTRY *) PG_GETARG_POINTER(1);
float *result = (float *) PG_GETARG_POINTER(2);
Numeric us, os, ds ;
GBT_VARKEY *org = (GBT_VARKEY *) DatumGetPointer(o->key);
GBT_VARKEY *newe = (GBT_VARKEY *) DatumGetPointer(n->key);
Datum uni ;
GBT_VARKEY_R rk , ok, uk ;
rk = gbt_var_key_readable ( org );
uni = PointerGetDatum( gbt_var_key_copy( &rk, TRUE ) );
gbt_var_bin_union ( &uni , newe, &tinfo );
ok = gbt_var_key_readable ( org );
uk = gbt_var_key_readable ( (GBT_VARKEY *) DatumGetPointer(uni) );
us = DatumGetNumeric(DirectFunctionCall2(
numeric_sub,
PointerGetDatum(uk.upper),
PointerGetDatum(uk.lower)
));
pfree ( DatumGetPointer(uni) );
os = DatumGetNumeric(DirectFunctionCall2(
numeric_sub,
PointerGetDatum(ok.upper),
PointerGetDatum(ok.lower)
));
ds = DatumGetNumeric(DirectFunctionCall2(
numeric_sub,
NumericGetDatum(us),
NumericGetDatum(os)
));
pfree ( os );
if ( NUMERIC_IS_NAN( us ) )
{
if ( NUMERIC_IS_NAN( os ) )
{
*result = 0.0;
} else {
*result = 1.0;
}
} else {
Numeric nul = DatumGetNumeric(DirectFunctionCall1( int4_numeric , Int32GetDatum (0) ) );
*result = 0.0;
if ( DirectFunctionCall2( numeric_gt , NumericGetDatum(ds), NumericGetDatum(nul) ) )
{
*result += FLT_MIN ;
os = DatumGetNumeric(DirectFunctionCall2(
numeric_div,
NumericGetDatum(ds),
NumericGetDatum(us)
));
*result += ( float4 ) DatumGetFloat8( DirectFunctionCall1( numeric_float8_no_overflow , NumericGetDatum(os) ) );
pfree ( os );
}
pfree ( nul );
}
if ( *result > 0 )
*result *= ( FLT_MAX / ( ( (GISTENTRY *) PG_GETARG_POINTER(0))->rel->rd_att->natts + 1 ) );
pfree ( us );
pfree ( ds );
PG_RETURN_POINTER( result );
}
Datum
gbt_numeric_picksplit(PG_FUNCTION_ARGS)
{
GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1);
gbt_var_picksplit ( entryvec, v, &tinfo );
PG_RETURN_POINTER(v);
}
#include "btree_gist.h"
#include "btree_utils_num.h"
typedef struct
{
Oid lower;
Oid upper;
} oidKEY;
/*
** OID ops
*/
PG_FUNCTION_INFO_V1(gbt_oid_compress);
PG_FUNCTION_INFO_V1(gbt_oid_union);
PG_FUNCTION_INFO_V1(gbt_oid_picksplit);
PG_FUNCTION_INFO_V1(gbt_oid_consistent);
PG_FUNCTION_INFO_V1(gbt_oid_penalty);
PG_FUNCTION_INFO_V1(gbt_oid_same);
Datum gbt_oid_compress(PG_FUNCTION_ARGS);
Datum gbt_oid_union(PG_FUNCTION_ARGS);
Datum gbt_oid_picksplit(PG_FUNCTION_ARGS);
Datum gbt_oid_consistent(PG_FUNCTION_ARGS);
Datum gbt_oid_penalty(PG_FUNCTION_ARGS);
Datum gbt_oid_same(PG_FUNCTION_ARGS);
static bool gbt_oidgt (const void *a, const void *b)
{
return ( *((Oid*)a) > *((Oid*)b) );
}
static bool gbt_oidge (const void *a, const void *b)
{
return ( *((Oid*)a) >= *((Oid*)b) );
}
static bool gbt_oideq (const void *a, const void *b)
{
return ( *((Oid*)a) == *((Oid*)b) );
}
static bool gbt_oidle (const void *a, const void *b)
{
return ( *((Oid*)a) <= *((Oid*)b) );
}
static bool gbt_oidlt (const void *a, const void *b)
{
return ( *((Oid*)a) < *((Oid*)b) );
}
static int
gbt_oidkey_cmp(const void *a, const void *b)
{
if ( *(Oid*)&(((Nsrt *) a)->t[0]) > *(Oid*)&(((Nsrt *) b)->t[0]) ){
return 1;
} else
if ( *(Oid*)&(((Nsrt *) a)->t[0]) < *(Oid*)&(((Nsrt *) b)->t[0]) ){
return -1;
}
return 0;
}
static const gbtree_ninfo tinfo =
{
gbt_t_oid,
sizeof(Oid),
gbt_oidgt,
gbt_oidge,
gbt_oideq,
gbt_oidle,
gbt_oidlt,
gbt_oidkey_cmp
};
/**************************************************
* Oid ops
**************************************************/
Datum
gbt_oid_compress(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
GISTENTRY *retval = NULL;
PG_RETURN_POINTER( gbt_num_compress( retval , entry , &tinfo ));
}
Datum
gbt_oid_consistent(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
Oid query = PG_GETARG_OID(1);
oidKEY *kkk = (oidKEY *) DatumGetPointer(entry->key);
GBT_NUMKEY_R key ;
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
key.lower = (GBT_NUMKEY*) &kkk->lower ;
key.upper = (GBT_NUMKEY*) &kkk->upper ;
PG_RETURN_BOOL(
gbt_num_consistent( &key, (void*)&query,&strategy,GIST_LEAF(entry),&tinfo)
);
}
Datum
gbt_oid_union(PG_FUNCTION_ARGS)
{
GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
void *out = palloc(sizeof(oidKEY));
*(int *) PG_GETARG_POINTER(1) = sizeof(oidKEY);
PG_RETURN_POINTER( gbt_num_union ( (void*)out, entryvec, &tinfo ) );
}
Datum
gbt_oid_penalty(PG_FUNCTION_ARGS)
{
oidKEY *origentry = (oidKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
oidKEY *newentry = (oidKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
float *result = (float *) PG_GETARG_POINTER(2);
Oid res ;
*result = 0.0;
res = Max(newentry->upper - origentry->upper, 0) +
Max(origentry->lower - newentry->lower, 0);
if ( res > 0 ){
*result += FLT_MIN ;
*result += (float) ( res / ( (double) ( res + origentry->upper - origentry->lower ) ) );
*result *= ( FLT_MAX / ( ( (GISTENTRY *) PG_GETARG_POINTER(0))->rel->rd_att->natts + 1 ) );
}
PG_RETURN_POINTER(result);
}
Datum
gbt_oid_picksplit(PG_FUNCTION_ARGS)
{
PG_RETURN_POINTER(gbt_num_picksplit(
(GistEntryVector *) PG_GETARG_POINTER(0),
(GIST_SPLITVEC *) PG_GETARG_POINTER(1),
&tinfo
));
}
Datum
gbt_oid_same(PG_FUNCTION_ARGS)
{
oidKEY *b1 = (oidKEY *) PG_GETARG_POINTER(0);
oidKEY *b2 = (oidKEY *) PG_GETARG_POINTER(1);
bool *result = (bool *) PG_GETARG_POINTER(2);
*result = gbt_num_same ( (void*)b1, (void*)b2, &tinfo );
PG_RETURN_POINTER(result);
}
#include "btree_gist.h"
#include "btree_utils_var.h"
#include "utils/builtins.h"
/*
** Text ops
*/
PG_FUNCTION_INFO_V1(gbt_text_compress);
PG_FUNCTION_INFO_V1(gbt_bpchar_compress);
PG_FUNCTION_INFO_V1(gbt_text_union);
PG_FUNCTION_INFO_V1(gbt_text_picksplit);
PG_FUNCTION_INFO_V1(gbt_text_consistent);
PG_FUNCTION_INFO_V1(gbt_bpchar_consistent);
PG_FUNCTION_INFO_V1(gbt_text_penalty);
PG_FUNCTION_INFO_V1(gbt_text_same);
Datum gbt_text_compress(PG_FUNCTION_ARGS);
Datum gbt_bpchar_compress(PG_FUNCTION_ARGS);
Datum gbt_text_union(PG_FUNCTION_ARGS);
Datum gbt_text_picksplit(PG_FUNCTION_ARGS);
Datum gbt_text_consistent(PG_FUNCTION_ARGS);
Datum gbt_bpchar_consistent(PG_FUNCTION_ARGS);
Datum gbt_text_penalty(PG_FUNCTION_ARGS);
Datum gbt_text_same(PG_FUNCTION_ARGS);
/* define for comparison */
static bool gbt_textgt (const void *a, const void *b)
{
return ( DatumGetBool(DirectFunctionCall2( text_gt ,PointerGetDatum( a ),PointerGetDatum( b ) ) ) );
}
static bool gbt_textge (const void *a, const void *b)
{
return ( DatumGetBool(DirectFunctionCall2( text_ge ,PointerGetDatum( a ),PointerGetDatum( b ) ) ) );
}
static bool gbt_texteq (const void *a, const void *b)
{
return ( DatumGetBool(DirectFunctionCall2( texteq ,PointerGetDatum( a ),PointerGetDatum( b ) ) ) );
}
static bool gbt_textle (const void *a, const void *b)
{
return ( DatumGetBool(DirectFunctionCall2( text_le ,PointerGetDatum( a ),PointerGetDatum( b ) ) ) );
}
static bool gbt_textlt (const void *a, const void *b)
{
return ( DatumGetBool(DirectFunctionCall2( text_lt ,PointerGetDatum( a ),PointerGetDatum( b ) ) ) );
}
static int32 gbt_textcmp ( const bytea * a , const bytea * b )
{
return strcmp( VARDATA(a), VARDATA(b) );
}
/*
* Converts data of leaf using strxfrm ( locale support )
*/
static bytea *
gbt_text_xfrm ( bytea * leaf )
{
bytea * out = leaf;
int32 ilen = VARSIZE (leaf) - VARHDRSZ;
int32 olen ;
char sin[ilen+1];
char * sou = NULL;
memcpy ( (void*)&sin[0], (void*) VARDATA(leaf) ,ilen );
sin[ilen] = '\0';
olen = strxfrm ( NULL, &sin[0], 0 ) + 1;
sou = palloc ( olen );
olen = strxfrm ( sou , &sin[0] , olen );
olen += VARHDRSZ;
out = palloc ( olen + 1 );
out->vl_len = olen+1;
memcpy( (void*) VARDATA(out), sou, olen-VARHDRSZ );
((char*)out)[olen] = '\0';
pfree(sou);
return out;
}
static GBT_VARKEY * gbt_text_l2n ( GBT_VARKEY * leaf )
{
GBT_VARKEY *out = leaf ;
GBT_VARKEY_R r = gbt_var_key_readable ( leaf );
bytea * o ;
o = gbt_text_xfrm ( r.lower );
r.lower = r.upper = o;
out = gbt_var_key_copy ( &r , TRUE );
pfree(o);
return out;
}
static const gbtree_vinfo tinfo =
{
gbt_t_text,
TRUE,
TRUE,
gbt_textgt,
gbt_textge,
gbt_texteq,
gbt_textle,
gbt_textlt,
gbt_textcmp,
gbt_text_l2n
};
/**************************************************
* Text ops
**************************************************/
Datum
gbt_text_compress (PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
PG_RETURN_POINTER ( gbt_var_compress( entry, &tinfo ) );
}
Datum
gbt_bpchar_compress (PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
GISTENTRY * retval ;
if (entry->leafkey)
{
Datum d = DirectFunctionCall1 ( rtrim1, entry->key );
GISTENTRY * trim = palloc(sizeof(GISTENTRY));
gistentryinit(*trim, d ,
entry->rel, entry->page,
entry->offset, VARSIZE(DatumGetPointer(d)), TRUE);
retval = gbt_var_compress( trim , &tinfo ) ;
pfree ( trim );
pfree ( DatumGetPointer(d) );
} else
retval = entry;
PG_RETURN_POINTER ( retval );
}
Datum
gbt_text_consistent(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
GBT_VARKEY *ktst = (GBT_VARKEY *) DatumGetPointer ( entry->key ) ;
GBT_VARKEY *key = (GBT_VARKEY *) DatumGetPointer ( PG_DETOAST_DATUM( entry->key ) );
void *qtst = ( void * ) DatumGetPointer( PG_GETARG_DATUM(1) );
void *query = ( void * ) DatumGetTextP ( PG_GETARG_DATUM(1) );
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
bool retval = FALSE;
GBT_VARKEY_R r = gbt_var_key_readable ( key );
if ( GIST_LEAF(entry) )
{
retval = gbt_var_consistent( &r, query, &strategy, TRUE, &tinfo );
} else {
bytea * q = gbt_text_xfrm ( ( bytea * ) query );
retval = gbt_var_consistent( &r, (void*)q, &strategy, FALSE, &tinfo );
if ( q != query )
pfree(q);
}
if ( ktst != key ){
pfree ( key );
}
if ( qtst != query ){
pfree ( query );
}
PG_RETURN_BOOL(retval);
}
Datum
gbt_bpchar_consistent(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
GBT_VARKEY *ktst = (GBT_VARKEY *) DatumGetPointer ( entry->key ) ;
GBT_VARKEY *key = (GBT_VARKEY *) DatumGetPointer ( PG_DETOAST_DATUM( entry->key ) );
void *qtst = ( void * ) DatumGetPointer ( PG_GETARG_DATUM(1) );
void *query = ( void * ) DatumGetPointer (PG_DETOAST_DATUM( PG_GETARG_DATUM(1) ) );
void *trim = ( void * ) DatumGetPointer ( DirectFunctionCall1 ( rtrim1, PointerGetDatum ( query ) ) ) ;
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
bool retval = FALSE;
GBT_VARKEY_R r = gbt_var_key_readable ( key );
if ( GIST_LEAF(entry) )
{
retval = gbt_var_consistent( &r, trim , &strategy, TRUE, &tinfo );
} else {
bytea * q = gbt_text_xfrm ( ( bytea * ) trim );
retval = gbt_var_consistent( &r, (void*)q, &strategy, FALSE, &tinfo );
if ( q != trim )
pfree(q);
}
pfree(trim);
if ( ktst != key ){
pfree ( key );
}
if ( qtst != query ){
pfree ( query );
}
PG_RETURN_BOOL(retval);
}
Datum
gbt_text_union(PG_FUNCTION_ARGS)
{
GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
int32 *size = (int *) PG_GETARG_POINTER(1);
PG_RETURN_POINTER( gbt_var_union ( entryvec , size , &tinfo ) );
}
Datum
gbt_text_picksplit(PG_FUNCTION_ARGS)
{
GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1);
gbt_var_picksplit ( entryvec, v, &tinfo );
PG_RETURN_POINTER(v);
}
Datum
gbt_text_same(PG_FUNCTION_ARGS)
{
Datum d1 = PG_GETARG_DATUM(0);
Datum d2 = PG_GETARG_DATUM(1);
bool *result = (bool *) PG_GETARG_POINTER(2);
PG_RETURN_POINTER( gbt_var_same ( result, d1 , d2 , &tinfo ));
}
Datum
gbt_text_penalty(PG_FUNCTION_ARGS)
{
float *result = (float *) PG_GETARG_POINTER(2);
GISTENTRY * o = (GISTENTRY *) PG_GETARG_POINTER(0);
GISTENTRY * n = (GISTENTRY *) PG_GETARG_POINTER(1);
PG_RETURN_POINTER( gbt_var_penalty ( result ,o , n, &tinfo ) );
}
#include "btree_gist.h"
#include "btree_utils_num.h"
#include "utils/date.h"
typedef struct
{
TimeADT lower;
TimeADT upper;
} timeKEY;
/*
** time ops
*/
PG_FUNCTION_INFO_V1(gbt_time_compress);
PG_FUNCTION_INFO_V1(gbt_timetz_compress);
PG_FUNCTION_INFO_V1(gbt_time_union);
PG_FUNCTION_INFO_V1(gbt_time_picksplit);
PG_FUNCTION_INFO_V1(gbt_time_consistent);
PG_FUNCTION_INFO_V1(gbt_timetz_consistent);
PG_FUNCTION_INFO_V1(gbt_time_penalty);
PG_FUNCTION_INFO_V1(gbt_time_same);
Datum gbt_time_compress(PG_FUNCTION_ARGS);
Datum gbt_timetz_compress(PG_FUNCTION_ARGS);
Datum gbt_time_union(PG_FUNCTION_ARGS);
Datum gbt_time_picksplit(PG_FUNCTION_ARGS);
Datum gbt_time_consistent(PG_FUNCTION_ARGS);
Datum gbt_timetz_consistent(PG_FUNCTION_ARGS);
Datum gbt_time_penalty(PG_FUNCTION_ARGS);
Datum gbt_time_same(PG_FUNCTION_ARGS);
static bool gbt_timegt (const void *a, const void *b)
{
return DatumGetBool(
DirectFunctionCall2(time_gt,TimeADTGetDatum( *((TimeADT*)a) ), TimeADTGetDatum( *((TimeADT*)b) ) )
);
}
static bool gbt_timege (const void *a, const void *b)
{
return DatumGetBool(
DirectFunctionCall2(time_ge,TimeADTGetDatum( *((TimeADT*)a) ), TimeADTGetDatum( *((TimeADT*)b) ) )
);
}
static bool gbt_timeeq (const void *a, const void *b)
{
return DatumGetBool(
DirectFunctionCall2(time_eq,TimeADTGetDatum( *((TimeADT*)a) ), TimeADTGetDatum( *((TimeADT*)b) ) )
);
}
static bool gbt_timele (const void *a, const void *b)
{
return DatumGetBool(
DirectFunctionCall2(time_le,TimeADTGetDatum( *((TimeADT*)a) ), TimeADTGetDatum( *((TimeADT*)b) ) )
);
}
static bool gbt_timelt (const void *a, const void *b)
{
return DatumGetBool(
DirectFunctionCall2(time_lt,TimeADTGetDatum( *((TimeADT*)a) ), TimeADTGetDatum( *((TimeADT*)b) ) )
);
}
static int
gbt_timekey_cmp(const void *a, const void *b)
{
if ( gbt_timegt( (void*)&(((Nsrt *) a)->t[0]) , (void*)&(((Nsrt *) b)->t[0]) ) ){
return 1;
} else
if ( gbt_timelt( (void*)&(((Nsrt *) a)->t[0]) , (void*)&(((Nsrt *) b)->t[0]) ) ){
return -1;
}
return 0;
}
static const gbtree_ninfo tinfo =
{
gbt_t_time,
sizeof(TimeADT),
gbt_timegt,
gbt_timege,
gbt_timeeq,
gbt_timele,
gbt_timelt,
gbt_timekey_cmp
};
/**************************************************
* time ops
**************************************************/
Datum
gbt_time_compress(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
GISTENTRY *retval = NULL;
PG_RETURN_POINTER( gbt_num_compress( retval , entry , &tinfo ));
}
Datum
gbt_timetz_compress(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
GISTENTRY *retval;
if (entry->leafkey)
{
timeKEY *r = (timeKEY *) palloc(sizeof(timeKEY));
TimeTzADT *tz = DatumGetTimeTzADTP(entry->key);
retval = palloc(sizeof(GISTENTRY));
/* We are using the time + zone only to compress */
r->lower = r->upper = ( tz->time + tz->zone ) ;
gistentryinit(*retval, PointerGetDatum(r),
entry->rel, entry->page,
entry->offset, sizeof(timeKEY), FALSE);
}
else
retval = entry;
PG_RETURN_POINTER(retval);
}
Datum
gbt_time_consistent(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
TimeADT query = PG_GETARG_TIMEADT( 1 );
timeKEY *kkk = (timeKEY *) DatumGetPointer(entry->key);
GBT_NUMKEY_R key ;
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
key.lower = (GBT_NUMKEY*) &kkk->lower ;
key.upper = (GBT_NUMKEY*) &kkk->upper ;
PG_RETURN_BOOL(
gbt_num_consistent( &key, (void*)&query,&strategy,GIST_LEAF(entry),&tinfo)
);
}
Datum
gbt_timetz_consistent(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
TimeTzADT *query = PG_GETARG_TIMETZADT_P( 1 );
TimeADT qqq = query->time + query->zone ;
timeKEY *kkk = (timeKEY *) DatumGetPointer(entry->key);
GBT_NUMKEY_R key ;
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
key.lower = (GBT_NUMKEY*) &kkk->lower ;
key.upper = (GBT_NUMKEY*) &kkk->upper ;
PG_RETURN_BOOL(
gbt_num_consistent( &key, (void*)&qqq, &strategy,GIST_LEAF(entry),&tinfo)
);
}
Datum
gbt_time_union(PG_FUNCTION_ARGS)
{
GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
void *out = palloc(sizeof(timeKEY));
*(int *) PG_GETARG_POINTER(1) = sizeof(timeKEY);
PG_RETURN_POINTER( gbt_num_union ( (void*)out, entryvec, &tinfo ) );
}
Datum
gbt_time_penalty(PG_FUNCTION_ARGS)
{
timeKEY *origentry = (timeKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
timeKEY *newentry = (timeKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
float *result = (float *) PG_GETARG_POINTER(2);
Interval *intr;
#ifdef HAVE_INT64_TIMESTAMP
int64 res;
#else
double res;
#endif
intr = DatumGetIntervalP(DirectFunctionCall2(
time_mi_time,
TimeADTGetDatum(newentry->upper),
TimeADTGetDatum(origentry->upper)));
/* see interval_larger */
res = Max(intr->time + intr->month * (30 * 86400), 0);
pfree(intr);
intr = DatumGetIntervalP(DirectFunctionCall2(
time_mi_time,
TimeADTGetDatum(origentry->lower),
TimeADTGetDatum(newentry->lower)));
/* see interval_larger */
res += Max(intr->time + intr->month * (30 * 86400), 0);
pfree(intr);
*result = 0.0;
if ( res > 0 ){
intr = DatumGetIntervalP(DirectFunctionCall2(
time_mi_time,
TimeADTGetDatum(origentry->upper),
TimeADTGetDatum(origentry->lower)));
*result += FLT_MIN ;
*result += (float) ( res / ( (double) ( res + intr->time + intr->month * (30 * 86400) ) ) );
*result *= ( FLT_MAX / ( ( (GISTENTRY *) PG_GETARG_POINTER(0))->rel->rd_att->natts + 1 ) );
pfree ( intr );
}
PG_RETURN_POINTER(result);
}
Datum
gbt_time_picksplit(PG_FUNCTION_ARGS)
{
PG_RETURN_POINTER(gbt_num_picksplit(
(GistEntryVector *) PG_GETARG_POINTER(0),
(GIST_SPLITVEC *) PG_GETARG_POINTER(1),
&tinfo
));
}
Datum
gbt_time_same(PG_FUNCTION_ARGS)
{
timeKEY *b1 = (timeKEY *) PG_GETARG_POINTER(0);
timeKEY *b2 = (timeKEY *) PG_GETARG_POINTER(1);
bool *result = (bool *) PG_GETARG_POINTER(2);
*result = gbt_num_same ( (void*)b1, (void*)b2, &tinfo );
PG_RETURN_POINTER(result);
}
This diff is collapsed.
This diff is collapsed.
typedef char GBT_NUMKEY;
/* Better readable key */
typedef struct
{
const GBT_NUMKEY * lower, * upper;
} GBT_NUMKEY_R;
/* for sorting */
typedef struct
{
int i;
GBT_NUMKEY * t;
} Nsrt;
/* type description */
typedef struct
{
/* Attribs */
enum gbtree_type t ; /* data type */
int32 size ; /* size of type , 0 means variable */
/* Methods */
bool (*f_gt) ( const void * , const void * ); /* greater then */
bool (*f_ge) ( const void * , const void * ); /* greater equal */
bool (*f_eq) ( const void * , const void * ); /* equal */
bool (*f_le) ( const void * , const void * ); /* less equal */
bool (*f_lt) ( const void * , const void * ); /* less then */
int (*f_cmp) ( const void * , const void * ); /* key compare function */
} gbtree_ninfo;
/*
* Numeric btree functions
*/
extern bool gbt_num_consistent( const GBT_NUMKEY_R * key , const void * query,
const StrategyNumber * strategy , bool is_leaf,
const gbtree_ninfo * tinfo );
extern GIST_SPLITVEC *gbt_num_picksplit ( const GistEntryVector *entryvec, GIST_SPLITVEC *v,
const gbtree_ninfo * tinfo );
extern GISTENTRY *gbt_num_compress( GISTENTRY *retval , GISTENTRY *entry ,
const gbtree_ninfo * tinfo );
extern void *gbt_num_union ( GBT_NUMKEY * out, const GistEntryVector * entryvec,
const gbtree_ninfo * tinfo );
extern bool gbt_num_same ( const GBT_NUMKEY * a, const GBT_NUMKEY * b,
const gbtree_ninfo * tinfo );
extern void gbt_num_bin_union(Datum * u , GBT_NUMKEY * e ,
const gbtree_ninfo * tinfo );
This diff is collapsed.
/* Variable length key */
typedef bytea GBT_VARKEY;
/* Better readable key */
typedef struct
{
bytea * lower, * upper;
} GBT_VARKEY_R;
/* used for key sorting */
typedef struct
{
int i ;
GBT_VARKEY * t ;
} Vsrt ;
/*
type description
*/
typedef struct
{
/* Attribs */
enum gbtree_type t ; /* data type */
bool str ; /* true, if string ( else binary ) */
bool trnc ; /* truncate (=compress) key */
/* Methods */
bool (*f_gt) ( const void * , const void * ); /* greater then */
bool (*f_ge) ( const void * , const void * ); /* greater equal */
bool (*f_eq) ( const void * , const void * ); /* equal */
bool (*f_le) ( const void * , const void * ); /* less equal */
bool (*f_lt) ( const void * , const void * ); /* less then */
int32 (*f_cmp) ( const bytea * , const bytea * ); /* node compare */
GBT_VARKEY* (*f_l2n) ( GBT_VARKEY * ); /* convert leaf to node */
} gbtree_vinfo;
extern GBT_VARKEY_R gbt_var_key_readable ( const GBT_VARKEY * k );
extern GBT_VARKEY *gbt_var_key_copy ( const GBT_VARKEY_R * u, bool force_node );
extern GISTENTRY *gbt_var_compress ( GISTENTRY *entry , const gbtree_vinfo * tinfo );
extern GBT_VARKEY *gbt_var_union ( const GistEntryVector * entryvec , int32 * size ,
const gbtree_vinfo * tinfo );
extern bool gbt_var_same ( bool * result, const Datum d1 , const Datum d2 ,
const gbtree_vinfo * tinfo );
extern float *gbt_var_penalty ( float * res , const GISTENTRY * o , const GISTENTRY * n,
const gbtree_vinfo * tinfo );
extern bool gbt_var_consistent( GBT_VARKEY_R * key , const void * query,
const StrategyNumber * strategy , bool is_leaf,
const gbtree_vinfo * tinfo );
extern GIST_SPLITVEC *gbt_var_picksplit ( const GistEntryVector *entryvec, GIST_SPLITVEC *v,
const gbtree_vinfo * tinfo );
extern void gbt_var_bin_union ( Datum * u , GBT_VARKEY * e ,
const gbtree_vinfo * tinfo );
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
-1890.000000000000000000000000000000000000000000000000000000000000000000000000001
-1889.999999999999999999999999999999999999999999999999999999999999999999999999999
123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567891
123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567892
10000
0
0
0
NaN
NaN
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
--
-- first, define the datatype. Turn off echoing so that expected file
-- does not depend on contents of btree_gist.sql.
--
\set ECHO none
\i btree_gist.sql
\set ECHO all
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment