2019-03-21 21:11:36 +04:00
|
|
|
/***********************************************************************************************************************************
|
|
|
|
PostgreSQL Version Interface
|
|
|
|
|
2022-06-06 13:52:56 -04:00
|
|
|
Macros for building version-specific functions that interface with the types in version.vendor.h. Due to the way PostgreSQL types
|
2019-03-21 21:11:36 +04:00
|
|
|
evolve over time, this seems to be the easiest way to extract information from them.
|
|
|
|
|
|
|
|
These macros should be kept as simple as possible, with most of the logic contained in postgres/interface.c.
|
|
|
|
***********************************************************************************************************************************/
|
2020-05-18 19:11:26 -04:00
|
|
|
#include "postgres/interface/version.vendor.h"
|
2022-06-06 13:52:56 -04:00
|
|
|
#include "postgres/version.h"
|
2019-03-21 21:11:36 +04:00
|
|
|
|
|
|
|
/***********************************************************************************************************************************
|
2022-06-06 13:52:56 -04:00
|
|
|
Determine if the supplied pg_control is for this version of PostgreSQL. When CATALOG_VERSION_NO_MAX is defined then the catalog will
|
|
|
|
be accepted as a range that lasts until the end of the encoded year. This allows pgBackRest to work with PostgreSQL during the
|
|
|
|
alpha/beta/rc period without needing to be updated, unless of course the actual interface changes.
|
2019-03-21 21:11:36 +04:00
|
|
|
***********************************************************************************************************************************/
|
|
|
|
#if PG_VERSION > PG_VERSION_MAX
|
|
|
|
|
2023-11-09 12:59:12 -03:00
|
|
|
#elif PG_VERSION >= PG_VERSION_94
|
2019-03-21 21:11:36 +04:00
|
|
|
|
2021-05-24 17:17:03 -04:00
|
|
|
#ifdef CATALOG_VERSION_NO_MAX
|
|
|
|
|
|
|
|
#define PG_INTERFACE_CONTROL_IS(version) \
|
2022-06-06 13:52:56 -04:00
|
|
|
static bool \
|
2021-05-24 17:17:03 -04:00
|
|
|
pgInterfaceControlIs##version(const unsigned char *controlFile) \
|
|
|
|
{ \
|
|
|
|
ASSERT(controlFile != NULL); \
|
|
|
|
\
|
|
|
|
return \
|
|
|
|
((ControlFileData *)controlFile)->pg_control_version == PG_CONTROL_VERSION && \
|
|
|
|
((ControlFileData *)controlFile)->catalog_version_no >= CATALOG_VERSION_NO && \
|
|
|
|
((ControlFileData *)controlFile)->catalog_version_no < (CATALOG_VERSION_NO / 100000 + 1) * 100000; \
|
|
|
|
}
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
2019-03-21 21:11:36 +04:00
|
|
|
#define PG_INTERFACE_CONTROL_IS(version) \
|
2022-06-06 13:52:56 -04:00
|
|
|
static bool \
|
2019-03-21 21:11:36 +04:00
|
|
|
pgInterfaceControlIs##version(const unsigned char *controlFile) \
|
|
|
|
{ \
|
|
|
|
ASSERT(controlFile != NULL); \
|
|
|
|
\
|
|
|
|
return \
|
|
|
|
((ControlFileData *)controlFile)->pg_control_version == PG_CONTROL_VERSION && \
|
|
|
|
((ControlFileData *)controlFile)->catalog_version_no == CATALOG_VERSION_NO; \
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2021-05-24 17:17:03 -04:00
|
|
|
#endif
|
|
|
|
|
2019-03-21 21:11:36 +04:00
|
|
|
/***********************************************************************************************************************************
|
|
|
|
Read the version specific pg_control into a general data structure
|
|
|
|
***********************************************************************************************************************************/
|
|
|
|
#if PG_VERSION > PG_VERSION_MAX
|
|
|
|
|
2023-11-09 12:59:12 -03:00
|
|
|
#elif PG_VERSION >= PG_VERSION_94
|
2019-03-21 21:11:36 +04:00
|
|
|
|
|
|
|
#define PG_INTERFACE_CONTROL(version) \
|
2022-06-06 13:52:56 -04:00
|
|
|
static PgControl \
|
2019-03-21 21:11:36 +04:00
|
|
|
pgInterfaceControl##version(const unsigned char *controlFile) \
|
|
|
|
{ \
|
|
|
|
ASSERT(controlFile != NULL); \
|
|
|
|
\
|
|
|
|
return (PgControl) \
|
|
|
|
{ \
|
|
|
|
.systemId = ((ControlFileData *)controlFile)->system_identifier, \
|
2020-09-18 16:55:26 -04:00
|
|
|
.catalogVersion = ((ControlFileData *)controlFile)->catalog_version_no, \
|
2021-12-07 09:21:07 -05:00
|
|
|
.checkpoint = ((ControlFileData *)controlFile)->checkPoint, \
|
|
|
|
.timeline = ((ControlFileData *)controlFile)->checkPointCopy.ThisTimeLineID, \
|
2019-03-21 21:11:36 +04:00
|
|
|
.pageSize = ((ControlFileData *)controlFile)->blcksz, \
|
|
|
|
.walSegmentSize = ((ControlFileData *)controlFile)->xlog_seg_size, \
|
2024-03-10 15:50:10 +13:00
|
|
|
.pageChecksumVersion = ((ControlFileData *)controlFile)->data_checksum_version, \
|
2019-03-21 21:11:36 +04:00
|
|
|
}; \
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2023-09-10 09:47:49 -04:00
|
|
|
/***********************************************************************************************************************************
|
|
|
|
Get control crc offset
|
|
|
|
***********************************************************************************************************************************/
|
|
|
|
#if PG_VERSION > PG_VERSION_MAX
|
|
|
|
|
2023-11-09 12:59:12 -03:00
|
|
|
#elif PG_VERSION >= PG_VERSION_94
|
2023-09-10 09:47:49 -04:00
|
|
|
|
|
|
|
#define PG_INTERFACE_CONTROL_CRC_OFFSET(version) \
|
|
|
|
static size_t \
|
|
|
|
pgInterfaceControlCrcOffset##version(void) \
|
|
|
|
{ \
|
|
|
|
return offsetof(ControlFileData, crc); \
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2024-03-10 17:08:42 +13:00
|
|
|
/***********************************************************************************************************************************
|
|
|
|
Invalidate control checkpoint. PostgreSQL skips the first segment so any LSN in that segment is invalid.
|
|
|
|
***********************************************************************************************************************************/
|
|
|
|
#if PG_VERSION > PG_VERSION_MAX
|
|
|
|
|
|
|
|
#elif PG_VERSION >= PG_VERSION_93
|
|
|
|
|
|
|
|
#define PG_INTERFACE_CONTROL_CHECKPOINT_INVALIDATE(version) \
|
|
|
|
static void \
|
|
|
|
pgInterfaceControlCheckpointInvalidate##version(unsigned char *const controlFile) \
|
|
|
|
{ \
|
|
|
|
((ControlFileData *)controlFile)->checkPoint = PG_CONTROL_CHECKPOINT_INVALID; \
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2019-09-07 18:04:39 -04:00
|
|
|
/***********************************************************************************************************************************
|
|
|
|
Get the control version
|
|
|
|
***********************************************************************************************************************************/
|
|
|
|
#if PG_VERSION > PG_VERSION_MAX
|
|
|
|
|
2023-11-09 12:59:12 -03:00
|
|
|
#elif PG_VERSION >= PG_VERSION_94
|
2019-09-07 18:04:39 -04:00
|
|
|
|
|
|
|
#define PG_INTERFACE_CONTROL_VERSION(version) \
|
2022-06-06 13:52:56 -04:00
|
|
|
static uint32_t \
|
2019-09-07 18:04:39 -04:00
|
|
|
pgInterfaceControlVersion##version(void) \
|
|
|
|
{ \
|
|
|
|
return PG_CONTROL_VERSION; \
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2019-03-21 21:11:36 +04:00
|
|
|
/***********************************************************************************************************************************
|
|
|
|
Determine if the supplied WAL is for this version of PostgreSQL
|
|
|
|
***********************************************************************************************************************************/
|
|
|
|
#if PG_VERSION > PG_VERSION_MAX
|
|
|
|
|
2023-11-09 12:59:12 -03:00
|
|
|
#elif PG_VERSION >= PG_VERSION_94
|
2019-03-21 21:11:36 +04:00
|
|
|
|
|
|
|
#define PG_INTERFACE_WAL_IS(version) \
|
2022-06-06 13:52:56 -04:00
|
|
|
static bool \
|
2019-03-21 21:11:36 +04:00
|
|
|
pgInterfaceWalIs##version(const unsigned char *walFile) \
|
|
|
|
{ \
|
|
|
|
ASSERT(walFile != NULL); \
|
|
|
|
\
|
|
|
|
return ((XLogPageHeaderData *)walFile)->xlp_magic == XLOG_PAGE_MAGIC; \
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/***********************************************************************************************************************************
|
|
|
|
Read the version specific WAL header into a general data structure
|
|
|
|
***********************************************************************************************************************************/
|
|
|
|
#if PG_VERSION > PG_VERSION_MAX
|
|
|
|
|
2023-11-09 12:59:12 -03:00
|
|
|
#elif PG_VERSION >= PG_VERSION_94
|
2019-03-21 21:11:36 +04:00
|
|
|
|
|
|
|
#define PG_INTERFACE_WAL(version) \
|
2022-06-06 13:52:56 -04:00
|
|
|
static PgWal \
|
2019-03-21 21:11:36 +04:00
|
|
|
pgInterfaceWal##version(const unsigned char *walFile) \
|
|
|
|
{ \
|
|
|
|
ASSERT(walFile != NULL); \
|
|
|
|
\
|
|
|
|
return (PgWal) \
|
|
|
|
{ \
|
|
|
|
.systemId = ((XLogLongPageHeaderData *)walFile)->xlp_sysid, \
|
2020-07-09 17:32:36 -04:00
|
|
|
.size = ((XLogLongPageHeaderData *)walFile)->xlp_seg_size, \
|
2019-03-21 21:11:36 +04:00
|
|
|
}; \
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|