@@ -46,7 +46,7 @@ detoast_external_attr(struct varlena *attr)
46
46
{
47
47
struct varlena * result ;
48
48
49
- if (VARATT_IS_EXTERNAL_ONDISK (attr ))
49
+ if (VARATT_IS_EXTERNAL_ONDISK (attr ) || VARATT_IS_EXTERNAL_ONDISK_INLINE ( attr ) )
50
50
{
51
51
/*
52
52
* This is an external stored plain value
@@ -115,7 +115,7 @@ detoast_external_attr(struct varlena *attr)
115
115
struct varlena *
116
116
detoast_attr (struct varlena * attr )
117
117
{
118
- if (VARATT_IS_EXTERNAL_ONDISK (attr ))
118
+ if (VARATT_IS_EXTERNAL_ONDISK (attr ) || VARATT_IS_EXTERNAL_ONDISK_INLINE ( attr ) )
119
119
{
120
120
/*
121
121
* This is an externally stored datum --- fetch it back from there
@@ -223,6 +223,9 @@ detoast_attr_slice(struct varlena *attr,
223
223
else if (pg_add_s32_overflow (sliceoffset , slicelength , & slicelimit ))
224
224
slicelength = slicelimit = -1 ;
225
225
226
+ if (VARATT_IS_EXTERNAL_ONDISK_INLINE (attr ))
227
+ elog (ERROR , "slicing of chunked attributes is not yet supported" ); /* FIXME */
228
+
226
229
if (VARATT_IS_EXTERNAL_ONDISK (attr ))
227
230
{
228
231
struct varatt_external toast_pointer ;
@@ -344,37 +347,45 @@ create_detoast_iterator(struct varlena *attr)
344
347
{
345
348
struct varatt_external toast_pointer ;
346
349
DetoastIterator iter ;
347
- if (VARATT_IS_EXTERNAL_ONDISK (attr ))
350
+ if (VARATT_IS_EXTERNAL_ONDISK (attr ) || VARATT_IS_EXTERNAL_ONDISK_INLINE ( attr ) )
348
351
{
349
352
FetchDatumIterator fetch_iter ;
353
+ int32 inlineSize ;
350
354
351
355
iter = (DetoastIterator ) palloc0 (sizeof (DetoastIteratorData ));
352
356
iter -> done = false;
353
357
iter -> nrefs = 1 ;
354
358
355
359
/* This is an externally stored datum --- initialize fetch datum iterator */
356
360
iter -> fetch_datum_iterator = fetch_iter = create_fetch_datum_iterator (attr );
357
- VARATT_EXTERNAL_GET_POINTER (toast_pointer , attr );
361
+
362
+ /* Must copy to access aligned fields */
363
+ inlineSize = VARATT_EXTERNAL_INLINE_GET_POINTER (toast_pointer , attr );
364
+
358
365
if (VARATT_EXTERNAL_IS_COMPRESSED (toast_pointer ))
359
366
{
360
367
iter -> compressed = true;
368
+ iter -> compression_method = VARATT_EXTERNAL_GET_COMPRESS_METHOD (toast_pointer );
361
369
362
370
/* prepare buffer to received decompressed data */
363
371
iter -> buf = create_toast_buffer (toast_pointer .va_rawsize , false);
364
-
365
- /* initialize state for pglz_decompress_iterate() */
366
- iter -> ctrl = 0 ;
367
- iter -> ctrlc = INVALID_CTRLC ;
368
- iter -> len = 0 ;
369
- iter -> off = 0 ;
370
372
}
371
373
else
372
374
{
373
375
iter -> compressed = false;
376
+ iter -> compression_method = TOAST_INVALID_COMPRESSION_ID ;
374
377
375
378
/* point the buffer directly at the raw data */
376
379
iter -> buf = fetch_iter -> buf ;
377
380
}
381
+
382
+ if (inlineSize > 0 )
383
+ {
384
+ memcpy ((void * ) fetch_iter -> buf -> limit ,
385
+ VARDATA_EXTERNAL_INLINE (attr ), inlineSize );
386
+ fetch_iter = - > buf -> limit += inlineSize ;
387
+ }
388
+
378
389
return iter ;
379
390
}
380
391
else if (VARATT_IS_EXTERNAL_INDIRECT (attr ))
@@ -404,16 +415,14 @@ create_detoast_iterator(struct varlena *attr)
404
415
iter -> fetch_datum_iterator -> buf = buf = create_toast_buffer (VARSIZE_ANY (attr ), true);
405
416
iter -> fetch_datum_iterator -> done = true;
406
417
iter -> compressed = true;
418
+ iter -> compression_method = VARDATA_COMPRESSED_GET_COMPRESS_METHOD (attr );
407
419
408
420
memcpy ((void * ) buf -> buf , attr , VARSIZE_ANY (attr ));
409
421
buf -> limit = (char * ) buf -> capacity ;
410
422
411
423
/* prepare buffer to received decompressed data */
412
- iter -> buf = create_toast_buffer (TOAST_COMPRESS_RAWSIZE (attr ) + VARHDRSZ , false);
424
+ iter -> buf = create_toast_buffer (TOAST_COMPRESS_EXTSIZE (attr ) + VARHDRSZ , false);
413
425
414
- /* initialize state for pglz_decompress_iterate() */
415
- iter -> ctrl = 0 ;
416
- iter -> ctrlc = INVALID_CTRLC ;
417
426
return iter ;
418
427
}
419
428
else
@@ -455,13 +464,13 @@ toast_fetch_datum(struct varlena *attr)
455
464
struct varlena * result ;
456
465
struct varatt_external toast_pointer ;
457
466
int32 attrsize ;
467
+ int32 inlineSize ;
458
468
459
- if (!VARATT_IS_EXTERNAL_ONDISK (attr ))
469
+ if (!VARATT_IS_EXTERNAL_ONDISK (attr ) && ! VARATT_IS_EXTERNAL_ONDISK_INLINE ( attr ) )
460
470
elog (ERROR , "toast_fetch_datum shouldn't be called for non-ondisk datums" );
461
471
462
472
/* Must copy to access aligned fields */
463
- VARATT_EXTERNAL_GET_POINTER (toast_pointer , attr );
464
-
473
+ inlineSize = VARATT_EXTERNAL_INLINE_GET_POINTER (toast_pointer , attr );
465
474
attrsize = VARATT_EXTERNAL_GET_EXTSIZE (toast_pointer );
466
475
467
476
result = (struct varlena * ) palloc (attrsize + VARHDRSZ );
@@ -475,14 +484,18 @@ toast_fetch_datum(struct varlena *attr)
475
484
return result ; /* Probably shouldn't happen, but just in
476
485
* case. */
477
486
487
+ if (inlineSize )
488
+ memcpy (VARDATA (result ), VARDATA_EXTERNAL_INLINE (attr ), inlineSize );
489
+
478
490
/*
479
491
* Open the toast relation and its indexes
480
492
*/
481
493
toastrel = table_open (toast_pointer .va_toastrelid , AccessShareLock );
482
494
483
495
/* Fetch all chunks */
484
496
table_relation_fetch_toast_slice (toastrel , toast_pointer .va_valueid ,
485
- attrsize , 0 , attrsize , result );
497
+ attrsize - inlineSize , 0 , attrsize - inlineSize ,
498
+ (struct varlena * )((char * ) result + inlineSize ));
486
499
487
500
/* Close toast table */
488
501
table_close (toastrel , AccessShareLock );
@@ -510,7 +523,7 @@ toast_fetch_datum_slice(struct varlena *attr, int32 sliceoffset,
510
523
struct varatt_external toast_pointer ;
511
524
int32 attrsize ;
512
525
513
- if (!VARATT_IS_EXTERNAL_ONDISK (attr ))
526
+ if (!VARATT_IS_EXTERNAL_ONDISK (attr )) /* FIXME */
514
527
elog (ERROR , "toast_fetch_datum_slice shouldn't be called for non-ondisk datums" );
515
528
516
529
/* Must copy to access aligned fields */
@@ -656,13 +669,14 @@ toast_raw_datum_size(Datum value)
656
669
struct varlena * attr = (struct varlena * ) DatumGetPointer (value );
657
670
Size result ;
658
671
659
- if (VARATT_IS_EXTERNAL_ONDISK (attr ))
672
+ if (VARATT_IS_EXTERNAL_ONDISK (attr ) || VARATT_IS_EXTERNAL_ONDISK_INLINE ( attr ) )
660
673
{
661
674
/* va_rawsize is the size of the original datum -- including header */
662
675
struct varatt_external toast_pointer ;
676
+ Size inlineSize ;
663
677
664
- VARATT_EXTERNAL_GET_POINTER (toast_pointer , attr );
665
- result = toast_pointer .va_rawsize ;
678
+ inlineSize = VARATT_EXTERNAL_INLINE_GET_POINTER (toast_pointer , attr );
679
+ result = toast_pointer .va_rawsize + inlineSize ;
666
680
}
667
681
else if (VARATT_IS_EXTERNAL_INDIRECT (attr ))
668
682
{
@@ -712,7 +726,8 @@ toast_datum_size(Datum value)
712
726
struct varlena * attr = (struct varlena * ) DatumGetPointer (value );
713
727
Size result ;
714
728
715
- if (VARATT_IS_EXTERNAL_ONDISK (attr ))
729
+ if (VARATT_IS_EXTERNAL_ONDISK (attr ) ||
730
+ VARATT_IS_EXTERNAL_ONDISK_INLINE (attr ))
716
731
{
717
732
/*
718
733
* Attribute is stored externally - return the extsize whether
@@ -721,8 +736,8 @@ toast_datum_size(Datum value)
721
736
*/
722
737
struct varatt_external toast_pointer ;
723
738
724
- VARATT_EXTERNAL_GET_POINTER (toast_pointer , attr );
725
- result = VARATT_EXTERNAL_GET_EXTSIZE (toast_pointer );
739
+ VARATT_EXTERNAL_INLINE_GET_POINTER (toast_pointer , attr );
740
+ result = VARATT_EXTERNAL_GET_EXTSIZE (toast_pointer ); /* FIXME inlineSize */
726
741
}
727
742
else if (VARATT_IS_EXTERNAL_INDIRECT (attr ))
728
743
{
0 commit comments