Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit2a6c032

Browse files
committed
Repair CLUSTER failure after ALTER TABLE SET WITHOUT OIDS. Turns out
there are corner cases involving dropping toasted columns in which theprevious coding would fail, too: the new version of the table might nothave any TOAST table, but we'd still propagate possibly-wide values ofdropped columns forward.
1 parent4f82112 commit2a6c032

File tree

1 file changed

+62
-11
lines changed

1 file changed

+62
-11
lines changed

‎src/backend/commands/cluster.c

Lines changed: 62 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
*
1212
*
1313
* IDENTIFICATION
14-
* $PostgreSQL: pgsql/src/backend/commands/cluster.c,v 1.131 2004/12/31 21:59:41 pgsql Exp $
14+
* $PostgreSQL: pgsql/src/backend/commands/cluster.c,v 1.132 2005/02/06 20:19:08 tgl Exp $
1515
*
1616
*-------------------------------------------------------------------------
1717
*/
@@ -605,32 +605,80 @@ copy_heap_data(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex)
605605
RelationNewHeap,
606606
OldHeap,
607607
OldIndex;
608+
TupleDescoldTupDesc;
609+
TupleDescnewTupDesc;
610+
intnatts;
611+
Datum*values;
612+
char*nulls;
608613
IndexScanDescscan;
609614
HeapTupletuple;
610615

611616
/*
612-
* Open the relations I need. Scan through the OldHeap on the OldIndex
613-
* and insert each tuple into the NewHeap.
617+
* Open the relations we need.
614618
*/
615619
NewHeap=heap_open(OIDNewHeap,AccessExclusiveLock);
616620
OldHeap=heap_open(OIDOldHeap,AccessExclusiveLock);
617621
OldIndex=index_open(OIDOldIndex);
618622

623+
/*
624+
* Their tuple descriptors should be exactly alike, but here we only
625+
* need assume that they have the same number of columns.
626+
*/
627+
oldTupDesc=RelationGetDescr(OldHeap);
628+
newTupDesc=RelationGetDescr(NewHeap);
629+
Assert(newTupDesc->natts==oldTupDesc->natts);
630+
631+
/* Preallocate values/nulls arrays */
632+
natts=newTupDesc->natts;
633+
values= (Datum*)palloc0(natts*sizeof(Datum));
634+
nulls= (char*)palloc(natts*sizeof(char));
635+
memset(nulls,'n',natts*sizeof(char));
636+
637+
/*
638+
* Scan through the OldHeap on the OldIndex and copy each tuple into the
639+
* NewHeap.
640+
*/
619641
scan=index_beginscan(OldHeap,OldIndex,SnapshotNow,0, (ScanKey)NULL);
620642

621643
while ((tuple=index_getnext(scan,ForwardScanDirection))!=NULL)
622644
{
623645
/*
624-
* We must copy the tuple because heap_insert() will overwrite the
625-
* commit-status fields of the tuple it's handed, and the
626-
* retrieved tuple will actually be in a disk buffer! Thus, the
627-
* source relation would get trashed, which is bad news if we
628-
* abort later on.(This was a bug in releases thru 7.0)
646+
* We cannot simply pass the tuple to heap_insert(), for several
647+
* reasons:
648+
*
649+
* 1. heap_insert() will overwrite the commit-status fields of the
650+
* tuple it's handed. This would trash the source relation, which is
651+
* bad news if we abort later on. (This was a bug in releases thru
652+
* 7.0)
653+
*
654+
* 2. We'd like to squeeze out the values of any dropped columns,
655+
* both to save space and to ensure we have no corner-case failures.
656+
* (It's possible for example that the new table hasn't got a TOAST
657+
* table and so is unable to store any large values of dropped cols.)
629658
*
630-
* Note that the copied tuple will have the original OID, if any, so
631-
* this does preserve OIDs.
659+
* 3. The tuple might not even be legal for the new table; this is
660+
* currently only known to happen as an after-effect of ALTER TABLE
661+
* SET WITHOUT OIDS.
662+
*
663+
* So, we must reconstruct the tuple from component Datums.
632664
*/
633-
HeapTuplecopiedTuple=heap_copytuple(tuple);
665+
HeapTuplecopiedTuple;
666+
inti;
667+
668+
heap_deformtuple(tuple,oldTupDesc,values,nulls);
669+
670+
/* Be sure to null out any dropped columns */
671+
for (i=0;i<natts;i++)
672+
{
673+
if (newTupDesc->attrs[i]->attisdropped)
674+
nulls[i]='n';
675+
}
676+
677+
copiedTuple=heap_formtuple(newTupDesc,values,nulls);
678+
679+
/* Preserve OID, if any */
680+
if (NewHeap->rd_rel->relhasoids)
681+
HeapTupleSetOid(copiedTuple,HeapTupleGetOid(tuple));
634682

635683
simple_heap_insert(NewHeap,copiedTuple);
636684

@@ -641,6 +689,9 @@ copy_heap_data(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex)
641689

642690
index_endscan(scan);
643691

692+
pfree(values);
693+
pfree(nulls);
694+
644695
index_close(OldIndex);
645696
heap_close(OldHeap,NoLock);
646697
heap_close(NewHeap,NoLock);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp