@@ -60,11 +60,13 @@ void _PG_init(void);
60
60
#define JBE_ISCONTAINER_PTR (je_ )(((je_) & JENTRY_TYPEMASK) == JENTRY_ISCONTAINER_PTR)
61
61
62
62
#define JBC_TOBJECT_TOASTED 0x10000000 /* object with toasted keys */
63
+ #define JBC_TOBJECT_COMPRESSED 0x60000000 /* object with compressed keys */
63
64
64
65
#define JB_HEADER (jb ) ((jb)->root.header)
65
66
#define JX_HEADER_IS_OBJECT (hdr ) (((hdr) & JBC_TMASK) == JBC_TOBJECT || \
66
67
((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)
68
70
#define JX_ROOT_IS_OBJECT (jbp_ ) JX_HEADER_IS_OBJECT(JB_HEADER(jbp_))
69
71
70
72
typedef struct varatt_external JsonbToastPointer ;
@@ -195,10 +197,11 @@ static bool JsonContainerIsToasted(JsonContainer *jc,
195
197
JsonbToastedContainerPointerData * jbcptr );
196
198
static bool JsonContainerIsCompressed (JsonContainer * jc ,
197
199
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 );
201
202
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 );
202
205
203
206
static bool jsonb_toast_fields = true; /* GUC */
204
207
static bool jsonb_toast_fields_recursively = true; /* GUC */
@@ -822,6 +825,7 @@ JsonxIteratorInit(JsonContainer *cont, const JsonbContainerHeader *container,
822
825
case JBC_TOBJECT :
823
826
case JBC_TOBJECT_SORTED :
824
827
case JBC_TOBJECT_TOASTED :
828
+ case JBC_TOBJECT_COMPRESSED :
825
829
it -> dataProper =
826
830
(char * ) it -> children + it -> nElems * sizeof (JEntry ) * 2 ;
827
831
it -> dataProper = initKVMap (& it -> kvmap , it -> dataProper , it -> nElems ,
@@ -902,9 +906,14 @@ JsonxEncode(StringInfoData *buffer, const JsonbValue *val, void *cxt)
902
906
static void *
903
907
jsonxEncode (JsonValue * jv , JsonContainerOps * ops , Oid toasterid )
904
908
{
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
+ }
908
917
909
918
return NULL ;
910
919
}
@@ -1204,24 +1213,83 @@ JsonContainerContainsToasted(JsonContainer *jc)
1204
1213
}
1205
1214
1206
1215
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 )
1208
1250
{
1209
1251
return jv -> type == jbvBinary &&
1210
1252
JsonContainerIsToasted (jv -> val .binary .data , jbcptr );
1211
1253
}
1212
1254
1213
1255
static bool
1214
- JsonValueIsCompressed (JsonValue * jv , JsonbCompressedContainerData * jbcptr )
1256
+ JsonValueIsCompressed (const JsonValue * jv , JsonbCompressedContainerData * jbcptr )
1215
1257
{
1216
1258
return jv -> type == jbvBinary &&
1217
1259
JsonContainerIsCompressed (jv -> val .binary .data , jbcptr );
1218
1260
}
1219
1261
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
+
1220
1284
static bool
1221
- JsonValueContainsToasted (const JsonValue * jv )
1285
+ JsonValueContainsToastedOrCompressed (const JsonValue * jv ,
1286
+ bool * toasted , bool * compressed )
1222
1287
{
1223
1288
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;
1225
1293
1226
1294
if (jv -> type == jbvObject )
1227
1295
{
@@ -1231,8 +1299,7 @@ JsonValueContainsToasted(const JsonValue *jv)
1231
1299
{
1232
1300
JsonValue * val = & jv -> val .object .pairs [i ].value ;
1233
1301
1234
- if (JsonValueIsToasted (val , NULL ) ||
1235
- JsonValueContainsToasted (val ))
1302
+ if (JsonValueContainsToastedOrCompressedAccum (val , toasted , compressed ))
1236
1303
return true;
1237
1304
}
1238
1305
}
@@ -1244,15 +1311,15 @@ JsonValueContainsToasted(const JsonValue *jv)
1244
1311
{
1245
1312
JsonValue * val = & jv -> val .array .elems [i ];
1246
1313
1247
- if (JsonValueIsToasted (val , NULL ) ||
1248
- JsonValueContainsToasted (val ))
1314
+ if (JsonValueContainsToastedOrCompressedAccum (val , toasted , compressed ))
1249
1315
return true;
1250
1316
}
1251
1317
}
1252
1318
1253
- return false ;
1319
+ return * toasted || * compressed ;
1254
1320
}
1255
1321
1322
+
1256
1323
static void
1257
1324
convertJsonbObject (StringInfo buffer , JEntry * pheader , const JsonbValue * val , int level )
1258
1325
{
@@ -1266,6 +1333,7 @@ convertJsonbObject(StringInfo buffer, JEntry *pheader, const JsonbValue *val, in
1266
1333
int kvmap_entry_size ;
1267
1334
bool sorted_values = jsonb_sort_field_values && nPairs > 1 ;
1268
1335
bool have_toasted_values = false;
1336
+ bool have_compressed_values = false;
1269
1337
struct
1270
1338
{
1271
1339
int size ;
@@ -1274,11 +1342,8 @@ convertJsonbObject(StringInfo buffer, JEntry *pheader, const JsonbValue *val, in
1274
1342
1275
1343
Assert (nPairs >= 0 );
1276
1344
1277
- if (JsonValueContainsToasted (val ))
1278
- {
1279
- have_toasted_values = true;
1345
+ if (JsonValueContainsToastedOrCompressed (val , & have_toasted_values , & have_compressed_values ))
1280
1346
sorted_values = false; /* FIXME */
1281
- }
1282
1347
1283
1348
values = sorted_values ? palloc (sizeof (* values ) * nPairs ) : NULL ;
1284
1349
@@ -1318,7 +1383,8 @@ convertJsonbObject(StringInfo buffer, JEntry *pheader, const JsonbValue *val, in
1318
1383
*/
1319
1384
header = nPairs |
1320
1385
(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 );
1322
1388
appendToBuffer (buffer , (char * ) & header , sizeof (uint32 ));
1323
1389
1324
1390
/* Reserve space for the JEntries of the keys and values. */
@@ -1617,6 +1683,7 @@ jsonxInitContainerFromHeader(JsonContainerData *jc, JsonbContainerHdr header)
1617
1683
case JBC_TOBJECT :
1618
1684
case JBC_TOBJECT_SORTED :
1619
1685
case JBC_TOBJECT_TOASTED :
1686
+ case JBC_TOBJECT_COMPRESSED :
1620
1687
jc -> type = jbvObject ;
1621
1688
break ;
1622
1689
case JBC_TARRAY :
0 commit comments