PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
_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 
24 
29 
31 
33 
34 #define NEXTVAL(x) ( (ltree*)( (char*)(x) + INTALIGN( VARSIZE(x) ) ) )
35 
36 static bool
37 array_iterator(ArrayType *la, PGCALL2 callback, void *param, ltree **found)
38 {
39  int num = ArrayGetNItems(ARR_NDIM(la), ARR_DIMS(la));
40  ltree *item = (ltree *) ARR_DATA_PTR(la);
41 
42  if (ARR_NDIM(la) > 1)
43  ereport(ERROR,
44  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
45  errmsg("array must be one-dimensional")));
46  if (array_contains_nulls(la))
47  ereport(ERROR,
48  (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
49  errmsg("array must not contain nulls")));
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
72 {
74  ltree *query = PG_GETARG_LTREE_P(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
84 {
86  PG_GETARG_DATUM(1),
88  ));
89 }
90 
91 Datum
93 {
95  ltree *query = PG_GETARG_LTREE_P(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
105 {
107  PG_GETARG_DATUM(1),
108  PG_GETARG_DATUM(0)
109  ));
110 }
111 
112 Datum
114 {
116  lquery *query = PG_GETARG_LQUERY_P(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
126 {
128  PG_GETARG_DATUM(1),
129  PG_GETARG_DATUM(0)
130  ));
131 }
132 
133 Datum
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  if (array_contains_nulls(_query))
147  ereport(ERROR,
148  (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
149  errmsg("array must not contain nulls")));
150 
151  while (num > 0)
152  {
153  if (array_iterator(_tree, ltq_regex, (void *) query, NULL))
154  {
155  res = true;
156  break;
157  }
158  num--;
159  query = (lquery *) NEXTVAL(query);
160  }
161 
162  PG_FREE_IF_COPY(_tree, 0);
163  PG_FREE_IF_COPY(_query, 1);
164  PG_RETURN_BOOL(res);
165 }
166 
167 Datum
169 {
171  PG_GETARG_DATUM(1),
172  PG_GETARG_DATUM(0)
173  ));
174 }
175 
176 
177 Datum
179 {
181  ltxtquery *query = PG_GETARG_LTXTQUERY_P(1);
182  bool res = array_iterator(la, ltxtq_exec, (void *) query, NULL);
183 
184  PG_FREE_IF_COPY(la, 0);
185  PG_FREE_IF_COPY(query, 1);
186  PG_RETURN_BOOL(res);
187 }
188 
189 Datum
191 {
193  PG_GETARG_DATUM(1),
194  PG_GETARG_DATUM(0)
195  ));
196 }
197 
198 
199 Datum
201 {
203  ltree *query = PG_GETARG_LTREE_P(1);
204  ltree *found,
205  *item;
206 
207  if (!array_iterator(la, ltree_isparent, (void *) query, &found))
208  {
209  PG_FREE_IF_COPY(la, 0);
210  PG_FREE_IF_COPY(query, 1);
211  PG_RETURN_NULL();
212  }
213 
214  item = (ltree *) palloc0(VARSIZE(found));
215  memcpy(item, found, VARSIZE(found));
216 
217  PG_FREE_IF_COPY(la, 0);
218  PG_FREE_IF_COPY(query, 1);
219  PG_RETURN_POINTER(item);
220 }
221 
222 Datum
224 {
226  ltree *query = PG_GETARG_LTREE_P(1);
227  ltree *found,
228  *item;
229 
230  if (!array_iterator(la, ltree_risparent, (void *) query, &found))
231  {
232  PG_FREE_IF_COPY(la, 0);
233  PG_FREE_IF_COPY(query, 1);
234  PG_RETURN_NULL();
235  }
236 
237  item = (ltree *) palloc0(VARSIZE(found));
238  memcpy(item, found, VARSIZE(found));
239 
240  PG_FREE_IF_COPY(la, 0);
241  PG_FREE_IF_COPY(query, 1);
242  PG_RETURN_POINTER(item);
243 }
244 
245 Datum
247 {
249  lquery *query = PG_GETARG_LQUERY_P(1);
250  ltree *found,
251  *item;
252 
253  if (!array_iterator(la, ltq_regex, (void *) query, &found))
254  {
255  PG_FREE_IF_COPY(la, 0);
256  PG_FREE_IF_COPY(query, 1);
257  PG_RETURN_NULL();
258  }
259 
260  item = (ltree *) palloc0(VARSIZE(found));
261  memcpy(item, found, VARSIZE(found));
262 
263  PG_FREE_IF_COPY(la, 0);
264  PG_FREE_IF_COPY(query, 1);
265  PG_RETURN_POINTER(item);
266 }
267 
268 Datum
270 {
272  ltxtquery *query = PG_GETARG_LTXTQUERY_P(1);
273  ltree *found,
274  *item;
275 
276  if (!array_iterator(la, ltxtq_exec, (void *) query, &found))
277  {
278  PG_FREE_IF_COPY(la, 0);
279  PG_FREE_IF_COPY(query, 1);
280  PG_RETURN_NULL();
281  }
282 
283  item = (ltree *) palloc0(VARSIZE(found));
284  memcpy(item, found, VARSIZE(found));
285 
286  PG_FREE_IF_COPY(la, 0);
287  PG_FREE_IF_COPY(query, 1);
288  PG_RETURN_POINTER(item);
289 }
290 
291 Datum
293 {
295  int num = ArrayGetNItems(ARR_NDIM(la), ARR_DIMS(la));
296  ltree *item = (ltree *) ARR_DATA_PTR(la);
297  ltree **a,
298  *res;
299 
300  if (ARR_NDIM(la) > 1)
301  ereport(ERROR,
302  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
303  errmsg("array must be one-dimensional")));
304  if (array_contains_nulls(la))
305  ereport(ERROR,
306  (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
307  errmsg("array must not contain nulls")));
308 
309  a = (ltree **) palloc(sizeof(ltree *) * num);
310  while (num > 0)
311  {
312  num--;
313  a[num] = item;
314  item = NEXTVAL(item);
315  }
316  res = lca_inner(a, ArrayGetNItems(ARR_NDIM(la), ARR_DIMS(la)));
317  pfree(a);
318 
319  PG_FREE_IF_COPY(la, 0);
320 
321  if (res)
322  PG_RETURN_POINTER(res);
323  else
324  PG_RETURN_NULL();
325 }
Datum _lt_q_rregex(PG_FUNCTION_ARGS)
Definition: _ltree_op.c:168
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:321
Datum _ltxtq_exec(PG_FUNCTION_ARGS)
Definition: _ltree_op.c:178
Datum _ltree_r_risparent(PG_FUNCTION_ARGS)
Definition: _ltree_op.c:104
#define VARSIZE(PTR)
Definition: postgres.h:304
#define PointerGetDatum(X)
Definition: postgres.h:562
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:233
Definition: ltree.h:69
int ArrayGetNItems(int ndim, const int *dims)
Definition: arrayutils.c:75
Datum ltree_risparent(PG_FUNCTION_ARGS)
Definition: ltree_op.c:172
int errcode(int sqlerrcode)
Definition: elog.c:575
#define PG_GETARG_LTREE_P(n)
Definition: ltree.h:171
#define NEXTVAL(x)
Definition: _ltree_op.c:34
Datum _ltq_extract_regex(PG_FUNCTION_ARGS)
Definition: _ltree_op.c:246
Datum _lt_q_regex(PG_FUNCTION_ARGS)
Definition: _ltree_op.c:134
Datum _ltree_isparent(PG_FUNCTION_ARGS)
Definition: _ltree_op.c:71
Datum _ltree_extract_isparent(PG_FUNCTION_ARGS)
Definition: _ltree_op.c:200
#define PG_GETARG_LQUERY_P(n)
Definition: ltree.h:176
PG_FUNCTION_INFO_V1(_ltree_isparent)
#define PG_GETARG_ARRAYTYPE_P(n)
Definition: array.h:248
Datum _ltq_regex(PG_FUNCTION_ARGS)
Definition: _ltree_op.c:113
void pfree(void *pointer)
Definition: mcxt.c:949
#define ERROR
Definition: elog.h:43
ltree * lca_inner(ltree **a, int len)
Definition: ltree_op.c:406
#define ARR_DIMS(a)
Definition: array.h:279
Datum ltq_regex(PG_FUNCTION_ARGS)
Definition: lquery_op.c:303
static void callback(struct sockaddr *addr, struct sockaddr *mask, void *unused)
Definition: test_ifaddrs.c:48
#define ARR_DATA_PTR(a)
Definition: array.h:307
static bool array_iterator(ArrayType *la, PGCALL2 callback, void *param, ltree **found)
Definition: _ltree_op.c:37
Datum(* PGCALL2)(PG_FUNCTION_ARGS)
Definition: _ltree_op.c:32
#define DatumGetBool(X)
Definition: postgres.h:399
Datum _ltxtq_rexec(PG_FUNCTION_ARGS)
Definition: _ltree_op.c:190
Datum _ltree_extract_risparent(PG_FUNCTION_ARGS)
Definition: _ltree_op.c:223
#define ereport(elevel, rest)
Definition: elog.h:122
Definition: ltree.h:19
Datum ltree_isparent(PG_FUNCTION_ARGS)
Definition: ltree_op.c:160
void * palloc0(Size size)
Definition: mcxt.c:877
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:319
uintptr_t Datum
Definition: postgres.h:372
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:313
Datum _ltxtq_extract_exec(PG_FUNCTION_ARGS)
Definition: _ltree_op.c:269
Datum ltxtq_exec(PG_FUNCTION_ARGS)
Definition: ltxtquery_op.c:87
Datum _ltree_r_isparent(PG_FUNCTION_ARGS)
Definition: _ltree_op.c:83
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:225
#define ARR_NDIM(a)
Definition: array.h:275
#define PG_GETARG_LTXTQUERY_P(n)
Definition: ltree.h:181
void * palloc(Size size)
Definition: mcxt.c:848
int errmsg(const char *fmt,...)
Definition: elog.c:797
Datum _ltree_risparent(PG_FUNCTION_ARGS)
Definition: _ltree_op.c:92
Datum _ltq_rregex(PG_FUNCTION_ARGS)
Definition: _ltree_op.c:125
#define PG_FUNCTION_ARGS
Definition: fmgr.h:158
bool array_contains_nulls(ArrayType *array)
Definition: arrayfuncs.c:3516
Datum _lca(PG_FUNCTION_ARGS)
Definition: _ltree_op.c:292
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:587
#define PG_RETURN_NULL()
Definition: fmgr.h:305