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 
37 static bool
38 array_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)
44  ereport(ERROR,
45  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
46  errmsg("array must be one-dimensional")));
47  if (array_contains_nulls(la))
48  ereport(ERROR,
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 
71 Datum
73 {
75  ltree *query = PG_GETARG_LTREE_P(1);
76  bool res = array_iterator(la, ltree_isparent, (void *) query, NULL);
77 
78  PG_FREE_IF_COPY(la, 0);
79  PG_FREE_IF_COPY(query, 1);
81 }
82 
83 Datum
85 {
87  PG_GETARG_DATUM(1),
89  ));
90 }
91 
92 Datum
94 {
96  ltree *query = PG_GETARG_LTREE_P(1);
97  bool res = array_iterator(la, ltree_risparent, (void *) query, NULL);
98 
99  PG_FREE_IF_COPY(la, 0);
100  PG_FREE_IF_COPY(query, 1);
102 }
103 
104 Datum
106 {
108  PG_GETARG_DATUM(1),
109  PG_GETARG_DATUM(0)
110  ));
111 }
112 
113 Datum
115 {
117  lquery *query = PG_GETARG_LQUERY_P(1);
118  bool res = array_iterator(la, ltq_regex, (void *) query, NULL);
119 
120  PG_FREE_IF_COPY(la, 0);
121  PG_FREE_IF_COPY(query, 1);
123 }
124 
125 Datum
127 {
129  PG_GETARG_DATUM(1),
130  PG_GETARG_DATUM(0)
131  ));
132 }
133 
134 Datum
136 {
137  ArrayType *_tree = PG_GETARG_ARRAYTYPE_P(0);
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)
144  ereport(ERROR,
145  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
146  errmsg("array must be one-dimensional")));
147  if (array_contains_nulls(_query))
148  ereport(ERROR,
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, (void *) 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 
168 Datum
170 {
172  PG_GETARG_DATUM(1),
173  PG_GETARG_DATUM(0)
174  ));
175 }
176 
177 
178 Datum
180 {
182  ltxtquery *query = PG_GETARG_LTXTQUERY_P(1);
183  bool res = array_iterator(la, ltxtq_exec, (void *) query, NULL);
184 
185  PG_FREE_IF_COPY(la, 0);
186  PG_FREE_IF_COPY(query, 1);
188 }
189 
190 Datum
192 {
194  PG_GETARG_DATUM(1),
195  PG_GETARG_DATUM(0)
196  ));
197 }
198 
199 
200 Datum
202 {
204  ltree *query = PG_GETARG_LTREE_P(1);
205  ltree *found,
206  *item;
207 
208  if (!array_iterator(la, ltree_isparent, (void *) query, &found))
209  {
210  PG_FREE_IF_COPY(la, 0);
211  PG_FREE_IF_COPY(query, 1);
212  PG_RETURN_NULL();
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 
223 Datum
225 {
227  ltree *query = PG_GETARG_LTREE_P(1);
228  ltree *found,
229  *item;
230 
231  if (!array_iterator(la, ltree_risparent, (void *) query, &found))
232  {
233  PG_FREE_IF_COPY(la, 0);
234  PG_FREE_IF_COPY(query, 1);
235  PG_RETURN_NULL();
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 
246 Datum
248 {
250  lquery *query = PG_GETARG_LQUERY_P(1);
251  ltree *found,
252  *item;
253 
254  if (!array_iterator(la, ltq_regex, (void *) query, &found))
255  {
256  PG_FREE_IF_COPY(la, 0);
257  PG_FREE_IF_COPY(query, 1);
258  PG_RETURN_NULL();
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 
269 Datum
271 {
273  ltxtquery *query = PG_GETARG_LTXTQUERY_P(1);
274  ltree *found,
275  *item;
276 
277  if (!array_iterator(la, ltxtq_exec, (void *) query, &found))
278  {
279  PG_FREE_IF_COPY(la, 0);
280  PG_FREE_IF_COPY(query, 1);
281  PG_RETURN_NULL();
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 
292 Datum
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)
302  ereport(ERROR,
303  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
304  errmsg("array must be one-dimensional")));
305  if (array_contains_nulls(la))
306  ereport(ERROR,
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
325  PG_RETURN_NULL();
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:3748
int ArrayGetNItems(int ndim, const int *dims)
Definition: arrayutils.c:57
int errcode(int sqlerrcode)
Definition: elog.c:859
int errmsg(const char *fmt,...)
Definition: elog.c:1072
#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:644
#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:69
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
#define PG_GETARG_LQUERY_P(n)
Definition: ltree.h:223
PGDLLEXPORT Datum ltree_risparent(PG_FUNCTION_ARGS)
Definition: ltree_op.c:248
PGDLLEXPORT Datum ltree_isparent(PG_FUNCTION_ARGS)
Definition: ltree_op.c:236
#define PG_GETARG_LTREE_P(n)
Definition: ltree.h:218
ltree * lca_inner(ltree **a, int len)
Definition: ltree_op.c:495
void pfree(void *pointer)
Definition: mcxt.c:1520
void * palloc0(Size size)
Definition: mcxt.c:1346
void * palloc(Size size)
Definition: mcxt.c:1316
static bool DatumGetBool(Datum X)
Definition: postgres.h:90
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:322
uintptr_t Datum
Definition: postgres.h:64
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