2
* op function for ltree[]
3
* Teodor Sigaev <teodor@stack.net>
8
#include "utils/array.h"
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);
21
Datum _ltree_r_isparent(PG_FUNCTION_ARGS);
22
Datum _ltree_r_risparent(PG_FUNCTION_ARGS);
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);
33
PG_FUNCTION_INFO_V1(_lca);
34
Datum _lca(PG_FUNCTION_ARGS);
36
typedef Datum (*PGCALL2) (PG_FUNCTION_ARGS);
38
#define NEXTVAL(x) ( (ltree*)( (char*)(x) + INTALIGN( VARSIZE(x) ) ) )
41
array_iterator(ArrayType *la, PGCALL2 callback, void *param, ltree ** found)
43
int num = ArrayGetNItems(ARR_NDIM(la), ARR_DIMS(la));
44
ltree *item = (ltree *) ARR_DATA_PTR(la);
46
if (ARR_NDIM(la) != 1)
48
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
49
errmsg("array must be one-dimensional")));
55
if (DatumGetBool(DirectFunctionCall2(callback,
56
PointerGetDatum(item), PointerGetDatum(param))))
71
_ltree_isparent(PG_FUNCTION_ARGS)
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);
77
PG_FREE_IF_COPY(la, 0);
78
PG_FREE_IF_COPY(query, 1);
83
_ltree_r_isparent(PG_FUNCTION_ARGS)
85
PG_RETURN_DATUM(DirectFunctionCall2(_ltree_isparent,
92
_ltree_risparent(PG_FUNCTION_ARGS)
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);
98
PG_FREE_IF_COPY(la, 0);
99
PG_FREE_IF_COPY(query, 1);
104
_ltree_r_risparent(PG_FUNCTION_ARGS)
106
PG_RETURN_DATUM(DirectFunctionCall2(_ltree_risparent,
113
_ltq_regex(PG_FUNCTION_ARGS)
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);
119
PG_FREE_IF_COPY(la, 0);
120
PG_FREE_IF_COPY(query, 1);
125
_ltq_rregex(PG_FUNCTION_ARGS)
127
PG_RETURN_DATUM(DirectFunctionCall2(_ltq_regex,
134
_lt_q_regex(PG_FUNCTION_ARGS)
136
ArrayType *_tree = PG_GETARG_ARRAYTYPE_P(0);
137
ArrayType *_query = PG_GETARG_ARRAYTYPE_P(1);
138
lquery *query = (lquery *) ARR_DATA_PTR(_query);
140
int num = ArrayGetNItems(ARR_NDIM(_query), ARR_DIMS(_query));
142
if (ARR_NDIM(_query) != 1)
144
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
145
errmsg("array must be one-dimensional")));
149
if (array_iterator(_tree, ltq_regex, (void *) query, NULL))
155
query = (lquery *) NEXTVAL(query);
158
PG_FREE_IF_COPY(_tree, 0);
159
PG_FREE_IF_COPY(_query, 1);
164
_lt_q_rregex(PG_FUNCTION_ARGS)
166
PG_RETURN_DATUM(DirectFunctionCall2(_lt_q_regex,
174
_ltxtq_exec(PG_FUNCTION_ARGS)
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);
180
PG_FREE_IF_COPY(la, 0);
181
PG_FREE_IF_COPY(query, 1);
186
_ltxtq_rexec(PG_FUNCTION_ARGS)
188
PG_RETURN_DATUM(DirectFunctionCall2(_ltxtq_exec,
196
_ltree_extract_isparent(PG_FUNCTION_ARGS)
198
ArrayType *la = PG_GETARG_ARRAYTYPE_P(0);
199
ltree *query = PG_GETARG_LTREE(1);
203
if (!array_iterator(la, ltree_isparent, (void *) query, &found))
205
PG_FREE_IF_COPY(la, 0);
206
PG_FREE_IF_COPY(query, 1);
210
item = (ltree *) palloc(found->len);
211
memcpy(item, found, found->len);
213
PG_FREE_IF_COPY(la, 0);
214
PG_FREE_IF_COPY(query, 1);
215
PG_RETURN_POINTER(item);
219
_ltree_extract_risparent(PG_FUNCTION_ARGS)
221
ArrayType *la = PG_GETARG_ARRAYTYPE_P(0);
222
ltree *query = PG_GETARG_LTREE(1);
226
if (!array_iterator(la, ltree_risparent, (void *) query, &found))
228
PG_FREE_IF_COPY(la, 0);
229
PG_FREE_IF_COPY(query, 1);
233
item = (ltree *) palloc(found->len);
234
memcpy(item, found, found->len);
236
PG_FREE_IF_COPY(la, 0);
237
PG_FREE_IF_COPY(query, 1);
238
PG_RETURN_POINTER(item);
242
_ltq_extract_regex(PG_FUNCTION_ARGS)
244
ArrayType *la = PG_GETARG_ARRAYTYPE_P(0);
245
lquery *query = PG_GETARG_LQUERY(1);
249
if (!array_iterator(la, ltq_regex, (void *) query, &found))
251
PG_FREE_IF_COPY(la, 0);
252
PG_FREE_IF_COPY(query, 1);
256
item = (ltree *) palloc(found->len);
257
memcpy(item, found, found->len);
259
PG_FREE_IF_COPY(la, 0);
260
PG_FREE_IF_COPY(query, 1);
261
PG_RETURN_POINTER(item);
265
_ltxtq_extract_exec(PG_FUNCTION_ARGS)
267
ArrayType *la = PG_GETARG_ARRAYTYPE_P(0);
268
ltxtquery *query = PG_GETARG_LTXTQUERY(1);
272
if (!array_iterator(la, ltxtq_exec, (void *) query, &found))
274
PG_FREE_IF_COPY(la, 0);
275
PG_FREE_IF_COPY(query, 1);
279
item = (ltree *) palloc(found->len);
280
memcpy(item, found, found->len);
282
PG_FREE_IF_COPY(la, 0);
283
PG_FREE_IF_COPY(query, 1);
284
PG_RETURN_POINTER(item);
288
_lca(PG_FUNCTION_ARGS)
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);
296
a = (ltree **) palloc(sizeof(ltree *) * num);
301
item = NEXTVAL(item);
303
res = lca_inner(a, ArrayGetNItems(ARR_NDIM(la), ARR_DIMS(la)));
306
PG_FREE_IF_COPY(la, 0);
309
PG_RETURN_POINTER(res);