580 lines
12 KiB
C
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 */
|