postgresql/src/include/postgres.h

580 lines
12 KiB
C

/*-------------------------------------------------------------------------
*
* 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-2024, 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 */