diff options
Diffstat (limited to 'src/include')
-rw-r--r-- | src/include/access/gin_tuple.h | 4 | ||||
-rw-r--r-- | src/include/access/spgist_private.h | 14 | ||||
-rw-r--r-- | src/include/access/tupmacs.h | 15 | ||||
-rw-r--r-- | src/include/c.h | 8 | ||||
-rw-r--r-- | src/include/catalog/catversion.h | 2 | ||||
-rw-r--r-- | src/include/catalog/pg_type.dat | 16 | ||||
-rw-r--r-- | src/include/fmgr.h | 2 | ||||
-rw-r--r-- | src/include/nodes/nodes.h | 8 | ||||
-rw-r--r-- | src/include/pg_config_manual.h | 13 | ||||
-rw-r--r-- | src/include/port/pg_bswap.h | 17 | ||||
-rw-r--r-- | src/include/postgres.h | 79 | ||||
-rw-r--r-- | src/include/utils/sortsupport.h | 4 |
12 files changed, 58 insertions, 124 deletions
diff --git a/src/include/access/gin_tuple.h b/src/include/access/gin_tuple.h index 702f7d12889..b4f103dec9a 100644 --- a/src/include/access/gin_tuple.h +++ b/src/include/access/gin_tuple.h @@ -15,7 +15,9 @@ #include "utils/sortsupport.h" /* - * Data for one key in a GIN index. + * Data for one key in a GIN index. (This is not the permanent in-index + * representation, but just a convenient format to use during the tuplesort + * stage of building a new GIN index.) */ typedef struct GinTuple { diff --git a/src/include/access/spgist_private.h b/src/include/access/spgist_private.h index cb43a278f46..56ac64f0597 100644 --- a/src/include/access/spgist_private.h +++ b/src/include/access/spgist_private.h @@ -285,10 +285,12 @@ typedef struct SpGistCache * If the prefix datum is of a pass-by-value type, it is stored in its * Datum representation, that is its on-disk representation is of length * sizeof(Datum). This is a fairly unfortunate choice, because in no other - * place does Postgres use Datum as an on-disk representation; it creates - * an unnecessary incompatibility between 32-bit and 64-bit builds. But the - * compatibility loss is mostly theoretical since MAXIMUM_ALIGNOF typically - * differs between such builds, too. Anyway we're stuck with it now. + * place does Postgres use Datum as an on-disk representation. Formerly it + * meant an unnecessary incompatibility between 32-bit and 64-bit builds, and + * as of v19 it instead creates a hazard for binary upgrades on 32-bit builds. + * Fortunately, that hazard seems mostly theoretical for lack of affected + * opclasses. Going forward, we will be using a fixed size of Datum so that + * there's no longer any pressing reason to change this. */ typedef struct SpGistInnerTupleData { @@ -377,8 +379,8 @@ typedef SpGistNodeTupleData *SpGistNodeTuple; * * size must be a multiple of MAXALIGN; also, it must be at least SGDTSIZE * so that the tuple can be converted to REDIRECT status later. (This - * restriction only adds bytes for a NULL leaf datum stored on a 32-bit - * machine; otherwise alignment restrictions force it anyway.) + * restriction only adds bytes for a NULL leaf datum; otherwise alignment + * restrictions force it anyway.) */ typedef struct SpGistLeafTupleData { diff --git a/src/include/access/tupmacs.h b/src/include/access/tupmacs.h index 6240ec930e7..84b3e7fd896 100644 --- a/src/include/access/tupmacs.h +++ b/src/include/access/tupmacs.h @@ -39,9 +39,6 @@ att_isnull(int ATT, const bits8 *BITS) * return the correct number of bytes fetched from the data area and extended * to Datum form. * - * On machines where Datum is 8 bytes, we support fetching 8-byte byval - * attributes; otherwise, only 1, 2, and 4-byte values are supported. - * * Note that T must already be properly aligned for this to work correctly. */ #define fetchatt(A,T) fetch_att(T, (A)->attbyval, (A)->attlen) @@ -62,10 +59,8 @@ fetch_att(const void *T, bool attbyval, int attlen) return Int16GetDatum(*((const int16 *) T)); case sizeof(int32): return Int32GetDatum(*((const int32 *) T)); -#if SIZEOF_DATUM == 8 - case sizeof(Datum): - return *((const Datum *) T); -#endif + case sizeof(int64): + return Int64GetDatum(*((const int64 *) T)); default: elog(ERROR, "unsupported byval length: %d", attlen); return 0; @@ -221,11 +216,9 @@ store_att_byval(void *T, Datum newdatum, int attlen) case sizeof(int32): *(int32 *) T = DatumGetInt32(newdatum); break; -#if SIZEOF_DATUM == 8 - case sizeof(Datum): - *(Datum *) T = newdatum; + case sizeof(int64): + *(int64 *) T = DatumGetInt64(newdatum); break; -#endif default: elog(ERROR, "unsupported byval length: %d", attlen); } diff --git a/src/include/c.h b/src/include/c.h index bbdaa88c63a..39022f8a9dd 100644 --- a/src/include/c.h +++ b/src/include/c.h @@ -609,11 +609,11 @@ typedef signed int Offset; typedef float float4; typedef double float8; -#ifdef USE_FLOAT8_BYVAL +/* + * float8, int8, and related datatypes are now always pass-by-value. + * We keep this symbol to avoid breaking extension code that may use it. + */ #define FLOAT8PASSBYVAL true -#else -#define FLOAT8PASSBYVAL false -#endif /* * Oid, RegProcedure, TransactionId, SubTransactionId, MultiXactId, diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index c4fe8b991af..0ca415b4261 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -57,6 +57,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 202508051 +#define CATALOG_VERSION_NO 202508131 #endif diff --git a/src/include/catalog/pg_type.dat b/src/include/catalog/pg_type.dat index 29e4ffffc98..cb730aeac86 100644 --- a/src/include/catalog/pg_type.dat +++ b/src/include/catalog/pg_type.dat @@ -54,7 +54,7 @@ typcollation => 'C' }, { oid => '20', array_type_oid => '1016', descr => '~18 digit integer, 8-byte storage', - typname => 'int8', typlen => '8', typbyval => 'FLOAT8PASSBYVAL', + typname => 'int8', typlen => '8', typbyval => 't', typcategory => 'N', typinput => 'int8in', typoutput => 'int8out', typreceive => 'int8recv', typsend => 'int8send', typalign => 'd' }, { oid => '21', array_type_oid => '1005', @@ -172,7 +172,7 @@ typoutput => 'pg_ddl_command_out', typreceive => 'pg_ddl_command_recv', typsend => 'pg_ddl_command_send', typalign => 'ALIGNOF_POINTER' }, { oid => '5069', array_type_oid => '271', descr => 'full transaction id', - typname => 'xid8', typlen => '8', typbyval => 'FLOAT8PASSBYVAL', + typname => 'xid8', typlen => '8', typbyval => 't', typcategory => 'U', typinput => 'xid8in', typoutput => 'xid8out', typreceive => 'xid8recv', typsend => 'xid8send', typalign => 'd' }, @@ -222,7 +222,7 @@ typsend => 'float4send', typalign => 'i' }, { oid => '701', array_type_oid => '1022', descr => 'double-precision floating point number, 8-byte storage', - typname => 'float8', typlen => '8', typbyval => 'FLOAT8PASSBYVAL', + typname => 'float8', typlen => '8', typbyval => 't', typcategory => 'N', typispreferred => 't', typinput => 'float8in', typoutput => 'float8out', typreceive => 'float8recv', typsend => 'float8send', typalign => 'd' }, @@ -237,7 +237,7 @@ typreceive => 'circle_recv', typsend => 'circle_send', typalign => 'd' }, { oid => '790', array_type_oid => '791', descr => 'monetary amounts, $d,ddd.cc', - typname => 'money', typlen => '8', typbyval => 'FLOAT8PASSBYVAL', + typname => 'money', typlen => '8', typbyval => 't', typcategory => 'N', typinput => 'cash_in', typoutput => 'cash_out', typreceive => 'cash_recv', typsend => 'cash_send', typalign => 'd' }, @@ -290,7 +290,7 @@ typinput => 'date_in', typoutput => 'date_out', typreceive => 'date_recv', typsend => 'date_send', typalign => 'i' }, { oid => '1083', array_type_oid => '1183', descr => 'time of day', - typname => 'time', typlen => '8', typbyval => 'FLOAT8PASSBYVAL', + typname => 'time', typlen => '8', typbyval => 't', typcategory => 'D', typinput => 'time_in', typoutput => 'time_out', typreceive => 'time_recv', typsend => 'time_send', typmodin => 'timetypmodin', typmodout => 'timetypmodout', typalign => 'd' }, @@ -298,14 +298,14 @@ # OIDS 1100 - 1199 { oid => '1114', array_type_oid => '1115', descr => 'date and time', - typname => 'timestamp', typlen => '8', typbyval => 'FLOAT8PASSBYVAL', + typname => 'timestamp', typlen => '8', typbyval => 't', typcategory => 'D', typinput => 'timestamp_in', typoutput => 'timestamp_out', typreceive => 'timestamp_recv', typsend => 'timestamp_send', typmodin => 'timestamptypmodin', typmodout => 'timestamptypmodout', typalign => 'd' }, { oid => '1184', array_type_oid => '1185', descr => 'date and time with time zone', - typname => 'timestamptz', typlen => '8', typbyval => 'FLOAT8PASSBYVAL', + typname => 'timestamptz', typlen => '8', typbyval => 't', typcategory => 'D', typispreferred => 't', typinput => 'timestamptz_in', typoutput => 'timestamptz_out', typreceive => 'timestamptz_recv', typsend => 'timestamptz_send', typmodin => 'timestamptztypmodin', @@ -413,7 +413,7 @@ # pg_lsn { oid => '3220', array_type_oid => '3221', descr => 'PostgreSQL LSN', - typname => 'pg_lsn', typlen => '8', typbyval => 'FLOAT8PASSBYVAL', + typname => 'pg_lsn', typlen => '8', typbyval => 't', typcategory => 'U', typinput => 'pg_lsn_in', typoutput => 'pg_lsn_out', typreceive => 'pg_lsn_recv', typsend => 'pg_lsn_send', typalign => 'd' }, diff --git a/src/include/fmgr.h b/src/include/fmgr.h index 0fe7b4ebc77..c7236e42972 100644 --- a/src/include/fmgr.h +++ b/src/include/fmgr.h @@ -469,7 +469,7 @@ typedef struct int funcmaxargs; /* FUNC_MAX_ARGS */ int indexmaxkeys; /* INDEX_MAX_KEYS */ int namedatalen; /* NAMEDATALEN */ - int float8byval; /* FLOAT8PASSBYVAL */ + int float8byval; /* FLOAT8PASSBYVAL (now vestigial) */ char abi_extra[32]; /* see pg_config_manual.h */ } Pg_abi_values; diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h index fbe333d88fa..b2dc380b57b 100644 --- a/src/include/nodes/nodes.h +++ b/src/include/nodes/nodes.h @@ -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 diff --git a/src/include/pg_config_manual.h b/src/include/pg_config_manual.h index 125d3eb5fff..7e1aa422332 100644 --- a/src/include/pg_config_manual.h +++ b/src/include/pg_config_manual.h @@ -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 /* diff --git a/src/include/port/pg_bswap.h b/src/include/port/pg_bswap.h index 33648433c63..b15f6f6ac38 100644 --- a/src/include/port/pg_bswap.h +++ b/src/include/port/pg_bswap.h @@ -130,8 +130,7 @@ pg_bswap64(uint64 x) /* * Rearrange the bytes of a Datum from big-endian order into the native byte - * order. On big-endian machines, this does nothing at all. Note that the C - * type Datum is an unsigned integer type on all platforms. + * order. On big-endian machines, this does nothing at all. * * One possible application of the DatumBigEndianToNative() macro is to make * bitwise comparisons cheaper. A simple 3-way comparison of Datums @@ -139,23 +138,11 @@ pg_bswap64(uint64 x) * the same result as a memcmp() of the corresponding original Datums, but can * be much cheaper. It's generally safe to do this on big-endian systems * without any special transformation occurring first. - * - * If SIZEOF_DATUM is not defined, then postgres.h wasn't included and these - * macros probably shouldn't be used, so we define nothing. Note that - * SIZEOF_DATUM == 8 would evaluate as 0 == 8 in that case, potentially - * leading to the wrong implementation being selected and confusing errors, so - * defining nothing is safest. */ -#ifdef SIZEOF_DATUM #ifdef WORDS_BIGENDIAN #define DatumBigEndianToNative(x) (x) #else /* !WORDS_BIGENDIAN */ -#if SIZEOF_DATUM == 8 -#define DatumBigEndianToNative(x) pg_bswap64(x) -#else /* SIZEOF_DATUM != 8 */ -#define DatumBigEndianToNative(x) pg_bswap32(x) -#endif /* SIZEOF_DATUM == 8 */ +#define DatumBigEndianToNative(x) UInt64GetDatum(pg_bswap64(DatumGetUInt64(x))) #endif /* WORDS_BIGENDIAN */ -#endif /* SIZEOF_DATUM */ #endif /* PG_BSWAP_H */ diff --git a/src/include/postgres.h b/src/include/postgres.h index 8a41a668687..357cbd6fd96 100644 --- a/src/include/postgres.h +++ b/src/include/postgres.h @@ -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; } /* @@ -383,68 +388,41 @@ NameGetDatum(const NameData *X) /* * DatumGetInt64 * Returns 64-bit integer value of a datum. - * - * Note: this function hides whether int64 is pass by value or by reference. */ static inline int64 DatumGetInt64(Datum X) { -#ifdef USE_FLOAT8_BYVAL return (int64) X; -#else - return *((int64 *) DatumGetPointer(X)); -#endif } /* * Int64GetDatum * Returns datum representation for a 64-bit integer. - * - * Note: if int64 is pass by reference, this function returns a reference - * to palloc'd space. */ -#ifdef USE_FLOAT8_BYVAL static inline Datum Int64GetDatum(int64 X) { return (Datum) X; } -#else -extern Datum Int64GetDatum(int64 X); -#endif - /* * DatumGetUInt64 * Returns 64-bit unsigned integer value of a datum. - * - * Note: this function hides whether int64 is pass by value or by reference. */ static inline uint64 DatumGetUInt64(Datum X) { -#ifdef USE_FLOAT8_BYVAL return (uint64) X; -#else - return *((uint64 *) DatumGetPointer(X)); -#endif } /* * UInt64GetDatum * Returns datum representation for a 64-bit unsigned integer. - * - * Note: if int64 is pass by reference, this function returns a reference - * to palloc'd space. */ static inline Datum UInt64GetDatum(uint64 X) { -#ifdef USE_FLOAT8_BYVAL return (Datum) X; -#else - return Int64GetDatum((int64) X); -#endif } /* @@ -492,13 +470,10 @@ Float4GetDatum(float4 X) /* * DatumGetFloat8 * Returns 8-byte floating point value of a datum. - * - * Note: this function hides whether float8 is pass by value or by reference. */ static inline float8 DatumGetFloat8(Datum X) { -#ifdef USE_FLOAT8_BYVAL union { int64 value; @@ -507,19 +482,12 @@ DatumGetFloat8(Datum X) myunion.value = DatumGetInt64(X); return myunion.retval; -#else - return *((float8 *) DatumGetPointer(X)); -#endif } /* * Float8GetDatum * Returns datum representation for an 8-byte floating point number. - * - * Note: if float8 is pass by reference, this function returns a reference - * to palloc'd space. */ -#ifdef USE_FLOAT8_BYVAL static inline Datum Float8GetDatum(float8 X) { @@ -532,35 +500,22 @@ Float8GetDatum(float8 X) myunion.value = X; return Int64GetDatum(myunion.retval); } -#else -extern Datum Float8GetDatum(float8 X); -#endif - /* * Int64GetDatumFast * Float8GetDatumFast * - * These macros are intended to allow writing code that does not depend on + * These macros were intended to allow writing code that does not depend on * whether int64 and float8 are pass-by-reference types, while not - * sacrificing performance when they are. The argument must be a variable - * that will exist and have the same value for as long as the Datum is needed. - * In the pass-by-ref case, the address of the variable is taken to use as - * the Datum. In the pass-by-val case, these are the same as the non-Fast - * functions, except for asserting that the variable is of the correct type. + * sacrificing performance when they are. They are no longer different + * from the regular functions, though we keep the assertions to protect + * code that might get back-patched into older branches. */ -#ifdef USE_FLOAT8_BYVAL #define Int64GetDatumFast(X) \ (AssertVariableIsOfTypeMacro(X, int64), Int64GetDatum(X)) #define Float8GetDatumFast(X) \ (AssertVariableIsOfTypeMacro(X, double), Float8GetDatum(X)) -#else -#define Int64GetDatumFast(X) \ - (AssertVariableIsOfTypeMacro(X, int64), PointerGetDatum(&(X))) -#define Float8GetDatumFast(X) \ - (AssertVariableIsOfTypeMacro(X, double), PointerGetDatum(&(X))) -#endif /* ---------------------------------------------------------------- diff --git a/src/include/utils/sortsupport.h b/src/include/utils/sortsupport.h index b7abaf7802d..c64527e2ee9 100644 --- a/src/include/utils/sortsupport.h +++ b/src/include/utils/sortsupport.h @@ -262,7 +262,6 @@ ApplyUnsignedSortComparator(Datum datum1, bool isNull1, return compare; } -#if SIZEOF_DATUM >= 8 static inline int ApplySignedSortComparator(Datum datum1, bool isNull1, Datum datum2, bool isNull2, @@ -296,7 +295,6 @@ ApplySignedSortComparator(Datum datum1, bool isNull1, return compare; } -#endif static inline int ApplyInt32SortComparator(Datum datum1, bool isNull1, @@ -376,9 +374,7 @@ ApplySortAbbrevFullComparator(Datum datum1, bool isNull1, * are eligible for faster sorting. */ extern int ssup_datum_unsigned_cmp(Datum x, Datum y, SortSupport ssup); -#if SIZEOF_DATUM >= 8 extern int ssup_datum_signed_cmp(Datum x, Datum y, SortSupport ssup); -#endif extern int ssup_datum_int32_cmp(Datum x, Datum y, SortSupport ssup); /* Other functions in utils/sort/sortsupport.c */ |