Skip to content

Commit 82f3945

Browse files
Jan WieckJan Wieck
authored andcommitted
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy