| /*------------------------------------------------------------------------- |
| * |
| * postgres.h |
| * Primary include file for PostgreSQL server .c files |
| * |
| * This should be the first file included by PostgreSQL backend modules. |
| * Client-side code should include postgres_fe.h instead. |
| * |
| * |
| * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group |
| * Portions Copyright (c) 1995, Regents of the University of California |
| * |
| * src/include/postgres.h |
| * |
| *------------------------------------------------------------------------- |
| */ |
| /* |
| *---------------------------------------------------------------- |
| * TABLE OF CONTENTS |
| * |
| * When adding stuff to this file, please try to put stuff |
| * into the relevant section, or add new sections as appropriate. |
| * |
| * section description |
| * ------- ------------------------------------------------ |
| * 1) Datum type + support functions |
| * 2) miscellaneous |
| * |
| * NOTES |
| * |
| * In general, this file should contain declarations that are widely needed |
| * in the backend environment, but are of no interest outside the backend. |
| * |
| * Simple type definitions live in c.h, where they are shared with |
| * postgres_fe.h. We do that since those type definitions are needed by |
| * frontend modules that want to deal with binary data transmission to or |
| * from the backend. Type definitions in this file should be for |
| * representations that never escape the backend, such as Datum. |
| * |
| *---------------------------------------------------------------- |
| */ |
| #ifndef POSTGRES_H |
| #define POSTGRES_H |
| |
| #include "c.h" |
| #include "utils/elog.h" |
| #include "utils/palloc.h" |
| |
| /* ---------------------------------------------------------------- |
| * Section 1: Datum type + support functions |
| * ---------------------------------------------------------------- |
| */ |
| |
| /* |
| * 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 |
| * |
| * Cloudberry CDB: |
| * Datum is always 8 bytes, regardless if it is 32bit or 64bit machine. |
| * so may be > sizeof(void *). To align with postgres, which defines Datum as |
| * uintptr_t type, it is defined as a uintptr_t to make sure the raw Datum |
| * comparator work. GPDB's document requires a x86_64 environment where |
| * uintptr_t is 64bits which doesn't violate the original 64bits definition. |
| * Although it is unclear why did GPDB had that restriction at the beginning. |
| * |
| * 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 union Datum_U |
| { |
| Datum d; |
| |
| float4 f4[2]; |
| float8 f8; |
| |
| void *ptr; |
| } Datum_U; |
| |
| |
| |
| /* |
| * A NullableDatum is used in places where both a Datum and its nullness needs |
| * to be stored. This can be more efficient than storing datums and nullness |
| * in separate arrays, due to better spatial locality, even if more space may |
| * be wasted due to padding. |
| */ |
| typedef struct NullableDatum |
| { |
| #define FIELDNO_NULLABLE_DATUM_DATUM 0 |
| Datum value; |
| #define FIELDNO_NULLABLE_DATUM_ISNULL 1 |
| bool isnull; |
| /* due to alignment padding this could be used for flags for free */ |
| } NullableDatum; |
| |
| #define SIZEOF_DATUM SIZEOF_VOID_P |
| StaticAssertDecl(SIZEOF_DATUM == 8, "sizeof datum is not 8"); |
| /* |
| * Conversion between Datum and type X. Changed from Macro to static inline |
| * functions to get proper type checking. |
| */ |
| |
| /* |
| * DatumGetBool |
| * Returns boolean value of a datum. |
| * |
| * Note: any nonzero value will be considered true. |
| */ |
| static inline bool |
| DatumGetBool(Datum X) |
| { |
| return (X != 0); |
| } |
| |
| /* |
| * BoolGetDatum |
| * Returns datum representation for a boolean. |
| * |
| * Note: any nonzero value will be considered true. |
| */ |
| static inline Datum |
| BoolGetDatum(bool X) |
| { |
| return (Datum) (X ? 1 : 0); |
| } |
| |
| /* |
| * DatumGetChar |
| * Returns character value of a datum. |
| */ |
| static inline char |
| DatumGetChar(Datum X) |
| { |
| return (char) X; |
| } |
| |
| /* |
| * CharGetDatum |
| * Returns datum representation for a character. |
| */ |
| static inline Datum |
| CharGetDatum(char X) |
| { |
| return (Datum) X; |
| } |
| |
| /* |
| * Int8GetDatum |
| * Returns datum representation for an 8-bit integer. |
| */ |
| static inline Datum |
| Int8GetDatum(int8 X) |
| { |
| return (Datum) X; |
| } |
| |
| /* |
| * DatumGetUInt8 |
| * Returns 8-bit unsigned integer value of a datum. |
| */ |
| static inline uint8 |
| DatumGetUInt8(Datum X) |
| { |
| return (uint8) X; |
| } |
| |
| /* |
| * UInt8GetDatum |
| * Returns datum representation for an 8-bit unsigned integer. |
| */ |
| static inline Datum |
| UInt8GetDatum(uint8 X) |
| { |
| return (Datum) X; |
| } |
| |
| /* |
| * DatumGetInt16 |
| * Returns 16-bit integer value of a datum. |
| */ |
| static inline int16 |
| DatumGetInt16(Datum X) |
| { |
| return (int16) X; |
| } |
| |
| /* |
| * Int16GetDatum |
| * Returns datum representation for a 16-bit integer. |
| */ |
| static inline Datum |
| Int16GetDatum(int16 X) |
| { |
| return (Datum) X; |
| } |
| |
| /* |
| * DatumGetUInt16 |
| * Returns 16-bit unsigned integer value of a datum. |
| */ |
| static inline uint16 |
| DatumGetUInt16(Datum X) |
| { |
| return (uint16) X; |
| } |
| |
| /* |
| * UInt16GetDatum |
| * Returns datum representation for a 16-bit unsigned integer. |
| */ |
| static inline Datum |
| UInt16GetDatum(uint16 X) |
| { |
| return (Datum) X; |
| } |
| |
| /* |
| * DatumGetInt32 |
| * Returns 32-bit integer value of a datum. |
| */ |
| static inline int32 |
| DatumGetInt32(Datum X) |
| { |
| return (int32) X; |
| } |
| |
| /* |
| * Int32GetDatum |
| * Returns datum representation for a 32-bit integer. |
| */ |
| static inline Datum |
| Int32GetDatum(int32 X) |
| { |
| return (Datum) X; |
| } |
| |
| /* |
| * DatumGetUInt32 |
| * Returns 32-bit unsigned integer value of a datum. |
| */ |
| static inline uint32 |
| DatumGetUInt32(Datum X) |
| { |
| return (uint32) X; |
| } |
| |
| /* |
| * UInt32GetDatum |
| * Returns datum representation for a 32-bit unsigned integer. |
| */ |
| static inline Datum |
| UInt32GetDatum(uint32 X) |
| { |
| return (Datum) X; |
| } |
| |
| /* |
| * DatumGetObjectId |
| * Returns object identifier value of a datum. |
| */ |
| static inline Oid |
| DatumGetObjectId(Datum X) |
| { |
| return (Oid) X; |
| } |
| |
| /* |
| * ObjectIdGetDatum |
| * Returns datum representation for an object identifier. |
| */ |
| static inline Datum |
| ObjectIdGetDatum(Oid X) |
| { |
| return (Datum) X; |
| } |
| |
| /* |
| * DatumGetTransactionId |
| * Returns transaction identifier value of a datum. |
| */ |
| static inline TransactionId |
| DatumGetTransactionId(Datum X) |
| { |
| return (TransactionId) X; |
| } |
| |
| /* |
| * TransactionIdGetDatum |
| * Returns datum representation for a transaction identifier. |
| */ |
| static inline Datum |
| TransactionIdGetDatum(TransactionId X) |
| { |
| return (Datum) X; |
| } |
| |
| /* |
| * MultiXactIdGetDatum |
| * Returns datum representation for a multixact identifier. |
| */ |
| static inline Datum |
| MultiXactIdGetDatum(MultiXactId X) |
| { |
| return (Datum) X; |
| } |
| |
| /* |
| * DatumGetCommandId |
| * Returns command identifier value of a datum. |
| */ |
| static inline CommandId |
| DatumGetCommandId(Datum X) |
| { |
| return (CommandId) X; |
| } |
| |
| /* |
| * CommandIdGetDatum |
| * Returns datum representation for a command identifier. |
| */ |
| static inline Datum |
| CommandIdGetDatum(CommandId X) |
| { |
| return (Datum) X; |
| } |
| |
| /* |
| * DatumGetPointer |
| * Returns pointer value of a datum. |
| */ |
| static inline Pointer |
| DatumGetPointer(Datum X) |
| { |
| return (Pointer) X; |
| } |
| |
| /* |
| * PointerGetDatum |
| * Returns datum representation for a pointer. |
| */ |
| static inline Datum |
| PointerGetDatum(const void *X) |
| { |
| return (Datum) X; |
| } |
| |
| /* |
| * DatumGetCString |
| * Returns C string (null-terminated string) value of a datum. |
| * |
| * Note: C string is not a full-fledged Postgres type at present, |
| * but type input functions use this conversion for their inputs. |
| */ |
| static inline char * |
| DatumGetCString(Datum X) |
| { |
| return (char *) DatumGetPointer(X); |
| } |
| |
| /* |
| * CStringGetDatum |
| * Returns datum representation for a C string (null-terminated string). |
| * |
| * Note: C string is not a full-fledged Postgres type at present, |
| * but type output functions use this conversion for their outputs. |
| * Note: CString is pass-by-reference; caller must ensure the pointed-to |
| * value has adequate lifetime. |
| */ |
| static inline Datum |
| CStringGetDatum(const char *X) |
| { |
| return PointerGetDatum(X); |
| } |
| |
| /* |
| * DatumGetName |
| * Returns name value of a datum. |
| */ |
| static inline Name |
| DatumGetName(Datum X) |
| { |
| return (Name) DatumGetPointer(X); |
| } |
| |
| /* |
| * NameGetDatum |
| * Returns datum representation for a name. |
| * |
| * Note: Name is pass-by-reference; caller must ensure the pointed-to |
| * value has adequate lifetime. |
| */ |
| static inline Datum |
| NameGetDatum(const NameData *X) |
| { |
| return CStringGetDatum(NameStr(*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 |
| } |
| |
| static inline Datum DistributedTransactionIdGetDatum(DistributedTransactionId tid) { return (Datum) tid; } |
| |
| /* |
| * DatumGetPointer |
| * Returns pointer value of a datum. |
| */ |
| #define DatumGetPointer(X) ((Pointer) (X)) |
| |
| /* |
| * Float4GetDatum |
| * Returns datum representation for a 4-byte floating point number. |
| */ |
| static inline Datum |
| Float4GetDatum(float4 X) |
| { |
| union |
| { |
| float4 value; |
| int32 retval; |
| } myunion; |
| |
| myunion.value = X; |
| return Int32GetDatum(myunion.retval); |
| } |
| |
| /* |
| * DatumGetFloat4 |
| * Returns 4-byte floating point value of a datum. |
| */ |
| static inline float4 |
| DatumGetFloat4(Datum X) |
| { |
| union |
| { |
| int32 value; |
| float4 retval; |
| } myunion; |
| |
| myunion.value = DatumGetInt32(X); |
| return myunion.retval; |
| } |
| |
| /*\ |
| * 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; |
| float8 retval; |
| } myunion; |
| |
| 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) |
| { |
| union |
| { |
| float8 value; |
| int64 retval; |
| } myunion; |
| |
| myunion.value = X; |
| return Int64GetDatum(myunion.retval); |
| } |
| #else |
| extern Datum Float8GetDatum(float8 X); |
| #endif |
| |
| |
| static inline bool IsAligned(void *p, int align) |
| { |
| int64 i = (int64) PointerGetDatum(p); |
| return ((i & (align-1)) == 0); |
| } |
| |
| |
| /* ---------------------------------------------------------------- |
| * Section 3: exception handling backend support |
| * ---------------------------------------------------------------- |
| */ |
| |
| #define COMPILE_ASSERT(e) ((void)sizeof(char[1-2*!(e)])) |
| #define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x))) |
| |
| /* |
| * Int64GetDatumFast |
| * Float8GetDatumFast |
| * |
| * These macros are 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. |
| */ |
| |
| #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 |
| |
| |
| /* ---------------------------------------------------------------- |
| * Section 2: miscellaneous |
| * ---------------------------------------------------------------- |
| */ |
| |
| /* |
| * NON_EXEC_STATIC: It's sometimes useful to define a variable or function |
| * that is normally static but extern when using EXEC_BACKEND (see |
| * pg_config_manual.h). There would then typically be some code in |
| * postmaster.c that uses those extern symbols to transfer state between |
| * processes or do whatever other things it needs to do in EXEC_BACKEND mode. |
| */ |
| #ifdef EXEC_BACKEND |
| #define NON_EXEC_STATIC |
| #else |
| #define NON_EXEC_STATIC static |
| #endif |
| |
| #endif /* POSTGRES_H */ |