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 ,
4748HeapTuple 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)
6774else
6875toast_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{
186209TupleDesc tupleDesc ;
187210Form_pg_attribute * att ;
@@ -204,6 +227,12 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
204227bool toast_free [MaxHeapAttributeNumber ];
205228bool 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 ));
224254for (i = 0 ;i < numAttrs ;i ++ )
225255{
226256varattrib * old_value ;
@@ -270,6 +300,25 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
270300 */
271301toast_action [i ]= 'p' ;
272302toast_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+
273322continue ;
274323}
275324}
@@ -320,10 +369,17 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
320369{
321370toast_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
323375toast_free [i ]= true;
324376need_change = true;
325377need_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 */
340396toast_action [i ]= 'p' ;
341397toast_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)
397456old_value = toast_values [i ];
398457
399458toast_values [i ]= toast_compress_datum (toast_values [i ]);
459+ #ifndef TOAST_INDICES
460+ toast_plains [i ]= toast_values [i ];
461+ #endif
400462
401463if (toast_free [i ])
402464pfree (DatumGetPointer (old_value ));
@@ -454,8 +516,14 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
454516newtup -> t_data -> t_oid ,
455517i + 1 ,
456518toast_values [i ]);
519+ #ifndef TOAST_INDICES
520+ need_plain = true;
521+ if (toast_free [i ])
522+ toast_freeplain [i ]= true;
523+ #else
457524if (toast_free [i ])
458525pfree (DatumGetPointer (old_value ));
526+ #endif
459527
460528toast_free [i ]= true;
461529toast_sizes [i ]= VARATT_SIZE (toast_values [i ]);
@@ -506,6 +574,9 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
506574old_value = toast_values [i ];
507575
508576toast_values [i ]= toast_compress_datum (toast_values [i ]);
577+ #ifndef TOAST_INDICES
578+ toast_plains [i ]= toast_values [i ];
579+ #endif
509580
510581if (toast_free [i ])
511582pfree (DatumGetPointer (old_value ));
@@ -562,8 +633,14 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
562633newtup -> t_data -> t_oid ,
563634i + 1 ,
564635toast_values [i ]);
636+ #ifndef TOAST_INDICES
637+ need_plain = true;
638+ if (toast_free [i ])
639+ toast_freeplain [i ]= true;
640+ #else
565641if (toast_free [i ])
566642pfree (DatumGetPointer (old_value ));
643+ #endif
567644
568645toast_free [i ]= true;
569646toast_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 */
644775if (need_free )
645776for (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
646785if (toast_free [i ])
647786pfree (DatumGetPointer (toast_values [i ]));
787+ #endif
648788
649789/* ----------
650790 * Delete external values from the old tuple