aboutsummaryrefslogtreecommitdiff
path: root/contrib/btree_gist/btree_ts.c
diff options
context:
space:
mode:
authorTeodor Sigaev <teodor@sigaev.ru>2005-07-01 13:44:56 +0000
committerTeodor Sigaev <teodor@sigaev.ru>2005-07-01 13:44:56 +0000
commitef770cbb6913cc4c816bb09acd7cb13f996281bd (patch)
treefe973e6aeb9c018d54ea6267f49d5d1b2d5d2f95 /contrib/btree_gist/btree_ts.c
parent8f6e8e8fed372a592f645d8900b6f456db82cc59 (diff)
downloadpostgresql-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.c62
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);
+
}