88 *
99 *
1010 * 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 $
1212 *
1313 *
1414 * INTERFACE ROUTINES
4343
4444static void toast_delete (Relation rel , HeapTuple oldtup );
4545static void toast_delete_datum (Relation rel , Datum value );
46+ #ifdef TOAST_INDICES
4647static void toast_insert_or_update (Relation rel , HeapTuple newtup ,
4748 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
4854static Datum toast_compress_datum (Datum value );
4955static Datum toast_save_datum (Relation rel , Oid mainoid , int16 attno , Datum value );
5056
@@ -59,6 +65,7 @@ static varattrib *toast_fetch_datum(varattrib *attr);
5965 * Calls the appropriate event specific action.
6066 * ----------
6167 */
68+ #ifdef TOAST_INDICES
6269void
6370heap_tuple_toast_attrs (Relation rel , HeapTuple newtup , HeapTuple oldtup )
6471{
@@ -67,6 +74,17 @@ heap_tuple_toast_attrs(Relation rel, HeapTuple newtup, HeapTuple oldtup)
6774 else
6875 toast_insert_or_update (rel , newtup , oldtup );
6976}
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
7088
7189
7290/* ----------
@@ -181,7 +199,12 @@ toast_delete(Relation rel, HeapTuple oldtup)
181199 * ----------
182200 */
183201static void
202+ #ifdef TOAST_INDICES
184203toast_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
185208{
186209 TupleDesc tupleDesc ;
187210 Form_pg_attribute * att ;
@@ -204,6 +227,12 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
204227 bool toast_free [MaxHeapAttributeNumber ];
205228 bool toast_delold [MaxHeapAttributeNumber ];
206229
230+ #ifndef TOAST_INDICES
231+ bool need_plain = false;
232+ Datum toast_plains [MaxHeapAttributeNumber ];
233+ bool toast_freeplain [MaxHeapAttributeNumber ];
234+ #endif
235+
207236 /* ----------
208237 * Get the tuple descriptor, the number of and attribute
209238 * descriptors and the location of the tuple values.
@@ -217,10 +246,11 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
217246 * Then collect information about the values given
218247 * ----------
219248 */
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 ));
224254 for (i = 0 ; i < numAttrs ; i ++ )
225255 {
226256 varattrib * old_value ;
@@ -270,6 +300,25 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
270300 */
271301 toast_action [i ] = 'p' ;
272302 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+
273322 continue ;
274323 }
275324 }
@@ -320,10 +369,17 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
320369 {
321370 toast_values [i ] = PointerGetDatum (heap_tuple_untoast_attr (
322371 (varattrib * )DatumGetPointer (toast_values [i ])));
372+ #ifndef TOAST_INDICES
373+ toast_plains [i ] = toast_values [i ];
374+ #endif
323375 toast_free [i ] = true;
324376 need_change = true;
325377 need_free = true;
326378 }
379+ #ifndef TOAST_INDICES
380+ else
381+ toast_plains [i ] = toast_values [i ];
382+ #endif
327383
328384 /* ----------
329385 * Remember the size of this attribute
@@ -339,6 +395,9 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
339395 */
340396 toast_action [i ] = 'p' ;
341397 toast_sizes [i ] = att [i ]-> attlen ;
398+ #ifndef TOAST_INDICES
399+ toast_plains [i ] = toast_values [i ];
400+ #endif
342401 }
343402 }
344403
@@ -397,6 +456,9 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
397456 old_value = toast_values [i ];
398457
399458 toast_values [i ] = toast_compress_datum (toast_values [i ]);
459+ #ifndef TOAST_INDICES
460+ toast_plains [i ] = toast_values [i ];
461+ #endif
400462
401463 if (toast_free [i ])
402464 pfree (DatumGetPointer (old_value ));
@@ -454,8 +516,14 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
454516 newtup -> t_data -> t_oid ,
455517 i + 1 ,
456518 toast_values [i ]);
519+ #ifndef TOAST_INDICES
520+ need_plain = true;
521+ if (toast_free [i ])
522+ toast_freeplain [i ] = true;
523+ #else
457524 if (toast_free [i ])
458525 pfree (DatumGetPointer (old_value ));
526+ #endif
459527
460528 toast_free [i ] = true;
461529 toast_sizes [i ] = VARATT_SIZE (toast_values [i ]);
@@ -506,6 +574,9 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
506574 old_value = toast_values [i ];
507575
508576 toast_values [i ] = toast_compress_datum (toast_values [i ]);
577+ #ifndef TOAST_INDICES
578+ toast_plains [i ] = toast_values [i ];
579+ #endif
509580
510581 if (toast_free [i ])
511582 pfree (DatumGetPointer (old_value ));
@@ -562,8 +633,14 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
562633 newtup -> t_data -> t_oid ,
563634 i + 1 ,
564635 toast_values [i ]);
636+ #ifndef TOAST_INDICES
637+ need_plain = true;
638+ if (toast_free [i ])
639+ toast_freeplain [i ] = true;
640+ #else
565641 if (toast_free [i ])
566642 pfree (DatumGetPointer (old_value ));
643+ #endif
567644
568645 toast_free [i ] = true;
569646 toast_sizes [i ] = VARATT_SIZE (toast_values [i ]);
@@ -637,14 +714,77 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
637714 }
638715
639716
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+
640771 /* ----------
641772 * Free allocated temp values
642773 * ----------
643774 */
644775 if (need_free )
645776 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
646785 if (toast_free [i ])
647786 pfree (DatumGetPointer (toast_values [i ]));
787+ #endif
648788
649789 /* ----------
650790 * Delete external values from the old tuple
0 commit comments