Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 82f3945

Browse files
Jan WieckJan Wieck
Jan Wieck
authored and
Jan Wieck
committed
Temporary fix to make TOAST vacuum-safe. All values are forced to be
in memory (plain or compressed) in the tuple returned from the heap-am. So no index will ever contain an external reference. Jan
1 parent 9e85183 commit 82f3945

File tree

3 files changed

+202
-7
lines changed

3 files changed

+202
-7
lines changed

src/backend/access/heap/heapam.c

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.79 2000/07/04 17:11:40 wieck Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.80 2000/07/21 10:31:30 wieck Exp $
1212
*
1313
*
1414
* INTERFACE ROUTINES
@@ -1274,6 +1274,10 @@ Oid
12741274
heap_insert(Relation relation, HeapTuple tup)
12751275
{
12761276
Buffer buffer;
1277+
#ifndef TOAST_INDICES
1278+
HeapTupleHeader plaintdata = NULL;
1279+
int32 plaintlen = 0;
1280+
#endif
12771281

12781282
/* increment access statistics */
12791283
tup->tableOid = relation->rd_id;
@@ -1309,7 +1313,11 @@ heap_insert(Relation relation, HeapTuple tup)
13091313
*/
13101314
if (HeapTupleHasExtended(tup) ||
13111315
(MAXALIGN(tup->t_len) > (MaxTupleSize / 4)))
1316+
#ifdef TOAST_INDICES
13121317
heap_tuple_toast_attrs(relation, tup, NULL);
1318+
#else
1319+
heap_tuple_toast_attrs(relation, tup, NULL, &plaintdata, &plaintlen);
1320+
#endif
13131321
#endif
13141322

13151323
/* Find buffer for this tuple */
@@ -1347,6 +1355,16 @@ heap_insert(Relation relation, HeapTuple tup)
13471355
if (IsSystemRelationName(RelationGetRelationName(relation)))
13481356
RelationMark4RollbackHeapTuple(relation, tup);
13491357

1358+
#ifndef TOAST_INDICES
1359+
if (plaintdata != NULL && tup->t_data != plaintdata)
1360+
{
1361+
if (tup->t_datamcxt != NULL && (char *) (tup->t_data) !=
1362+
((char *) tup + HEAPTUPLESIZE))
1363+
pfree(tup->t_data);
1364+
tup->t_data = plaintdata;
1365+
tup->t_len = plaintlen;
1366+
}
1367+
#endif
13501368
return tup->t_data->t_oid;
13511369
}
13521370

@@ -1461,7 +1479,11 @@ heap_delete(Relation relation, ItemPointer tid, ItemPointer ctid)
14611479
* ----------
14621480
*/
14631481
if (HeapTupleHasExtended(&tp))
1482+
#ifdef TOAST_INDICES
14641483
heap_tuple_toast_attrs(relation, NULL, &(tp));
1484+
#else
1485+
heap_tuple_toast_attrs(relation, NULL, &(tp), NULL, NULL);
1486+
#endif
14651487
#endif
14661488

14671489
LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
@@ -1486,6 +1508,10 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
14861508
PageHeader dp;
14871509
Buffer buffer, newbuf;
14881510
int result;
1511+
#ifndef TOAST_INDICES
1512+
HeapTupleHeader plaintdata = NULL;
1513+
int32 plaintlen = 0;
1514+
#endif
14891515

14901516
newtup->tableOid = relation->rd_id;
14911517
/* increment access statistics */
@@ -1574,7 +1600,11 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
15741600
if (HeapTupleHasExtended(&oldtup) ||
15751601
HeapTupleHasExtended(newtup) ||
15761602
(MAXALIGN(newtup->t_len) > (MaxTupleSize / 4)))
1603+
#ifdef TOAST_INDICES
15771604
heap_tuple_toast_attrs(relation, newtup, &oldtup);
1605+
#else
1606+
heap_tuple_toast_attrs(relation, newtup, &oldtup, &plaintdata, &plaintlen);
1607+
#endif
15781608
#endif
15791609

15801610
/* Find buffer for new tuple */
@@ -1637,6 +1667,17 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
16371667
RelationInvalidateHeapTuple(relation, &oldtup);
16381668
RelationMark4RollbackHeapTuple(relation, newtup);
16391669

1670+
#ifndef TOAST_INDICES
1671+
if (plaintdata != NULL && newtup->t_data != plaintdata)
1672+
{
1673+
if (newtup->t_datamcxt != NULL && (char *) (newtup->t_data) !=
1674+
((char *) newtup + HEAPTUPLESIZE))
1675+
pfree(newtup->t_data);
1676+
newtup->t_data = plaintdata;
1677+
newtup->t_len = plaintlen;
1678+
}
1679+
#endif
1680+
16401681
return HeapTupleMayBeUpdated;
16411682
}
16421683

src/backend/access/heap/tuptoaster.c

Lines changed: 145 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
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
@@ -43,8 +43,14 @@
4343

4444
static void toast_delete(Relation rel, HeapTuple oldtup);
4545
static void toast_delete_datum(Relation rel, Datum value);
46+
#ifdef TOAST_INDICES
4647
static 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
4854
static Datum toast_compress_datum(Datum value);
4955
static 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
6269
void
6370
heap_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
*/
183201
static void
202+
#ifdef TOAST_INDICES
184203
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
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

Comments
 (0)