diff options
author | Teodor Sigaev <teodor@sigaev.ru> | 2005-07-01 13:44:56 +0000 |
---|---|---|
committer | Teodor Sigaev <teodor@sigaev.ru> | 2005-07-01 13:44:56 +0000 |
commit | ef770cbb6913cc4c816bb09acd7cb13f996281bd (patch) | |
tree | fe973e6aeb9c018d54ea6267f49d5d1b2d5d2f95 /contrib/btree_gist/btree_ts.c | |
parent | 8f6e8e8fed372a592f645d8900b6f456db82cc59 (diff) | |
download | postgresql-ef770cbb6913cc4c816bb09acd7cb13f996281bd.tar.gz postgresql-ef770cbb6913cc4c816bb09acd7cb13f996281bd.zip |
Fixes from Janko Richter <jankorichter@yahoo.de>
- Fix wrong index results on text, char, varchar for multibyte strings
- Fix some SIGFPE signals
- Add support for infinite timestamps
- Because of locale settings, btree_gist can not be a prefix index anymore (for text).
Each node holds now just the lower and upper boundary.
Diffstat (limited to 'contrib/btree_gist/btree_ts.c')
-rw-r--r-- | contrib/btree_gist/btree_ts.c | 62 |
1 files changed, 25 insertions, 37 deletions
diff --git a/contrib/btree_gist/btree_ts.c b/contrib/btree_gist/btree_ts.c index 37f72d3a516..6c9481b4b2e 100644 --- a/contrib/btree_gist/btree_ts.c +++ b/contrib/btree_gist/btree_ts.c @@ -114,7 +114,7 @@ tstz_to_ts_gmt(Timestamp *gmt, TimestampTz *ts) *gmt = *ts; DecodeSpecial(0, "gmt", &val); - if (!TIMESTAMP_NOT_FINITE(*ts)) + if ( *ts < DT_NOEND && *ts > DT_NOBEGIN ) { tz = val * 60; @@ -218,6 +218,14 @@ gbt_ts_union(PG_FUNCTION_ARGS) } +#define penalty_check_max_float(val) do { \ + if ( val > FLT_MAX ) \ + val = FLT_MAX; \ + if ( val < -FLT_MAX ) \ + val = -FLT_MAX; \ +} while(false); + + Datum gbt_ts_penalty(PG_FUNCTION_ARGS) { @@ -225,48 +233,28 @@ gbt_ts_penalty(PG_FUNCTION_ARGS) tsKEY *origentry = (tsKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key); tsKEY *newentry = (tsKEY *) 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( - timestamp_mi, - P_TimestampGetDatum(newentry->upper), - P_TimestampGetDatum(origentry->upper) - )); + double orgdbl[2], + newdbl[2]; - /* see interval_larger */ + /* + We are allways using "double" timestamps here. + Precision should be good enough. + */ + orgdbl[0] = ( (double) origentry->lower ) ; + orgdbl[1] = ( (double) origentry->upper ) ; + newdbl[0] = ( (double) newentry->lower ) ; + newdbl[1] = ( (double) newentry->upper ) ; - res = Max(intr->time + intr->month * (30 * 86400), 0); + penalty_check_max_float( orgdbl[0] ); + penalty_check_max_float( orgdbl[1] ); + penalty_check_max_float( newdbl[0] ); + penalty_check_max_float( newdbl[1] ); - intr = DatumGetIntervalP(DirectFunctionCall2( - timestamp_mi, - P_TimestampGetDatum(origentry->lower), - P_TimestampGetDatum(newentry->lower) - )); - - /* see interval_larger */ - res += Max(intr->time + intr->month * (30 * 86400), 0); - - *result = 0.0; - - if (res > 0) - { - intr = DatumGetIntervalP(DirectFunctionCall2( - timestamp_mi, - P_TimestampGetDatum(origentry->upper), - P_TimestampGetDatum(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)); - } + penalty_num(result,orgdbl[0],orgdbl[1],newdbl[0],newdbl[1]); PG_RETURN_POINTER(result); + } |