PostgreSQL Source Code git master
_ltree_op.c
Go to the documentation of this file.
1/*
2 * contrib/ltree/_ltree_op.c
3 *
4 *
5 * op function for ltree[]
6 * Teodor Sigaev <teodor@stack.net>
7 */
8#include "postgres.h"
9
10#include <ctype.h>
11
12#include "ltree.h"
13#include "utils/array.h"
14
25
30
32
34
35#define NEXTVAL(x) ( (ltree*)( (char*)(x) + INTALIGN( VARSIZE(x) ) ) )
36
37static bool
38array_iterator(ArrayType *la, PGCALL2 callback, void *param, ltree **found)
39{
40 int num = ArrayGetNItems(ARR_NDIM(la), ARR_DIMS(la));
41 ltree *item = (ltree *) ARR_DATA_PTR(la);
42
43 if (ARR_NDIM(la) > 1)
45 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
46 errmsg("array must be one-dimensional")));
49 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
50 errmsg("array must not contain nulls")));
51
52 if (found)
53 *found = NULL;
54 while (num > 0)
55 {
57 PointerGetDatum(item), PointerGetDatum(param))))
58 {
59
60 if (found)
61 *found = item;
62 return true;
63 }
64 num--;
65 item = NEXTVAL(item);
66 }
67
68 return false;
69}
70
73{
75 ltree *query = PG_GETARG_LTREE_P(1);
76 bool res = array_iterator(la, ltree_isparent, query, NULL);
77
78 PG_FREE_IF_COPY(la, 0);
79 PG_FREE_IF_COPY(query, 1);
81}
82
85{
89 ));
90}
91
94{
96 ltree *query = PG_GETARG_LTREE_P(1);
97 bool res = array_iterator(la, ltree_risparent, query, NULL);
98
99 PG_FREE_IF_COPY(la, 0);
100 PG_FREE_IF_COPY(query, 1);
102}
103
104Datum
106{
110 ));
111}
112
113Datum
115{
117 lquery *query = PG_GETARG_LQUERY_P(1);
118 bool res = array_iterator(la, ltq_regex, query, NULL);
119
120 PG_FREE_IF_COPY(la, 0);
121 PG_FREE_IF_COPY(query, 1);
123}
124
125Datum
127{
131 ));
132}
133
134Datum
136{
138 ArrayType *_query = PG_GETARG_ARRAYTYPE_P(1);
139 lquery *query = (lquery *) ARR_DATA_PTR(_query);
140 bool res = false;
141 int num = ArrayGetNItems(ARR_NDIM(_query), ARR_DIMS(_query));
142
143 if (ARR_NDIM(_query) > 1)
145 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
146 errmsg("array must be one-dimensional")));
147 if (array_contains_nulls(_query))
149 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
150 errmsg("array must not contain nulls")));
151
152 while (num > 0)
153 {
154 if (array_iterator(_tree, ltq_regex, query, NULL))
155 {
156 res = true;
157 break;
158 }
159 num--;
160 query = (lquery *) NEXTVAL(query);
161 }
162
163 PG_FREE_IF_COPY(_tree, 0);
164 PG_FREE_IF_COPY(_query, 1);
166}
167
168Datum
170{
174 ));
175}
176
177
178Datum
180{
183 bool res = array_iterator(la, ltxtq_exec, query, NULL);
184
185 PG_FREE_IF_COPY(la, 0);
186 PG_FREE_IF_COPY(query, 1);
188}
189
190Datum
192{
196 ));
197}
198
199
200Datum
202{
204 ltree *query = PG_GETARG_LTREE_P(1);
205 ltree *found,
206 *item;
207
208 if (!array_iterator(la, ltree_isparent, query, &found))
209 {
210 PG_FREE_IF_COPY(la, 0);
211 PG_FREE_IF_COPY(query, 1);
213 }
214
215 item = (ltree *) palloc0(VARSIZE(found));
216 memcpy(item, found, VARSIZE(found));
217
218 PG_FREE_IF_COPY(la, 0);
219 PG_FREE_IF_COPY(query, 1);
220 PG_RETURN_POINTER(item);
221}
222
223Datum
225{
227 ltree *query = PG_GETARG_LTREE_P(1);
228 ltree *found,
229 *item;
230
231 if (!array_iterator(la, ltree_risparent, query, &found))
232 {
233 PG_FREE_IF_COPY(la, 0);
234 PG_FREE_IF_COPY(query, 1);
236 }
237
238 item = (ltree *) palloc0(VARSIZE(found));
239 memcpy(item, found, VARSIZE(found));
240
241 PG_FREE_IF_COPY(la, 0);
242 PG_FREE_IF_COPY(query, 1);
243 PG_RETURN_POINTER(item);
244}
245
246Datum
248{
250 lquery *query = PG_GETARG_LQUERY_P(1);
251 ltree *found,
252 *item;
253
254 if (!array_iterator(la, ltq_regex, query, &found))
255 {
256 PG_FREE_IF_COPY(la, 0);
257 PG_FREE_IF_COPY(query, 1);
259 }
260
261 item = (ltree *) palloc0(VARSIZE(found));
262 memcpy(item, found, VARSIZE(found));
263
264 PG_FREE_IF_COPY(la, 0);
265 PG_FREE_IF_COPY(query, 1);
266 PG_RETURN_POINTER(item);
267}
268
269Datum
271{
274 ltree *found,
275 *item;
276
277 if (!array_iterator(la, ltxtq_exec, query, &found))
278 {
279 PG_FREE_IF_COPY(la, 0);
280 PG_FREE_IF_COPY(query, 1);
282 }
283
284 item = (ltree *) palloc0(VARSIZE(found));
285 memcpy(item, found, VARSIZE(found));
286
287 PG_FREE_IF_COPY(la, 0);
288 PG_FREE_IF_COPY(query, 1);
289 PG_RETURN_POINTER(item);
290}
291
292Datum
294{
296 int num = ArrayGetNItems(ARR_NDIM(la), ARR_DIMS(la));
297 ltree *item = (ltree *) ARR_DATA_PTR(la);
298 ltree **a,
299 *res;
300
301 if (ARR_NDIM(la) > 1)
303 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
304 errmsg("array must be one-dimensional")));
305 if (array_contains_nulls(la))
307 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
308 errmsg("array must not contain nulls")));
309
310 a = (ltree **) palloc(sizeof(ltree *) * num);
311 while (num > 0)
312 {
313 num--;
314 a[num] = item;
315 item = NEXTVAL(item);
316 }
318 pfree(a);
319
320 PG_FREE_IF_COPY(la, 0);
321
322 if (res)
324 else
326}
#define NEXTVAL(x)
Definition: _ltree_op.c:35
Datum _ltxtq_exec(PG_FUNCTION_ARGS)
Definition: _ltree_op.c:179
Datum _ltree_risparent(PG_FUNCTION_ARGS)
Definition: _ltree_op.c:93
Datum _ltxtq_extract_exec(PG_FUNCTION_ARGS)
Definition: _ltree_op.c:270
static bool array_iterator(ArrayType *la, PGCALL2 callback, void *param, ltree **found)
Definition: _ltree_op.c:38
Datum _lca(PG_FUNCTION_ARGS)
Definition: _ltree_op.c:293
Datum(* PGCALL2)(PG_FUNCTION_ARGS)
Definition: _ltree_op.c:33
Datum _ltree_r_isparent(PG_FUNCTION_ARGS)
Definition: _ltree_op.c:84
Datum _lt_q_rregex(PG_FUNCTION_ARGS)
Definition: _ltree_op.c:169
Datum _ltree_isparent(PG_FUNCTION_ARGS)
Definition: _ltree_op.c:72
Datum _ltree_extract_risparent(PG_FUNCTION_ARGS)
Definition: _ltree_op.c:224
Datum _ltq_extract_regex(PG_FUNCTION_ARGS)
Definition: _ltree_op.c:247
Datum _ltq_rregex(PG_FUNCTION_ARGS)
Definition: _ltree_op.c:126
Datum _ltree_extract_isparent(PG_FUNCTION_ARGS)
Definition: _ltree_op.c:201
Datum _ltree_r_risparent(PG_FUNCTION_ARGS)
Definition: _ltree_op.c:105
Datum _ltxtq_rexec(PG_FUNCTION_ARGS)
Definition: _ltree_op.c:191
PG_FUNCTION_INFO_V1(_ltree_isparent)
Datum _ltq_regex(PG_FUNCTION_ARGS)
Definition: _ltree_op.c:114
Datum _lt_q_regex(PG_FUNCTION_ARGS)
Definition: _ltree_op.c:135
#define ARR_NDIM(a)
Definition: array.h:290
#define PG_GETARG_ARRAYTYPE_P(n)
Definition: array.h:263
#define ARR_DATA_PTR(a)
Definition: array.h:322
#define ARR_DIMS(a)
Definition: array.h:294
bool array_contains_nulls(ArrayType *array)
Definition: arrayfuncs.c:3767
int ArrayGetNItems(int ndim, const int *dims)
Definition: arrayutils.c:57
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:260
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:643
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:268
#define PG_RETURN_NULL()
Definition: fmgr.h:345
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:353
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:361
#define PG_FUNCTION_ARGS
Definition: fmgr.h:193
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
int a
Definition: isn.c:68
Datum ltq_regex(PG_FUNCTION_ARGS)
Definition: lquery_op.c:215
#define PG_GETARG_LTXTQUERY_P(n)
Definition: ltree.h:228
PGDLLEXPORT Datum ltxtq_exec(PG_FUNCTION_ARGS)
Definition: ltxtquery_op.c:84
ltree * lca_inner(ltree **a, int len)
Definition: ltree_op.c:493
#define PG_GETARG_LQUERY_P(n)
Definition: ltree.h:223
PGDLLEXPORT Datum ltree_risparent(PG_FUNCTION_ARGS)
Definition: ltree_op.c:246
PGDLLEXPORT Datum ltree_isparent(PG_FUNCTION_ARGS)
Definition: ltree_op.c:234
#define PG_GETARG_LTREE_P(n)
Definition: ltree.h:218
void pfree(void *pointer)
Definition: mcxt.c:1521
void * palloc0(Size size)
Definition: mcxt.c:1347
void * palloc(Size size)
Definition: mcxt.c:1317
static bool DatumGetBool(Datum X)
Definition: postgres.h:95
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:327
uintptr_t Datum
Definition: postgres.h:69
Definition: ltree.h:114
Definition: ltree.h:43
static void callback(struct sockaddr *addr, struct sockaddr *mask, void *unused)
Definition: test_ifaddrs.c:46
#define VARSIZE(PTR)
Definition: varatt.h:279