Skip to content

Commit c4bd4d8

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

File tree

5 files changed

+52
-11
lines changed

5 files changed

+52
-11
lines changed

src/backend/utils/adt/json.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
#define jsonb_to_recordset json_to_recordset
6464

6565
#define JsonxContainerOps (&jsontContainerOps)
66+
#define JsonxGetUniquified(json) (json)
6667
#ifdef JSON_FLATTEN_INTO_TARGET
6768
# define JsonxGetDatum(json) \
6869
PointerGetDatum(cstring_to_text(JsonToCString(JsonRoot(json))))

src/backend/utils/adt/json_gin.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#define gin_triconsistent_jsonb_path gin_triconsistent_json_path
2020

2121
#define JsonxContainerOps (&jsontContainerOps)
22+
#define JsonxGetUniquified(json) (json)
2223
#ifdef JSON_FLATTEN_INTO_TARGET
2324
# define JsonxGetDatum(json) \
2425
PointerGetDatum(cstring_to_text(JsonToCString(JsonRoot(json))))

src/backend/utils/adt/json_op.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#define jsonb_hash json_hash
2424

2525
#define JsonxContainerOps (&jsontContainerOps)
26+
#define JsonxGetUniquified(json) (json)
2627
#ifdef JSON_FLATTEN_INTO_TARGET
2728
# define JsonxGetDatum(json) \
2829
PointerGetDatum(cstring_to_text(JsonToCString(JsonRoot(json))))

src/backend/utils/adt/jsonb_util.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2038,6 +2038,9 @@ JsonValueUniquify(JsonValue *res, const JsonValue *val)
20382038
{
20392039
check_stack_depth();
20402040

2041+
if (!res)
2042+
res = (JsonValue *) palloc(sizeof(JsonValue));
2043+
20412044
if (val->type == jbvObject &&
20422045
(!val->val.object.valuesUniquified || !val->val.object.uniquified))
20432046
{
@@ -2091,6 +2094,31 @@ JsonValueUniquify(JsonValue *res, const JsonValue *val)
20912094
return res;
20922095
}
20932096

2097+
Json *
2098+
JsonUniquify(Json *json)
2099+
{
2100+
if (JsonRoot(json)->ops == &jsontContainerOps)
2101+
{
2102+
JsonValue val;
2103+
Json *res = JsonValueToJson(JsonValueUnpackBinary(JsonToJsonValue(json, &val)));
2104+
res->is_json = json->is_json;
2105+
return res;
2106+
}
2107+
else if (JsonRoot(json)->ops == &jsonvContainerOps)
2108+
{
2109+
const JsonValue *val = (const JsonValue *) JsonRoot(json)->data;
2110+
2111+
if (!JsonValueIsUniquified(val))
2112+
{
2113+
Json *res = JsonValueToJson(JsonValueUniquify(NULL, val));
2114+
res->is_json = json->is_json;
2115+
return res;
2116+
}
2117+
}
2118+
2119+
return json;
2120+
}
2121+
20942122
static void
20952123
jsonbInitContainer(JsonContainerData *jc, JsonbContainer *jbc, int len)
20962124
{

src/include/utils/json_generic.h

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -121,17 +121,19 @@ typedef struct Json
121121

122122
#undef JsonbGetDatum
123123
#ifdef JSON_FLATTEN_INTO_TARGET
124-
# define JsonbGetDatum(json) JsonFlattenToJsonbDatum(json)
124+
# define JsonbGetDatum(json) JsonFlattenToJsonbDatum(JsonGetUniquified(json))
125125
#else
126-
# define JsonbGetDatum(json) JsonGetEOHDatum(json)
126+
# define JsonbGetDatum(json) JsonGetEOHDatum(JsonGetUniquified(json))
127127
#endif
128128

129-
#ifndef JsonxGetDatum
130-
# define JsonxGetDatum(json) JsonbGetDatum(json)
129+
#ifdef JsonxGetDatum
130+
# define JsonGetDatum(json) JsonxGetDatum(json)
131+
#elif defined(JsonxGetUniquified)
132+
# define JsonGetDatum(json) JsonGetEOHDatum(JsonxGetUniquified(json))
133+
#else
134+
# define JsonGetDatum(json) JsonbGetDatum(json)
131135
#endif
132136

133-
#define JsonGetDatum(json) JsonxGetDatum(json)
134-
135137
#undef DatumGetJsonb
136138
#define DatumGetJsonb(datum) \
137139
DatumGetJson(datum, &jsonbContainerOps, NULL, NULL)
@@ -180,14 +182,15 @@ typedef struct Json
180182
((jc)->ops != &jsonvContainerOps || \
181183
JsonValueIsUniquified((JsonValue *) jc->data)))
182184

185+
#define JsonIsUniquified(json) JsonContainerIsUniquified(JsonRoot(json))
186+
183187
#define JsonValueIsScalar(jsval) IsAJsonbScalar(jsval)
184188

185189
#define JsonContainerGetType(jc) ((jc)->ops->type)
186190
#define JsonContainerGetOpsByType(type) \
187191
((type) == JsonContainerJsont ? &jsontContainerOps : \
188192
(type) == JsonContainerJsonb ? &jsonbContainerOps : NULL)
189193

190-
191194
#ifdef JSONB_UTIL_C
192195
#define JsonbValueToJsonb JsonValueToJsonb
193196
#else
@@ -256,11 +259,16 @@ JsonIteratorNext(JsonIterator **it, JsonValue *val, bool skipNested)
256259
#define compareJsonbContainers JsonCompareContainers
257260
#define equalsJsonbScalarValue JsonValueScalarEquals
258261

262+
extern JsonContainerOps jsonbContainerOps;
263+
extern JsonContainerOps jsontContainerOps;
264+
extern JsonContainerOps jsonvContainerOps;
265+
259266
extern Json *DatumGetJson(Datum val, JsonContainerOps *ops,
260267
CompressionOptions options, Json *tmp);
261268

262269
extern void JsonFree(Json *json);
263270
extern Json *JsonCopyTemporary(Json *tmp);
271+
extern Json *JsonUniquify(Json *json);
264272

265273
#define JsonContainerAlloc() \
266274
((JsonContainerData *) palloc(sizeof(JsonContainerData)))
@@ -302,6 +310,12 @@ JsonGetNonTemporary(Json *json)
302310
return JsonIsTemporary(json) ? JsonCopyTemporary(json) : json;
303311
}
304312

313+
static inline Json *
314+
JsonGetUniquified(Json *json)
315+
{
316+
return JsonIsUniquified(json) ? json : JsonUniquify(json);
317+
}
318+
305319
static inline JsonValue *
306320
JsonValueInitObject(JsonValue *val, int nPairs, int nPairsAllocated,
307321
bool uniquified)
@@ -410,8 +424,4 @@ extern void JsonbEncode(StringInfo, const JsonValue *, CompressionOptions);
410424

411425
extern int lengthCompareJsonbStringValue(const void *a, const void *b);
412426

413-
extern JsonContainerOps jsonbContainerOps;
414-
extern JsonContainerOps jsontContainerOps;
415-
extern JsonContainerOps jsonvContainerOps;
416-
417427
#endif /* UTILS_JSON_GENERIC_H */

0 commit comments

Comments
 (0)