From 7b81988f9b5275e2cdf7bbb0ca0620a24f1afc82 Mon Sep 17 00:00:00 2001 From: Teodor Sigaev Date: Thu, 3 Jun 2004 12:26:10 +0000 Subject: [PATCH] - Add aligment of variable data types - Add aligment for interval data types - Avoid floating point overflow in penalty functions Janko Richter and teodor --- contrib/btree_gist/btree_cash.c | 3 +- contrib/btree_gist/btree_date.c | 3 +- contrib/btree_gist/btree_float4.c | 7 +- contrib/btree_gist/btree_float8.c | 4 +- contrib/btree_gist/btree_gist.sql.in | 7 +- contrib/btree_gist/btree_inet.c | 6 +- contrib/btree_gist/btree_int2.c | 3 +- contrib/btree_gist/btree_int4.c | 4 +- contrib/btree_gist/btree_int8.c | 3 +- contrib/btree_gist/btree_interval.c | 133 +++++++++++++++++---------- contrib/btree_gist/btree_macaddr.c | 23 ++--- contrib/btree_gist/btree_oid.c | 6 +- contrib/btree_gist/btree_time.c | 7 +- contrib/btree_gist/btree_ts.c | 10 +- contrib/btree_gist/btree_utils_num.c | 23 +++-- contrib/btree_gist/btree_utils_num.h | 11 +++ contrib/btree_gist/btree_utils_var.c | 18 ++-- 17 files changed, 161 insertions(+), 110 deletions(-) diff --git a/contrib/btree_gist/btree_cash.c b/contrib/btree_gist/btree_cash.c index feadd7a73e4..6c5acb3e7e1 100644 --- a/contrib/btree_gist/btree_cash.c +++ b/contrib/btree_gist/btree_cash.c @@ -126,8 +126,7 @@ gbt_cash_penalty(PG_FUNCTION_ARGS) *result = 0.0; - res = Max(newentry->upper - origentry->upper, 0) + - Max(origentry->lower - newentry->lower, 0); + penalty_range_enlarge ( origentry->lower, origentry->upper, newentry->lower, newentry->upper ); if ( res > 0 ){ *result += FLT_MIN ; diff --git a/contrib/btree_gist/btree_date.c b/contrib/btree_gist/btree_date.c index be7d6d9324f..9522d386252 100644 --- a/contrib/btree_gist/btree_date.c +++ b/contrib/btree_gist/btree_date.c @@ -112,9 +112,10 @@ gbt_date_consistent(PG_FUNCTION_ARGS) 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) ); diff --git a/contrib/btree_gist/btree_float4.c b/contrib/btree_gist/btree_float4.c index 1c40c145a8e..621532d9a99 100644 --- a/contrib/btree_gist/btree_float4.c +++ b/contrib/btree_gist/btree_float4.c @@ -91,8 +91,8 @@ 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); + 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 ; @@ -125,8 +125,7 @@ gbt_float4_penalty(PG_FUNCTION_ARGS) *result = 0.0; - res = Max(newentry->upper - origentry->upper, 0) + - Max(origentry->lower - newentry->lower, 0); + penalty_range_enlarge ( origentry->lower, origentry->upper, newentry->lower, newentry->upper ); if ( res > 0 ){ *result += FLT_MIN ; diff --git a/contrib/btree_gist/btree_float8.c b/contrib/btree_gist/btree_float8.c index a50fb627376..e19632fd78c 100644 --- a/contrib/btree_gist/btree_float8.c +++ b/contrib/btree_gist/btree_float8.c @@ -91,6 +91,7 @@ gbt_float8_compress(PG_FUNCTION_ARGS) 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); @@ -126,8 +127,7 @@ gbt_float8_penalty(PG_FUNCTION_ARGS) *result = 0.0; - res = Max(newentry->upper - origentry->upper, 0) + - Max(origentry->lower - newentry->lower, 0); + penalty_range_enlarge ( origentry->lower, origentry->upper, newentry->lower, newentry->upper ); if ( res > 0 ){ *result += FLT_MIN ; diff --git a/contrib/btree_gist/btree_gist.sql.in b/contrib/btree_gist/btree_gist.sql.in index a99c1ea6edb..5dafe15960b 100644 --- a/contrib/btree_gist/btree_gist.sql.in +++ b/contrib/btree_gist/btree_gist.sql.in @@ -676,6 +676,11 @@ RETURNS internal AS 'MODULE_PATHNAME' LANGUAGE 'C'; +CREATE FUNCTION gbt_intv_decompress(internal) +RETURNS internal +AS 'MODULE_PATHNAME' +LANGUAGE 'C'; + CREATE FUNCTION gbt_intv_penalty(internal,internal,internal) RETURNS internal AS 'MODULE_PATHNAME' @@ -708,7 +713,7 @@ AS FUNCTION 1 gbt_intv_consistent (internal, interval, int2), FUNCTION 2 gbt_intv_union (bytea, internal), FUNCTION 3 gbt_intv_compress (internal), - FUNCTION 4 gbt_decompress (internal), + FUNCTION 4 gbt_intv_decompress (internal), FUNCTION 5 gbt_intv_penalty (internal, internal, internal), FUNCTION 6 gbt_intv_picksplit (internal, internal), FUNCTION 7 gbt_intv_same (internal, internal, internal), diff --git a/contrib/btree_gist/btree_inet.c b/contrib/btree_gist/btree_inet.c index 9517036f72f..5b3f66789de 100644 --- a/contrib/btree_gist/btree_inet.c +++ b/contrib/btree_gist/btree_inet.c @@ -134,9 +134,10 @@ gbt_inet_consistent_internal ( ){ 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) ); @@ -189,8 +190,7 @@ gbt_inet_penalty(PG_FUNCTION_ARGS) *result = 0.0; - res = Max(newentry->upper - origentry->upper, 0) + - Max(origentry->lower - newentry->lower, 0); + penalty_range_enlarge ( origentry->lower, origentry->upper, newentry->lower, newentry->upper ); if ( res > 0 ){ *result += FLT_MIN ; diff --git a/contrib/btree_gist/btree_int2.c b/contrib/btree_gist/btree_int2.c index 69393aee82e..9b791df2c37 100644 --- a/contrib/btree_gist/btree_int2.c +++ b/contrib/btree_gist/btree_int2.c @@ -128,8 +128,7 @@ gbt_int2_penalty(PG_FUNCTION_ARGS) *result = 0.0; - res = Max(newentry->upper - origentry->upper, 0) + - Max(origentry->lower - newentry->lower, 0); + penalty_range_enlarge ( origentry->lower, origentry->upper, newentry->lower, newentry->upper ); if ( res > 0 ){ *result += FLT_MIN ; diff --git a/contrib/btree_gist/btree_int4.c b/contrib/btree_gist/btree_int4.c index 22e3fa1618a..6e26752e5f3 100644 --- a/contrib/btree_gist/btree_int4.c +++ b/contrib/btree_gist/btree_int4.c @@ -91,6 +91,7 @@ gbt_int4_compress(PG_FUNCTION_ARGS) 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); @@ -125,8 +126,7 @@ gbt_int4_penalty(PG_FUNCTION_ARGS) *result = 0.0; - res = Max(newentry->upper - origentry->upper, 0) + - Max(origentry->lower - newentry->lower, 0); + penalty_range_enlarge ( origentry->lower, origentry->upper, newentry->lower, newentry->upper ); if ( res > 0 ){ *result += FLT_MIN ; diff --git a/contrib/btree_gist/btree_int8.c b/contrib/btree_gist/btree_int8.c index 254fc740f87..c12d078f4cd 100644 --- a/contrib/btree_gist/btree_int8.c +++ b/contrib/btree_gist/btree_int8.c @@ -125,8 +125,7 @@ gbt_int8_penalty(PG_FUNCTION_ARGS) *result = 0.0; - res = Max(newentry->upper - origentry->upper, 0) + - Max(origentry->lower - newentry->lower, 0); + penalty_range_enlarge ( origentry->lower, origentry->upper, newentry->lower, newentry->upper ); if ( res > 0 ){ *result += FLT_MIN ; diff --git a/contrib/btree_gist/btree_interval.c b/contrib/btree_gist/btree_interval.c index 74f7624e1e9..9dd37010846 100644 --- a/contrib/btree_gist/btree_interval.c +++ b/contrib/btree_gist/btree_interval.c @@ -3,8 +3,7 @@ typedef struct { - Interval lower, - upper; + Interval lower, upper; } intvKEY; @@ -12,6 +11,7 @@ typedef struct ** Interval ops */ PG_FUNCTION_INFO_V1(gbt_intv_compress); +PG_FUNCTION_INFO_V1(gbt_intv_decompress); PG_FUNCTION_INFO_V1(gbt_intv_union); PG_FUNCTION_INFO_V1(gbt_intv_picksplit); PG_FUNCTION_INFO_V1(gbt_intv_consistent); @@ -19,6 +19,7 @@ PG_FUNCTION_INFO_V1(gbt_intv_penalty); PG_FUNCTION_INFO_V1(gbt_intv_same); Datum gbt_intv_compress(PG_FUNCTION_ARGS); +Datum gbt_intv_decompress(PG_FUNCTION_ARGS); Datum gbt_intv_union(PG_FUNCTION_ARGS); Datum gbt_intv_picksplit(PG_FUNCTION_ARGS); Datum gbt_intv_consistent(PG_FUNCTION_ARGS); @@ -28,27 +29,27 @@ 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 ) ); + return DatumGetBool(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 ) ); + return DatumGetBool(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 ) ); + return DatumGetBool(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 ) ); + return DatumGetBool(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 ) ); + return DatumGetBool(DirectFunctionCall2 ( interval_lt , IntervalPGetDatum ( a ) , IntervalPGetDatum ( b ) )); } static int @@ -56,12 +57,32 @@ gbt_intvkey_cmp(const void *a, const void *b) { return DatumGetInt32 ( DirectFunctionCall2 ( interval_cmp , - IntervalPGetDatum(&((Nsrt *) a)->t[0]) , - IntervalPGetDatum(&((Nsrt *) b)->t[0]) + IntervalPGetDatum(((Nsrt *) a)->t) , + IntervalPGetDatum(((Nsrt *) b)->t) ) ); } + +static double intr2num ( const Interval * i ) +{ + double ret = 0.0; + struct pg_tm tm; + fsec_t fsec; + interval2tm( *i, &tm, &fsec); + ret += ( tm.tm_year * 360.0 * 86400.0 ) ; + ret += ( tm.tm_mon * 12.0 * 86400.0 ) ; + ret += ( tm.tm_mday * 86400.0 ) ; + ret += ( tm.tm_hour * 3600.0 ) ; + ret += ( tm.tm_min * 60.0 ) ; + ret += ( tm.tm_sec ) ; + ret += ( fsec / 1000000.0 ); + + return ( ret ); +} + +#define INTERVALSIZE 12 + static const gbtree_ninfo tinfo = { gbt_t_intv, @@ -84,10 +105,51 @@ 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 )); + GISTENTRY *retval = entry; + if ( entry->leafkey || INTERVALSIZE != sizeof(Interval) ) { + char *r = ( char * ) palloc(2 * INTERVALSIZE); + + retval = palloc(sizeof(GISTENTRY)); + + if ( entry->leafkey ) { + Interval *key = DatumGetIntervalP(entry->key); + memcpy( (void*) r , (void*)key, INTERVALSIZE); + memcpy( (void*)(r + INTERVALSIZE), (void*)key, INTERVALSIZE); + } else { + intvKEY *key = ( intvKEY * ) DatumGetPointer(entry->key); + memcpy(r, &key->lower, INTERVALSIZE); + memcpy(r + INTERVALSIZE, &key->upper, INTERVALSIZE); + } + gistentryinit(*retval, PointerGetDatum(r), + entry->rel, entry->page, + entry->offset, 2 * INTERVALSIZE, FALSE); + } + + PG_RETURN_POINTER(retval); + } - + +Datum +gbt_intv_decompress(PG_FUNCTION_ARGS) +{ + GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); + GISTENTRY *retval = entry; + + if ( INTERVALSIZE != sizeof(Interval) ) { + intvKEY *r = palloc(sizeof(intvKEY)); + char *key = DatumGetPointer(entry->key); + + retval = palloc(sizeof(GISTENTRY)); + memcpy( &r->lower, key, INTERVALSIZE); + memcpy( &r->upper, key+ INTERVALSIZE, INTERVALSIZE); + + gistentryinit(*retval, PointerGetDatum(r), + entry->rel, entry->page, + entry->offset, sizeof(intvKEY), FALSE); + } + PG_RETURN_POINTER(retval); +} + Datum gbt_intv_consistent(PG_FUNCTION_ARGS) @@ -97,6 +159,7 @@ gbt_intv_consistent(PG_FUNCTION_ARGS) 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 ; @@ -121,56 +184,26 @@ 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 */ + float *result = (float *) PG_GETARG_POINTER(2); + double iorg[2], inew[2], res; - res = Max(intr->time + intr->month * (30 * 86400), 0); - pfree(intr); + iorg[0] = intr2num ( &origentry->lower ); + iorg[1] = intr2num ( &origentry->upper ); + inew[0] = intr2num ( &newentry->lower ); + inew[1] = intr2num ( &newentry->upper ); - 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); + penalty_range_enlarge ( iorg[0], iorg[1], inew[0], inew[1] ); *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 += (float) ( res / ( res + iorg[1] - iorg[0] ) ); *result *= ( FLT_MAX / ( ( (GISTENTRY *) PG_GETARG_POINTER(0))->rel->rd_att->natts + 1 ) ); - - pfree ( intr ); - } PG_RETURN_POINTER(result); - } Datum diff --git a/contrib/btree_gist/btree_macaddr.c b/contrib/btree_gist/btree_macaddr.c index 25531eafb4b..b6e9c672f1d 100644 --- a/contrib/btree_gist/btree_macaddr.c +++ b/contrib/btree_gist/btree_macaddr.c @@ -84,12 +84,12 @@ static const gbtree_ninfo tinfo = -static int64 mac_2_int64 ( macaddr * m ){ +static uint64 mac_2_uint64 ( macaddr * m ){ unsigned char * mi = ( unsigned char * ) m; - int64 res = 0; + uint64 res = 0; int i; for (i=0; i<6; i++ ){ - res += mi[i] << ( (5-i)*8 ); + res += ( ( (uint64) mi[i] ) << ( (uint64) ( (5-i)*8 ) ) ); } return res; } @@ -108,6 +108,7 @@ gbt_macad_compress(PG_FUNCTION_ARGS) 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); @@ -138,21 +139,21 @@ 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 ; + uint64 iorg[2], inew[2]; + uint64 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 ); + iorg[0] = mac_2_uint64 ( &origentry->lower ); + iorg[1] = mac_2_uint64 ( &origentry->upper ); + inew[0] = mac_2_uint64 ( &newentry->lower ); + inew[1] = mac_2_uint64 ( &newentry->upper ); - res = Max(inew[1] - iorg[1], 0) + - Max(iorg[0] - inew[0] , 0); + penalty_range_enlarge ( iorg[0], iorg[1], inew[0], inew[1] ); *result = 0.0; if ( res > 0 ){ *result += FLT_MIN ; - *result += (float) ( res / ( (double) ( res + iorg[1] - iorg[0] ) ) ); + *result += (float) ( ( (double)res ) / ( (double)res + (double)iorg[1] - (double)iorg[0] ) ); *result *= ( FLT_MAX / ( ( (GISTENTRY *) PG_GETARG_POINTER(0))->rel->rd_att->natts + 1 ) ); } diff --git a/contrib/btree_gist/btree_oid.c b/contrib/btree_gist/btree_oid.c index 204846e43d2..d7d98e4a7b3 100644 --- a/contrib/btree_gist/btree_oid.c +++ b/contrib/btree_gist/btree_oid.c @@ -91,6 +91,7 @@ gbt_oid_compress(PG_FUNCTION_ARGS) 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); @@ -122,12 +123,11 @@ gbt_oid_penalty(PG_FUNCTION_ARGS) oidKEY *newentry = (oidKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key); float *result = (float *) PG_GETARG_POINTER(2); - Oid res ; + Oid res = 0 ; *result = 0.0; - res = Max(newentry->upper - origentry->upper, 0) + - Max(origentry->lower - newentry->lower, 0); + penalty_range_enlarge ( origentry->lower, origentry->upper, newentry->lower , newentry->upper ); if ( res > 0 ){ *result += FLT_MIN ; diff --git a/contrib/btree_gist/btree_time.c b/contrib/btree_gist/btree_time.c index cd5076723c7..410bec0fe43 100644 --- a/contrib/btree_gist/btree_time.c +++ b/contrib/btree_gist/btree_time.c @@ -138,11 +138,13 @@ 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); + 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) @@ -155,9 +157,10 @@ 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); + 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 ; diff --git a/contrib/btree_gist/btree_ts.c b/contrib/btree_gist/btree_ts.c index 3c73a7b83cc..97f209ed74a 100644 --- a/contrib/btree_gist/btree_ts.c +++ b/contrib/btree_gist/btree_ts.c @@ -140,7 +140,7 @@ gbt_tstz_compress(PG_FUNCTION_ARGS) if (entry->leafkey) { tsKEY *r = (tsKEY *) palloc(sizeof(tsKEY)); - + TimestampTz ts = *(TimestampTz *) DatumGetPointer(entry->key); Timestamp gmt ; @@ -167,6 +167,7 @@ gbt_ts_consistent(PG_FUNCTION_ARGS) tsKEY *kkk = (tsKEY *) 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 ; @@ -180,12 +181,13 @@ gbt_tstz_consistent(PG_FUNCTION_ARGS) { GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); TimestampTz *query = (Timestamp *) PG_GETARG_POINTER(1); - tsKEY *kkk = (tsKEY *) DatumGetPointer(entry->key); + char *kkk = (char *) DatumGetPointer(entry->key); GBT_NUMKEY_R key ; StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2); Timestamp qqq ; - key.lower = (GBT_NUMKEY*) &kkk->lower ; - key.upper = (GBT_NUMKEY*) &kkk->upper ; + + key.lower = (GBT_NUMKEY*) &kkk[0]; + key.upper = (GBT_NUMKEY*) &kkk[MAXALIGN(tinfo.size)]; tstz_to_ts_gmt ( &qqq, query ); PG_RETURN_BOOL( diff --git a/contrib/btree_gist/btree_utils_num.c b/contrib/btree_gist/btree_utils_num.c index 80fccbaef05..cba5739dcf2 100644 --- a/contrib/btree_gist/btree_utils_num.c +++ b/contrib/btree_gist/btree_utils_num.c @@ -15,8 +15,8 @@ gbt_num_compress( GISTENTRY *retval , GISTENTRY *entry , const gbtree_ninfo * TimeADT ts; DateADT dt; } v ; - - GBT_NUMKEY *r = ( GBT_NUMKEY * ) palloc(2 * tinfo->size); + + GBT_NUMKEY *r = ( GBT_NUMKEY * ) palloc(2 * tinfo->size ); void *leaf = NULL; switch ( tinfo->t ) @@ -45,12 +45,12 @@ gbt_num_compress( GISTENTRY *retval , GISTENTRY *entry , const gbtree_ninfo * leaf = DatumGetPointer(entry->key); } - memcpy ( (void*) &r[0] , leaf, tinfo->size ); - memcpy ( (void*) &r[tinfo->size] , leaf, tinfo->size ); - + memset ( (void*) &r[0] , 0 , 2*tinfo->size ); + 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); + entry->offset,( 2 * tinfo->size ), FALSE); } else retval = entry; @@ -72,8 +72,8 @@ gbt_num_union( GBT_NUMKEY * out, const GistEntryVector * entryvec, const gbtree_ GBT_NUMKEY * cur ; GBT_NUMKEY_R o, c; - numranges = entryvec->n; - cur = (GBT_NUMKEY *) DatumGetPointer((entryvec->vector[0].key)); + numranges = entryvec->n; + cur = (GBT_NUMKEY *) DatumGetPointer((entryvec->vector[0].key)); o.lower = &((GBT_NUMKEY *)out)[0]; @@ -86,7 +86,6 @@ gbt_num_union( GBT_NUMKEY * out, const GistEntryVector * entryvec, const gbtree_ 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 */ @@ -127,26 +126,26 @@ 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) )[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.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 ); } - } diff --git a/contrib/btree_gist/btree_utils_num.h b/contrib/btree_gist/btree_utils_num.h index e9e9e9eb234..122fba379a1 100644 --- a/contrib/btree_gist/btree_utils_num.h +++ b/contrib/btree_gist/btree_utils_num.h @@ -41,6 +41,17 @@ typedef struct * Numeric btree functions */ + +#define penalty_range_enlarge(olower,oupper,nlower,nupper) do { \ + res = 0; \ + if ( (nupper) > (oupper) ) \ + res += ( (nupper) - (oupper) ); \ + if ( (olower) > (nlower) ) \ + res += ( (olower) - (nlower) ); \ +} while (0); + + + extern bool gbt_num_consistent( const GBT_NUMKEY_R * key , const void * query, const StrategyNumber * strategy , bool is_leaf, const gbtree_ninfo * tinfo ); diff --git a/contrib/btree_gist/btree_utils_var.c b/contrib/btree_gist/btree_utils_var.c index 65ecbf33aef..95333d45286 100644 --- a/contrib/btree_gist/btree_utils_var.c +++ b/contrib/btree_gist/btree_utils_var.c @@ -9,7 +9,7 @@ extern GBT_VARKEY_R gbt_var_key_readable ( const GBT_VARKEY * k ){ GBT_VARKEY_R r ; r.lower = ( bytea * ) &(((char*)k)[VARHDRSZ] ) ; if ( VARSIZE(k) > ( VARHDRSZ+(VARSIZE(r.lower)) ) ) - r.upper = ( bytea * ) &(((char*)k)[VARHDRSZ+(VARSIZE(r.lower))] ) ; + r.upper = ( bytea * ) &(((char*)k)[VARHDRSZ+INTALIGN(VARSIZE(r.lower))] ) ; else r.upper = r.lower; return r; @@ -28,10 +28,10 @@ extern GBT_VARKEY * gbt_var_key_copy ( const GBT_VARKEY_R * u , bool force_node } else { /* node key mode */ - r = (GBT_VARKEY *) palloc(VARSIZE(u->lower) + VARSIZE(u->upper) + VARHDRSZ ); + r = (GBT_VARKEY *) palloc(INTALIGN(VARSIZE(u->lower)) + VARSIZE(u->upper) + VARHDRSZ ); memcpy ( (void*) VARDATA(r) , (void*) u->lower , VARSIZE(u->lower) ); - memcpy ( (void*)&(((char *)r)[VARHDRSZ+VARSIZE(u->lower)]), (void*) u->upper , VARSIZE(u->upper) ); - r->vl_len = VARSIZE(u->lower) + VARSIZE(u->upper) + VARHDRSZ ; + memcpy ( (void*)&(((char *)r)[VARHDRSZ+INTALIGN(VARSIZE(u->lower))]), (void*) u->upper , VARSIZE(u->upper) ); + r->vl_len = INTALIGN(VARSIZE(u->lower)) + VARSIZE(u->upper) + VARHDRSZ ; } return r; @@ -153,19 +153,19 @@ static GBT_VARKEY * gbt_var_node_truncate ( const GBT_VARKEY * node , int32 leng len1 = Min( len1, length ) ; len2 = Min( len2, length ) ; - si = 3*VARHDRSZ + len1 + len2; + si = 2*VARHDRSZ + INTALIGN(VARHDRSZ+len1) + len2; out = (GBT_VARKEY *) palloc ( si ); out->vl_len = si; memcpy ( (void*) &(((char*)out)[VARHDRSZ]) , (void*)r.lower, len1+VARHDRSZ-s ); - memcpy ( (void*) &(((char*)out)[2*VARHDRSZ+len1]) , (void*)r.upper, len2+VARHDRSZ-s ); + memcpy ( (void*) &(((char*)out)[VARHDRSZ+INTALIGN(VARHDRSZ+len1)]) , (void*)r.upper, len2+VARHDRSZ-s ); if (tinfo->str) { - ((char*)out)[2*VARHDRSZ+len1-1] = '\0'; - ((char*)out)[3*VARHDRSZ+len1+len2-1] = '\0'; + ((char*)out)[VARHDRSZ+INTALIGN(VARHDRSZ+len1)-1] = '\0'; + ((char*)out)[2*VARHDRSZ+INTALIGN(VARHDRSZ+len1)+len2-1] = '\0'; } *((int32*)&(((char*)out)[VARHDRSZ])) = len1 + VARHDRSZ; - *((int32*)&(((char*)out)[2*VARHDRSZ+len1])) = len2 + VARHDRSZ; + *((int32*)&(((char*)out)[VARHDRSZ+INTALIGN(VARHDRSZ+len1)])) = len2 + VARHDRSZ; return out; } -- 2.30.2