Skip to content

Commit 5950bca

Browse files
author
Nikita Glukhov
committed
Add built-in jsonb compression method
1 parent bd489c6 commit 5950bca

File tree

16 files changed

+685
-16
lines changed

16 files changed

+685
-16
lines changed

src/backend/utils/adt/json.c

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@
6868
#ifdef JSON_FLATTEN_INTO_TARGET
6969
# define JsonxGetDatum(json) \
7070
PointerGetDatum(cstring_to_text(JsonToCString(JsonRoot(json))))
71-
#else
71+
#elif defined(JSON_FLATTEN_EOH_INTO_TARGET)
7272
# define JsonxGetDatum(json) JsontGetDatum(json)
7373
#endif
7474

@@ -95,7 +95,7 @@
9595
#include "utils/typcache.h"
9696
#include "utils/syscache.h"
9797

98-
#ifndef JSON_FLATTEN_INTO_TARGET
98+
#ifdef JSON_FLATTEN_EOH_INTO_TARGET
9999
static inline Datum
100100
JsontGetDatum(Json *json)
101101
{
@@ -3032,3 +3032,28 @@ jsontContainerOps =
30323032
jsontToString,
30333033
JsonCopyFlat,
30343034
};
3035+
3036+
static Datum
3037+
jsontCompress(Datum value, CompressionOptions options)
3038+
{
3039+
Json *json = DatumGetJsont(value);
3040+
char *str = JsonToCString(JsonRoot(json));
3041+
text *text = cstring_to_text(str);
3042+
pfree(str);
3043+
return PointerGetDatum(text);
3044+
}
3045+
3046+
Datum
3047+
json_null_cm_handler(PG_FUNCTION_ARGS)
3048+
{
3049+
CompressionMethodRoutine *cmr = makeNode(CompressionMethodRoutine);
3050+
3051+
cmr->flags = CM_EXTENDED_REPRESENTATION;
3052+
cmr->options = NULL;
3053+
cmr->addAttr = NULL;
3054+
cmr->dropAttr = NULL;
3055+
cmr->compress = jsontCompress;
3056+
cmr->decompress = NULL;
3057+
3058+
PG_RETURN_POINTER(cmr);
3059+
}

src/backend/utils/adt/json_generic.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -721,12 +721,11 @@ JsonToJsonValue(Json *json, JsonValue *jv)
721721
return JsonValueInitBinary(jv, &json->root);
722722
}
723723

724-
#define JSON_FLATTEN_INTO_TARGET
725-
/*
724+
/* #define JSON_FLATTEN_INTO_TARGET */
725+
726726
#define JSON_FLATTEN_INTO_JSONEXT
727727
#define JSON_FLATTEN_INTO_JSONB
728728
#define flatContainerOps &jsonbContainerOps
729-
*/
730729

731730
#ifdef JSON_FLATTEN_INTO_JSONEXT
732731
typedef struct varatt_extended_json

src/backend/utils/adt/json_gin.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,13 @@
2323
#ifdef JSON_FLATTEN_INTO_TARGET
2424
# define JsonxGetDatum(json) \
2525
PointerGetDatum(cstring_to_text(JsonToCString(JsonRoot(json))))
26-
#else
27-
# define JsonxGetDatum(json) JsontGetDatum(json)
26+
#elif defined(JSON_FLATTEN_EOH_INTO_TARGET)
27+
# define JsonxGetDatum(json) JsontGetDatum(json)
2828
#endif
2929

3030
#include "utils/json_generic.h"
3131

32-
#ifndef JSON_FLATTEN_INTO_TARGET
32+
#ifdef JSON_FLATTEN_EOH_INTO_TARGET
3333
static inline Datum
3434
JsontGetDatum(Json *json)
3535
{

src/backend/utils/adt/json_op.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,13 @@
2727
#ifdef JSON_FLATTEN_INTO_TARGET
2828
# define JsonxGetDatum(json) \
2929
PointerGetDatum(cstring_to_text(JsonToCString(JsonRoot(json))))
30-
#else
30+
#elif defined(JSON_FLATTEN_EOH_INTO_TARGET)
3131
# define JsonxGetDatum(json) JsontGetDatum(json)
3232
#endif
3333

3434
#include "utils/json_generic.h"
3535

36-
#ifndef JSON_FLATTEN_INTO_TARGET
36+
#ifdef JSON_FLATTEN_EOH_INTO_TARGET
3737
static inline Datum
3838
JsontGetDatum(Json *json)
3939
{

src/backend/utils/adt/jsonb_util.c

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,14 @@
1515
#include "miscadmin.h"
1616
#include "access/compression.h"
1717
#include "access/hash.h"
18+
#include "catalog/pg_type.h"
1819
#include "catalog/pg_collation.h"
1920
#include "miscadmin.h"
2021
#include "utils/builtins.h"
2122
#define JSONB_UTIL_C
2223
#include "utils/jsonb.h"
2324
#include "utils/json_generic.h"
25+
#include "utils/lsyscache.h"
2426
#include "utils/memutils.h"
2527
#include "utils/varlena.h"
2628

@@ -2155,3 +2157,96 @@ jsonbContainerOps =
21552157
JsonbToCStringRaw,
21562158
JsonCopyFlat,
21572159
};
2160+
2161+
static void
2162+
jsonbAddAttr(Form_pg_attribute attr, List *options)
2163+
{
2164+
if (getBaseType(attr->atttypid) != JSONOID)
2165+
elog(ERROR, "jsonb compression method is only applicable to json type");
2166+
2167+
if (options != NIL)
2168+
elog(ERROR, "jsonb compression method has no options");
2169+
}
2170+
2171+
static Datum
2172+
jsonbCompressJsont(Datum value, CompressionOptions options)
2173+
{
2174+
#ifdef JSON_FULL_DECOMPRESSION
2175+
text *js = DatumGetTextP(value);
2176+
JsonValue *jv = JsonValueFromCString(VARDATA(js), VARSIZE(js) - VARHDRSZ);
2177+
Jsonb *jb = JsonbValueToJsonb(jv);
2178+
pfree(jv);
2179+
#else
2180+
Json *json = DatumGetJsont(value);
2181+
JsonValue jv;
2182+
Jsonb *jb = JsonValueToJsonb(JsonToJsonValue(json, &jv));
2183+
JsonFreeIfCopy(json, value);
2184+
#endif
2185+
return PointerGetDatum(jb);
2186+
}
2187+
2188+
static Datum
2189+
jsonbCompressJsonb(Datum value, CompressionOptions options)
2190+
{
2191+
#ifdef JSON_FULL_DECOMPRESSION
2192+
Jsonb *jb = DatumGetJsonb(value);
2193+
#else
2194+
Json *json = DatumGetJsonb(value);
2195+
JsonValue jv;
2196+
Jsonb *jb = JsonValueToJsonb(JsonToJsonValue(json, &jv));
2197+
JsonFreeIfCopy(json, value);
2198+
#endif
2199+
return PointerGetDatum(jb);
2200+
}
2201+
2202+
static Datum
2203+
jsonbDecompress(Datum value, CompressionOptions options)
2204+
{
2205+
#ifdef JSON_FULL_DECOMPRESSION
2206+
JsonContainerData jsc;
2207+
char *json;
2208+
Datum text;
2209+
2210+
jsonbInit(&jsc, value);
2211+
2212+
json = JsonToCString(&jsc);
2213+
text = PointerGetDatum(cstring_to_text(json));
2214+
2215+
pfree(json);
2216+
2217+
return text;
2218+
#else
2219+
Json *json = DatumGetJsonb(value);
2220+
return JsonGetDatum(json);
2221+
#endif
2222+
}
2223+
2224+
Datum
2225+
jsonb_null_cm_handler(PG_FUNCTION_ARGS)
2226+
{
2227+
CompressionMethodRoutine *cmr = makeNode(CompressionMethodRoutine);
2228+
2229+
cmr->flags = CM_EXTENDED_REPRESENTATION;
2230+
cmr->options = NULL;
2231+
cmr->addAttr = NULL;
2232+
cmr->dropAttr = NULL;
2233+
cmr->compress = jsonbCompressJsonb;
2234+
cmr->decompress = NULL;
2235+
2236+
PG_RETURN_POINTER(cmr);
2237+
}
2238+
2239+
Datum
2240+
jsonb_handler(PG_FUNCTION_ARGS)
2241+
{
2242+
CompressionMethodRoutine *cmr = makeNode(CompressionMethodRoutine);
2243+
2244+
cmr->flags = CM_EXTENDED_REPRESENTATION;
2245+
cmr->options = NULL;
2246+
cmr->addAttr = jsonbAddAttr;
2247+
cmr->dropAttr = NULL;
2248+
cmr->compress = jsonbCompressJsont;
2249+
cmr->decompress = jsonbDecompress;
2250+
2251+
PG_RETURN_POINTER(cmr);
2252+
}

src/include/catalog/pg_compression.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,4 +59,14 @@ typedef FormData_pg_compression *Form_pg_compression;
5959
* ----------------
6060
*/
6161

62+
DATA(insert OID = 3451 ( json_null json_null_cm_handler 0 ));
63+
DESCR("json null compression method");
64+
#define JSON_NULL_CM_OID 3451
65+
DATA(insert OID = 3452 ( jsonb_null jsonb_null_cm_handler 0 ));
66+
DESCR("jsonb null compression method");
67+
#define JSONB_NULL_CM_OID 3452
68+
DATA(insert OID = 3403 ( jsonb jsonb_handler 0 ));
69+
DESCR("jsonb compression method");
70+
#define JSONB_CM_OID 3403
71+
6272
#endif /* PG_COMPRESSION_H */

src/include/catalog/pg_proc.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4567,6 +4567,15 @@ DESCR("less-equal-greater");
45674567
DATA(insert OID = 3252 ( pg_lsn_hash PGNSP PGUID 12 1 0 0 0 f f f f t f i s 1 0 23 "3220" _null_ _null_ _null_ _null_ _null_ pg_lsn_hash _null_ _null_ _null_ ));
45684568
DESCR("hash");
45694569

4570+
/* Compression method handlers */
4571+
DATA(insert OID = 3449 ( json_null_cm_handler PGNSP PGUID 12 1 0 0 0 f f f f t f v s 1 0 3411 "2281" _null_ _null_ _null_ _null_ _null_ json_null_cm_handler _null_ _null_ _null_ ));
4572+
DESCR("json compression method handler");
4573+
DATA(insert OID = 3450 ( jsonb_null_cm_handler PGNSP PGUID 12 1 0 0 0 f f f f t f v s 1 0 3411 "2281" _null_ _null_ _null_ _null_ _null_ jsonb_null_cm_handler _null_ _null_ _null_ ));
4574+
DESCR("jsonb compression method handler");
4575+
DATA(insert OID = 3414 ( jsonb_handler PGNSP PGUID 12 1 0 0 0 f f f f t f v s 1 0 3411 "2281" _null_ _null_ _null_ _null_ _null_ jsonb_handler _null_ _null_ _null_ ));
4576+
DESCR("jsonb compression method handler");
4577+
4578+
45704579
/* enum related procs */
45714580
DATA(insert OID = 3504 ( anyenum_in PGNSP PGUID 12 1 0 0 0 f f f f t f i s 1 0 3500 "2275" _null_ _null_ _null_ _null_ _null_ anyenum_in _null_ _null_ _null_ ));
45724581
DESCR("I/O");

src/include/catalog/pg_type.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,7 @@ DATA(insert OID = 81 ( pg_proc PGNSP PGUID -1 f c C f t \054 1255 0 0 record_i
360360
DATA(insert OID = 83 ( pg_class PGNSP PGUID -1 f c C f t \054 1259 0 0 record_in record_out record_recv record_send - - - d x f 0 -1 0 0 0 0 _null_ _null_ _null_ ));
361361

362362
/* OIDS 100 - 199 */
363-
DATA(insert OID = 114 ( json PGNSP PGUID -1 f b U f t \054 0 0 199 json_in json_out json_recv json_send - - - i x f 0 -1 0 0 0 0 _null_ _null_ _null_ ));
363+
DATA(insert OID = 114 ( json PGNSP PGUID -1 f b U f t \054 0 0 199 json_in json_out json_recv json_send - - - i x f 0 -1 0 0 0 3451 _null_ _null_ _null_ ));
364364
#define JSONOID 114
365365
DATA(insert OID = 142 ( xml PGNSP PGUID -1 f b U f t \054 0 0 143 xml_in xml_out xml_recv xml_send - - - i x f 0 -1 0 0 0 0 _null_ _null_ _null_ ));
366366
DESCR("XML content");
@@ -641,7 +641,7 @@ DATA(insert OID = 3735 ( _regconfig PGNSP PGUID -1 f b A f t \054 0 3734 0 arra
641641
DATA(insert OID = 3770 ( _regdictionary PGNSP PGUID -1 f b A f t \054 0 3769 0 array_in array_out array_recv array_send - - array_typanalyze i x f 0 -1 0 0 0 0 _null_ _null_ _null_ ));
642642

643643
/* jsonb */
644-
DATA(insert OID = 3802 ( jsonb PGNSP PGUID -1 f b U f t \054 0 0 3807 jsonb_in jsonb_out jsonb_recv jsonb_send - - - i x f 0 -1 0 0 0 0 _null_ _null_ _null_ ));
644+
DATA(insert OID = 3802 ( jsonb PGNSP PGUID -1 f b U f t \054 0 0 3807 jsonb_in jsonb_out jsonb_recv jsonb_send - - - i x f 0 -1 0 0 0 3452 _null_ _null_ _null_ ));
645645
DESCR("Binary JSON");
646646
#define JSONBOID 3802
647647
DATA(insert OID = 3807 ( _jsonb PGNSP PGUID -1 f b A f t \054 0 3802 0 array_in array_out array_recv array_send - - array_typanalyze i x f 0 -1 0 0 0 0 _null_ _null_ _null_ ));

0 commit comments

Comments
 (0)