8
8
*
9
9
*
10
10
* IDENTIFICATION
11
- * $Header: /cvsroot/pgsql/src/backend/access/heap/tuptoaster.c,v 1.12 2000/08/04 04:16:07 tgl Exp $
11
+ * $Header: /cvsroot/pgsql/src/backend/access/heap/tuptoaster.c,v 1.13 2000/10/23 23:42:04 tgl Exp $
12
12
*
13
13
*
14
14
* INTERFACE ROUTINES
@@ -247,6 +247,11 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
247
247
248
248
/* ----------
249
249
* Then collect information about the values given
250
+ *
251
+ * NOTE: toast_action[i] can have these values:
252
+ * ' ' default handling
253
+ * 'p' already processed --- don't touch it
254
+ * 'x' incompressible, but OK to move off
250
255
* ----------
251
256
*/
252
257
memset (toast_action , ' ' , numAttrs * sizeof (char ));
@@ -397,14 +402,15 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
397
402
int biggest_attno = -1 ;
398
403
int32 biggest_size = MAXALIGN (sizeof (varattrib ));
399
404
Datum old_value ;
405
+ Datum new_value ;
400
406
401
407
/* ----------
402
408
* Search for the biggest yet uncompressed internal attribute
403
409
* ----------
404
410
*/
405
411
for (i = 0 ; i < numAttrs ; i ++ )
406
412
{
407
- if (toast_action [i ] == 'p ' )
413
+ if (toast_action [i ] != ' ' )
408
414
continue ;
409
415
if (VARATT_IS_EXTENDED (toast_values [i ]))
410
416
continue ;
@@ -421,20 +427,29 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
421
427
break ;
422
428
423
429
/* ----------
424
- * Compress it inline
430
+ * Attempt to compress it inline
425
431
* ----------
426
432
*/
427
433
i = biggest_attno ;
428
434
old_value = toast_values [i ];
435
+ new_value = toast_compress_datum (old_value );
429
436
430
- toast_values [i ] = toast_compress_datum (toast_values [i ]);
431
- if (toast_free [i ])
432
- pfree (DatumGetPointer (old_value ));
433
- toast_free [i ] = true;
434
- toast_sizes [i ] = VARATT_SIZE (toast_values [i ]);
435
-
436
- need_change = true;
437
- need_free = true;
437
+ if (DatumGetPointer (new_value ) != NULL )
438
+ {
439
+ /* successful compression */
440
+ if (toast_free [i ])
441
+ pfree (DatumGetPointer (old_value ));
442
+ toast_values [i ] = new_value ;
443
+ toast_free [i ] = true;
444
+ toast_sizes [i ] = VARATT_SIZE (toast_values [i ]);
445
+ need_change = true;
446
+ need_free = true;
447
+ }
448
+ else
449
+ {
450
+ /* incompressible data, ignore on subsequent compression passes */
451
+ toast_action [i ] = 'x' ;
452
+ }
438
453
}
439
454
440
455
/* ----------
@@ -504,14 +519,15 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
504
519
int biggest_attno = -1 ;
505
520
int32 biggest_size = MAXALIGN (sizeof (varattrib ));
506
521
Datum old_value ;
522
+ Datum new_value ;
507
523
508
524
/* ----------
509
525
* Search for the biggest yet uncompressed internal attribute
510
526
* ----------
511
527
*/
512
528
for (i = 0 ; i < numAttrs ; i ++ )
513
529
{
514
- if (toast_action [i ] == 'p ' )
530
+ if (toast_action [i ] != ' ' )
515
531
continue ;
516
532
if (VARATT_IS_EXTENDED (toast_values [i ]))
517
533
continue ;
@@ -528,22 +544,29 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
528
544
break ;
529
545
530
546
/* ----------
531
- * Compress it inline
547
+ * Attempt to compress it inline
532
548
* ----------
533
549
*/
534
550
i = biggest_attno ;
535
551
old_value = toast_values [i ];
552
+ new_value = toast_compress_datum (old_value );
536
553
537
- toast_values [i ] = toast_compress_datum (toast_values [i ]);
538
-
539
- if (toast_free [i ])
540
- pfree (DatumGetPointer (old_value ));
541
-
542
- toast_free [i ] = true;
543
- toast_sizes [i ] = VARATT_SIZE (toast_values [i ]);
544
-
545
- need_change = true;
546
- need_free = true;
554
+ if (DatumGetPointer (new_value ) != NULL )
555
+ {
556
+ /* successful compression */
557
+ if (toast_free [i ])
558
+ pfree (DatumGetPointer (old_value ));
559
+ toast_values [i ] = new_value ;
560
+ toast_free [i ] = true;
561
+ toast_sizes [i ] = VARATT_SIZE (toast_values [i ]);
562
+ need_change = true;
563
+ need_free = true;
564
+ }
565
+ else
566
+ {
567
+ /* incompressible data, ignore on subsequent compression passes */
568
+ toast_action [i ] = 'x' ;
569
+ }
547
570
}
548
571
549
572
/* ----------
@@ -690,20 +713,33 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
690
713
* toast_compress_datum -
691
714
*
692
715
* Create a compressed version of a varlena datum
716
+ *
717
+ * If we fail (ie, compressed result is actually bigger than original)
718
+ * then return NULL. We must not use compressed data if it'd expand
719
+ * the tuple!
693
720
* ----------
694
721
*/
695
722
static Datum
696
723
toast_compress_datum (Datum value )
697
724
{
698
725
varattrib * tmp ;
699
726
700
- tmp = (varattrib * )palloc (sizeof (PGLZ_Header ) + VARATT_SIZE (value ));
727
+ tmp = (varattrib * ) palloc (sizeof (PGLZ_Header ) + VARATT_SIZE (value ));
701
728
pglz_compress (VARATT_DATA (value ), VARATT_SIZE (value ) - VARHDRSZ ,
702
- (PGLZ_Header * )tmp ,
703
- PGLZ_strategy_default );
704
- VARATT_SIZEP (tmp ) |= VARATT_FLAG_COMPRESSED ;
705
-
706
- return PointerGetDatum (tmp );
729
+ (PGLZ_Header * ) tmp ,
730
+ PGLZ_strategy_default );
731
+ if (VARATT_SIZE (tmp ) < VARATT_SIZE (value ))
732
+ {
733
+ /* successful compression */
734
+ VARATT_SIZEP (tmp ) |= VARATT_FLAG_COMPRESSED ;
735
+ return PointerGetDatum (tmp );
736
+ }
737
+ else
738
+ {
739
+ /* incompressible data */
740
+ pfree (tmp );
741
+ return PointerGetDatum (NULL );
742
+ }
707
743
}
708
744
709
745
0 commit comments