Skip to content

Commit c2cd19a

Browse files
author
Nikita Glukhov
committed
Add uniquification for binary jsons in JsonbGetDatum()
1 parent d1ddafc commit c2cd19a

File tree

5 files changed

+57
-16
lines changed

5 files changed

+57
-16
lines changed

src/backend/utils/adt/json.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
#define jsonb_to_recordset json_to_recordset
6767

6868
#define JsonxContainerOps (&jsontContainerOps)
69+
#define JsonxGetUniquified(json) (json)
6970
#define JsonxPGetDatum(json) JsontPGetDatum(json)
7071

7172
#include "postgres.h"

src/backend/utils/adt/json_gin.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@
1919
#define gin_triconsistent_jsonb_path gin_triconsistent_json_path
2020

2121
#define JsonxContainerOps (&jsontContainerOps)
22-
#define JsonxGetDatum(json) JsontGetDatum(json)
22+
#define JsonxGetUniquified(json) (json)
23+
#define JsonxPGetDatum(json) JsontGetDatum(json)
2324

2425
#include "utils/json_generic.h"
2526

src/backend/utils/adt/json_op.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@
2424
#define jsonb_hash_extended json_hash_extended
2525

2626
#define JsonxContainerOps (&jsontContainerOps)
27-
#define JsonxGetDatum(json) JsontGetDatum(json)
27+
#define JsonxGetUniquified(json) (json)
28+
#define JsonxPGetDatum(json) JsontGetDatum(json)
2829

2930
#include "utils/json_generic.h"
3031

src/backend/utils/adt/jsonb_util.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2133,6 +2133,9 @@ JsonValueUniquify(JsonValue *res, const JsonValue *val)
21332133
{
21342134
check_stack_depth();
21352135

2136+
if (!res)
2137+
res = (JsonValue *) palloc(sizeof(JsonValue));
2138+
21362139
if (val->type == jbvObject &&
21372140
(!val->val.object.valuesUniquified || !val->val.object.uniquified))
21382141
{
@@ -2186,6 +2189,31 @@ JsonValueUniquify(JsonValue *res, const JsonValue *val)
21862189
return res;
21872190
}
21882191

2192+
Json *
2193+
JsonUniquify(Json *json)
2194+
{
2195+
if (JsonRoot(json)->ops == &jsontContainerOps)
2196+
{
2197+
JsonValue val;
2198+
Json *res = JsonValueToJson(JsonValueUnpackBinary(JsonToJsonValue(json, &val)));
2199+
res->is_json = json->is_json;
2200+
return res;
2201+
}
2202+
else if (JsonRoot(json)->ops == &jsonvContainerOps)
2203+
{
2204+
const JsonValue *val = (const JsonValue *) JsonRoot(json)->data;
2205+
2206+
if (!JsonValueIsUniquified(val))
2207+
{
2208+
Json *res = JsonValueToJson(JsonValueUniquify(NULL, val));
2209+
res->is_json = json->is_json;
2210+
return res;
2211+
}
2212+
}
2213+
2214+
return json;
2215+
}
2216+
21892217
static void
21902218
jsonbInitContainer(JsonContainerData *jc, JsonbContainer *jbc, int len)
21912219
{

src/include/utils/json_generic.h

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -115,14 +115,10 @@ typedef struct Json
115115
*/
116116

117117
#undef JsonbPGetDatum
118-
#define JsonbPGetDatum(json) JsonFlattenToJsonbDatum(json)
119-
120-
#ifndef JsonxPGetDatum
121-
# ifdef JSON_FLATTEN_INTO_TARGET
122-
# define JsonxPGetDatum(json) JsonbPGetDatum(json)
123-
# else
124-
# define JsonxPGetDatum(json) JsonGetEOHDatum(json)
125-
# endif
118+
#ifdef JSON_FLATTEN_INTO_TARGET
119+
# define JsonbPGetDatum(json) JsonFlattenToJsonbDatum(JsonGetUniquified(json))
120+
#else
121+
# define JsonbPGetDatum(json) JsonGetEOHDatum(JsonGetUniquified(json))
126122
#endif
127123

128124
#ifdef JSON_FLATTEN_INTO_TARGET
@@ -137,7 +133,13 @@ JsontPGetDatum(Json *json)
137133
}
138134
#endif
139135

140-
#define JsonGetDatum(json) JsonxPGetDatum(json)
136+
#ifdef JsonxPGetDatum
137+
# define JsonGetDatum(json) JsonxPGetDatum(json)
138+
#elif defined(JsonxGetUniquified)
139+
# define JsonGetDatum(json) JsonGetEOHDatum(JsonxGetUniquified(json))
140+
#else
141+
# define JsonGetDatum(json) JsonbPGetDatum(json)
142+
#endif
141143

142144
#undef DatumGetJsonbP
143145
#define DatumGetJsonbP(datum) DatumGetJson(datum, &jsonbContainerOps, NULL)
@@ -191,14 +193,15 @@ JsontPGetDatum(Json *json)
191193
((jc)->ops != &jsonvContainerOps || \
192194
JsonValueIsUniquified((JsonValue *) jc->data)))
193195

196+
#define JsonIsUniquified(json) JsonContainerIsUniquified(JsonRoot(json))
197+
194198
#define JsonValueIsScalar(jsval) IsAJsonbScalar(jsval)
195199

196200
#define JsonContainerGetType(jc) ((jc)->ops->type)
197201
#define JsonContainerGetOpsByType(type) \
198202
((type) == JsonContainerJsont ? &jsontContainerOps : \
199203
(type) == JsonContainerJsonb ? &jsonbContainerOps : NULL)
200204

201-
202205
#ifdef JSONB_UTIL_C
203206
#define JsonbValueToJsonb JsonValueToJsonb
204207
#else
@@ -270,10 +273,15 @@ JsonIteratorNext(JsonIterator **it, JsonValue *val, bool skipNested)
270273
#define compareJsonbContainers JsonCompareContainers
271274
#define equalsJsonbScalarValue JsonValueScalarEquals
272275

276+
extern JsonContainerOps jsonbContainerOps;
277+
extern JsonContainerOps jsontContainerOps;
278+
extern JsonContainerOps jsonvContainerOps;
279+
273280
extern Json *DatumGetJson(Datum val, JsonContainerOps *ops, Json *tmp);
274281

275282
extern void JsonFree(Json *json);
276283
extern Json *JsonCopyTemporary(Json *tmp);
284+
extern Json *JsonUniquify(Json *json);
277285

278286
#define JsonContainerAlloc() \
279287
((JsonContainerData *) palloc(sizeof(JsonContainerData)))
@@ -315,6 +323,12 @@ JsonGetNonTemporary(Json *json)
315323
return JsonIsTemporary(json) ? JsonCopyTemporary(json) : json;
316324
}
317325

326+
static inline Json *
327+
JsonGetUniquified(Json *json)
328+
{
329+
return JsonIsUniquified(json) ? json : JsonUniquify(json);
330+
}
331+
318332
static inline JsonValue *
319333
JsonValueInitObject(JsonValue *val, int nPairs, int nPairsAllocated,
320334
bool uniquified)
@@ -425,8 +439,4 @@ extern int lengthCompareJsonbStringValue(const void *a, const void *b);
425439
extern int lengthCompareJsonbString(const char *val1, int len1,
426440
const char *val2, int len2);
427441

428-
extern JsonContainerOps jsonbContainerOps;
429-
extern JsonContainerOps jsontContainerOps;
430-
extern JsonContainerOps jsonvContainerOps;
431-
432442
#endif /* UTILS_JSON_GENERIC_H */

0 commit comments

Comments
 (0)