19
19
#include "access/heaptoast.h"
20
20
#include "access/table.h"
21
21
#include "access/toast_internals.h"
22
+ #include "access/generic_toaster.h"
22
23
#include "catalog/toasting.h"
23
24
#include "access/xact.h"
24
25
#include "catalog/catalog.h"
@@ -165,9 +166,22 @@ toast_save_datum_ext(Relation rel, Oid toasterid, Datum value,
165
166
{
166
167
struct varatt_external old_toast_pointer ;
167
168
168
- Assert (VARATT_IS_EXTERNAL_ONDISK (oldexternal ));
169
+ /* New case - Generic TOAST working with Custom pointer */
170
+ if (VARATT_IS_CUSTOM (oldexternal ))
171
+ {
172
+ ExternalToastData data ;
173
+ VARATT_CUSTOM_GET_EXTERNAL_DATA (PointerGetDatum (oldexternal ), data );
174
+ old_toast_pointer .va_toastrelid = get_uint32align16 (& data .va_toastrelid );
175
+ old_toast_pointer .va_valueid = get_uint32align16 (& data .va_valueid );
176
+ }
177
+ else
178
+ {
179
+ Assert (VARATT_IS_EXTERNAL_ONDISK (oldexternal ));
180
+ VARATT_EXTERNAL_GET_POINTER (old_toast_pointer , oldexternal );
181
+ }
169
182
/* Must copy to access aligned fields */
170
- VARATT_EXTERNAL_GET_POINTER (old_toast_pointer , oldexternal );
183
+ /* VARATT_EXTERNAL_GET_POINTER(old_toast_pointer, oldexternal); */
184
+ /* XXX if (old_toast_pointer.va_toastrelid == rel->rd_toastoid) */
171
185
if (old_toast_pointer .va_toastrelid == real_toastrelid )
172
186
{
173
187
/* This value came from the old toast table; reuse its OID */
@@ -265,17 +279,34 @@ toast_delete_datum(Datum value, bool is_speculative)
265
279
int num_indexes ;
266
280
int validIndex ;
267
281
SnapshotData SnapshotToast ;
282
+ ExternalToastData data ;
283
+ Oid va_toastrelid ;
284
+ Oid va_valueid ;
268
285
269
- if (!VARATT_IS_EXTERNAL_ONDISK (attr ))
286
+ if (!VARATT_IS_EXTERNAL_ONDISK (attr ) && ! VARATT_IS_CUSTOM ( attr ) )
270
287
return ;
271
288
272
289
/* Must copy to access aligned fields */
273
- VARATT_EXTERNAL_GET_POINTER (toast_pointer , attr );
290
+ if (VARATT_IS_CUSTOM (attr ))
291
+ {
292
+ /* process custom Toast Pointer */
293
+ VARATT_CUSTOM_GET_EXTERNAL_DATA (attr , data );
294
+
295
+ va_toastrelid = get_uint32align16 (& data .va_toastrelid );
296
+ va_valueid = get_uint32align16 (& data .va_valueid );
297
+ }
298
+ else
299
+ {
300
+ VARATT_EXTERNAL_GET_POINTER (toast_pointer , attr );
301
+
302
+ va_toastrelid = toast_pointer .va_toastrelid ;
303
+ va_valueid = toast_pointer .va_valueid ;
304
+ }
274
305
275
306
/*
276
307
* Open the toast relation and its indexes
277
308
*/
278
- toastrel = table_open (toast_pointer . va_toastrelid , RowExclusiveLock );
309
+ toastrel = table_open (va_toastrelid , RowExclusiveLock );
279
310
280
311
/* Fetch valid relation used for process */
281
312
validIndex = toast_open_indexes (toastrel ,
@@ -289,7 +320,7 @@ toast_delete_datum(Datum value, bool is_speculative)
289
320
ScanKeyInit (& toastkey ,
290
321
(AttrNumber ) 1 ,
291
322
BTEqualStrategyNumber , F_OIDEQ ,
292
- ObjectIdGetDatum (toast_pointer . va_valueid ));
323
+ ObjectIdGetDatum (va_valueid ));
293
324
294
325
/*
295
326
* Find all the chunks. (We don't actually care whether we see them in
@@ -405,19 +436,43 @@ toast_fetch_datum(struct varlena *attr)
405
436
Relation toastrel ;
406
437
struct varlena * result ;
407
438
struct varatt_external toast_pointer ;
439
+ ExternalToastData data ;
440
+ Oid va_toastrelid ;
441
+ Oid va_valueid ;
408
442
int32 attrsize ;
443
+ bool is_compressed = false;
409
444
410
- if (!VARATT_IS_EXTERNAL_ONDISK (attr ))
411
- elog (ERROR , "toast_fetch_datum shouldn't be called for non-ondisk datums" );
445
+ if (!VARATT_IS_EXTERNAL_ONDISK (attr ) && ! VARATT_IS_CUSTOM ( attr ) )
446
+ elog (ERROR , "toast_fetch_datum_slice shouldn't be called for non-ondisk or non-custom datums" );
412
447
413
448
/* Must copy to access aligned fields */
414
- VARATT_EXTERNAL_GET_POINTER (toast_pointer , attr );
449
+ if (VARATT_IS_CUSTOM (attr ))
450
+ {
451
+ /* process custom Toast Pointer */
452
+ VARATT_CUSTOM_GET_EXTERNAL_DATA (attr , data );
453
+
454
+ attrsize = get_uint32align16 (& data .va_extinfo );
455
+ va_toastrelid = get_uint32align16 (& data .va_toastrelid );
456
+ va_valueid = get_uint32align16 (& data .va_valueid );
457
+
458
+ if (VARATT_CUSTOM_EXTERNAL_IS_COMPRESSED (attr , attrsize ))
459
+ is_compressed = true;
460
+ }
461
+ else
462
+ {
463
+ VARATT_EXTERNAL_GET_POINTER (toast_pointer , attr );
415
464
416
- attrsize = VARATT_EXTERNAL_GET_EXTSIZE (toast_pointer );
465
+ va_toastrelid = toast_pointer .va_toastrelid ;
466
+ va_valueid = toast_pointer .va_valueid ;
467
+
468
+ attrsize = VARATT_EXTERNAL_GET_EXTSIZE (toast_pointer );
469
+ if (VARATT_EXTERNAL_IS_COMPRESSED (toast_pointer ))
470
+ is_compressed = true;
471
+ }
417
472
418
473
result = (struct varlena * ) palloc (attrsize + VARHDRSZ );
419
474
420
- if (VARATT_EXTERNAL_IS_COMPRESSED ( toast_pointer ) )
475
+ if (is_compressed )
421
476
SET_VARSIZE_COMPRESSED (result , attrsize + VARHDRSZ );
422
477
else
423
478
SET_VARSIZE (result , attrsize + VARHDRSZ );
@@ -429,10 +484,10 @@ toast_fetch_datum(struct varlena *attr)
429
484
/*
430
485
* Open the toast relation and its indexes
431
486
*/
432
- toastrel = table_open (toast_pointer . va_toastrelid , AccessShareLock );
487
+ toastrel = table_open (va_toastrelid , AccessShareLock );
433
488
434
489
/* Fetch all chunks */
435
- toast_fetch_toast_slice (toastrel , toast_pointer . va_valueid ,
490
+ toast_fetch_toast_slice (toastrel , va_valueid ,
436
491
attr , attrsize , 0 , attrsize , result , 0 ,
437
492
NULL , NULL );
438
493
@@ -460,22 +515,47 @@ toast_fetch_datum_slice(struct varlena *attr, int32 sliceoffset,
460
515
Relation toastrel ;
461
516
struct varlena * result ;
462
517
struct varatt_external toast_pointer ;
518
+ ExternalToastData data ;
519
+ Oid va_toastrelid ;
520
+ Oid va_valueid ;
463
521
int32 attrsize ;
522
+ bool is_compressed = false;
464
523
465
- if (!VARATT_IS_EXTERNAL_ONDISK (attr ))
466
- elog (ERROR , "toast_fetch_datum_slice shouldn't be called for non-ondisk datums" );
524
+ if (!( VARATT_IS_EXTERNAL_ONDISK (attr ) || VARATT_IS_CUSTOM ( attr ) ))
525
+ elog (ERROR , "toast_fetch_datum_slice shouldn't be called for non-ondisk or non-custom datums" );
467
526
468
527
/* Must copy to access aligned fields */
469
- VARATT_EXTERNAL_GET_POINTER (toast_pointer , attr );
528
+ if (VARATT_IS_CUSTOM (attr ))
529
+ {
530
+ /* process custom Toast Pointer */
531
+ VARATT_CUSTOM_GET_EXTERNAL_DATA (attr , data );
470
532
471
- /*
472
- * It's nonsense to fetch slices of a compressed datum unless when it's a
473
- * prefix -- this isn't lo_* we can't return a compressed datum which is
474
- * meaningful to toast later.
475
- */
476
- Assert (!VARATT_EXTERNAL_IS_COMPRESSED (toast_pointer ) || 0 == sliceoffset );
533
+ attrsize = get_uint32align16 (& data .va_extinfo );
534
+ va_toastrelid = get_uint32align16 (& data .va_toastrelid );
535
+ va_valueid = get_uint32align16 (& data .va_valueid );
536
+
537
+ if (VARATT_CUSTOM_EXTERNAL_IS_COMPRESSED (attr , attrsize ) && slicelength > 0 )
538
+ is_compressed = true;
539
+ }
540
+ else
541
+ {
542
+ VARATT_EXTERNAL_GET_POINTER (toast_pointer , attr );
543
+
544
+ va_toastrelid = toast_pointer .va_toastrelid ;
545
+ va_valueid = toast_pointer .va_valueid ;
546
+
547
+ /*
548
+ * It's nonsense to fetch slices of a compressed datum unless when it's a
549
+ * prefix -- this isn't lo_* we can't return a compressed datum which is
550
+ * meaningful to toast later.
551
+ */
552
+ Assert (!VARATT_EXTERNAL_IS_COMPRESSED (toast_pointer ) || 0 == sliceoffset );
553
+
554
+ attrsize = VARATT_EXTERNAL_GET_EXTSIZE (toast_pointer );
555
+ if (VARATT_EXTERNAL_IS_COMPRESSED (toast_pointer ) && slicelength > 0 )
556
+ is_compressed = true;
557
+ }
477
558
478
- attrsize = VARATT_EXTERNAL_GET_EXTSIZE (toast_pointer );
479
559
480
560
if (sliceoffset >= attrsize )
481
561
{
@@ -488,7 +568,8 @@ toast_fetch_datum_slice(struct varlena *attr, int32 sliceoffset,
488
568
* space required by va_tcinfo, which is stored at the beginning as an
489
569
* int32 value.
490
570
*/
491
- if (VARATT_EXTERNAL_IS_COMPRESSED (toast_pointer ) && slicelength > 0 )
571
+ /* if (VARATT_EXTERNAL_IS_COMPRESSED(toast_pointer) && slicelength > 0) */
572
+ if (is_compressed )
492
573
slicelength = slicelength + sizeof (int32 );
493
574
494
575
/*
@@ -501,7 +582,7 @@ toast_fetch_datum_slice(struct varlena *attr, int32 sliceoffset,
501
582
502
583
result = (struct varlena * ) palloc (slicelength + VARHDRSZ );
503
584
504
- if ( VARATT_EXTERNAL_IS_COMPRESSED ( toast_pointer ) )
585
+ if ( is_compressed )
505
586
SET_VARSIZE_COMPRESSED (result , slicelength + VARHDRSZ );
506
587
else
507
588
SET_VARSIZE (result , slicelength + VARHDRSZ );
@@ -510,10 +591,10 @@ toast_fetch_datum_slice(struct varlena *attr, int32 sliceoffset,
510
591
return result ; /* Can save a lot of work at this point! */
511
592
512
593
/* Open the toast relation */
513
- toastrel = table_open (toast_pointer . va_toastrelid , AccessShareLock );
594
+ toastrel = table_open (va_toastrelid , AccessShareLock );
514
595
515
596
/* Fetch all chunks */
516
- toast_fetch_toast_slice (toastrel , toast_pointer . va_valueid ,
597
+ toast_fetch_toast_slice (toastrel , va_valueid ,
517
598
attr , attrsize , sliceoffset , slicelength ,
518
599
result , 0 , NULL , NULL );
519
600
0 commit comments