mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-10-03 02:56:52 +02:00
Avoid assuming that struct varattrib_pointer doesn't get padded by the
compiler --- at least on ARM, it does. I suspect that the varvarlena patch has been creating larger-than-intended toast pointers all along on ARM, but it wasn't exposed until the latest tweak added some Asserts that calculated the expected size in a different way. We could probably have fixed this by adding __attribute__((packed)) as is done for ItemPointerData, but struct varattrib_pointer isn't really all that useful anyway, so it seems cleanest to just get rid of it and have only struct varattrib_1b_e. Per results from buildfarm member quagga.
This commit is contained in:
parent
b8ce3d3494
commit
b526462f9e
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/access/heap/tuptoaster.c,v 1.76 2007/09/30 19:54:58 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/access/heap/tuptoaster.c,v 1.77 2007/10/01 16:25:56 tgl Exp $
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* INTERFACE ROUTINES
|
* INTERFACE ROUTINES
|
||||||
@ -42,6 +42,9 @@
|
|||||||
|
|
||||||
#undef TOAST_DEBUG
|
#undef TOAST_DEBUG
|
||||||
|
|
||||||
|
/* Size of an EXTERNAL datum that contains a standard TOAST pointer */
|
||||||
|
#define TOAST_POINTER_SIZE (VARHDRSZ_EXTERNAL + sizeof(struct varatt_external))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Testing whether an externally-stored value is compressed now requires
|
* Testing whether an externally-stored value is compressed now requires
|
||||||
* comparing extsize (the actual length of the external data) to rawsize
|
* comparing extsize (the actual length of the external data) to rawsize
|
||||||
@ -597,7 +600,7 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup,
|
|||||||
toast_values, toast_isnull) > maxDataLen)
|
toast_values, toast_isnull) > maxDataLen)
|
||||||
{
|
{
|
||||||
int biggest_attno = -1;
|
int biggest_attno = -1;
|
||||||
int32 biggest_size = MAXALIGN(sizeof(varattrib_pointer));
|
int32 biggest_size = MAXALIGN(TOAST_POINTER_SIZE);
|
||||||
Datum old_value;
|
Datum old_value;
|
||||||
Datum new_value;
|
Datum new_value;
|
||||||
|
|
||||||
@ -660,7 +663,7 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup,
|
|||||||
rel->rd_rel->reltoastrelid != InvalidOid)
|
rel->rd_rel->reltoastrelid != InvalidOid)
|
||||||
{
|
{
|
||||||
int biggest_attno = -1;
|
int biggest_attno = -1;
|
||||||
int32 biggest_size = MAXALIGN(sizeof(varattrib_pointer));
|
int32 biggest_size = MAXALIGN(TOAST_POINTER_SIZE);
|
||||||
Datum old_value;
|
Datum old_value;
|
||||||
|
|
||||||
/*------
|
/*------
|
||||||
@ -710,7 +713,7 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup,
|
|||||||
toast_values, toast_isnull) > maxDataLen)
|
toast_values, toast_isnull) > maxDataLen)
|
||||||
{
|
{
|
||||||
int biggest_attno = -1;
|
int biggest_attno = -1;
|
||||||
int32 biggest_size = MAXALIGN(sizeof(varattrib_pointer));
|
int32 biggest_size = MAXALIGN(TOAST_POINTER_SIZE);
|
||||||
Datum old_value;
|
Datum old_value;
|
||||||
Datum new_value;
|
Datum new_value;
|
||||||
|
|
||||||
@ -772,7 +775,7 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup,
|
|||||||
rel->rd_rel->reltoastrelid != InvalidOid)
|
rel->rd_rel->reltoastrelid != InvalidOid)
|
||||||
{
|
{
|
||||||
int biggest_attno = -1;
|
int biggest_attno = -1;
|
||||||
int32 biggest_size = MAXALIGN(sizeof(varattrib_pointer));
|
int32 biggest_size = MAXALIGN(TOAST_POINTER_SIZE);
|
||||||
Datum old_value;
|
Datum old_value;
|
||||||
|
|
||||||
/*--------
|
/*--------
|
||||||
@ -1085,7 +1088,7 @@ toast_save_datum(Relation rel, Datum value,
|
|||||||
Datum t_values[3];
|
Datum t_values[3];
|
||||||
bool t_isnull[3];
|
bool t_isnull[3];
|
||||||
CommandId mycid = GetCurrentCommandId();
|
CommandId mycid = GetCurrentCommandId();
|
||||||
varattrib_pointer *result;
|
struct varlena *result;
|
||||||
struct varatt_external toast_pointer;
|
struct varatt_external toast_pointer;
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
@ -1206,8 +1209,8 @@ toast_save_datum(Relation rel, Datum value,
|
|||||||
/*
|
/*
|
||||||
* Create the TOAST pointer value that we'll return
|
* Create the TOAST pointer value that we'll return
|
||||||
*/
|
*/
|
||||||
result = (varattrib_pointer *) palloc(sizeof(varattrib_pointer));
|
result = (struct varlena *) palloc(TOAST_POINTER_SIZE);
|
||||||
SET_VARSIZE_EXTERNAL(result, sizeof(varattrib_pointer));
|
SET_VARSIZE_EXTERNAL(result, TOAST_POINTER_SIZE);
|
||||||
memcpy(VARDATA_EXTERNAL(result), &toast_pointer, sizeof(toast_pointer));
|
memcpy(VARDATA_EXTERNAL(result), &toast_pointer, sizeof(toast_pointer));
|
||||||
|
|
||||||
return PointerGetDatum(result);
|
return PointerGetDatum(result);
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1995, Regents of the University of California
|
* Portions Copyright (c) 1995, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/postgres.h,v 1.84 2007/09/30 19:54:58 tgl Exp $
|
* $PostgreSQL: pgsql/src/include/postgres.h,v 1.85 2007/10/01 16:25:56 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -110,13 +110,6 @@ typedef struct
|
|||||||
char va_data[1]; /* Data (for now always a TOAST pointer) */
|
char va_data[1]; /* Data (for now always a TOAST pointer) */
|
||||||
} varattrib_1b_e;
|
} varattrib_1b_e;
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint8 va_header; /* Always 0x80 or 0x01 */
|
|
||||||
uint8 va_len_1be; /* Physical length of datum */
|
|
||||||
char va_data[sizeof(struct varatt_external)];
|
|
||||||
} varattrib_pointer;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Bit layouts for varlena headers on big-endian machines:
|
* Bit layouts for varlena headers on big-endian machines:
|
||||||
*
|
*
|
||||||
@ -225,6 +218,8 @@ typedef struct
|
|||||||
#define VARATT_CONVERTED_SHORT_SIZE(PTR) \
|
#define VARATT_CONVERTED_SHORT_SIZE(PTR) \
|
||||||
(VARSIZE(PTR) - VARHDRSZ + VARHDRSZ_SHORT)
|
(VARSIZE(PTR) - VARHDRSZ + VARHDRSZ_SHORT)
|
||||||
|
|
||||||
|
#define VARHDRSZ_EXTERNAL 2
|
||||||
|
|
||||||
#define VARDATA_4B(PTR) (((varattrib_4b *) (PTR))->va_4byte.va_data)
|
#define VARDATA_4B(PTR) (((varattrib_4b *) (PTR))->va_4byte.va_data)
|
||||||
#define VARDATA_4B_C(PTR) (((varattrib_4b *) (PTR))->va_compressed.va_data)
|
#define VARDATA_4B_C(PTR) (((varattrib_4b *) (PTR))->va_compressed.va_data)
|
||||||
#define VARDATA_1B(PTR) (((varattrib_1b *) (PTR))->va_data)
|
#define VARDATA_1B(PTR) (((varattrib_1b *) (PTR))->va_data)
|
||||||
@ -276,9 +271,9 @@ typedef struct
|
|||||||
VARSIZE_4B(PTR)))
|
VARSIZE_4B(PTR)))
|
||||||
|
|
||||||
#define VARSIZE_ANY_EXHDR(PTR) \
|
#define VARSIZE_ANY_EXHDR(PTR) \
|
||||||
(VARATT_IS_1B_E(PTR) ? VARSIZE_1B_E(PTR)-2 : \
|
(VARATT_IS_1B_E(PTR) ? VARSIZE_1B_E(PTR)-VARHDRSZ_EXTERNAL : \
|
||||||
(VARATT_IS_1B(PTR) ? VARSIZE_1B(PTR)-1 : \
|
(VARATT_IS_1B(PTR) ? VARSIZE_1B(PTR)-VARHDRSZ_SHORT : \
|
||||||
VARSIZE_4B(PTR)-4))
|
VARSIZE_4B(PTR)-VARHDRSZ))
|
||||||
|
|
||||||
/* caution: this will not work on an external or compressed-in-line Datum */
|
/* caution: this will not work on an external or compressed-in-line Datum */
|
||||||
/* caution: this will return a possibly unaligned pointer */
|
/* caution: this will return a possibly unaligned pointer */
|
||||||
|
Loading…
Reference in New Issue
Block a user