Skip to content

Commit 2a600a9

Browse files
committed
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
1 parent 66f8765 commit 2a600a9

File tree

6 files changed

+27
-26
lines changed

6 files changed

+27
-26
lines changed

src/backend/storage/ipc/ipc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,7 @@ cancel_before_shmem_exit(pg_on_exit_callback function, Datum arg)
399399
before_shmem_exit_list[before_shmem_exit_index - 1].arg == arg)
400400
--before_shmem_exit_index;
401401
else
402-
elog(ERROR, "before_shmem_exit callback (%p,0x%" PRIxPTR ") is not the latest entry",
402+
elog(ERROR, "before_shmem_exit callback (%p,0x%" PRIx64 ") is not the latest entry",
403403
function, arg);
404404
}
405405

src/backend/utils/resowner/resowner.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -231,11 +231,8 @@ hash_resource_elem(Datum value, const ResourceOwnerDesc *kind)
231231
* 'kind' into the hash. Just add it with hash_combine(), it perturbs the
232232
* result enough for our purposes.
233233
*/
234-
#if SIZEOF_DATUM == 8
235-
return hash_combine64(murmurhash64((uint64) value), (uint64) kind);
236-
#else
237-
return hash_combine(murmurhash32((uint32) value), (uint32) kind);
238-
#endif
234+
return hash_combine64(murmurhash64((uint64) value),
235+
(uint64) (uintptr_t) kind);
239236
}
240237

241238
/*

src/include/catalog/catversion.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,6 @@
5757
*/
5858

5959
/* yyyymmddN */
60-
#define CATALOG_VERSION_NO 202508051
60+
#define CATALOG_VERSION_NO 202508131
6161

6262
#endif

src/include/nodes/nodes.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,8 @@ castNodeImpl(NodeTag type, void *ptr)
188188
* ----------------------------------------------------------------
189189
*/
190190

191+
#ifndef FRONTEND
192+
191193
/*
192194
* nodes/{outfuncs.c,print.c}
193195
*/
@@ -198,7 +200,7 @@ extern void outNode(struct StringInfoData *str, const void *obj);
198200
extern void outToken(struct StringInfoData *str, const char *s);
199201
extern void outBitmapset(struct StringInfoData *str,
200202
const struct Bitmapset *bms);
201-
extern void outDatum(struct StringInfoData *str, uintptr_t value,
203+
extern void outDatum(struct StringInfoData *str, Datum value,
202204
int typlen, bool typbyval);
203205
extern char *nodeToString(const void *obj);
204206
extern char *nodeToStringWithLocations(const void *obj);
@@ -212,7 +214,7 @@ extern void *stringToNode(const char *str);
212214
extern void *stringToNodeWithLocations(const char *str);
213215
#endif
214216
extern struct Bitmapset *readBitmapset(void);
215-
extern uintptr_t readDatum(bool typbyval);
217+
extern Datum readDatum(bool typbyval);
216218
extern bool *readBoolCols(int numCols);
217219
extern int *readIntCols(int numCols);
218220
extern Oid *readOidCols(int numCols);
@@ -235,6 +237,8 @@ extern void *copyObjectImpl(const void *from);
235237
*/
236238
extern bool equal(const void *a, const void *b);
237239

240+
#endif /* !FRONTEND */
241+
238242

239243
/*
240244
* Typedef for parse location. This is just an int, but this way

src/include/pg_config_manual.h

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -74,17 +74,12 @@
7474
#define PARTITION_MAX_KEYS 32
7575

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

8984

9085
/*

src/include/postgres.h

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -58,15 +58,22 @@
5858

5959
/*
6060
* A Datum contains either a value of a pass-by-value type or a pointer to a
61-
* value of a pass-by-reference type. Therefore, we require:
62-
*
63-
* sizeof(Datum) == sizeof(void *) == 4 or 8
61+
* value of a pass-by-reference type. Therefore, we must have
62+
* sizeof(Datum) >= sizeof(void *). No current or foreseeable Postgres
63+
* platform has pointers wider than 8 bytes, and standardizing on Datum being
64+
* exactly 8 bytes has advantages in reducing cross-platform differences.
6465
*
6566
* The functions below and the analogous functions for other types should be used to
6667
* convert between a Datum and the appropriate C type.
6768
*/
6869

69-
typedef uintptr_t Datum;
70+
typedef uint64_t Datum;
71+
72+
/*
73+
* This symbol is now vestigial, but we continue to define it so as not to
74+
* unnecessarily break extension code.
75+
*/
76+
#define SIZEOF_DATUM 8
7077

7178
/*
7279
* A NullableDatum is used in places where both a Datum and its nullness needs
@@ -83,8 +90,6 @@ typedef struct NullableDatum
8390
/* due to alignment padding this could be used for flags for free */
8491
} NullableDatum;
8592

86-
#define SIZEOF_DATUM SIZEOF_VOID_P
87-
8893
/*
8994
* DatumGetBool
9095
* Returns boolean value of a datum.
@@ -316,7 +321,7 @@ CommandIdGetDatum(CommandId X)
316321
static inline Pointer
317322
DatumGetPointer(Datum X)
318323
{
319-
return (Pointer) X;
324+
return (Pointer) (uintptr_t) X;
320325
}
321326

322327
/*
@@ -326,7 +331,7 @@ DatumGetPointer(Datum X)
326331
static inline Datum
327332
PointerGetDatum(const void *X)
328333
{
329-
return (Datum) X;
334+
return (Datum) (uintptr_t) X;
330335
}
331336

332337
/*

0 commit comments

Comments
 (0)