Skip to content

Commit a749f88

Browse files
author
Nikita Glukhov
committed
Add uniquification for binary jsons in JsonbGetDatum()
1 parent 65ff5d6 commit a749f88

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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy