From 028e13bc08b52fad446a098a80a522d938beb06c Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Mon, 11 Feb 2002 22:41:59 +0000 Subject: [PATCH] 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. --- src/backend/access/gist/gist.c | 42 ++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/src/backend/access/gist/gist.c b/src/backend/access/gist/gist.c index db57a5f3ff..1ce1914304 100644 --- a/src/backend/access/gist/gist.c +++ b/src/backend/access/gist/gist.c @@ -8,7 +8,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/gist/gist.c,v 1.87 2002/01/15 22:14:16 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/gist/gist.c,v 1.88 2002/02/11 22:41:59 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -659,6 +659,7 @@ gistunion(Relation r, IndexTuple *itvec, int len, GISTSTATE *giststate) Datum attr[INDEX_MAX_KEYS]; bool whatfree[INDEX_MAX_KEYS]; char isnull[INDEX_MAX_KEYS]; + char *storage; bytea *evec; Datum datum; int datumsize, @@ -671,7 +672,9 @@ gistunion(Relation r, IndexTuple *itvec, int len, GISTSTATE *giststate) int reallen; needfree = (bool *) palloc(((len == 1) ? 2 : len) * sizeof(bool)); - evec = (bytea *) palloc(((len == 1) ? 2 : len) * sizeof(GISTENTRY) + VARHDRSZ); + /* workaround for 64-bit: ensure GISTENTRY array is maxaligned */ + storage = (char*)palloc( ((len == 1) ? 2 : len) * sizeof(GISTENTRY) + MAXALIGN(VARHDRSZ)); + evec = (bytea *) (storage + MAXALIGN(VARHDRSZ) - VARHDRSZ); for (j = 0; j < r->rd_att->natts; j++) { @@ -737,7 +740,7 @@ gistunion(Relation r, IndexTuple *itvec, int len, GISTSTATE *giststate) } } - pfree(evec); + pfree(storage); /* pfree(evec); */ pfree(needfree); newtup = (IndexTuple) index_formtuple(giststate->tupdesc, attr, isnull); @@ -772,11 +775,13 @@ gistgetadjusted(Relation r, IndexTuple oldtup, IndexTuple addtup, GISTSTATE *gis adddec[INDEX_MAX_KEYS]; bool oldisnull[INDEX_MAX_KEYS], addisnull[INDEX_MAX_KEYS]; - IndexTuple newtup = NULL; + char *storage; int j; - evec = (bytea *) palloc(2 * sizeof(GISTENTRY) + VARHDRSZ); + /* workaround for 64-bit: ensure GISTENTRY array is maxaligned */ + storage = (char*) palloc( 2 * sizeof(GISTENTRY) + MAXALIGN(VARHDRSZ)); + evec = (bytea *) (storage + MAXALIGN(VARHDRSZ) - VARHDRSZ); VARATT_SIZEP(evec) = 2 * sizeof(GISTENTRY) + VARHDRSZ; ev0p = &((GISTENTRY *) VARDATA(evec))[0]; ev1p = &((GISTENTRY *) VARDATA(evec))[1]; @@ -844,7 +849,7 @@ gistgetadjusted(Relation r, IndexTuple oldtup, IndexTuple addtup, GISTSTATE *gis whatfree[j] = FALSE; } } - pfree(evec); + pfree(storage); /* pfree(evec); */ if (neednew) { @@ -873,6 +878,7 @@ gistunionsubkey(Relation r, GISTSTATE *giststate, IndexTuple *itvec, GIST_SPLITV *attrsize; OffsetNumber *entries; bytea *evec; + char *storage; Datum datum; int datumsize; int reallen; @@ -898,7 +904,10 @@ gistunionsubkey(Relation r, GISTSTATE *giststate, IndexTuple *itvec, GIST_SPLITV } needfree = (bool *) palloc(((len == 1) ? 2 : len) * sizeof(bool)); - evec = (bytea *) palloc(((len == 1) ? 2 : len) * sizeof(GISTENTRY) + VARHDRSZ); + /* workaround for 64-bit: ensure GISTENTRY array is maxaligned */ + storage = (char*)palloc( ((len == 1) ? 2 : len) * sizeof(GISTENTRY) + MAXALIGN(VARHDRSZ)); + evec = (bytea *) (storage + MAXALIGN(VARHDRSZ) - VARHDRSZ); + for (j = 1; j < r->rd_att->natts; j++) { reallen = 0; @@ -958,7 +967,7 @@ gistunionsubkey(Relation r, GISTSTATE *giststate, IndexTuple *itvec, GIST_SPLITV attr[j] = datum; attrsize[j] = datumsize; } - pfree(evec); + pfree(storage); /* pfree(evec); */ pfree(needfree); } } @@ -1050,6 +1059,7 @@ gistadjsubkey(Relation r, float lpenalty, rpenalty; bytea *evec; + char *storage; int datumsize; bool isnull[INDEX_MAX_KEYS]; int i, @@ -1081,7 +1091,9 @@ gistadjsubkey(Relation r, curlen--; v->spl_nright = curlen; - evec = (bytea *) palloc(2 * sizeof(GISTENTRY) + VARHDRSZ); + /* workaround for 64-bit: ensure GISTENTRY array is maxaligned */ + storage = (char*)palloc( 2 * sizeof(GISTENTRY) + MAXALIGN(VARHDRSZ)); + evec = (bytea *) (storage + MAXALIGN(VARHDRSZ) - VARHDRSZ); VARATT_SIZEP(evec) = 2 * sizeof(GISTENTRY) + VARHDRSZ; ev0p = &((GISTENTRY *) VARDATA(evec))[0]; ev1p = &((GISTENTRY *) VARDATA(evec))[1]; @@ -1189,7 +1201,7 @@ gistadjsubkey(Relation r, } gistFreeAtt(r, identry, decfree); } - pfree(evec); + pfree(storage); /* pfree(evec); */ } /* @@ -1216,6 +1228,7 @@ gistSplit(Relation r, GISTPageOpaque opaque; GIST_SPLITVEC v; bytea *entryvec; + char *storage; bool *decompvec; int i, j, @@ -1227,7 +1240,6 @@ gistSplit(Relation r, p = (Page) BufferGetPage(buffer); opaque = (GISTPageOpaque) PageGetSpecialPointer(p); - /* * The root of the tree is the first block in the relation. If we're * about to split the root, we need to do some hocus-pocus to enforce @@ -1255,8 +1267,10 @@ gistSplit(Relation r, right = (Page) BufferGetPage(rightbuf); /* generate the item array */ - entryvec = (bytea *) palloc(VARHDRSZ + (*len + 1) * sizeof(GISTENTRY)); - decompvec = (bool *) palloc(VARHDRSZ + (*len + 1) * sizeof(bool)); + /* workaround for 64-bit: ensure GISTENTRY array is maxaligned */ + storage = palloc(MAXALIGN(VARHDRSZ) + (*len + 1) * sizeof(GISTENTRY)); + entryvec = (bytea *) (storage + MAXALIGN(VARHDRSZ) - VARHDRSZ); + decompvec = (bool *) palloc( (*len + 1) * sizeof(bool)); VARATT_SIZEP(entryvec) = (*len + 1) * sizeof(GISTENTRY) + VARHDRSZ; for (i = 1; i <= *len; i++) { @@ -1322,7 +1336,7 @@ gistSplit(Relation r, for (i = 1; i <= *len; i++) if (decompvec[i]) pfree(DatumGetPointer(((GISTENTRY *) VARDATA(entryvec))[i].key)); - pfree(entryvec); + pfree(storage); /* pfree(entryvec); */ pfree(decompvec); /* form left and right vector */