Skip to content

Commit 028e13b

Browse files
committed
Tweak GiST code to work correctly on machines where 8-byte alignment
of pointers is required. Patch from Teodor Sigaev per pghackers discussion. It's an ugly kluge but avoids forcing initdb; we'll put a better fix into 7.3 or later.
1 parent 2bd15ad commit 028e13b

File tree

1 file changed

+28
-14
lines changed

1 file changed

+28
-14
lines changed

src/backend/access/gist/gist.c

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/access/gist/gist.c,v 1.87 2002/01/15 22:14:16 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/access/gist/gist.c,v 1.88 2002/02/11 22:41:59 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -659,6 +659,7 @@ gistunion(Relation r, IndexTuple *itvec, int len, GISTSTATE *giststate)
659659
Datum attr[INDEX_MAX_KEYS];
660660
bool whatfree[INDEX_MAX_KEYS];
661661
char isnull[INDEX_MAX_KEYS];
662+
char *storage;
662663
bytea *evec;
663664
Datum datum;
664665
int datumsize,
@@ -671,7 +672,9 @@ gistunion(Relation r, IndexTuple *itvec, int len, GISTSTATE *giststate)
671672
int reallen;
672673

673674
needfree = (bool *) palloc(((len == 1) ? 2 : len) * sizeof(bool));
674-
evec = (bytea *) palloc(((len == 1) ? 2 : len) * sizeof(GISTENTRY) + VARHDRSZ);
675+
/* workaround for 64-bit: ensure GISTENTRY array is maxaligned */
676+
storage = (char*)palloc( ((len == 1) ? 2 : len) * sizeof(GISTENTRY) + MAXALIGN(VARHDRSZ));
677+
evec = (bytea *) (storage + MAXALIGN(VARHDRSZ) - VARHDRSZ);
675678

676679
for (j = 0; j < r->rd_att->natts; j++)
677680
{
@@ -737,7 +740,7 @@ gistunion(Relation r, IndexTuple *itvec, int len, GISTSTATE *giststate)
737740
}
738741
}
739742

740-
pfree(evec);
743+
pfree(storage); /* pfree(evec); */
741744
pfree(needfree);
742745

743746
newtup = (IndexTuple) index_formtuple(giststate->tupdesc, attr, isnull);
@@ -772,11 +775,13 @@ gistgetadjusted(Relation r, IndexTuple oldtup, IndexTuple addtup, GISTSTATE *gis
772775
adddec[INDEX_MAX_KEYS];
773776
bool oldisnull[INDEX_MAX_KEYS],
774777
addisnull[INDEX_MAX_KEYS];
775-
776778
IndexTuple newtup = NULL;
779+
char *storage;
777780
int j;
778781

779-
evec = (bytea *) palloc(2 * sizeof(GISTENTRY) + VARHDRSZ);
782+
/* workaround for 64-bit: ensure GISTENTRY array is maxaligned */
783+
storage = (char*) palloc( 2 * sizeof(GISTENTRY) + MAXALIGN(VARHDRSZ));
784+
evec = (bytea *) (storage + MAXALIGN(VARHDRSZ) - VARHDRSZ);
780785
VARATT_SIZEP(evec) = 2 * sizeof(GISTENTRY) + VARHDRSZ;
781786
ev0p = &((GISTENTRY *) VARDATA(evec))[0];
782787
ev1p = &((GISTENTRY *) VARDATA(evec))[1];
@@ -844,7 +849,7 @@ gistgetadjusted(Relation r, IndexTuple oldtup, IndexTuple addtup, GISTSTATE *gis
844849
whatfree[j] = FALSE;
845850
}
846851
}
847-
pfree(evec);
852+
pfree(storage); /* pfree(evec); */
848853

849854
if (neednew)
850855
{
@@ -873,6 +878,7 @@ gistunionsubkey(Relation r, GISTSTATE *giststate, IndexTuple *itvec, GIST_SPLITV
873878
*attrsize;
874879
OffsetNumber *entries;
875880
bytea *evec;
881+
char *storage;
876882
Datum datum;
877883
int datumsize;
878884
int reallen;
@@ -898,7 +904,10 @@ gistunionsubkey(Relation r, GISTSTATE *giststate, IndexTuple *itvec, GIST_SPLITV
898904
}
899905

900906
needfree = (bool *) palloc(((len == 1) ? 2 : len) * sizeof(bool));
901-
evec = (bytea *) palloc(((len == 1) ? 2 : len) * sizeof(GISTENTRY) + VARHDRSZ);
907+
/* workaround for 64-bit: ensure GISTENTRY array is maxaligned */
908+
storage = (char*)palloc( ((len == 1) ? 2 : len) * sizeof(GISTENTRY) + MAXALIGN(VARHDRSZ));
909+
evec = (bytea *) (storage + MAXALIGN(VARHDRSZ) - VARHDRSZ);
910+
902911
for (j = 1; j < r->rd_att->natts; j++)
903912
{
904913
reallen = 0;
@@ -958,7 +967,7 @@ gistunionsubkey(Relation r, GISTSTATE *giststate, IndexTuple *itvec, GIST_SPLITV
958967
attr[j] = datum;
959968
attrsize[j] = datumsize;
960969
}
961-
pfree(evec);
970+
pfree(storage); /* pfree(evec); */
962971
pfree(needfree);
963972
}
964973
}
@@ -1050,6 +1059,7 @@ gistadjsubkey(Relation r,
10501059
float lpenalty,
10511060
rpenalty;
10521061
bytea *evec;
1062+
char *storage;
10531063
int datumsize;
10541064
bool isnull[INDEX_MAX_KEYS];
10551065
int i,
@@ -1081,7 +1091,9 @@ gistadjsubkey(Relation r,
10811091
curlen--;
10821092
v->spl_nright = curlen;
10831093

1084-
evec = (bytea *) palloc(2 * sizeof(GISTENTRY) + VARHDRSZ);
1094+
/* workaround for 64-bit: ensure GISTENTRY array is maxaligned */
1095+
storage = (char*)palloc( 2 * sizeof(GISTENTRY) + MAXALIGN(VARHDRSZ));
1096+
evec = (bytea *) (storage + MAXALIGN(VARHDRSZ) - VARHDRSZ);
10851097
VARATT_SIZEP(evec) = 2 * sizeof(GISTENTRY) + VARHDRSZ;
10861098
ev0p = &((GISTENTRY *) VARDATA(evec))[0];
10871099
ev1p = &((GISTENTRY *) VARDATA(evec))[1];
@@ -1189,7 +1201,7 @@ gistadjsubkey(Relation r,
11891201
}
11901202
gistFreeAtt(r, identry, decfree);
11911203
}
1192-
pfree(evec);
1204+
pfree(storage); /* pfree(evec); */
11931205
}
11941206

11951207
/*
@@ -1216,6 +1228,7 @@ gistSplit(Relation r,
12161228
GISTPageOpaque opaque;
12171229
GIST_SPLITVEC v;
12181230
bytea *entryvec;
1231+
char *storage;
12191232
bool *decompvec;
12201233
int i,
12211234
j,
@@ -1227,7 +1240,6 @@ gistSplit(Relation r,
12271240
p = (Page) BufferGetPage(buffer);
12281241
opaque = (GISTPageOpaque) PageGetSpecialPointer(p);
12291242

1230-
12311243
/*
12321244
* The root of the tree is the first block in the relation. If we're
12331245
* about to split the root, we need to do some hocus-pocus to enforce
@@ -1255,8 +1267,10 @@ gistSplit(Relation r,
12551267
right = (Page) BufferGetPage(rightbuf);
12561268

12571269
/* generate the item array */
1258-
entryvec = (bytea *) palloc(VARHDRSZ + (*len + 1) * sizeof(GISTENTRY));
1259-
decompvec = (bool *) palloc(VARHDRSZ + (*len + 1) * sizeof(bool));
1270+
/* workaround for 64-bit: ensure GISTENTRY array is maxaligned */
1271+
storage = palloc(MAXALIGN(VARHDRSZ) + (*len + 1) * sizeof(GISTENTRY));
1272+
entryvec = (bytea *) (storage + MAXALIGN(VARHDRSZ) - VARHDRSZ);
1273+
decompvec = (bool *) palloc( (*len + 1) * sizeof(bool));
12601274
VARATT_SIZEP(entryvec) = (*len + 1) * sizeof(GISTENTRY) + VARHDRSZ;
12611275
for (i = 1; i <= *len; i++)
12621276
{
@@ -1322,7 +1336,7 @@ gistSplit(Relation r,
13221336
for (i = 1; i <= *len; i++)
13231337
if (decompvec[i])
13241338
pfree(DatumGetPointer(((GISTENTRY *) VARDATA(entryvec))[i].key));
1325-
pfree(entryvec);
1339+
pfree(storage); /* pfree(entryvec); */
13261340
pfree(decompvec);
13271341

13281342
/* form left and right vector */

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