PostgreSQL Source Code  git master
jsonb_op.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * jsonb_op.c
4  * Special operators for jsonb only, used by various index access methods
5  *
6  * Copyright (c) 2014-2022, PostgreSQL Global Development Group
7  *
8  *
9  * IDENTIFICATION
10  * src/backend/utils/adt/jsonb_op.c
11  *
12  *-------------------------------------------------------------------------
13  */
14 #include "postgres.h"
15 
16 #include "catalog/pg_type.h"
17 #include "miscadmin.h"
18 #include "utils/builtins.h"
19 #include "utils/jsonb.h"
20 
21 Datum
23 {
24  Jsonb *jb = PG_GETARG_JSONB_P(0);
26  JsonbValue kval;
27  JsonbValue *v = NULL;
28 
29  /*
30  * We only match Object keys (which are naturally always Strings), or
31  * string elements in arrays. In particular, we do not match non-string
32  * scalar elements. Existence of a key/element is only considered at the
33  * top level. No recursion occurs.
34  */
35  kval.type = jbvString;
36  kval.val.string.val = VARDATA_ANY(key);
37  kval.val.string.len = VARSIZE_ANY_EXHDR(key);
38 
41  &kval);
42 
43  PG_RETURN_BOOL(v != NULL);
44 }
45 
46 Datum
48 {
49  Jsonb *jb = PG_GETARG_JSONB_P(0);
51  int i;
52  Datum *key_datums;
53  bool *key_nulls;
54  int elem_count;
55 
56  deconstruct_array_builtin(keys, TEXTOID, &key_datums, &key_nulls, &elem_count);
57 
58  for (i = 0; i < elem_count; i++)
59  {
61 
62  if (key_nulls[i])
63  continue;
64 
65  strVal.type = jbvString;
66  strVal.val.string.val = VARDATA(key_datums[i]);
67  strVal.val.string.len = VARSIZE(key_datums[i]) - VARHDRSZ;
68 
71  &strVal) != NULL)
72  PG_RETURN_BOOL(true);
73  }
74 
75  PG_RETURN_BOOL(false);
76 }
77 
78 Datum
80 {
81  Jsonb *jb = PG_GETARG_JSONB_P(0);
83  int i;
84  Datum *key_datums;
85  bool *key_nulls;
86  int elem_count;
87 
88  deconstruct_array_builtin(keys, TEXTOID, &key_datums, &key_nulls, &elem_count);
89 
90  for (i = 0; i < elem_count; i++)
91  {
93 
94  if (key_nulls[i])
95  continue;
96 
97  strVal.type = jbvString;
98  strVal.val.string.val = VARDATA(key_datums[i]);
99  strVal.val.string.len = VARSIZE(key_datums[i]) - VARHDRSZ;
100 
103  &strVal) == NULL)
104  PG_RETURN_BOOL(false);
105  }
106 
107  PG_RETURN_BOOL(true);
108 }
109 
110 Datum
112 {
114  Jsonb *tmpl = PG_GETARG_JSONB_P(1);
115 
116  JsonbIterator *it1,
117  *it2;
118 
120  PG_RETURN_BOOL(false);
121 
122  it1 = JsonbIteratorInit(&val->root);
123  it2 = JsonbIteratorInit(&tmpl->root);
124 
125  PG_RETURN_BOOL(JsonbDeepContains(&it1, &it2));
126 }
127 
128 Datum
130 {
131  /* Commutator of "contains" */
132  Jsonb *tmpl = PG_GETARG_JSONB_P(0);
134 
135  JsonbIterator *it1,
136  *it2;
137 
139  PG_RETURN_BOOL(false);
140 
141  it1 = JsonbIteratorInit(&val->root);
142  it2 = JsonbIteratorInit(&tmpl->root);
143 
144  PG_RETURN_BOOL(JsonbDeepContains(&it1, &it2));
145 }
146 
147 Datum
149 {
150  Jsonb *jba = PG_GETARG_JSONB_P(0);
151  Jsonb *jbb = PG_GETARG_JSONB_P(1);
152  bool res;
153 
154  res = (compareJsonbContainers(&jba->root, &jbb->root) != 0);
155 
156  PG_FREE_IF_COPY(jba, 0);
157  PG_FREE_IF_COPY(jbb, 1);
159 }
160 
161 /*
162  * B-Tree operator class operators, support function
163  */
164 Datum
166 {
167  Jsonb *jba = PG_GETARG_JSONB_P(0);
168  Jsonb *jbb = PG_GETARG_JSONB_P(1);
169  bool res;
170 
171  res = (compareJsonbContainers(&jba->root, &jbb->root) < 0);
172 
173  PG_FREE_IF_COPY(jba, 0);
174  PG_FREE_IF_COPY(jbb, 1);
176 }
177 
178 Datum
180 {
181  Jsonb *jba = PG_GETARG_JSONB_P(0);
182  Jsonb *jbb = PG_GETARG_JSONB_P(1);
183  bool res;
184 
185  res = (compareJsonbContainers(&jba->root, &jbb->root) > 0);
186 
187  PG_FREE_IF_COPY(jba, 0);
188  PG_FREE_IF_COPY(jbb, 1);
190 }
191 
192 Datum
194 {
195  Jsonb *jba = PG_GETARG_JSONB_P(0);
196  Jsonb *jbb = PG_GETARG_JSONB_P(1);
197  bool res;
198 
199  res = (compareJsonbContainers(&jba->root, &jbb->root) <= 0);
200 
201  PG_FREE_IF_COPY(jba, 0);
202  PG_FREE_IF_COPY(jbb, 1);
204 }
205 
206 Datum
208 {
209  Jsonb *jba = PG_GETARG_JSONB_P(0);
210  Jsonb *jbb = PG_GETARG_JSONB_P(1);
211  bool res;
212 
213  res = (compareJsonbContainers(&jba->root, &jbb->root) >= 0);
214 
215  PG_FREE_IF_COPY(jba, 0);
216  PG_FREE_IF_COPY(jbb, 1);
218 }
219 
220 Datum
222 {
223  Jsonb *jba = PG_GETARG_JSONB_P(0);
224  Jsonb *jbb = PG_GETARG_JSONB_P(1);
225  bool res;
226 
227  res = (compareJsonbContainers(&jba->root, &jbb->root) == 0);
228 
229  PG_FREE_IF_COPY(jba, 0);
230  PG_FREE_IF_COPY(jbb, 1);
232 }
233 
234 Datum
236 {
237  Jsonb *jba = PG_GETARG_JSONB_P(0);
238  Jsonb *jbb = PG_GETARG_JSONB_P(1);
239  int res;
240 
241  res = compareJsonbContainers(&jba->root, &jbb->root);
242 
243  PG_FREE_IF_COPY(jba, 0);
244  PG_FREE_IF_COPY(jbb, 1);
246 }
247 
248 /*
249  * Hash operator class jsonb hashing function
250  */
251 Datum
253 {
254  Jsonb *jb = PG_GETARG_JSONB_P(0);
255  JsonbIterator *it;
256  JsonbValue v;
258  uint32 hash = 0;
259 
260  if (JB_ROOT_COUNT(jb) == 0)
261  PG_RETURN_INT32(0);
262 
263  it = JsonbIteratorInit(&jb->root);
264 
265  while ((r = JsonbIteratorNext(&it, &v, false)) != WJB_DONE)
266  {
267  switch (r)
268  {
269  /* Rotation is left to JsonbHashScalarValue() */
270  case WJB_BEGIN_ARRAY:
271  hash ^= JB_FARRAY;
272  break;
273  case WJB_BEGIN_OBJECT:
274  hash ^= JB_FOBJECT;
275  break;
276  case WJB_KEY:
277  case WJB_VALUE:
278  case WJB_ELEM:
280  break;
281  case WJB_END_ARRAY:
282  case WJB_END_OBJECT:
283  break;
284  default:
285  elog(ERROR, "invalid JsonbIteratorNext rc: %d", (int) r);
286  }
287  }
288 
289  PG_FREE_IF_COPY(jb, 0);
291 }
292 
293 Datum
295 {
296  Jsonb *jb = PG_GETARG_JSONB_P(0);
297  uint64 seed = PG_GETARG_INT64(1);
298  JsonbIterator *it;
299  JsonbValue v;
301  uint64 hash = 0;
302 
303  if (JB_ROOT_COUNT(jb) == 0)
304  PG_RETURN_UINT64(seed);
305 
306  it = JsonbIteratorInit(&jb->root);
307 
308  while ((r = JsonbIteratorNext(&it, &v, false)) != WJB_DONE)
309  {
310  switch (r)
311  {
312  /* Rotation is left to JsonbHashScalarValueExtended() */
313  case WJB_BEGIN_ARRAY:
314  hash ^= ((uint64) JB_FARRAY) << 32 | JB_FARRAY;
315  break;
316  case WJB_BEGIN_OBJECT:
317  hash ^= ((uint64) JB_FOBJECT) << 32 | JB_FOBJECT;
318  break;
319  case WJB_KEY:
320  case WJB_VALUE:
321  case WJB_ELEM:
323  break;
324  case WJB_END_ARRAY:
325  case WJB_END_OBJECT:
326  break;
327  default:
328  elog(ERROR, "invalid JsonbIteratorNext rc: %d", (int) r);
329  }
330  }
331 
332  PG_FREE_IF_COPY(jb, 0);
334 }
#define PG_GETARG_ARRAYTYPE_P(n)
Definition: array.h:256
void deconstruct_array_builtin(ArrayType *array, Oid elmtype, Datum **elemsp, bool **nullsp, int *nelemsp)
Definition: arrayfuncs.c:3642
unsigned int uint32
Definition: c.h:442
#define VARHDRSZ
Definition: c.h:628
#define ERROR
Definition: elog.h:35
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:260
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:309
#define PG_GETARG_INT64(n)
Definition: fmgr.h:283
#define PG_RETURN_UINT64(x)
Definition: fmgr.h:369
#define PG_RETURN_INT32(x)
Definition: fmgr.h:354
#define PG_FUNCTION_ARGS
Definition: fmgr.h:193
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
long val
Definition: informix.c:664
int i
Definition: isn.c:73
@ jbvString
Definition: jsonb.h:229
#define JB_ROOT_IS_OBJECT(jbp_)
Definition: jsonb.h:221
#define PG_GETARG_JSONB_P(x)
Definition: jsonb.h:389
#define JB_FARRAY
Definition: jsonb.h:203
JsonbIteratorToken
Definition: jsonb.h:21
@ WJB_KEY
Definition: jsonb.h:23
@ WJB_DONE
Definition: jsonb.h:22
@ WJB_END_ARRAY
Definition: jsonb.h:27
@ WJB_VALUE
Definition: jsonb.h:24
@ WJB_END_OBJECT
Definition: jsonb.h:29
@ WJB_ELEM
Definition: jsonb.h:25
@ WJB_BEGIN_OBJECT
Definition: jsonb.h:28
@ WJB_BEGIN_ARRAY
Definition: jsonb.h:26
#define JB_ROOT_COUNT(jbp_)
Definition: jsonb.h:219
#define JB_FOBJECT
Definition: jsonb.h:202
Datum jsonb_le(PG_FUNCTION_ARGS)
Definition: jsonb_op.c:193
Datum jsonb_exists_all(PG_FUNCTION_ARGS)
Definition: jsonb_op.c:79
Datum jsonb_gt(PG_FUNCTION_ARGS)
Definition: jsonb_op.c:179
Datum jsonb_hash_extended(PG_FUNCTION_ARGS)
Definition: jsonb_op.c:294
Datum jsonb_exists_any(PG_FUNCTION_ARGS)
Definition: jsonb_op.c:47
Datum jsonb_hash(PG_FUNCTION_ARGS)
Definition: jsonb_op.c:252
Datum jsonb_contains(PG_FUNCTION_ARGS)
Definition: jsonb_op.c:111
Datum jsonb_lt(PG_FUNCTION_ARGS)
Definition: jsonb_op.c:165
Datum jsonb_contained(PG_FUNCTION_ARGS)
Definition: jsonb_op.c:129
Datum jsonb_cmp(PG_FUNCTION_ARGS)
Definition: jsonb_op.c:235
Datum jsonb_ge(PG_FUNCTION_ARGS)
Definition: jsonb_op.c:207
Datum jsonb_ne(PG_FUNCTION_ARGS)
Definition: jsonb_op.c:148
Datum jsonb_eq(PG_FUNCTION_ARGS)
Definition: jsonb_op.c:221
Datum jsonb_exists(PG_FUNCTION_ARGS)
Definition: jsonb_op.c:22
JsonbIterator * JsonbIteratorInit(JsonbContainer *container)
Definition: jsonb_util.c:813
int compareJsonbContainers(JsonbContainer *a, JsonbContainer *b)
Definition: jsonb_util.c:192
void JsonbHashScalarValue(const JsonbValue *scalarVal, uint32 *hash)
Definition: jsonb_util.c:1312
JsonbIteratorToken JsonbIteratorNext(JsonbIterator **it, JsonbValue *val, bool skipNested)
Definition: jsonb_util.c:849
JsonbValue * findJsonbValueFromContainer(JsonbContainer *container, uint32 flags, JsonbValue *key)
Definition: jsonb_util.c:345
void JsonbHashScalarValueExtended(const JsonbValue *scalarVal, uint64 *hash, uint64 seed)
Definition: jsonb_util.c:1355
bool JsonbDeepContains(JsonbIterator **val, JsonbIterator **mContained)
Definition: jsonb_util.c:1058
uintptr_t Datum
Definition: postgres.h:412
#define VARDATA(PTR)
Definition: postgres.h:316
#define VARDATA_ANY(PTR)
Definition: postgres.h:362
#define VARSIZE(PTR)
Definition: postgres.h:317
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:355
static unsigned hash(unsigned *uv, int n)
Definition: rege_dfa.c:715
enum jbvType type
Definition: jsonb.h:255
char * val
Definition: jsonb.h:264
Definition: jsonb.h:213
JsonbContainer root
Definition: jsonb.h:215
Definition: c.h:623
#define strVal(v)
Definition: value.h:82