mirror of
https://github.com/postgres/postgres.git
synced 2026-05-17 03:50:39 -04:00
The argument was marked as "const void *X", but that might rightly give the compiler the idea that *X cannot be modified through the resulting Datum, and make incorrect optimizations based on that. Some functions use pointer Datums to pass output arguments, like GIN support functions. Coverity started to complain after commit6f5ad00ab7that there's dead code in ginExtractEntries(), because it didn't see that it passes PointerGetDatum(&nentries) to a function that sets it. This issue goes back to commitc8b2ef05f4(version 16), which changed PointerGetDatum() from a macro to a static inline function. This commit changes it back to a macro, but uses a trick with a dummy conditional expression to still produce a compiler error if you try to pass a non-pointer as the argument. Even though this goes back to v16, I'm only committing this to 'master' for now, to verify that this silences the Coverity warning. If this works, we might want to introduce separate const and non-const versions of PointerGetDatum() instead of this, but that's a bigger patch. It's also not decided yet whether to back-patch this (or some other fix), given that we haven't yet seen any hard evidence of compilers actually producing buggy code because of this. Discussion: https://www.postgresql.org/message-id/342012.1776017102@sss.pgh.pa.us
576 lines
12 KiB
C
576 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-2026, PostgreSQL Global Development Group
|
|
* Portions Copyright (c) 1995, Regents of the University of California
|
|
*
|
|
* src/include/postgres.h
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
/* IWYU pragma: always_keep */
|
|
/*
|
|
*----------------------------------------------------------------
|
|
* 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
|
|
|
|
/* IWYU pragma: begin_exports */
|
|
|
|
#include "c.h"
|
|
#include "utils/elog.h"
|
|
#include "utils/palloc.h"
|
|
|
|
/* IWYU pragma: end_exports */
|
|
|
|
/* ----------------------------------------------------------------
|
|
* 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 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 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
|
|
* 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;
|
|
|
|
/*
|
|
* 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;
|
|
}
|
|
|
|
/*
|
|
* 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;
|
|
}
|
|
|
|
/*
|
|
* DatumGetObjectId8
|
|
* Returns 8-byte object identifier value of a datum.
|
|
*/
|
|
static inline Oid8
|
|
DatumGetObjectId8(Datum X)
|
|
{
|
|
return (Oid8) X;
|
|
}
|
|
|
|
/*
|
|
* ObjectId8GetDatum
|
|
* Returns datum representation for an 8-byte object identifier
|
|
*/
|
|
static inline Datum
|
|
ObjectId8GetDatum(Oid8 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) (uintptr_t) X;
|
|
}
|
|
|
|
/*
|
|
* PointerGetDatum
|
|
* Returns datum representation for a pointer.
|
|
*
|
|
* This used to be defined as "static inline Datum PointerGetDatum(const void
|
|
* *X) ", but it had the problem that the compiler would see the const
|
|
* attribute, and could rightly assume that the function won't modify *X.
|
|
* While PointerGetDatum() itself doesn't modify *X, the resulting Datum could
|
|
* later be passed to a function that converts it back to a non-const pointer
|
|
* and modifies it. Most functions don't modify their arguments passed by
|
|
* reference - that would be very bogus for any operators or functions exposed
|
|
* in SQL - but some functions like GIN support functions do have output
|
|
* arguments that are pointer Datums.
|
|
*
|
|
* The odd-looking "true ? (X) : NULL" conditional expression has the effect
|
|
* of producing a compiler error if X is not a pointer.
|
|
*/
|
|
#define PointerGetDatum(X) \
|
|
((Datum) (uintptr_t) (true ? (X) : NULL))
|
|
|
|
/*
|
|
* 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).
|
|
*
|
|
* We assume that the resulting Datum is not used to modify the string, hence
|
|
* the argument can be marked as const.
|
|
*
|
|
* 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.
|
|
*/
|
|
static inline int64
|
|
DatumGetInt64(Datum X)
|
|
{
|
|
return (int64) X;
|
|
}
|
|
|
|
/*
|
|
* Int64GetDatum
|
|
* Returns datum representation for a 64-bit integer.
|
|
*/
|
|
static inline Datum
|
|
Int64GetDatum(int64 X)
|
|
{
|
|
return (Datum) X;
|
|
}
|
|
|
|
/*
|
|
* DatumGetUInt64
|
|
* Returns 64-bit unsigned integer value of a datum.
|
|
*/
|
|
static inline uint64
|
|
DatumGetUInt64(Datum X)
|
|
{
|
|
return (uint64) X;
|
|
}
|
|
|
|
/*
|
|
* UInt64GetDatum
|
|
* Returns datum representation for a 64-bit unsigned integer.
|
|
*/
|
|
static inline Datum
|
|
UInt64GetDatum(uint64 X)
|
|
{
|
|
return (Datum) X;
|
|
}
|
|
|
|
/*
|
|
* 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.
|
|
*/
|
|
static inline float8
|
|
DatumGetFloat8(Datum X)
|
|
{
|
|
union
|
|
{
|
|
int64 value;
|
|
float8 retval;
|
|
} myunion;
|
|
|
|
myunion.value = DatumGetInt64(X);
|
|
return myunion.retval;
|
|
}
|
|
|
|
/*
|
|
* Float8GetDatum
|
|
* Returns datum representation for an 8-byte floating point number.
|
|
*/
|
|
static inline Datum
|
|
Float8GetDatum(float8 X)
|
|
{
|
|
union
|
|
{
|
|
float8 value;
|
|
int64 retval;
|
|
} myunion;
|
|
|
|
myunion.value = X;
|
|
return Int64GetDatum(myunion.retval);
|
|
}
|
|
|
|
/*
|
|
* Int64GetDatumFast
|
|
* Float8GetDatumFast
|
|
*
|
|
* 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. 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.
|
|
*/
|
|
|
|
#define Int64GetDatumFast(X) \
|
|
(StaticAssertVariableIsOfTypeMacro(X, int64), Int64GetDatum(X))
|
|
#define Float8GetDatumFast(X) \
|
|
(StaticAssertVariableIsOfTypeMacro(X, double), Float8GetDatum(X))
|
|
|
|
|
|
/* ----------------------------------------------------------------
|
|
* Section 2: miscellaneous
|
|
* ----------------------------------------------------------------
|
|
*/
|
|
|
|
/*
|
|
* pg_ternary
|
|
* Boolean value with an extra "unset" value
|
|
*
|
|
* This enum can be used for values that want to distinguish between true,
|
|
* false, and unset.
|
|
*/
|
|
typedef enum pg_ternary
|
|
{
|
|
PG_TERNARY_FALSE = 0,
|
|
PG_TERNARY_TRUE = 1,
|
|
PG_TERNARY_UNSET = -1
|
|
} pg_ternary;
|
|
|
|
/*
|
|
* 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 */
|