~vcs-imports/mammoth-replicator/trunk

« back to all changes in this revision

Viewing changes to contrib/btree_gist/btree_ts.c

  • Committer: alvherre
  • Date: 2005-12-16 21:24:52 UTC
  • Revision ID: svn-v4:db760fc0-0f08-0410-9d63-cc6633f64896:trunk:1
Initial import of the REL8_0_3 sources from the Pgsql CVS repository.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include "btree_gist.h"
 
2
#include "btree_utils_num.h"
 
3
 
 
4
typedef struct
 
5
{
 
6
        Timestamp       lower;
 
7
        Timestamp       upper;
 
8
}       tsKEY;
 
9
 
 
10
/*
 
11
** timestamp ops
 
12
*/
 
13
PG_FUNCTION_INFO_V1(gbt_ts_compress);
 
14
PG_FUNCTION_INFO_V1(gbt_tstz_compress);
 
15
PG_FUNCTION_INFO_V1(gbt_ts_union);
 
16
PG_FUNCTION_INFO_V1(gbt_ts_picksplit);
 
17
PG_FUNCTION_INFO_V1(gbt_ts_consistent);
 
18
PG_FUNCTION_INFO_V1(gbt_tstz_consistent);
 
19
PG_FUNCTION_INFO_V1(gbt_ts_penalty);
 
20
PG_FUNCTION_INFO_V1(gbt_ts_same);
 
21
 
 
22
Datum           gbt_ts_compress(PG_FUNCTION_ARGS);
 
23
Datum           gbt_tstz_compress(PG_FUNCTION_ARGS);
 
24
Datum           gbt_ts_union(PG_FUNCTION_ARGS);
 
25
Datum           gbt_ts_picksplit(PG_FUNCTION_ARGS);
 
26
Datum           gbt_ts_consistent(PG_FUNCTION_ARGS);
 
27
Datum           gbt_tstz_consistent(PG_FUNCTION_ARGS);
 
28
Datum           gbt_ts_penalty(PG_FUNCTION_ARGS);
 
29
Datum           gbt_ts_same(PG_FUNCTION_ARGS);
 
30
 
 
31
 
 
32
#define P_TimestampGetDatum(x)  PointerGetDatum( &(x) )
 
33
 
 
34
static bool
 
35
gbt_tsgt(const void *a, const void *b)
 
36
{
 
37
        return DatumGetBool(
 
38
                                                DirectFunctionCall2(timestamp_gt, PointerGetDatum(a), PointerGetDatum(b))
 
39
                );
 
40
}
 
41
 
 
42
static bool
 
43
gbt_tsge(const void *a, const void *b)
 
44
{
 
45
        return DatumGetBool(
 
46
                                                DirectFunctionCall2(timestamp_ge, PointerGetDatum(a), PointerGetDatum(b))
 
47
                );
 
48
}
 
49
 
 
50
static bool
 
51
gbt_tseq(const void *a, const void *b)
 
52
{
 
53
        return DatumGetBool(
 
54
                                                DirectFunctionCall2(timestamp_eq, PointerGetDatum(a), PointerGetDatum(b))
 
55
                );
 
56
}
 
57
 
 
58
static bool
 
59
gbt_tsle(const void *a, const void *b)
 
60
{
 
61
        return DatumGetBool(
 
62
                                                DirectFunctionCall2(timestamp_le, PointerGetDatum(a), PointerGetDatum(b))
 
63
                );
 
64
}
 
65
 
 
66
static bool
 
67
gbt_tslt(const void *a, const void *b)
 
68
{
 
69
        return DatumGetBool(
 
70
                                                DirectFunctionCall2(timestamp_lt, PointerGetDatum(a), PointerGetDatum(b))
 
71
                );
 
72
}
 
73
 
 
74
 
 
75
static int
 
76
gbt_tskey_cmp(const void *a, const void *b)
 
77
{
 
78
        if (gbt_tsgt((void *) &(((Nsrt *) a)->t[0]), (void *) &(((Nsrt *) b)->t[0])))
 
79
                return 1;
 
80
        else if (gbt_tslt((void *) &(((Nsrt *) a)->t[0]), (void *) &(((Nsrt *) b)->t[0])))
 
81
                return -1;
 
82
        return 0;
 
83
}
 
84
 
 
85
 
 
86
static const gbtree_ninfo tinfo =
 
87
{
 
88
        gbt_t_ts,
 
89
        sizeof(Timestamp),
 
90
        gbt_tsgt,
 
91
        gbt_tsge,
 
92
        gbt_tseq,
 
93
        gbt_tsle,
 
94
        gbt_tslt,
 
95
        gbt_tskey_cmp
 
96
};
 
97
 
 
98
 
 
99
/**************************************************
 
100
 * timestamp ops
 
101
 **************************************************/
 
102
 
 
103
 
 
104
 
 
105
static Timestamp *
 
106
tstz_to_ts_gmt(Timestamp *gmt, TimestampTz *ts)
 
107
{
 
108
        int                     val,
 
109
                                tz;
 
110
 
 
111
        *gmt = *ts;
 
112
        DecodeSpecial(0, "gmt", &val);
 
113
 
 
114
        if (!TIMESTAMP_NOT_FINITE(*ts))
 
115
        {
 
116
                tz = val * 60;
 
117
 
 
118
#ifdef HAVE_INT64_TIMESTAMP
 
119
                *gmt -= (tz * INT64CONST(1000000));
 
120
#else
 
121
                *gmt -= tz;
 
122
                *gmt = JROUND(*gmt);
 
123
#endif
 
124
 
 
125
        }
 
126
        return gmt;
 
127
}
 
128
 
 
129
 
 
130
 
 
131
 
 
132
Datum
 
133
gbt_ts_compress(PG_FUNCTION_ARGS)
 
134
{
 
135
        GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
 
136
        GISTENTRY  *retval = NULL;
 
137
 
 
138
        PG_RETURN_POINTER(gbt_num_compress(retval, entry, &tinfo));
 
139
}
 
140
 
 
141
 
 
142
Datum
 
143
gbt_tstz_compress(PG_FUNCTION_ARGS)
 
144
{
 
145
        GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
 
146
        GISTENTRY  *retval;
 
147
 
 
148
        if (entry->leafkey)
 
149
        {
 
150
                tsKEY      *r = (tsKEY *) palloc(sizeof(tsKEY));
 
151
 
 
152
                TimestampTz ts = *(TimestampTz *) DatumGetPointer(entry->key);
 
153
                Timestamp       gmt;
 
154
 
 
155
                tstz_to_ts_gmt(&gmt, &ts);
 
156
 
 
157
                retval = palloc(sizeof(GISTENTRY));
 
158
                r->lower = r->upper = gmt;
 
159
                gistentryinit(*retval, PointerGetDatum(r),
 
160
                                          entry->rel, entry->page,
 
161
                                          entry->offset, sizeof(tsKEY), FALSE);
 
162
        }
 
163
        else
 
164
                retval = entry;
 
165
 
 
166
        PG_RETURN_POINTER(retval);
 
167
}
 
168
 
 
169
 
 
170
Datum
 
171
gbt_ts_consistent(PG_FUNCTION_ARGS)
 
172
{
 
173
        GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
 
174
        Timestamp  *query = (Timestamp *) PG_GETARG_POINTER(1);
 
175
        tsKEY      *kkk = (tsKEY *) DatumGetPointer(entry->key);
 
176
        GBT_NUMKEY_R key;
 
177
        StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
 
178
 
 
179
        key.lower = (GBT_NUMKEY *) & kkk->lower;
 
180
        key.upper = (GBT_NUMKEY *) & kkk->upper;
 
181
 
 
182
        PG_RETURN_BOOL(
 
183
                                   gbt_num_consistent(&key, (void *) query, &strategy, GIST_LEAF(entry), &tinfo)
 
184
                );
 
185
}
 
186
 
 
187
Datum
 
188
gbt_tstz_consistent(PG_FUNCTION_ARGS)
 
189
{
 
190
        GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
 
191
        TimestampTz *query = (Timestamp *) PG_GETARG_POINTER(1);
 
192
        char       *kkk = (char *) DatumGetPointer(entry->key);
 
193
        GBT_NUMKEY_R key;
 
194
        StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
 
195
        Timestamp       qqq;
 
196
 
 
197
        key.lower = (GBT_NUMKEY *) & kkk[0];
 
198
        key.upper = (GBT_NUMKEY *) & kkk[MAXALIGN(tinfo.size)];
 
199
        tstz_to_ts_gmt(&qqq, query);
 
200
 
 
201
        PG_RETURN_BOOL(
 
202
                                   gbt_num_consistent(&key, (void *) &qqq, &strategy, GIST_LEAF(entry), &tinfo)
 
203
                );
 
204
}
 
205
 
 
206
 
 
207
Datum
 
208
gbt_ts_union(PG_FUNCTION_ARGS)
 
209
{
 
210
        GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
 
211
        void       *out = palloc(sizeof(tsKEY));
 
212
 
 
213
        *(int *) PG_GETARG_POINTER(1) = sizeof(tsKEY);
 
214
        PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo));
 
215
}
 
216
 
 
217
 
 
218
Datum
 
219
gbt_ts_penalty(PG_FUNCTION_ARGS)
 
220
{
 
221
 
 
222
        tsKEY      *origentry = (tsKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
 
223
        tsKEY      *newentry = (tsKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
 
224
        float      *result = (float *) PG_GETARG_POINTER(2);
 
225
        Interval   *intr;
 
226
 
 
227
#ifdef HAVE_INT64_TIMESTAMP
 
228
        int64           res;
 
229
 
 
230
#else
 
231
        double          res;
 
232
#endif
 
233
 
 
234
        intr = DatumGetIntervalP(DirectFunctionCall2(
 
235
                                                                                                 timestamp_mi,
 
236
                                                                          P_TimestampGetDatum(newentry->upper),
 
237
                                                                          P_TimestampGetDatum(origentry->upper)
 
238
                                                                                                 ));
 
239
 
 
240
        /* see interval_larger */
 
241
 
 
242
        res = Max(intr->time + intr->month * (30 * 86400), 0);
 
243
        pfree(intr);
 
244
 
 
245
        intr = DatumGetIntervalP(DirectFunctionCall2(
 
246
                                                                                                 timestamp_mi,
 
247
                                                                         P_TimestampGetDatum(origentry->lower),
 
248
                                                                           P_TimestampGetDatum(newentry->lower)
 
249
                                                                                                 ));
 
250
 
 
251
        /* see interval_larger */
 
252
        res += Max(intr->time + intr->month * (30 * 86400), 0);
 
253
        pfree(intr);
 
254
 
 
255
        *result = 0.0;
 
256
 
 
257
        if (res > 0)
 
258
        {
 
259
                intr = DatumGetIntervalP(DirectFunctionCall2(
 
260
                                                                                                         timestamp_mi,
 
261
                                                                         P_TimestampGetDatum(origentry->upper),
 
262
                                                                          P_TimestampGetDatum(origentry->lower)
 
263
                                                                                                         ));
 
264
                *result += FLT_MIN;
 
265
                *result += (float) (res / ((double) (res + intr->time + intr->month * (30 * 86400))));
 
266
                *result *= (FLT_MAX / (((GISTENTRY *) PG_GETARG_POINTER(0))->rel->rd_att->natts + 1));
 
267
                pfree(intr);
 
268
        }
 
269
 
 
270
        PG_RETURN_POINTER(result);
 
271
 
 
272
}
 
273
 
 
274
 
 
275
Datum
 
276
gbt_ts_picksplit(PG_FUNCTION_ARGS)
 
277
{
 
278
        PG_RETURN_POINTER(gbt_num_picksplit(
 
279
                                                                (GistEntryVector *) PG_GETARG_POINTER(0),
 
280
                                                                  (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
 
281
                                                                                &tinfo
 
282
                                                                                ));
 
283
}
 
284
 
 
285
Datum
 
286
gbt_ts_same(PG_FUNCTION_ARGS)
 
287
{
 
288
        tsKEY      *b1 = (tsKEY *) PG_GETARG_POINTER(0);
 
289
        tsKEY      *b2 = (tsKEY *) PG_GETARG_POINTER(1);
 
290
        bool       *result = (bool *) PG_GETARG_POINTER(2);
 
291
 
 
292
        *result = gbt_num_same((void *) b1, (void *) b2, &tinfo);
 
293
        PG_RETURN_POINTER(result);
 
294
}