Make type Datum be 8 bytes wide everywhere.

This patch makes sizeof(Datum) be 8 on all platforms including
32-bit ones.  The objective is to allow USE_FLOAT8_BYVAL to be true
everywhere, and in consequence to remove a lot of code that is
specific to pass-by-reference handling of float8, int8, etc.  The
code for abbreviated sort keys can be simplified similarly.  In this
way we can reduce the maintenance effort involved in supporting 32-bit
platforms, without going so far as to actually desupport them.  Since
Datum is strictly an in-memory concept, this has no impact on on-disk
storage, though an initdb or pg_upgrade will be needed to fix affected
catalog entries.

We have required platforms to support [u]int64 for ages, so this
breaks no supported platform.  We can expect that this change will
make 32-bit builds a bit slower and more memory-hungry, although being
able to use pass-by-value handling of 8-byte types may buy back some
of that.  But we stopped optimizing for 32-bit cases a long time ago,
and this seems like just another step on that path.

This initial patch simply forces the correct type definition and
USE_FLOAT8_BYVAL setting, and cleans up a couple of minor compiler
complaints that ensued.  This is sufficient for testing purposes.
In the wake of a bunch of Datum-conversion cleanups by Peter
Eisentraut, this now compiles cleanly with gcc on a 32-bit platform.
(I'd only tested the previous version with clang, which it turns out
is less picky than gcc about width-changing coercions.)

There is a good deal of now-dead code that I'll remove in separate
follow-up patches.

A catversion bump is required because this affects initial catalog
contents (on 32-bit machines) in two ways: pg_type.typbyval changes
for some built-in types, and Const nodes in stored views/rules will
now have 8 bytes not 4 for pass-by-value types.

Author: Tom Lane <tgl@sss.pgh.pa.us>
Reviewed-by: Peter Eisentraut <peter@eisentraut.org>
Discussion: https://postgr.es/m/1749799.1752797397@sss.pgh.pa.us
pull/239/head
Tom Lane 4 weeks ago
parent 66f8765c53
commit 2a600a93c7
  1. 2
      src/backend/storage/ipc/ipc.c
  2. 7
      src/backend/utils/resowner/resowner.c
  3. 2
      src/include/catalog/catversion.h
  4. 8
      src/include/nodes/nodes.h
  5. 13
      src/include/pg_config_manual.h
  6. 21
      src/include/postgres.h

@ -399,7 +399,7 @@ cancel_before_shmem_exit(pg_on_exit_callback function, Datum arg)
before_shmem_exit_list[before_shmem_exit_index - 1].arg == arg)
--before_shmem_exit_index;
else
elog(ERROR, "before_shmem_exit callback (%p,0x%" PRIxPTR ") is not the latest entry",
elog(ERROR, "before_shmem_exit callback (%p,0x%" PRIx64 ") is not the latest entry",
function, arg);
}

@ -231,11 +231,8 @@ hash_resource_elem(Datum value, const ResourceOwnerDesc *kind)
* 'kind' into the hash. Just add it with hash_combine(), it perturbs the
* result enough for our purposes.
*/
#if SIZEOF_DATUM == 8
return hash_combine64(murmurhash64((uint64) value), (uint64) kind);
#else
return hash_combine(murmurhash32((uint32) value), (uint32) kind);
#endif
return hash_combine64(murmurhash64((uint64) value),
(uint64) (uintptr_t) kind);
}
/*

@ -57,6 +57,6 @@
*/
/* yyyymmddN */
#define CATALOG_VERSION_NO 202508051
#define CATALOG_VERSION_NO 202508131
#endif

@ -188,6 +188,8 @@ castNodeImpl(NodeTag type, void *ptr)
* ----------------------------------------------------------------
*/
#ifndef FRONTEND
/*
* nodes/{outfuncs.c,print.c}
*/
@ -198,7 +200,7 @@ extern void outNode(struct StringInfoData *str, const void *obj);
extern void outToken(struct StringInfoData *str, const char *s);
extern void outBitmapset(struct StringInfoData *str,
const struct Bitmapset *bms);
extern void outDatum(struct StringInfoData *str, uintptr_t value,
extern void outDatum(struct StringInfoData *str, Datum value,
int typlen, bool typbyval);
extern char *nodeToString(const void *obj);
extern char *nodeToStringWithLocations(const void *obj);
@ -212,7 +214,7 @@ extern void *stringToNode(const char *str);
extern void *stringToNodeWithLocations(const char *str);
#endif
extern struct Bitmapset *readBitmapset(void);
extern uintptr_t readDatum(bool typbyval);
extern Datum readDatum(bool typbyval);
extern bool *readBoolCols(int numCols);
extern int *readIntCols(int numCols);
extern Oid *readOidCols(int numCols);
@ -235,6 +237,8 @@ extern void *copyObjectImpl(const void *from);
*/
extern bool equal(const void *a, const void *b);
#endif /* !FRONTEND */
/*
* Typedef for parse location. This is just an int, but this way

@ -74,17 +74,12 @@
#define PARTITION_MAX_KEYS 32
/*
* Decide whether built-in 8-byte types, including float8, int8, and
* timestamp, are passed by value. This is on by default if sizeof(Datum) >=
* 8 (that is, on 64-bit platforms). If sizeof(Datum) < 8 (32-bit platforms),
* this must be off. We keep this here as an option so that it is easy to
* test the pass-by-reference code paths on 64-bit platforms.
*
* Changing this requires an initdb.
* This symbol is now vestigial: built-in 8-byte types, including float8,
* int8, and timestamp, are always passed by value since we require Datum
* to be wide enough to permit that. We continue to define the symbol here
* so as not to unnecessarily break extension code.
*/
#if SIZEOF_VOID_P >= 8
#define USE_FLOAT8_BYVAL 1
#endif
/*

@ -58,15 +58,22 @@
/*
* A Datum contains either a value of a pass-by-value type or a pointer to a
* value of a pass-by-reference type. Therefore, we require:
*
* sizeof(Datum) == sizeof(void *) == 4 or 8
* value of a pass-by-reference type. Therefore, we must have
* sizeof(Datum) >= sizeof(void *). No current or foreseeable Postgres
* platform has pointers wider than 8 bytes, and standardizing on Datum being
* exactly 8 bytes has advantages in reducing cross-platform differences.
*
* The functions below and the analogous functions for other types should be used to
* convert between a Datum and the appropriate C type.
*/
typedef uintptr_t Datum;
typedef uint64_t Datum;
/*
* This symbol is now vestigial, but we continue to define it so as not to
* unnecessarily break extension code.
*/
#define SIZEOF_DATUM 8
/*
* A NullableDatum is used in places where both a Datum and its nullness needs
@ -83,8 +90,6 @@ typedef struct NullableDatum
/* due to alignment padding this could be used for flags for free */
} NullableDatum;
#define SIZEOF_DATUM SIZEOF_VOID_P
/*
* DatumGetBool
* Returns boolean value of a datum.
@ -316,7 +321,7 @@ CommandIdGetDatum(CommandId X)
static inline Pointer
DatumGetPointer(Datum X)
{
return (Pointer) X;
return (Pointer) (uintptr_t) X;
}
/*
@ -326,7 +331,7 @@ DatumGetPointer(Datum X)
static inline Datum
PointerGetDatum(const void *X)
{
return (Datum) X;
return (Datum) (uintptr_t) X;
}
/*

Loading…
Cancel
Save