~ubuntu-branches/ubuntu/lucid/postgresql-8.4/lucid-proposed

« back to all changes in this revision

Viewing changes to contrib/btree_gist/btree_interval.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2009-03-20 12:00:13 UTC
  • Revision ID: james.westby@ubuntu.com-20090320120013-hogj7egc5mjncc5g
Tags: upstream-8.4~0cvs20090328
ImportĀ upstreamĀ versionĀ 8.4~0cvs20090328

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * $PostgreSQL:$ 
 
3
 */
 
4
#include "btree_gist.h"
 
5
#include "btree_utils_num.h"
 
6
#include "utils/timestamp.h"
 
7
 
 
8
typedef struct
 
9
{
 
10
        Interval        lower,
 
11
                                upper;
 
12
}       intvKEY;
 
13
 
 
14
 
 
15
/*
 
16
** Interval ops
 
17
*/
 
18
PG_FUNCTION_INFO_V1(gbt_intv_compress);
 
19
PG_FUNCTION_INFO_V1(gbt_intv_decompress);
 
20
PG_FUNCTION_INFO_V1(gbt_intv_union);
 
21
PG_FUNCTION_INFO_V1(gbt_intv_picksplit);
 
22
PG_FUNCTION_INFO_V1(gbt_intv_consistent);
 
23
PG_FUNCTION_INFO_V1(gbt_intv_penalty);
 
24
PG_FUNCTION_INFO_V1(gbt_intv_same);
 
25
 
 
26
Datum           gbt_intv_compress(PG_FUNCTION_ARGS);
 
27
Datum           gbt_intv_decompress(PG_FUNCTION_ARGS);
 
28
Datum           gbt_intv_union(PG_FUNCTION_ARGS);
 
29
Datum           gbt_intv_picksplit(PG_FUNCTION_ARGS);
 
30
Datum           gbt_intv_consistent(PG_FUNCTION_ARGS);
 
31
Datum           gbt_intv_penalty(PG_FUNCTION_ARGS);
 
32
Datum           gbt_intv_same(PG_FUNCTION_ARGS);
 
33
 
 
34
 
 
35
static bool
 
36
gbt_intvgt(const void *a, const void *b)
 
37
{
 
38
        return DatumGetBool(DirectFunctionCall2(interval_gt, IntervalPGetDatum(a), IntervalPGetDatum(b)));
 
39
}
 
40
 
 
41
static bool
 
42
gbt_intvge(const void *a, const void *b)
 
43
{
 
44
        return DatumGetBool(DirectFunctionCall2(interval_ge, IntervalPGetDatum(a), IntervalPGetDatum(b)));
 
45
}
 
46
 
 
47
static bool
 
48
gbt_intveq(const void *a, const void *b)
 
49
{
 
50
        return DatumGetBool(DirectFunctionCall2(interval_eq, IntervalPGetDatum(a), IntervalPGetDatum(b)));
 
51
}
 
52
 
 
53
static bool
 
54
gbt_intvle(const void *a, const void *b)
 
55
{
 
56
        return DatumGetBool(DirectFunctionCall2(interval_le, IntervalPGetDatum(a), IntervalPGetDatum(b)));
 
57
}
 
58
 
 
59
static bool
 
60
gbt_intvlt(const void *a, const void *b)
 
61
{
 
62
        return DatumGetBool(DirectFunctionCall2(interval_lt, IntervalPGetDatum(a), IntervalPGetDatum(b)));
 
63
}
 
64
 
 
65
static int
 
66
gbt_intvkey_cmp(const void *a, const void *b)
 
67
{
 
68
        return DatumGetInt32(
 
69
                                                 DirectFunctionCall2(interval_cmp,
 
70
                                                                                  IntervalPGetDatum(((Nsrt *) a)->t),
 
71
                                                                                   IntervalPGetDatum(((Nsrt *) b)->t)
 
72
                                                                                         )
 
73
                );
 
74
}
 
75
 
 
76
 
 
77
static double
 
78
intr2num(const Interval *i)
 
79
{
 
80
        return INTERVAL_TO_SEC(i);
 
81
}
 
82
 
 
83
/*
 
84
 * INTERVALSIZE should be the actual size-on-disk of an Interval, as shown
 
85
 * in pg_type.  This might be less than sizeof(Interval) if the compiler
 
86
 * insists on adding alignment padding at the end of the struct.
 
87
 */
 
88
#define INTERVALSIZE 16
 
89
 
 
90
static const gbtree_ninfo tinfo =
 
91
{
 
92
        gbt_t_intv,
 
93
        sizeof(Interval),
 
94
        gbt_intvgt,
 
95
        gbt_intvge,
 
96
        gbt_intveq,
 
97
        gbt_intvle,
 
98
        gbt_intvlt,
 
99
        gbt_intvkey_cmp
 
100
};
 
101
 
 
102
 
 
103
/**************************************************
 
104
 * interval ops
 
105
 **************************************************/
 
106
 
 
107
 
 
108
Datum
 
109
gbt_intv_compress(PG_FUNCTION_ARGS)
 
110
{
 
111
        GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
 
112
        GISTENTRY  *retval = entry;
 
113
 
 
114
        if (entry->leafkey || INTERVALSIZE != sizeof(Interval))
 
115
        {
 
116
                char       *r = (char *) palloc(2 * INTERVALSIZE);
 
117
 
 
118
                retval = palloc(sizeof(GISTENTRY));
 
119
 
 
120
                if (entry->leafkey)
 
121
                {
 
122
                        Interval   *key = DatumGetIntervalP(entry->key);
 
123
 
 
124
                        memcpy((void *) r, (void *) key, INTERVALSIZE);
 
125
                        memcpy((void *) (r + INTERVALSIZE), (void *) key, INTERVALSIZE);
 
126
                }
 
127
                else
 
128
                {
 
129
                        intvKEY    *key = (intvKEY *) DatumGetPointer(entry->key);
 
130
 
 
131
                        memcpy(r, &key->lower, INTERVALSIZE);
 
132
                        memcpy(r + INTERVALSIZE, &key->upper, INTERVALSIZE);
 
133
                }
 
134
                gistentryinit(*retval, PointerGetDatum(r),
 
135
                                          entry->rel, entry->page,
 
136
                                          entry->offset, FALSE);
 
137
        }
 
138
 
 
139
        PG_RETURN_POINTER(retval);
 
140
 
 
141
}
 
142
 
 
143
Datum
 
144
gbt_intv_decompress(PG_FUNCTION_ARGS)
 
145
{
 
146
        GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
 
147
        GISTENTRY  *retval = entry;
 
148
 
 
149
        if (INTERVALSIZE != sizeof(Interval))
 
150
        {
 
151
                intvKEY    *r = palloc(sizeof(intvKEY));
 
152
                char       *key = DatumGetPointer(entry->key);
 
153
 
 
154
                retval = palloc(sizeof(GISTENTRY));
 
155
                memcpy(&r->lower, key, INTERVALSIZE);
 
156
                memcpy(&r->upper, key + INTERVALSIZE, INTERVALSIZE);
 
157
 
 
158
                gistentryinit(*retval, PointerGetDatum(r),
 
159
                                          entry->rel, entry->page,
 
160
                                          entry->offset, FALSE);
 
161
        }
 
162
        PG_RETURN_POINTER(retval);
 
163
}
 
164
 
 
165
 
 
166
Datum
 
167
gbt_intv_consistent(PG_FUNCTION_ARGS)
 
168
{
 
169
        GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
 
170
        Interval   *query = PG_GETARG_INTERVAL_P(1);
 
171
        StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
 
172
        /* Oid          subtype = PG_GETARG_OID(3); */
 
173
        bool       *recheck = (bool *) PG_GETARG_POINTER(4);
 
174
        intvKEY    *kkk = (intvKEY *) DatumGetPointer(entry->key);
 
175
        GBT_NUMKEY_R key;
 
176
 
 
177
        /* All cases served by this function are exact */
 
178
        *recheck = false;
 
179
 
 
180
        key.lower = (GBT_NUMKEY *) & kkk->lower;
 
181
        key.upper = (GBT_NUMKEY *) & kkk->upper;
 
182
 
 
183
        PG_RETURN_BOOL(
 
184
                                   gbt_num_consistent(&key, (void *) query, &strategy, GIST_LEAF(entry), &tinfo)
 
185
                );
 
186
}
 
187
 
 
188
 
 
189
Datum
 
190
gbt_intv_union(PG_FUNCTION_ARGS)
 
191
{
 
192
        GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
 
193
        void       *out = palloc(sizeof(intvKEY));
 
194
 
 
195
        *(int *) PG_GETARG_POINTER(1) = sizeof(intvKEY);
 
196
        PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo));
 
197
}
 
198
 
 
199
 
 
200
Datum
 
201
gbt_intv_penalty(PG_FUNCTION_ARGS)
 
202
{
 
203
        intvKEY    *origentry = (intvKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
 
204
        intvKEY    *newentry = (intvKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
 
205
        float      *result = (float *) PG_GETARG_POINTER(2);
 
206
        double          iorg[2],
 
207
                                inew[2];
 
208
 
 
209
        iorg[0] = intr2num(&origentry->lower);
 
210
        iorg[1] = intr2num(&origentry->upper);
 
211
        inew[0] = intr2num(&newentry->lower);
 
212
        inew[1] = intr2num(&newentry->upper);
 
213
 
 
214
        penalty_num(result, iorg[0], iorg[1], inew[0], inew[1]);
 
215
 
 
216
        PG_RETURN_POINTER(result);
 
217
 
 
218
}
 
219
 
 
220
Datum
 
221
gbt_intv_picksplit(PG_FUNCTION_ARGS)
 
222
{
 
223
        PG_RETURN_POINTER(gbt_num_picksplit(
 
224
                                                                        (GistEntryVector *) PG_GETARG_POINTER(0),
 
225
                                                                          (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
 
226
                                                                                &tinfo
 
227
                                                                                ));
 
228
}
 
229
 
 
230
Datum
 
231
gbt_intv_same(PG_FUNCTION_ARGS)
 
232
{
 
233
        intvKEY    *b1 = (intvKEY *) PG_GETARG_POINTER(0);
 
234
        intvKEY    *b2 = (intvKEY *) PG_GETARG_POINTER(1);
 
235
        bool       *result = (bool *) PG_GETARG_POINTER(2);
 
236
 
 
237
        *result = gbt_num_same((void *) b1, (void *) b2, &tinfo);
 
238
        PG_RETURN_POINTER(result);
 
239
}