8
8
*
9
9
*
10
10
* IDENTIFICATION
11
- * $Header: /cvsroot/pgsql/src/backend/access/heap/tuptoaster.c,v 1.7 2000/07/11 12:32:03 wieck Exp $
11
+ * $Header: /cvsroot/pgsql/src/backend/access/heap/tuptoaster.c,v 1.8 2000/07/21 10:31:30 wieck Exp $
12
12
*
13
13
*
14
14
* INTERFACE ROUTINES
43
43
44
44
static void toast_delete (Relation rel , HeapTuple oldtup );
45
45
static void toast_delete_datum (Relation rel , Datum value );
46
+ #ifdef TOAST_INDICES
46
47
static void toast_insert_or_update (Relation rel , HeapTuple newtup ,
47
48
HeapTuple oldtup );
49
+ #else
50
+ static void toast_insert_or_update (Relation rel , HeapTuple newtup ,
51
+ HeapTuple oldtup , HeapTupleHeader * plaintdata ,
52
+ int32 * plaintlen );
53
+ #endif
48
54
static Datum toast_compress_datum (Datum value );
49
55
static Datum toast_save_datum (Relation rel , Oid mainoid , int16 attno , Datum value );
50
56
@@ -59,6 +65,7 @@ static varattrib *toast_fetch_datum(varattrib *attr);
59
65
* Calls the appropriate event specific action.
60
66
* ----------
61
67
*/
68
+ #ifdef TOAST_INDICES
62
69
void
63
70
heap_tuple_toast_attrs (Relation rel , HeapTuple newtup , HeapTuple oldtup )
64
71
{
@@ -67,6 +74,17 @@ heap_tuple_toast_attrs(Relation rel, HeapTuple newtup, HeapTuple oldtup)
67
74
else
68
75
toast_insert_or_update (rel , newtup , oldtup );
69
76
}
77
+ #else
78
+ void
79
+ heap_tuple_toast_attrs (Relation rel , HeapTuple newtup ,
80
+ HeapTuple oldtup , HeapTupleHeader * plaintdata , int32 * plaintlen )
81
+ {
82
+ if (newtup == NULL )
83
+ toast_delete (rel , oldtup );
84
+ else
85
+ toast_insert_or_update (rel , newtup , oldtup , plaintdata , plaintlen );
86
+ }
87
+ #endif
70
88
71
89
72
90
/* ----------
@@ -181,7 +199,12 @@ toast_delete(Relation rel, HeapTuple oldtup)
181
199
* ----------
182
200
*/
183
201
static void
202
+ #ifdef TOAST_INDICES
184
203
toast_insert_or_update (Relation rel , HeapTuple newtup , HeapTuple oldtup )
204
+ #else
205
+ toast_insert_or_update (Relation rel , HeapTuple newtup , HeapTuple oldtup ,
206
+ HeapTupleHeader * plaintdata , int32 * plaintlen )
207
+ #endif
185
208
{
186
209
TupleDesc tupleDesc ;
187
210
Form_pg_attribute * att ;
@@ -204,6 +227,12 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
204
227
bool toast_free [MaxHeapAttributeNumber ];
205
228
bool toast_delold [MaxHeapAttributeNumber ];
206
229
230
+ #ifndef TOAST_INDICES
231
+ bool need_plain = false;
232
+ Datum toast_plains [MaxHeapAttributeNumber ];
233
+ bool toast_freeplain [MaxHeapAttributeNumber ];
234
+ #endif
235
+
207
236
/* ----------
208
237
* Get the tuple descriptor, the number of and attribute
209
238
* descriptors and the location of the tuple values.
@@ -217,10 +246,11 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
217
246
* Then collect information about the values given
218
247
* ----------
219
248
*/
220
- memset (toast_action , ' ' , numAttrs * sizeof (char ));
221
- memset (toast_nulls , ' ' , numAttrs * sizeof (char ));
222
- memset (toast_free , 0 , numAttrs * sizeof (bool ));
223
- memset (toast_delold , 0 , numAttrs * sizeof (bool ));
249
+ memset (toast_action , ' ' , numAttrs * sizeof (char ));
250
+ memset (toast_nulls , ' ' , numAttrs * sizeof (char ));
251
+ memset (toast_free , 0 , numAttrs * sizeof (bool ));
252
+ memset (toast_freeplain , 0 , numAttrs * sizeof (bool ));
253
+ memset (toast_delold , 0 , numAttrs * sizeof (bool ));
224
254
for (i = 0 ; i < numAttrs ; i ++ )
225
255
{
226
256
varattrib * old_value ;
@@ -270,6 +300,25 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
270
300
*/
271
301
toast_action [i ] = 'p' ;
272
302
toast_sizes [i ] = VARATT_SIZE (toast_values [i ]);
303
+
304
+ #ifndef TOAST_INDICES
305
+ /* ----------
306
+ * But the tuple returned by the heap-am
307
+ * function must not contain external references.
308
+ * So we have to construct another plain tuple
309
+ * later.
310
+ * ----------
311
+ */
312
+ if (att [i ]-> attstorage == 'x' || att [i ]-> attstorage == 'm' )
313
+ toast_plains [i ] = PointerGetDatum (
314
+ toast_fetch_datum (new_value ));
315
+ else
316
+ toast_plains [i ] = PointerGetDatum (
317
+ heap_tuple_untoast_attr (new_value ));
318
+ toast_freeplain [i ] = true;
319
+ need_plain = true;
320
+ #endif
321
+
273
322
continue ;
274
323
}
275
324
}
@@ -320,10 +369,17 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
320
369
{
321
370
toast_values [i ] = PointerGetDatum (heap_tuple_untoast_attr (
322
371
(varattrib * )DatumGetPointer (toast_values [i ])));
372
+ #ifndef TOAST_INDICES
373
+ toast_plains [i ] = toast_values [i ];
374
+ #endif
323
375
toast_free [i ] = true;
324
376
need_change = true;
325
377
need_free = true;
326
378
}
379
+ #ifndef TOAST_INDICES
380
+ else
381
+ toast_plains [i ] = toast_values [i ];
382
+ #endif
327
383
328
384
/* ----------
329
385
* Remember the size of this attribute
@@ -339,6 +395,9 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
339
395
*/
340
396
toast_action [i ] = 'p' ;
341
397
toast_sizes [i ] = att [i ]-> attlen ;
398
+ #ifndef TOAST_INDICES
399
+ toast_plains [i ] = toast_values [i ];
400
+ #endif
342
401
}
343
402
}
344
403
@@ -397,6 +456,9 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
397
456
old_value = toast_values [i ];
398
457
399
458
toast_values [i ] = toast_compress_datum (toast_values [i ]);
459
+ #ifndef TOAST_INDICES
460
+ toast_plains [i ] = toast_values [i ];
461
+ #endif
400
462
401
463
if (toast_free [i ])
402
464
pfree (DatumGetPointer (old_value ));
@@ -454,8 +516,14 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
454
516
newtup -> t_data -> t_oid ,
455
517
i + 1 ,
456
518
toast_values [i ]);
519
+ #ifndef TOAST_INDICES
520
+ need_plain = true;
521
+ if (toast_free [i ])
522
+ toast_freeplain [i ] = true;
523
+ #else
457
524
if (toast_free [i ])
458
525
pfree (DatumGetPointer (old_value ));
526
+ #endif
459
527
460
528
toast_free [i ] = true;
461
529
toast_sizes [i ] = VARATT_SIZE (toast_values [i ]);
@@ -506,6 +574,9 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
506
574
old_value = toast_values [i ];
507
575
508
576
toast_values [i ] = toast_compress_datum (toast_values [i ]);
577
+ #ifndef TOAST_INDICES
578
+ toast_plains [i ] = toast_values [i ];
579
+ #endif
509
580
510
581
if (toast_free [i ])
511
582
pfree (DatumGetPointer (old_value ));
@@ -562,8 +633,14 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
562
633
newtup -> t_data -> t_oid ,
563
634
i + 1 ,
564
635
toast_values [i ]);
636
+ #ifndef TOAST_INDICES
637
+ need_plain = true;
638
+ if (toast_free [i ])
639
+ toast_freeplain [i ] = true;
640
+ #else
565
641
if (toast_free [i ])
566
642
pfree (DatumGetPointer (old_value ));
643
+ #endif
567
644
568
645
toast_free [i ] = true;
569
646
toast_sizes [i ] = VARATT_SIZE (toast_values [i ]);
@@ -637,14 +714,77 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
637
714
}
638
715
639
716
717
+ #ifndef TOAST_INDICES
718
+ /* ----------
719
+ * In the case we toasted any values, we need to build
720
+ * a new heap tuple with the changed values.
721
+ * ----------
722
+ */
723
+ if (need_plain )
724
+ {
725
+ int32 new_len ;
726
+ MemoryContext oldcxt ;
727
+
728
+ /* ----------
729
+ * Calculate the new size of the tuple
730
+ * ----------
731
+ */
732
+ new_len = offsetof(HeapTupleHeaderData , t_bits );
733
+ if (has_nulls )
734
+ new_len += BITMAPLEN (numAttrs );
735
+ new_len = MAXALIGN (new_len );
736
+ new_len += ComputeDataSize (tupleDesc , toast_plains , toast_nulls );
737
+
738
+ /* ----------
739
+ * Switch to the memory context of the HeapTuple structure
740
+ * and allocate the new tuple.
741
+ * ----------
742
+ */
743
+ oldcxt = MemoryContextSwitchTo (newtup -> t_datamcxt );
744
+ * plaintdata = palloc (new_len );
745
+ * plaintlen = new_len ;
746
+
747
+ /* ----------
748
+ * Put the tuple header and the changed values into place
749
+ * ----------
750
+ */
751
+ memcpy (* plaintdata , newtup -> t_data , newtup -> t_data -> t_hoff );
752
+
753
+ DataFill ((char * )(MAXALIGN ((long )(* plaintdata ) +
754
+ offsetof(HeapTupleHeaderData , t_bits ) +
755
+ ((has_nulls ) ? BITMAPLEN (numAttrs ) : 0 ))),
756
+ tupleDesc ,
757
+ toast_plains ,
758
+ toast_nulls ,
759
+ & ((* plaintdata )-> t_infomask ),
760
+ has_nulls ? (* plaintdata )-> t_bits : NULL );
761
+
762
+ /* ----------
763
+ * Switch back to the old memory context
764
+ * ----------
765
+ */
766
+ MemoryContextSwitchTo (oldcxt );
767
+ }
768
+ #endif
769
+
770
+
640
771
/* ----------
641
772
* Free allocated temp values
642
773
* ----------
643
774
*/
644
775
if (need_free )
645
776
for (i = 0 ; i < numAttrs ; i ++ )
777
+ #ifndef TOAST_INDICES
778
+ {
779
+ if (toast_free [i ])
780
+ pfree (DatumGetPointer (toast_values [i ]));
781
+ if (toast_freeplain [i ])
782
+ pfree (DatumGetPointer (toast_plains [i ]));
783
+ }
784
+ #else
646
785
if (toast_free [i ])
647
786
pfree (DatumGetPointer (toast_values [i ]));
787
+ #endif
648
788
649
789
/* ----------
650
790
* Delete external values from the old tuple
0 commit comments