summaryrefslogtreecommitdiff
path: root/contrib/btree_gist/btree_ts.c
diff options
context:
space:
mode:
authorTeodor Sigaev <teodor@sigaev.ru>2004-05-28 10:43:32 +0000
committerTeodor Sigaev <teodor@sigaev.ru>2004-05-28 10:43:32 +0000
commit42d069886f38687839388c615af608706508b557 (patch)
tree0409615407a17d22e2511ac14745277467853453 /contrib/btree_gist/btree_ts.c
parent1a321f26d88e5c64bccba9d36920aede1e201729 (diff)
New version. Add support for int2, int8, float4, float8, timestamp with/without time zone, time with/without time zone, date, interval, oid, money and macaddr, char, varchar/text, bytea, numeric, bit, varbit, inet/cidr types for GiST
Diffstat (limited to 'contrib/btree_gist/btree_ts.c')
-rw-r--r--contrib/btree_gist/btree_ts.c467
1 files changed, 230 insertions, 237 deletions
diff --git a/contrib/btree_gist/btree_ts.c b/contrib/btree_gist/btree_ts.c
index 658528dcb99..3c73a7b83cc 100644
--- a/contrib/btree_gist/btree_ts.c
+++ b/contrib/btree_gist/btree_ts.c
@@ -1,288 +1,281 @@
#include "btree_gist.h"
+#include "btree_utils_num.h"
-
-typedef struct tskey
+typedef struct
{
- Timestamp lower;
- Timestamp upper;
-} TSKEY;
-
+ Timestamp lower;
+ Timestamp upper;
+} tsKEY;
/*
-** tskey in/out
+** timestamp ops
*/
-PG_FUNCTION_INFO_V1(tskey_in);
-PG_FUNCTION_INFO_V1(tskey_out);
-Datum tskey_in(PG_FUNCTION_ARGS);
-Datum tskey_out(PG_FUNCTION_ARGS);
+PG_FUNCTION_INFO_V1(gbt_ts_compress);
+PG_FUNCTION_INFO_V1(gbt_tstz_compress);
+PG_FUNCTION_INFO_V1(gbt_ts_union);
+PG_FUNCTION_INFO_V1(gbt_ts_picksplit);
+PG_FUNCTION_INFO_V1(gbt_ts_consistent);
+PG_FUNCTION_INFO_V1(gbt_tstz_consistent);
+PG_FUNCTION_INFO_V1(gbt_ts_penalty);
+PG_FUNCTION_INFO_V1(gbt_ts_same);
+
+Datum gbt_ts_compress(PG_FUNCTION_ARGS);
+Datum gbt_tstz_compress(PG_FUNCTION_ARGS);
+Datum gbt_ts_union(PG_FUNCTION_ARGS);
+Datum gbt_ts_picksplit(PG_FUNCTION_ARGS);
+Datum gbt_ts_consistent(PG_FUNCTION_ARGS);
+Datum gbt_tstz_consistent(PG_FUNCTION_ARGS);
+Datum gbt_ts_penalty(PG_FUNCTION_ARGS);
+Datum gbt_ts_same(PG_FUNCTION_ARGS);
+
+
+static bool gbt_tsgt (const void *a, const void *b)
+{
+ return DatumGetBool(
+ DirectFunctionCall2(timestamp_gt,PointerGetDatum( a ), PointerGetDatum( b ) )
+ );
+}
+static bool gbt_tsge (const void *a, const void *b)
+{
+ return DatumGetBool(
+ DirectFunctionCall2(timestamp_ge,PointerGetDatum( a ), PointerGetDatum( b ) )
+ );
+}
-/*
-** timestamp ops
-*/
-PG_FUNCTION_INFO_V1(gts_compress);
-PG_FUNCTION_INFO_V1(gts_union);
-PG_FUNCTION_INFO_V1(gts_picksplit);
-PG_FUNCTION_INFO_V1(gts_consistent);
-PG_FUNCTION_INFO_V1(gts_penalty);
-PG_FUNCTION_INFO_V1(gts_same);
-
-Datum gts_compress(PG_FUNCTION_ARGS);
-Datum gts_union(PG_FUNCTION_ARGS);
-Datum gts_picksplit(PG_FUNCTION_ARGS);
-Datum gts_consistent(PG_FUNCTION_ARGS);
-Datum gts_penalty(PG_FUNCTION_ARGS);
-Datum gts_same(PG_FUNCTION_ARGS);
-
-static void gts_binary_union(Datum *r1, char *r2);
-static int tskey_cmp(const void *a, const void *b);
-
-#define TimestampGetDatumFast(X) Float8GetDatumFast(X)
-
-/* define for comparison */
-#define TSGE( ts1, ts2 ) (DatumGetBool(DirectFunctionCall2( \
- timestamp_ge, \
- PointerGetDatum( ts1 ), \
- PointerGetDatum( ts2 ) \
-)))
-#define TSGT( ts1, ts2 ) (DatumGetBool(DirectFunctionCall2( \
- timestamp_gt, \
- PointerGetDatum( ts1 ), \
- PointerGetDatum( ts2 ) \
-)))
-#define TSEQ( ts1, ts2 ) (DatumGetBool(DirectFunctionCall2( \
- timestamp_eq, \
- PointerGetDatum( ts1 ), \
- PointerGetDatum( ts2 ) \
-)))
-#define TSLT( ts1, ts2 ) (DatumGetBool(DirectFunctionCall2( \
- timestamp_lt, \
- PointerGetDatum( ts1 ), \
- PointerGetDatum( ts2 ) \
-)))
-#define TSLE( ts1, ts2 ) (DatumGetBool(DirectFunctionCall2( \
- timestamp_le, \
- PointerGetDatum( ts1 ), \
- PointerGetDatum( ts2 ) \
-)))
+static bool gbt_tseq (const void *a, const void *b)
+{
+ return DatumGetBool(
+ DirectFunctionCall2(timestamp_eq,PointerGetDatum( a ), PointerGetDatum( b ) )
+ );
+}
+
+static bool gbt_tsle (const void *a, const void *b)
+{
+ return DatumGetBool(
+ DirectFunctionCall2(timestamp_le,PointerGetDatum( a ), PointerGetDatum( b ) )
+ );
+}
+
+static bool gbt_tslt (const void *a, const void *b)
+{
+ return DatumGetBool(
+ DirectFunctionCall2(timestamp_lt,PointerGetDatum( a ), PointerGetDatum( b ) )
+ );
+}
+
+
+static int
+gbt_tskey_cmp(const void *a, const void *b)
+{
+ if ( gbt_tsgt( (void*)&(((Nsrt *) a)->t[0]) , (void*)&(((Nsrt *) b)->t[0]) ) ){
+ return 1;
+ } else
+ if ( gbt_tslt( (void*)&(((Nsrt *) a)->t[0]) , (void*)&(((Nsrt *) b)->t[0]) ) ){
+ return -1;
+ }
+ return 0;
+}
+static const gbtree_ninfo tinfo =
+{
+ gbt_t_ts,
+ sizeof(Timestamp),
+ gbt_tsgt,
+ gbt_tsge,
+ gbt_tseq,
+ gbt_tsle,
+ gbt_tslt,
+ gbt_tskey_cmp
+};
+
/**************************************************
* timestamp ops
**************************************************/
-Datum
-gts_compress(PG_FUNCTION_ARGS)
+
+
+static Timestamp * tstz_to_ts_gmt ( Timestamp * gmt, TimestampTz * ts )
{
- GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
- GISTENTRY *retval;
-
- if (entry->leafkey)
- {
- TSKEY *r = (TSKEY *) palloc(sizeof(TSKEY));
-
- retval = palloc(sizeof(GISTENTRY));
- r->lower = r->upper = *(Timestamp *) (entry->key);
- gistentryinit(*retval, PointerGetDatum(r),
- entry->rel, entry->page,
- entry->offset, sizeof(TSKEY), FALSE);
- }
- else
- retval = entry;
- PG_RETURN_POINTER(retval);
+ int val, tz ;
+
+ *gmt = *ts;
+ DecodeSpecial(0, "gmt", &val);
+
+ if ( ! TIMESTAMP_NOT_FINITE(*ts))
+ {
+ tz = val * 60;
+
+#ifdef HAVE_INT64_TIMESTAMP
+ *gmt -= (tz * INT64CONST(1000000));
+#else
+ *gmt -= tz;
+ *gmt = JROUND(*gmt);
+#endif
+
+ }
+ return gmt;
}
+
+
+
Datum
-gts_consistent(PG_FUNCTION_ARGS)
+gbt_ts_compress(PG_FUNCTION_ARGS)
{
- GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
- Timestamp *query = (Timestamp *) PG_GETARG_POINTER(1);
- StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
- bool retval;
- TSKEY *key;
-
- /*
- * * if entry is not leaf, use gbox_internal_consistent, * else use
- * gbox_leaf_consistent
- */
- if (!entry->key)
- return FALSE;
- key = (TSKEY *) DatumGetPointer(entry->key);
-
- switch (strategy)
- {
- case BTLessEqualStrategyNumber:
- retval = TSGE(query, &(key->lower));
- break;
- case BTLessStrategyNumber:
- if (GIST_LEAF(entry))
- retval = TSGT(query, &(key->lower));
- else
- retval = TSGE(query, &(key->lower));
- break;
- case BTEqualStrategyNumber:
- /* in leaf page key->lower always = key->upper */
- if (GIST_LEAF(entry))
- retval = TSEQ(query, &(key->lower));
- else
- retval = (TSLE(&(key->lower), query) && TSLE(query, &(key->upper)));
- break;
- case BTGreaterStrategyNumber:
- if (GIST_LEAF(entry))
- retval = TSLT(query, &(key->upper));
- else
- retval = TSLE(query, &(key->upper));
- break;
- case BTGreaterEqualStrategyNumber:
- retval = TSLE(query, &(key->upper));
- break;
- default:
- retval = FALSE;
- }
- PG_RETURN_BOOL(retval);
+ GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
+ GISTENTRY *retval = NULL;
+ PG_RETURN_POINTER( gbt_num_compress( retval , entry , &tinfo ));
}
+
Datum
-gts_union(PG_FUNCTION_ARGS)
+gbt_tstz_compress(PG_FUNCTION_ARGS)
{
- GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
- int i,
- numranges;
- TSKEY *cur,
- *out = palloc(sizeof(TSKEY));
-
- numranges = entryvec->n;
- *(int *) PG_GETARG_POINTER(1) = sizeof(TSKEY);
-
- cur = (TSKEY *) DatumGetPointer((entryvec->vector[0].key));
- out->lower = cur->lower;
- out->upper = cur->upper;
-
- for (i = 1; i < numranges; i++)
- {
- cur = (TSKEY *) DatumGetPointer((entryvec->vector[i].key));
- if (TSGT(&out->lower, &cur->lower))
- out->lower = cur->lower;
- if (TSLT(&out->upper, &cur->upper))
- out->upper = cur->upper;
- }
-
- PG_RETURN_POINTER(out);
+ GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
+ GISTENTRY *retval ;
+
+ if (entry->leafkey)
+ {
+ tsKEY *r = (tsKEY *) palloc(sizeof(tsKEY));
+
+ TimestampTz ts = *(TimestampTz *) DatumGetPointer(entry->key);
+ Timestamp gmt ;
+
+ tstz_to_ts_gmt ( &gmt, &ts );
+
+ retval = palloc(sizeof(GISTENTRY));
+ r->lower = r->upper = gmt ;
+ gistentryinit(*retval, PointerGetDatum(r),
+ entry->rel, entry->page,
+ entry->offset, sizeof(tsKEY), FALSE);
+ }
+ else
+ retval = entry;
+
+ PG_RETURN_POINTER( retval );
}
+
Datum
-gts_penalty(PG_FUNCTION_ARGS)
+gbt_ts_consistent(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;
-
- intr = DatumGetIntervalP(DirectFunctionCall2(
- timestamp_mi,
- TimestampGetDatumFast(newentry->upper),
- TimestampGetDatumFast(origentry->upper)));
-
- /* see interval_larger */
- *result = Max(intr->time + intr->month * (30.0 * 86400), 0);
- pfree(intr);
-
- intr = DatumGetIntervalP(DirectFunctionCall2(
- timestamp_mi,
- TimestampGetDatumFast(origentry->lower),
- TimestampGetDatumFast(newentry->lower)));
-
- /* see interval_larger */
- *result += Max(intr->time + intr->month * (30.0 * 86400), 0);
- pfree(intr);
-
- PG_RETURN_POINTER(result);
+ GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
+ Timestamp *query = (Timestamp *) PG_GETARG_POINTER(1);
+ 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 ;
+
+ PG_RETURN_BOOL(
+ gbt_num_consistent( &key, (void*)query,&strategy,GIST_LEAF(entry),&tinfo)
+ );
}
Datum
-gts_picksplit(PG_FUNCTION_ARGS)
+gbt_tstz_consistent(PG_FUNCTION_ARGS)
{
- PG_RETURN_POINTER(btree_picksplit(
- (GistEntryVector *) PG_GETARG_POINTER(0),
- (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
- gts_binary_union,
- tskey_cmp
- ));
+ GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
+ TimestampTz *query = (Timestamp *) PG_GETARG_POINTER(1);
+ tsKEY *kkk = (tsKEY *) 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 ;
+ tstz_to_ts_gmt ( &qqq, query );
+
+ PG_RETURN_BOOL(
+ gbt_num_consistent( &key, (void*)&qqq,&strategy,GIST_LEAF(entry),&tinfo)
+ );
}
+
Datum
-gts_same(PG_FUNCTION_ARGS)
+gbt_ts_union(PG_FUNCTION_ARGS)
{
- TSKEY *b1 = (TSKEY *) PG_GETARG_POINTER(0);
- TSKEY *b2 = (TSKEY *) PG_GETARG_POINTER(1);
-
- bool *result = (bool *) PG_GETARG_POINTER(2);
-
- if (b1 && b2)
- *result = (TSEQ(&(b1->lower), &(b2->lower)) && TSEQ(&(b1->upper), &(b2->upper))) ? TRUE : FALSE;
- else
- *result = (b1 == NULL && b2 == NULL) ? TRUE : FALSE;
- PG_RETURN_POINTER(result);
+ GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
+ void *out = palloc(sizeof(tsKEY));
+ *(int *) PG_GETARG_POINTER(1) = sizeof(tsKEY);
+ PG_RETURN_POINTER( gbt_num_union ( (void*)out, entryvec, &tinfo ) );
}
-static void
-gts_binary_union(Datum *r1, char *r2)
-{
- TSKEY *b1;
- TSKEY *b2 = (TSKEY *) r2;
-
- if (!DatumGetPointer(*r1))
- {
- *r1 = PointerGetDatum(palloc(sizeof(TSKEY)));
- b1 = (TSKEY *) DatumGetPointer(*r1);
- b1->upper = b2->upper;
- b1->lower = b2->lower;
- }
- else
- {
- b1 = (TSKEY *) DatumGetPointer(*r1);
-
- b1->lower = (TSGT(&b1->lower, &b2->lower)) ?
- b2->lower : b1->lower;
- b1->upper = (TSGT(&b1->upper, &b2->upper)) ?
- b1->upper : b2->upper;
- }
-}
-static int
-tskey_cmp(const void *a, const void *b)
+Datum
+gbt_ts_penalty(PG_FUNCTION_ARGS)
{
- return DatumGetInt32(
- DirectFunctionCall2(
- timestamp_cmp,
- TimestampGetDatumFast(((TSKEY *) (((RIX *) a)->r))->lower),
- TimestampGetDatumFast(((TSKEY *) (((RIX *) b)->r))->lower)
- )
- );
-}
+ 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,
+ TimestampGetDatum(newentry->upper),
+ TimestampGetDatum(origentry->upper)
+ ));
+
+ /* see interval_larger */
+
+ res = Max(intr->time + intr->month * (30 * 86400), 0);
+ pfree(intr);
+
+ intr = DatumGetIntervalP(DirectFunctionCall2(
+ timestamp_mi,
+ TimestampGetDatum(origentry->lower),
+ TimestampGetDatum(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(
+ timestamp_mi,
+ TimestampGetDatum(origentry->upper),
+ 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 ) );
+ pfree(intr);
+ }
+
+ PG_RETURN_POINTER(result);
+
+}
-/**************************************************
- * In/Out for keys, not really needed
- **************************************************/
Datum
-tskey_in(PG_FUNCTION_ARGS)
+gbt_ts_picksplit(PG_FUNCTION_ARGS)
{
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("feature not implemented")));
-
- PG_RETURN_POINTER(NULL);
+ PG_RETURN_POINTER(gbt_num_picksplit(
+ (GistEntryVector *) PG_GETARG_POINTER(0),
+ (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
+ &tinfo
+ ));
}
Datum
-tskey_out(PG_FUNCTION_ARGS)
+gbt_ts_same(PG_FUNCTION_ARGS)
{
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("feature not implemented")));
+ tsKEY *b1 = (tsKEY *) PG_GETARG_POINTER(0);
+ tsKEY *b2 = (tsKEY *) PG_GETARG_POINTER(1);
+ bool *result = (bool *) PG_GETARG_POINTER(2);
- PG_RETURN_POINTER(NULL);
+ *result = gbt_num_same ( (void*)b1, (void*)b2, &tinfo );
+ PG_RETURN_POINTER(result);
}
+