Fix getDatumCopy(): don't use store_att_byval to copy into a Datum
variable (this accounts for regression failures on PPC64, and in fact won't work on any big-endian machine). Get rid of hardwired knowledge about datum size rules; make it look just like datumCopy().
This commit is contained in:
parent
e040ab44e4
commit
c36418be40
@ -8,12 +8,15 @@
|
|||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/access/gin/ginbulk.c,v 1.3 2006/07/14 14:52:16 momjian Exp $
|
* $PostgreSQL: pgsql/src/backend/access/gin/ginbulk.c,v 1.4 2006/07/16 00:54:22 tgl Exp $
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
#include "access/gin.h"
|
#include "access/gin.h"
|
||||||
|
#include "utils/datum.h"
|
||||||
|
|
||||||
|
|
||||||
#define DEF_NENTRY 2048
|
#define DEF_NENTRY 2048
|
||||||
#define DEF_NPTR 4
|
#define DEF_NPTR 4
|
||||||
@ -66,37 +69,31 @@ ginInsertData(BuildAccumulator *accum, EntryAccumulator *entry, ItemPointer heap
|
|||||||
entry->number++;
|
entry->number++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is basically the same as datumCopy(), but we duplicate some code
|
||||||
|
* to avoid computing the datum size twice.
|
||||||
|
*/
|
||||||
static Datum
|
static Datum
|
||||||
getDatumCopy(BuildAccumulator *accum, Datum value) {
|
getDatumCopy(BuildAccumulator *accum, Datum value) {
|
||||||
Form_pg_attribute *att = accum->ginstate->tupdesc->attrs;
|
Form_pg_attribute *att = accum->ginstate->tupdesc->attrs;
|
||||||
Datum newvalue;
|
Datum res;
|
||||||
int data_length = 0;
|
|
||||||
void *ptr;
|
|
||||||
|
|
||||||
if ( att[0]->attbyval ) {
|
if (att[0]->attbyval)
|
||||||
store_att_byval(&newvalue, value, att[0]->attlen);
|
res = value;
|
||||||
} else {
|
else
|
||||||
/* pass-by-reference */
|
{
|
||||||
if (att[0]->attlen == -1) {
|
Size realSize;
|
||||||
/* varlena */
|
char *s;
|
||||||
data_length = VARATT_SIZE(DatumGetPointer(value));
|
|
||||||
} else if (att[0]->attlen == -2) {
|
realSize = datumGetSize(value, false, att[0]->attlen);
|
||||||
/* c-string */
|
|
||||||
data_length = strlen(DatumGetCString(value)) + 1;
|
s = (char *) palloc(realSize);
|
||||||
} else {
|
memcpy(s, DatumGetPointer(value), realSize);
|
||||||
/* fixed-length pass-by-reference */
|
res = PointerGetDatum(s);
|
||||||
Assert(att[0]->attlen > 0);
|
|
||||||
data_length = att[0]->attlen;
|
accum->allocatedMemory += realSize;
|
||||||
}
|
}
|
||||||
|
return res;
|
||||||
ptr = palloc( data_length );
|
|
||||||
memcpy(ptr, DatumGetPointer(value), data_length);
|
|
||||||
newvalue = PointerGetDatum(ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
accum->allocatedMemory+=data_length;
|
|
||||||
|
|
||||||
return newvalue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user