~vcs-imports/mammoth-replicator/trunk

« back to all changes in this revision

Viewing changes to contrib/ltree/_ltree_op.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
/*
 
2
 * op function for ltree[]
 
3
 * Teodor Sigaev <teodor@stack.net>
 
4
 */
 
5
 
 
6
#include "ltree.h"
 
7
#include <ctype.h>
 
8
#include "utils/array.h"
 
9
 
 
10
PG_FUNCTION_INFO_V1(_ltree_isparent);
 
11
PG_FUNCTION_INFO_V1(_ltree_r_isparent);
 
12
PG_FUNCTION_INFO_V1(_ltree_risparent);
 
13
PG_FUNCTION_INFO_V1(_ltree_r_risparent);
 
14
PG_FUNCTION_INFO_V1(_ltq_regex);
 
15
PG_FUNCTION_INFO_V1(_ltq_rregex);
 
16
PG_FUNCTION_INFO_V1(_lt_q_regex);
 
17
PG_FUNCTION_INFO_V1(_lt_q_rregex);
 
18
PG_FUNCTION_INFO_V1(_ltxtq_exec);
 
19
PG_FUNCTION_INFO_V1(_ltxtq_rexec);
 
20
 
 
21
Datum           _ltree_r_isparent(PG_FUNCTION_ARGS);
 
22
Datum           _ltree_r_risparent(PG_FUNCTION_ARGS);
 
23
 
 
24
PG_FUNCTION_INFO_V1(_ltree_extract_isparent);
 
25
PG_FUNCTION_INFO_V1(_ltree_extract_risparent);
 
26
PG_FUNCTION_INFO_V1(_ltq_extract_regex);
 
27
PG_FUNCTION_INFO_V1(_ltxtq_extract_exec);
 
28
Datum           _ltree_extract_isparent(PG_FUNCTION_ARGS);
 
29
Datum           _ltree_extract_risparent(PG_FUNCTION_ARGS);
 
30
Datum           _ltq_extract_regex(PG_FUNCTION_ARGS);
 
31
Datum           _ltxtq_extract_exec(PG_FUNCTION_ARGS);
 
32
 
 
33
PG_FUNCTION_INFO_V1(_lca);
 
34
Datum           _lca(PG_FUNCTION_ARGS);
 
35
 
 
36
typedef Datum (*PGCALL2) (PG_FUNCTION_ARGS);
 
37
 
 
38
#define NEXTVAL(x) ( (ltree*)( (char*)(x) + INTALIGN( VARSIZE(x) ) ) )
 
39
 
 
40
static bool
 
41
array_iterator(ArrayType *la, PGCALL2 callback, void *param, ltree ** found)
 
42
{
 
43
        int                     num = ArrayGetNItems(ARR_NDIM(la), ARR_DIMS(la));
 
44
        ltree      *item = (ltree *) ARR_DATA_PTR(la);
 
45
 
 
46
        if (ARR_NDIM(la) != 1)
 
47
                ereport(ERROR,
 
48
                                (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
 
49
                                 errmsg("array must be one-dimensional")));
 
50
 
 
51
        if (found)
 
52
                *found = NULL;
 
53
        while (num > 0)
 
54
        {
 
55
                if (DatumGetBool(DirectFunctionCall2(callback,
 
56
                                                 PointerGetDatum(item), PointerGetDatum(param))))
 
57
                {
 
58
 
 
59
                        if (found)
 
60
                                *found = item;
 
61
                        return true;
 
62
                }
 
63
                num--;
 
64
                item = NEXTVAL(item);
 
65
        }
 
66
 
 
67
        return false;
 
68
}
 
69
 
 
70
Datum
 
71
_ltree_isparent(PG_FUNCTION_ARGS)
 
72
{
 
73
        ArrayType  *la = PG_GETARG_ARRAYTYPE_P(0);
 
74
        ltree      *query = PG_GETARG_LTREE(1);
 
75
        bool            res = array_iterator(la, ltree_isparent, (void *) query, NULL);
 
76
 
 
77
        PG_FREE_IF_COPY(la, 0);
 
78
        PG_FREE_IF_COPY(query, 1);
 
79
        PG_RETURN_BOOL(res);
 
80
}
 
81
 
 
82
Datum
 
83
_ltree_r_isparent(PG_FUNCTION_ARGS)
 
84
{
 
85
        PG_RETURN_DATUM(DirectFunctionCall2(_ltree_isparent,
 
86
                                                                                PG_GETARG_DATUM(1),
 
87
                                                                                PG_GETARG_DATUM(0)
 
88
                                                                                ));
 
89
}
 
90
 
 
91
Datum
 
92
_ltree_risparent(PG_FUNCTION_ARGS)
 
93
{
 
94
        ArrayType  *la = PG_GETARG_ARRAYTYPE_P(0);
 
95
        ltree      *query = PG_GETARG_LTREE(1);
 
96
        bool            res = array_iterator(la, ltree_risparent, (void *) query, NULL);
 
97
 
 
98
        PG_FREE_IF_COPY(la, 0);
 
99
        PG_FREE_IF_COPY(query, 1);
 
100
        PG_RETURN_BOOL(res);
 
101
}
 
102
 
 
103
Datum
 
104
_ltree_r_risparent(PG_FUNCTION_ARGS)
 
105
{
 
106
        PG_RETURN_DATUM(DirectFunctionCall2(_ltree_risparent,
 
107
                                                                                PG_GETARG_DATUM(1),
 
108
                                                                                PG_GETARG_DATUM(0)
 
109
                                                                                ));
 
110
}
 
111
 
 
112
Datum
 
113
_ltq_regex(PG_FUNCTION_ARGS)
 
114
{
 
115
        ArrayType  *la = PG_GETARG_ARRAYTYPE_P(0);
 
116
        lquery     *query = PG_GETARG_LQUERY(1);
 
117
        bool            res = array_iterator(la, ltq_regex, (void *) query, NULL);
 
118
 
 
119
        PG_FREE_IF_COPY(la, 0);
 
120
        PG_FREE_IF_COPY(query, 1);
 
121
        PG_RETURN_BOOL(res);
 
122
}
 
123
 
 
124
Datum
 
125
_ltq_rregex(PG_FUNCTION_ARGS)
 
126
{
 
127
        PG_RETURN_DATUM(DirectFunctionCall2(_ltq_regex,
 
128
                                                                                PG_GETARG_DATUM(1),
 
129
                                                                                PG_GETARG_DATUM(0)
 
130
                                                                                ));
 
131
}
 
132
 
 
133
Datum
 
134
_lt_q_regex(PG_FUNCTION_ARGS)
 
135
{
 
136
        ArrayType  *_tree = PG_GETARG_ARRAYTYPE_P(0);
 
137
        ArrayType  *_query = PG_GETARG_ARRAYTYPE_P(1);
 
138
        lquery     *query = (lquery *) ARR_DATA_PTR(_query);
 
139
        bool            res = false;
 
140
        int                     num = ArrayGetNItems(ARR_NDIM(_query), ARR_DIMS(_query));
 
141
 
 
142
        if (ARR_NDIM(_query) != 1)
 
143
                ereport(ERROR,
 
144
                                (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
 
145
                                 errmsg("array must be one-dimensional")));
 
146
 
 
147
        while (num > 0)
 
148
        {
 
149
                if (array_iterator(_tree, ltq_regex, (void *) query, NULL))
 
150
                {
 
151
                        res = true;
 
152
                        break;
 
153
                }
 
154
                num--;
 
155
                query = (lquery *) NEXTVAL(query);
 
156
        }
 
157
 
 
158
        PG_FREE_IF_COPY(_tree, 0);
 
159
        PG_FREE_IF_COPY(_query, 1);
 
160
        PG_RETURN_BOOL(res);
 
161
}
 
162
 
 
163
Datum
 
164
_lt_q_rregex(PG_FUNCTION_ARGS)
 
165
{
 
166
        PG_RETURN_DATUM(DirectFunctionCall2(_lt_q_regex,
 
167
                                                                                PG_GETARG_DATUM(1),
 
168
                                                                                PG_GETARG_DATUM(0)
 
169
                                                                                ));
 
170
}
 
171
 
 
172
 
 
173
Datum
 
174
_ltxtq_exec(PG_FUNCTION_ARGS)
 
175
{
 
176
        ArrayType  *la = PG_GETARG_ARRAYTYPE_P(0);
 
177
        ltxtquery  *query = PG_GETARG_LTXTQUERY(1);
 
178
        bool            res = array_iterator(la, ltxtq_exec, (void *) query, NULL);
 
179
 
 
180
        PG_FREE_IF_COPY(la, 0);
 
181
        PG_FREE_IF_COPY(query, 1);
 
182
        PG_RETURN_BOOL(res);
 
183
}
 
184
 
 
185
Datum
 
186
_ltxtq_rexec(PG_FUNCTION_ARGS)
 
187
{
 
188
        PG_RETURN_DATUM(DirectFunctionCall2(_ltxtq_exec,
 
189
                                                                                PG_GETARG_DATUM(1),
 
190
                                                                                PG_GETARG_DATUM(0)
 
191
                                                                                ));
 
192
}
 
193
 
 
194
 
 
195
Datum
 
196
_ltree_extract_isparent(PG_FUNCTION_ARGS)
 
197
{
 
198
        ArrayType  *la = PG_GETARG_ARRAYTYPE_P(0);
 
199
        ltree      *query = PG_GETARG_LTREE(1);
 
200
        ltree      *found,
 
201
                           *item;
 
202
 
 
203
        if (!array_iterator(la, ltree_isparent, (void *) query, &found))
 
204
        {
 
205
                PG_FREE_IF_COPY(la, 0);
 
206
                PG_FREE_IF_COPY(query, 1);
 
207
                PG_RETURN_NULL();
 
208
        }
 
209
 
 
210
        item = (ltree *) palloc(found->len);
 
211
        memcpy(item, found, found->len);
 
212
 
 
213
        PG_FREE_IF_COPY(la, 0);
 
214
        PG_FREE_IF_COPY(query, 1);
 
215
        PG_RETURN_POINTER(item);
 
216
}
 
217
 
 
218
Datum
 
219
_ltree_extract_risparent(PG_FUNCTION_ARGS)
 
220
{
 
221
        ArrayType  *la = PG_GETARG_ARRAYTYPE_P(0);
 
222
        ltree      *query = PG_GETARG_LTREE(1);
 
223
        ltree      *found,
 
224
                           *item;
 
225
 
 
226
        if (!array_iterator(la, ltree_risparent, (void *) query, &found))
 
227
        {
 
228
                PG_FREE_IF_COPY(la, 0);
 
229
                PG_FREE_IF_COPY(query, 1);
 
230
                PG_RETURN_NULL();
 
231
        }
 
232
 
 
233
        item = (ltree *) palloc(found->len);
 
234
        memcpy(item, found, found->len);
 
235
 
 
236
        PG_FREE_IF_COPY(la, 0);
 
237
        PG_FREE_IF_COPY(query, 1);
 
238
        PG_RETURN_POINTER(item);
 
239
}
 
240
 
 
241
Datum
 
242
_ltq_extract_regex(PG_FUNCTION_ARGS)
 
243
{
 
244
        ArrayType  *la = PG_GETARG_ARRAYTYPE_P(0);
 
245
        lquery     *query = PG_GETARG_LQUERY(1);
 
246
        ltree      *found,
 
247
                           *item;
 
248
 
 
249
        if (!array_iterator(la, ltq_regex, (void *) query, &found))
 
250
        {
 
251
                PG_FREE_IF_COPY(la, 0);
 
252
                PG_FREE_IF_COPY(query, 1);
 
253
                PG_RETURN_NULL();
 
254
        }
 
255
 
 
256
        item = (ltree *) palloc(found->len);
 
257
        memcpy(item, found, found->len);
 
258
 
 
259
        PG_FREE_IF_COPY(la, 0);
 
260
        PG_FREE_IF_COPY(query, 1);
 
261
        PG_RETURN_POINTER(item);
 
262
}
 
263
 
 
264
Datum
 
265
_ltxtq_extract_exec(PG_FUNCTION_ARGS)
 
266
{
 
267
        ArrayType  *la = PG_GETARG_ARRAYTYPE_P(0);
 
268
        ltxtquery  *query = PG_GETARG_LTXTQUERY(1);
 
269
        ltree      *found,
 
270
                           *item;
 
271
 
 
272
        if (!array_iterator(la, ltxtq_exec, (void *) query, &found))
 
273
        {
 
274
                PG_FREE_IF_COPY(la, 0);
 
275
                PG_FREE_IF_COPY(query, 1);
 
276
                PG_RETURN_NULL();
 
277
        }
 
278
 
 
279
        item = (ltree *) palloc(found->len);
 
280
        memcpy(item, found, found->len);
 
281
 
 
282
        PG_FREE_IF_COPY(la, 0);
 
283
        PG_FREE_IF_COPY(query, 1);
 
284
        PG_RETURN_POINTER(item);
 
285
}
 
286
 
 
287
Datum
 
288
_lca(PG_FUNCTION_ARGS)
 
289
{
 
290
        ArrayType  *la = PG_GETARG_ARRAYTYPE_P(0);
 
291
        int                     num = ArrayGetNItems(ARR_NDIM(la), ARR_DIMS(la));
 
292
        ltree      *item = (ltree *) ARR_DATA_PTR(la);
 
293
        ltree     **a,
 
294
                           *res;
 
295
 
 
296
        a = (ltree **) palloc(sizeof(ltree *) * num);
 
297
        while (num > 0)
 
298
        {
 
299
                num--;
 
300
                a[num] = item;
 
301
                item = NEXTVAL(item);
 
302
        }
 
303
        res = lca_inner(a, ArrayGetNItems(ARR_NDIM(la), ARR_DIMS(la)));
 
304
        pfree(a);
 
305
 
 
306
        PG_FREE_IF_COPY(la, 0);
 
307
 
 
308
        if (res)
 
309
                PG_RETURN_POINTER(res);
 
310
        else
 
311
                PG_RETURN_NULL();
 
312
}