Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 7d45e77

Browse files
author
Nikita Glukhov
committed
Add uniquification for binary jsons in JsonbGetDatum()
1 parent 031b22c commit 7d45e77

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
@@ -68,6 +68,7 @@
6868
#define jsonb_set_element json_set_element
6969

7070
#define JsonxContainerOps (&jsontContainerOps)
71+
#define JsonxGetUniquified(json) (json)
7172
#define JsonxPGetDatum(json) JsontPGetDatum(json)
7273

7374
#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
@@ -2196,6 +2196,9 @@ JsonValueUniquify(JsonValue *res, const JsonValue *val)
21962196
{
21972197
check_stack_depth();
21982198

2199+
if (!res)
2200+
res = (JsonValue *) palloc(sizeof(JsonValue));
2201+
21992202
if (val->type == jbvObject &&
22002203
(!val->val.object.valuesUniquified || !val->val.object.uniquified))
22012204
{
@@ -2249,6 +2252,31 @@ JsonValueUniquify(JsonValue *res, const JsonValue *val)
22492252
return res;
22502253
}
22512254

2255+
Json *
2256+
JsonUniquify(Json *json)
2257+
{
2258+
if (JsonRoot(json)->ops == &jsontContainerOps)
2259+
{
2260+
JsonValue val;
2261+
Json *res = JsonValueToJson(JsonValueUnpackBinary(JsonToJsonValue(json, &val)));
2262+
res->is_json = json->is_json;
2263+
return res;
2264+
}
2265+
else if (JsonRoot(json)->ops == &jsonvContainerOps)
2266+
{
2267+
const JsonValue *val = (const JsonValue *) JsonRoot(json)->data;
2268+
2269+
if (!JsonValueIsUniquified(val))
2270+
{
2271+
Json *res = JsonValueToJson(JsonValueUniquify(NULL, val));
2272+
res->is_json = json->is_json;
2273+
return res;
2274+
}
2275+
}
2276+
2277+
return json;
2278+
}
2279+
22522280
static void
22532281
jsonbInitContainer(JsonContainerData *jc, JsonbContainer *jbc, int len)
22542282
{

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)