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)
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