diff options
Diffstat (limited to 'src/include/postgres.h')
-rw-r--r-- | src/include/postgres.h | 579 |
1 files changed, 579 insertions, 0 deletions
diff --git a/src/include/postgres.h b/src/include/postgres.h new file mode 100644 index 0000000..8a028ff --- /dev/null +++ b/src/include/postgres.h @@ -0,0 +1,579 @@ +/*------------------------------------------------------------------------- + * + * 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 + * + * 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; + +/* + * 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 + +/* + * 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 +} + +/* + * Float <-> Datum conversions + * + * These have to be implemented as inline functions rather than macros, when + * passing by value, because many machines pass int and float function + * parameters/results differently; so we need to play weird games with unions. + */ + +/* + * 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; +} + +/* + * 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); +} + +/* + * 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 + + +/* + * 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 */ |