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-2025, 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 "utils/fmgrprotos.h"
18#include "utils/jsonb.h"
19
22{
23 Jsonb *jb = PG_GETARG_JSONB_P(0);
25 JsonbValue kval;
26 JsonbValue *v = NULL;
27
28 /*
29 * We only match Object keys (which are naturally always Strings), or
30 * string elements in arrays. In particular, we do not match non-string
31 * scalar elements. Existence of a key/element is only considered at the
32 * top level. No recursion occurs.
33 */
34 kval.type = jbvString;
35 kval.val.string.val = VARDATA_ANY(key);
36 kval.val.string.len = VARSIZE_ANY_EXHDR(key);
37
40 &kval);
41
42 PG_RETURN_BOOL(v != NULL);
43}
44
47{
48 Jsonb *jb = PG_GETARG_JSONB_P(0);
50 int i;
51 Datum *key_datums;
52 bool *key_nulls;
53 int elem_count;
54
55 deconstruct_array_builtin(keys, TEXTOID, &key_datums, &key_nulls, &elem_count);
56
57 for (i = 0; i < elem_count; i++)
58 {
60
61 if (key_nulls[i])
62 continue;
63
64 strVal.type = jbvString;
65 /* We rely on the array elements not being toasted */
66 strVal.val.string.val = VARDATA_ANY(key_datums[i]);
67 strVal.val.string.len = VARSIZE_ANY_EXHDR(key_datums[i]);
68
71 &strVal) != NULL)
72 PG_RETURN_BOOL(true);
73 }
74
75 PG_RETURN_BOOL(false);
76}
77
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 /* We rely on the array elements not being toasted */
99 strVal.val.string.val = VARDATA_ANY(key_datums[i]);
100 strVal.val.string.len = VARSIZE_ANY_EXHDR(key_datums[i]);
101
104 &strVal) == NULL)
105 PG_RETURN_BOOL(false);
106 }
107
108 PG_RETURN_BOOL(true);
109}
110
111Datum
113{
115 Jsonb *tmpl = PG_GETARG_JSONB_P(1);
116
117 JsonbIterator *it1,
118 *it2;
119
121 PG_RETURN_BOOL(false);
122
123 it1 = JsonbIteratorInit(&val->root);
124 it2 = JsonbIteratorInit(&tmpl->root);
125
127}
128
129Datum
131{
132 /* Commutator of "contains" */
133 Jsonb *tmpl = PG_GETARG_JSONB_P(0);
135
136 JsonbIterator *it1,
137 *it2;
138
140 PG_RETURN_BOOL(false);
141
142 it1 = JsonbIteratorInit(&val->root);
143 it2 = JsonbIteratorInit(&tmpl->root);
144
146}
147
148Datum
150{
151 Jsonb *jba = PG_GETARG_JSONB_P(0);
152 Jsonb *jbb = PG_GETARG_JSONB_P(1);
153 bool res;
154
155 res = (compareJsonbContainers(&jba->root, &jbb->root) != 0);
156
157 PG_FREE_IF_COPY(jba, 0);
158 PG_FREE_IF_COPY(jbb, 1);
160}
161
162/*
163 * B-Tree operator class operators, support function
164 */
165Datum
167{
168 Jsonb *jba = PG_GETARG_JSONB_P(0);
169 Jsonb *jbb = PG_GETARG_JSONB_P(1);
170 bool res;
171
172 res = (compareJsonbContainers(&jba->root, &jbb->root) < 0);
173
174 PG_FREE_IF_COPY(jba, 0);
175 PG_FREE_IF_COPY(jbb, 1);
177}
178
179Datum
181{
182 Jsonb *jba = PG_GETARG_JSONB_P(0);
183 Jsonb *jbb = PG_GETARG_JSONB_P(1);
184 bool res;
185
186 res = (compareJsonbContainers(&jba->root, &jbb->root) > 0);
187
188 PG_FREE_IF_COPY(jba, 0);
189 PG_FREE_IF_COPY(jbb, 1);
191}
192
193Datum
195{
196 Jsonb *jba = PG_GETARG_JSONB_P(0);
197 Jsonb *jbb = PG_GETARG_JSONB_P(1);
198 bool res;
199
200 res = (compareJsonbContainers(&jba->root, &jbb->root) <= 0);
201
202 PG_FREE_IF_COPY(jba, 0);
203 PG_FREE_IF_COPY(jbb, 1);
205}
206
207Datum
209{
210 Jsonb *jba = PG_GETARG_JSONB_P(0);
211 Jsonb *jbb = PG_GETARG_JSONB_P(1);
212 bool res;
213
214 res = (compareJsonbContainers(&jba->root, &jbb->root) >= 0);
215
216 PG_FREE_IF_COPY(jba, 0);
217 PG_FREE_IF_COPY(jbb, 1);
219}
220
221Datum
223{
224 Jsonb *jba = PG_GETARG_JSONB_P(0);
225 Jsonb *jbb = PG_GETARG_JSONB_P(1);
226 bool res;
227
228 res = (compareJsonbContainers(&jba->root, &jbb->root) == 0);
229
230 PG_FREE_IF_COPY(jba, 0);
231 PG_FREE_IF_COPY(jbb, 1);
233}
234
235Datum
237{
238 Jsonb *jba = PG_GETARG_JSONB_P(0);
239 Jsonb *jbb = PG_GETARG_JSONB_P(1);
240 int res;
241
242 res = compareJsonbContainers(&jba->root, &jbb->root);
243
244 PG_FREE_IF_COPY(jba, 0);
245 PG_FREE_IF_COPY(jbb, 1);
247}
248
249/*
250 * Hash operator class jsonb hashing function
251 */
252Datum
254{
255 Jsonb *jb = PG_GETARG_JSONB_P(0);
256 JsonbIterator *it;
257 JsonbValue v;
259 uint32 hash = 0;
260
261 if (JB_ROOT_COUNT(jb) == 0)
263
264 it = JsonbIteratorInit(&jb->root);
265
266 while ((r = JsonbIteratorNext(&it, &v, false)) != WJB_DONE)
267 {
268 switch (r)
269 {
270 /* Rotation is left to JsonbHashScalarValue() */
271 case WJB_BEGIN_ARRAY:
272 hash ^= JB_FARRAY;
273 break;
274 case WJB_BEGIN_OBJECT:
275 hash ^= JB_FOBJECT;
276 break;
277 case WJB_KEY:
278 case WJB_VALUE:
279 case WJB_ELEM:
281 break;
282 case WJB_END_ARRAY:
283 case WJB_END_OBJECT:
284 break;
285 default:
286 elog(ERROR, "invalid JsonbIteratorNext rc: %d", (int) r);
287 }
288 }
289
290 PG_FREE_IF_COPY(jb, 0);
292}
293
294Datum
296{
297 Jsonb *jb = PG_GETARG_JSONB_P(0);
298 uint64 seed = PG_GETARG_INT64(1);
299 JsonbIterator *it;
300 JsonbValue v;
302 uint64 hash = 0;
303
304 if (JB_ROOT_COUNT(jb) == 0)
305 PG_RETURN_UINT64(seed);
306
307 it = JsonbIteratorInit(&jb->root);
308
309 while ((r = JsonbIteratorNext(&it, &v, false)) != WJB_DONE)
310 {
311 switch (r)
312 {
313 /* Rotation is left to JsonbHashScalarValueExtended() */
314 case WJB_BEGIN_ARRAY:
315 hash ^= ((uint64) JB_FARRAY) << 32 | JB_FARRAY;
316 break;
317 case WJB_BEGIN_OBJECT:
318 hash ^= ((uint64) JB_FOBJECT) << 32 | JB_FOBJECT;
319 break;
320 case WJB_KEY:
321 case WJB_VALUE:
322 case WJB_ELEM:
324 break;
325 case WJB_END_ARRAY:
326 case WJB_END_OBJECT:
327 break;
328 default:
329 elog(ERROR, "invalid JsonbIteratorNext rc: %d", (int) r);
330 }
331 }
332
333 PG_FREE_IF_COPY(jb, 0);
335}
#define PG_GETARG_ARRAYTYPE_P(n)
Definition: array.h:263
void deconstruct_array_builtin(ArrayType *array, Oid elmtype, Datum **elemsp, bool **nullsp, int *nelemsp)
Definition: arrayfuncs.c:3697
uint64_t uint64
Definition: c.h:489
uint32_t uint32
Definition: c.h:488
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:225
#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:689
int i
Definition: isn.c:72
@ jbvString
Definition: jsonb.h:229
#define JB_ROOT_IS_OBJECT(jbp_)
Definition: jsonb.h:221
#define PG_GETARG_JSONB_P(x)
Definition: jsonb.h:391
#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:194
Datum jsonb_exists_all(PG_FUNCTION_ARGS)
Definition: jsonb_op.c:79
Datum jsonb_gt(PG_FUNCTION_ARGS)
Definition: jsonb_op.c:180
Datum jsonb_hash_extended(PG_FUNCTION_ARGS)
Definition: jsonb_op.c:295
Datum jsonb_exists_any(PG_FUNCTION_ARGS)
Definition: jsonb_op.c:46
Datum jsonb_hash(PG_FUNCTION_ARGS)
Definition: jsonb_op.c:253
Datum jsonb_contains(PG_FUNCTION_ARGS)
Definition: jsonb_op.c:112
Datum jsonb_lt(PG_FUNCTION_ARGS)
Definition: jsonb_op.c:166
Datum jsonb_contained(PG_FUNCTION_ARGS)
Definition: jsonb_op.c:130
Datum jsonb_cmp(PG_FUNCTION_ARGS)
Definition: jsonb_op.c:236
Datum jsonb_ge(PG_FUNCTION_ARGS)
Definition: jsonb_op.c:208
Datum jsonb_ne(PG_FUNCTION_ARGS)
Definition: jsonb_op.c:149
Datum jsonb_eq(PG_FUNCTION_ARGS)
Definition: jsonb_op.c:222
Datum jsonb_exists(PG_FUNCTION_ARGS)
Definition: jsonb_op.c:21
int compareJsonbContainers(JsonbContainer *a, JsonbContainer *b)
Definition: jsonb_util.c:191
JsonbIterator * JsonbIteratorInit(JsonbContainer *container)
Definition: jsonb_util.c:824
void JsonbHashScalarValue(const JsonbValue *scalarVal, uint32 *hash)
Definition: jsonb_util.c:1323
JsonbValue * findJsonbValueFromContainer(JsonbContainer *container, uint32 flags, JsonbValue *key)
Definition: jsonb_util.c:351
JsonbIteratorToken JsonbIteratorNext(JsonbIterator **it, JsonbValue *val, bool skipNested)
Definition: jsonb_util.c:860
void JsonbHashScalarValueExtended(const JsonbValue *scalarVal, uint64 *hash, uint64 seed)
Definition: jsonb_util.c:1366
bool JsonbDeepContains(JsonbIterator **val, JsonbIterator **mContained)
Definition: jsonb_util.c:1069
uintptr_t Datum
Definition: postgres.h:69
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:644
#define strVal(v)
Definition: value.h:82
#define VARDATA_ANY(PTR)
Definition: varatt.h:324
#define VARSIZE_ANY_EXHDR(PTR)
Definition: varatt.h:317