@@ -71,7 +71,7 @@ static void encode_varbyte(uint32 val, unsigned char *ptr, int *len);
71
71
static uint32 decode_varbyte (unsigned char * ptr );
72
72
static char * packJsonbValue (JsonbValue * val , int header_size , int * len );
73
73
static void setup_guc_variables (void );
74
- static void jsonbc_get_keys (Oid cmoptoid , uint32 * ids , int nkeys , char * * keys );
74
+ static char * jsonbc_get_keys (Oid cmoptoid , uint32 * ids , int nkeys , size_t * buflen );
75
75
static void jsonbc_get_key_ids (Oid cmoptoid , char * buf , int buflen , uint32 * idsbuf , int nkeys );
76
76
77
77
static size_t
@@ -278,16 +278,13 @@ ids_callback(char *res, size_t reslen, void *arg)
278
278
279
279
typedef struct
280
280
{
281
- char * * keys ;
282
- int nkeys ;
281
+ size_t buflen ;
282
+ char * buf ;
283
283
} keys_callback_state ;
284
284
285
285
static bool
286
286
keys_callback (char * res , size_t reslen , void * arg )
287
287
{
288
- int i = 0 ,
289
- nkeys = 0 ;
290
-
291
288
keys_callback_state * state = (keys_callback_state * ) arg ;
292
289
293
290
/* it should at least two symbols in the response */
@@ -302,16 +299,13 @@ keys_callback(char *res, size_t reslen, void *arg)
302
299
compression_buffers -> buflen = reslen ;
303
300
}
304
301
302
+ /* save the received data */
305
303
memcpy (compression_buffers -> buf , res , reslen );
306
304
307
- while (reslen -- )
308
- {
309
- if (res [i ] != '\0' )
310
- state -> keys [nkeys ++ ] = & compression_buffers -> buf [i ];
311
- i ++ ;
312
- }
305
+ state -> buf = compression_buffers -> buf ;
306
+ state -> buflen = reslen ;
313
307
314
- return ( nkeys == state -> nkeys ) ;
308
+ return true ;
315
309
}
316
310
317
311
static void
@@ -392,13 +386,13 @@ jsonbc_get_key_ids(Oid cmoptoid, char *buf, int buflen, uint32 *idsbuf, int nkey
392
386
ids_callback_state state ;
393
387
394
388
iov [0 ].data = (void * ) & nkeys ;
395
- iov [0 ].len = sizeof (int );
389
+ iov [0 ].len = sizeof (nkeys );
396
390
397
391
iov [1 ].data = (void * ) & cmoptoid ;
398
- iov [1 ].len = sizeof (Oid );
392
+ iov [1 ].len = sizeof (cmoptoid );
399
393
400
394
iov [2 ].data = (void * ) & cmd ;
401
- iov [2 ].len = sizeof (JsonbcCommand );
395
+ iov [2 ].len = sizeof (cmd );
402
396
403
397
iov [3 ].data = buf ;
404
398
iov [3 ].len = buflen ;
@@ -409,28 +403,31 @@ jsonbc_get_key_ids(Oid cmoptoid, char *buf, int buflen, uint32 *idsbuf, int nkey
409
403
}
410
404
411
405
/* Get keys by their IDs using workers */
412
- static void
413
- jsonbc_get_keys (Oid cmoptoid , uint32 * ids , int nkeys , char * * keys )
406
+ static char *
407
+ jsonbc_get_keys (Oid cmoptoid , uint32 * ids , int nkeys , size_t * buflen )
414
408
{
415
409
JsonbcCommand cmd = JSONBC_CMD_GET_KEYS ;
416
410
shm_mq_iovec iov [4 ];
417
411
keys_callback_state state ;
418
412
419
413
iov [0 ].data = (void * ) & nkeys ;
420
- iov [0 ].len = sizeof (int );
414
+ iov [0 ].len = sizeof (nkeys );
421
415
422
416
iov [1 ].data = (void * ) & cmoptoid ;
423
- iov [1 ].len = sizeof (Oid );
417
+ iov [1 ].len = sizeof (cmoptoid );
424
418
425
419
iov [2 ].data = (void * ) & cmd ;
426
- iov [2 ].len = sizeof (JsonbcCommand );
420
+ iov [2 ].len = sizeof (cmd );
427
421
428
422
iov [3 ].data = (char * ) ids ;
429
423
iov [3 ].len = sizeof (uint32 ) * nkeys ;
430
424
431
- state .keys = keys ;
432
- state .nkeys = nkeys ;
425
+ state .buf = NULL ;
426
+ state .buflen = 0 ;
433
427
jsonbc_communicate (iov , 4 , keys_callback , & state );
428
+
429
+ * buflen = state .buflen ;
430
+ return state .buf ;
434
431
}
435
432
436
433
/*
@@ -698,7 +695,7 @@ jsonbc_decompress(AttributeCompression *ac, const struct varlena *data)
698
695
JsonbParseState * state = NULL ;
699
696
struct varlena * res ;
700
697
701
- init_memory_context (false );
698
+ init_memory_context (true );
702
699
Assert (VARATT_IS_CUSTOM_COMPRESSED (data ));
703
700
704
701
jb = (Jsonb * ) ((char * ) data + VARHDRSZ_CUSTOM_COMPRESSED - offsetof(Jsonb , root ));
@@ -709,7 +706,9 @@ jsonbc_decompress(AttributeCompression *ac, const struct varlena *data)
709
706
710
707
if (r == WJB_END_OBJECT && jbv -> type == jbvObject )
711
708
{
712
- char * * keys ;
709
+ char * buf ;
710
+ size_t buflen ,
711
+ offset = 0 ;
713
712
int i ,
714
713
nkeys = jbv -> val .object .nPairs ;
715
714
@@ -721,7 +720,7 @@ jsonbc_decompress(AttributeCompression *ac, const struct varlena *data)
721
720
compression_buffers -> idslen = nkeys ;
722
721
}
723
722
724
- /* decode keys */
723
+ /* decode key ids */
725
724
for (i = 0 ; i < nkeys ; i ++ )
726
725
{
727
726
int32 key_id ;
@@ -733,18 +732,24 @@ jsonbc_decompress(AttributeCompression *ac, const struct varlena *data)
733
732
compression_buffers -> idsbuf [i ] = key_id ;
734
733
}
735
734
736
- /* retrieve or generate ids */
737
- keys = (char * * ) palloc (sizeof (char * ) * nkeys );
738
- jsonbc_get_keys (ac -> cmoptoid , compression_buffers -> idsbuf , nkeys , keys );
735
+ /* retrieve keys */
736
+ buf = jsonbc_get_keys (ac -> cmoptoid , compression_buffers -> idsbuf , nkeys , & buflen );
737
+ if (buf == NULL )
738
+ elog (ERROR , "jsonbc: decompression error" );
739
739
740
740
/* replace the encoded keys with real keys */
741
741
for (i = 0 ; i < nkeys ; i ++ )
742
742
{
743
+ size_t oldoff = offset ;
744
+
743
745
JsonbValue * v = & jbv -> val .object .pairs [i ].key ;
744
- v -> val .string .val = keys [i ];
745
- v -> val .string .len = strlen (keys [i ]);
746
+ v -> val .string .val = & buf [offset ];
747
+ while (buf [offset ++ ] != '\0' );
748
+ v -> val .string .len = offset - oldoff - 2 ;
746
749
}
747
- pfree (keys );
750
+
751
+ /* check correctness */
752
+ Assert (offset == buflen );
748
753
}
749
754
}
750
755
0 commit comments