pg_version_compatibility.h
text/x-chdr
/*-------------------------------------------------------------------------
*
* pg_version_compatibility.h
* Forward-compatibility helpers to allow limited use of new
* server functions when compiling against old PostgreSQL versions
*
* The idea is that you write your extension against the latest PostgreSQL
* server version, and this file provides compatibility macros so that the
* source code still compiles against older PostgreSQL versions with minimal
* changes.
*
* Usage
* -----
*
* Copy this file to your project.
*
* The latest version of this file can be found at: XXX
*
* - PostgreSQL doesn't make any guarantees on backwards- or forwards-
* compatibility of interfaces that extensions might use. It's on a best
* effort basis.
*
* - This file is not comprehensive. It only covers some common
* incompatibilities that are easy and safe to implement in a compatible
* manner.
*
* - See XXX for more version-specific guides on updating
*
* - This file may be updated time to time, even between PostgreSQL
* releases. It's not necessary to regularly watch for updates, but if
* you're doing new development and run into version incompatibilities with
* old server versions, you might want to check for updates.
*
*
* License
* -------
*
* This file is released under the PostgreSQL license: XXX
*
*-------------------------------------------------------------------------
*/
#ifndef PG_VERSION_COMPATIBILITY_H
#define PG_VERSION_COMPATIBILITY_H
/* The latest version is PostgreSQL 18 */
/*
* Version 16 -> 17: "Proc number" as a concept existed in previous versions
* too, but there was no typedef for it.
*/
#if PG_VERSION_NUM < 170000
typedef int ProcNumber;
#endif
/*
* Version 17 -> 18: Latches were replaced with Interrupts
*/
#if PG_VERSION_NUM >= 180000
#include "storage/interrupt.h"
#else
#include "storage/latch.h"
#include "storage/proc.h"
typedef enum
{
/*
* Raising INTERRUPT_GENERAL_WAKEUP is equivalent to setting the
* per-process latch in older versions. There was direct no counterpart
* for other interrupts, so define only this one.
*/
INTERRUPT_GENERAL_WAKEUP,
} InterruptType;
/*
* The WaitLatch WL_* flags were repurposed for WaitInterrupts, except that
* WL_LATCH_SET was renamed to WL_INTERRUPT.
*/
#define WL_INTERRUPT WL_LATCH_SET
static inline void
RaiseInterrupt(InterruptType reason)
{
Assert(reason == INTERRUPT_GENERAL_WAKEUP);
SetLatch(MyLatch);
}
static inline void
SendInterrupt(InterruptType reason, ProcNumber pgprocno)
{
PGPROC *proc;
Assert(reason == INTERRUPT_GENERAL_WAKEUP);
proc = GetPGProcByNumber(pgprocno);
SetLatch(&proc->procLatch);
}
static inline int
WaitInterrupt(uint32 interruptMask, int wakeEvents, long timeout,
uint32 wait_event_info)
{
Assert(interruptMask == (1 << INTERRUPT_GENERAL_WAKEUP) || interruptMask == 0);
if ((interruptMask & (1 << INTERRUPT_GENERAL_WAKEUP)) == 0)
wakeEvents &= ~WL_INTERRUPT;
return WaitLatch(MyLatch, wakeEvents, timeout, wait_event_info);
}
static inline int
WaitInterruptOrSocket(uint32 interruptMask, int wakeEvents, pgsocket sock,
long timeout, uint32 wait_event_info)
{
Assert(interruptMask == (1 << INTERRUPT_GENERAL_WAKEUP) || interruptMask == 0);
if ((interruptMask & (1 << INTERRUPT_GENERAL_WAKEUP)) == 0)
wakeEvents &= ~WL_INTERRUPT;
return WaitLatchOrSocket(MyLatch, wakeEvents, timeout, sock, wait_event_info);
}
static inline void
ClearInterrupt(InterruptType reason)
{
Assert(reason == INTERRUPT_GENERAL_WAKEUP);
SetLatch(MyLatch);
}
static inline bool
ConsumeInterrupt(InterruptType reason)
{
if (likely(!MyLatch->is_set))
return false;
ClearInterrupt(reason);
return true;
}
#endif
#endif /* PG_VERSION_COMPATIBILITY_H */