Skip to content

Commit 3f322af

Browse files
author
Nikita Glukhov
committed
Add JBC_TOBJECT_COMPRESSED
1 parent e080b22 commit 3f322af

File tree

1 file changed

+88
-21
lines changed

1 file changed

+88
-21
lines changed

contrib/jsonb_toaster/jsonb_toaster.c

Lines changed: 88 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,13 @@ void _PG_init(void);
6060
#define JBE_ISCONTAINER_PTR(je_)(((je_) & JENTRY_TYPEMASK) == JENTRY_ISCONTAINER_PTR)
6161

6262
#define JBC_TOBJECT_TOASTED 0x10000000 /* object with toasted keys */
63+
#define JBC_TOBJECT_COMPRESSED 0x60000000 /* object with compressed keys */
6364

6465
#define JB_HEADER(jb) ((jb)->root.header)
6566
#define JX_HEADER_IS_OBJECT(hdr) (((hdr) & JBC_TMASK) == JBC_TOBJECT || \
6667
((hdr) & JBC_TMASK) == JBC_TOBJECT_SORTED || \
67-
((hdr) & JBC_TMASK) == JBC_TOBJECT_TOASTED)
68+
((hdr) & JBC_TMASK) == JBC_TOBJECT_TOASTED || \
69+
((hdr) & JBC_TMASK) == JBC_TOBJECT_COMPRESSED)
6870
#define JX_ROOT_IS_OBJECT(jbp_) JX_HEADER_IS_OBJECT(JB_HEADER(jbp_))
6971

7072
typedef struct varatt_external JsonbToastPointer;
@@ -195,10 +197,11 @@ static bool JsonContainerIsToasted(JsonContainer *jc,
195197
JsonbToastedContainerPointerData *jbcptr);
196198
static bool JsonContainerIsCompressed(JsonContainer *jc,
197199
JsonbCompressedContainerData *jbcptr);
198-
static bool JsonValueContainsToasted(const JsonValue *jv);
199-
static bool JsonValueIsToasted(JsonValue *jv, JsonbToastedContainerPointerData *jbcptr);
200-
static bool JsonValueIsCompressed(JsonValue *jv, JsonbCompressedContainerData *jbcptr);
200+
static bool JsonValueIsToasted(const JsonValue *jv, JsonbToastedContainerPointerData *jbcptr);
201+
static bool JsonValueIsCompressed(const JsonValue *jv, JsonbCompressedContainerData *jbcptr);
201202
static bool JsonContainerContainsToasted(JsonContainer *jc);
203+
static bool JsonContainerContainsToastedOrCompressed(JsonContainer *jc, bool *toasted, bool *compressed);
204+
static bool JsonValueContainsToastedOrCompressed(const JsonValue *jv, bool *toasted, bool *compressed);
202205

203206
static bool jsonb_toast_fields = true; /* GUC */
204207
static bool jsonb_toast_fields_recursively = true; /* GUC */
@@ -822,6 +825,7 @@ JsonxIteratorInit(JsonContainer *cont, const JsonbContainerHeader *container,
822825
case JBC_TOBJECT:
823826
case JBC_TOBJECT_SORTED:
824827
case JBC_TOBJECT_TOASTED:
828+
case JBC_TOBJECT_COMPRESSED:
825829
it->dataProper =
826830
(char *) it->children + it->nElems * sizeof(JEntry) * 2;
827831
it->dataProper = initKVMap(&it->kvmap, it->dataProper, it->nElems,
@@ -902,9 +906,14 @@ JsonxEncode(StringInfoData *buffer, const JsonbValue *val, void *cxt)
902906
static void *
903907
jsonxEncode(JsonValue *jv, JsonContainerOps *ops, Oid toasterid)
904908
{
905-
if (ops == &jsonbContainerOps &&
906-
JsonValueContainsToasted(jv))
907-
return JsonEncode(jv, JsonxEncode, (void *)(intptr_t) toasterid);
909+
if (ops == &jsonbContainerOps)
910+
{
911+
bool toasted;
912+
bool compressed;
913+
914+
if (JsonValueContainsToastedOrCompressed(jv, &toasted, &compressed))
915+
return JsonEncode(jv, JsonxEncode, (void *)(intptr_t) toasterid);
916+
}
908917

909918
return NULL;
910919
}
@@ -1204,24 +1213,83 @@ JsonContainerContainsToasted(JsonContainer *jc)
12041213
}
12051214

12061215
static bool
1207-
JsonValueIsToasted(JsonValue *jv, JsonbToastedContainerPointerData *jbcptr)
1216+
JsonContainerContainsToastedOrCompressed(JsonContainer *jc,
1217+
bool *toasted, bool *compressed)
1218+
{
1219+
if (jc->ops == &jsonxContainerOps)
1220+
{
1221+
JsonbContainerHeader *jbc = JsonContainerDataPtr(jc);
1222+
1223+
*toasted = (jbc->header & JBC_TMASK) == JBC_TOBJECT_TOASTED;
1224+
*compressed = (jbc->header & JBC_TMASK) == JBC_TOBJECT_COMPRESSED;
1225+
1226+
return *toasted || *compressed;
1227+
}
1228+
else if (jc->ops == &jsonxzContainerOps)
1229+
{
1230+
CompressedJsonx *cjb = jsonxzGetCompressedJsonx(jc);
1231+
1232+
*toasted = (cjb->header & JBC_TMASK) == JBC_TOBJECT_TOASTED;
1233+
*compressed = (cjb->header & JBC_TMASK) == JBC_TOBJECT_COMPRESSED;
1234+
1235+
return *toasted || *compressed;
1236+
}
1237+
#if 0 /* XXX jsonv */
1238+
else if (jc->ops == &jsonvContainerOps)
1239+
return JsonValueContainsToastedOrCompressed(JsonContainerDataPtr(jc), toasted, compressed);
1240+
#endif
1241+
else
1242+
{
1243+
*toasted = *compressed = false;
1244+
return false; /* XXX other container types */
1245+
}
1246+
}
1247+
1248+
static bool
1249+
JsonValueIsToasted(const JsonValue *jv, JsonbToastedContainerPointerData *jbcptr)
12081250
{
12091251
return jv->type == jbvBinary &&
12101252
JsonContainerIsToasted(jv->val.binary.data, jbcptr);
12111253
}
12121254

12131255
static bool
1214-
JsonValueIsCompressed(JsonValue *jv, JsonbCompressedContainerData *jbcptr)
1256+
JsonValueIsCompressed(const JsonValue *jv, JsonbCompressedContainerData *jbcptr)
12151257
{
12161258
return jv->type == jbvBinary &&
12171259
JsonContainerIsCompressed(jv->val.binary.data, jbcptr);
12181260
}
12191261

1262+
static inline bool
1263+
JsonValueContainsToastedOrCompressedAccum(const JsonValue *val,
1264+
bool *toasted, bool *compressed)
1265+
{
1266+
bool has_toasted;
1267+
bool has_compressed;
1268+
1269+
*toasted |= JsonValueIsToasted(val, NULL);
1270+
*compressed |= JsonValueIsCompressed(val, NULL);
1271+
1272+
if (*toasted && *compressed)
1273+
return true;
1274+
1275+
if (JsonValueContainsToastedOrCompressed(val, &has_toasted, &has_compressed))
1276+
{
1277+
*toasted |= has_toasted;
1278+
*compressed |= has_compressed;
1279+
}
1280+
1281+
return *toasted && *compressed;
1282+
}
1283+
12201284
static bool
1221-
JsonValueContainsToasted(const JsonValue *jv)
1285+
JsonValueContainsToastedOrCompressed(const JsonValue *jv,
1286+
bool *toasted, bool *compressed)
12221287
{
12231288
if (jv->type == jbvBinary)
1224-
return JsonContainerContainsToasted(jv->val.binary.data);
1289+
return JsonContainerContainsToastedOrCompressed(jv->val.binary.data,
1290+
toasted, compressed);
1291+
1292+
*toasted = *compressed = false;
12251293

12261294
if (jv->type == jbvObject)
12271295
{
@@ -1231,8 +1299,7 @@ JsonValueContainsToasted(const JsonValue *jv)
12311299
{
12321300
JsonValue *val = &jv->val.object.pairs[i].value;
12331301

1234-
if (JsonValueIsToasted(val, NULL) ||
1235-
JsonValueContainsToasted(val))
1302+
if (JsonValueContainsToastedOrCompressedAccum(val, toasted, compressed))
12361303
return true;
12371304
}
12381305
}
@@ -1244,15 +1311,15 @@ JsonValueContainsToasted(const JsonValue *jv)
12441311
{
12451312
JsonValue *val = &jv->val.array.elems[i];
12461313

1247-
if (JsonValueIsToasted(val, NULL) ||
1248-
JsonValueContainsToasted(val))
1314+
if (JsonValueContainsToastedOrCompressedAccum(val, toasted, compressed))
12491315
return true;
12501316
}
12511317
}
12521318

1253-
return false;
1319+
return *toasted || *compressed;
12541320
}
12551321

1322+
12561323
static void
12571324
convertJsonbObject(StringInfo buffer, JEntry *pheader, const JsonbValue *val, int level)
12581325
{
@@ -1266,6 +1333,7 @@ convertJsonbObject(StringInfo buffer, JEntry *pheader, const JsonbValue *val, in
12661333
int kvmap_entry_size;
12671334
bool sorted_values = jsonb_sort_field_values && nPairs > 1;
12681335
bool have_toasted_values = false;
1336+
bool have_compressed_values = false;
12691337
struct
12701338
{
12711339
int size;
@@ -1274,11 +1342,8 @@ convertJsonbObject(StringInfo buffer, JEntry *pheader, const JsonbValue *val, in
12741342

12751343
Assert(nPairs >= 0);
12761344

1277-
if (JsonValueContainsToasted(val))
1278-
{
1279-
have_toasted_values = true;
1345+
if (JsonValueContainsToastedOrCompressed(val, &have_toasted_values, &have_compressed_values))
12801346
sorted_values = false; /* FIXME */
1281-
}
12821347

12831348
values = sorted_values ? palloc(sizeof(*values) * nPairs) : NULL;
12841349

@@ -1318,7 +1383,8 @@ convertJsonbObject(StringInfo buffer, JEntry *pheader, const JsonbValue *val, in
13181383
*/
13191384
header = nPairs |
13201385
(sorted_values ? JBC_TOBJECT_SORTED :
1321-
have_toasted_values ? JBC_TOBJECT_TOASTED : JBC_TOBJECT);
1386+
have_toasted_values ? JBC_TOBJECT_TOASTED :
1387+
have_compressed_values ? JBC_TOBJECT_COMPRESSED : JBC_TOBJECT);
13221388
appendToBuffer(buffer, (char *) &header, sizeof(uint32));
13231389

13241390
/* Reserve space for the JEntries of the keys and values. */
@@ -1617,6 +1683,7 @@ jsonxInitContainerFromHeader(JsonContainerData *jc, JsonbContainerHdr header)
16171683
case JBC_TOBJECT:
16181684
case JBC_TOBJECT_SORTED:
16191685
case JBC_TOBJECT_TOASTED:
1686+
case JBC_TOBJECT_COMPRESSED:
16201687
jc->type = jbvObject;
16211688
break;
16221689
case JBC_TARRAY:

0 commit comments

Comments
 (0)