ProvSQL C/C++ API
Adding support for provenance and uncertainty management to PostgreSQL databases
Loading...
Searching...
No Matches
compatibility.h
Go to the documentation of this file.
1/**
2 * @file compatibility.h
3 * @brief PostgreSQL cross-version compatibility shims for ProvSQL.
4 *
5 * ProvSQL supports a range of PostgreSQL major versions. This header
6 * centralises the small API differences between those versions so that
7 * the rest of the codebase can call a single, stable interface.
8 *
9 * Currently handled differences:
10 * - **List API (13+)**: @c list_delete_cell() and @c lnext() gained or
11 * lost a @p prev argument between PostgreSQL 12 and 13. The
12 * @c my_list_delete_cell() and @c my_lnext() wrappers hide this.
13 * - **list_insert_nth() (< 13)**: In PostgreSQL 12 and earlier the
14 * list implementation was a linked list and this helper did not exist;
15 * @c compatibility.c provides a backport.
16 * - **Predefined function OIDs (< 14)**: The @c F_COUNT_ANY,
17 * @c F_COUNT_, and @c F_SUM_INT4 macros were introduced in PostgreSQL
18 * 14. Stable OID values for older releases are defined here.
19 * - **list_make5() (13)**: existed pre-13, dropped by the PG13 list
20 * rewrite, re-added in PG14; backported for the PG13 gap as a macro
21 * over @c list_make4() + @c lappend().
22 * - **FuncnameGetCandidates() / OpernameGetCandidates() (14, 19)**:
23 * PostgreSQL 14 added an @p include_out_arguments parameter to the
24 * former; PostgreSQL 19 added a mandatory @p fgc_flags out-parameter
25 * to both. The @c *Compat wrappers take the PG 14-style argument
26 * list and drop / dummy-fill the extra arguments as needed.
27 */
28#ifndef COMPATIBILITY_H
29#define COMPATIBILITY_H
30
31#include "postgres.h"
32#include "nodes/pg_list.h"
33#include "catalog/namespace.h"
34
35/**
36 * @brief Version-agnostic wrapper around @c list_delete_cell().
37 *
38 * PostgreSQL 13 changed @c list_delete_cell() to no longer require the
39 * previous cell pointer (because lists became arrays). This inline
40 * helper selects the correct call form at compile time.
41 *
42 * @param list The list to modify.
43 * @param cell The cell to delete.
44 * @param prev The cell immediately before @p cell (ignored on PG ≥ 13).
45 * @return The modified list.
46 */
47static inline List *my_list_delete_cell(List *list, ListCell *cell, ListCell *prev) {
48#if PG_VERSION_NUM >= 130000
49 return list_delete_cell(list, cell);
50#else
51 return list_delete_cell(list, cell, prev);
52#endif
53}
54
55/**
56 * @brief Version-agnostic wrapper around @c lnext().
57 *
58 * PostgreSQL 13 added the list pointer parameter to @c lnext() to
59 * support the array-based list implementation. This inline helper
60 * selects the correct call form at compile time.
61 *
62 * @param l The list (ignored on PG < 13).
63 * @param c The current cell.
64 * @return The next cell, or @c NULL if @p c is the last element.
65 */
66static inline ListCell *my_lnext(const List *l, const ListCell *c)
67{
68#if PG_VERSION_NUM >= 130000
69 return lnext(l, c);
70#else
71 return lnext(c);
72#endif
73}
74
75/**
76 * @brief Version-agnostic wrapper around @c FuncnameGetCandidates().
77 *
78 * Takes the PostgreSQL 14+ argument list. On PG < 14 the
79 * @p include_out_arguments parameter (added in 14) is dropped; on
80 * PG >= 19 the @p fgc_flags out-parameter (added in 19, must not be
81 * @c NULL) receives a discarded local, as no caller inspects the
82 * lookup-failure flags.
83 */
84static inline FuncCandidateList
85FuncnameGetCandidatesCompat(List *names, int nargs, List *argnames,
86 bool expand_variadic, bool expand_defaults,
87 bool include_out_arguments, bool missing_ok)
88{
89#if PG_VERSION_NUM >= 190000
90 int fgc_flags;
91 return FuncnameGetCandidates(names, nargs, argnames, expand_variadic,
92 expand_defaults, include_out_arguments,
93 missing_ok, &fgc_flags);
94#elif PG_VERSION_NUM >= 140000
95 return FuncnameGetCandidates(names, nargs, argnames, expand_variadic,
96 expand_defaults, include_out_arguments,
97 missing_ok);
98#else
99 return FuncnameGetCandidates(names, nargs, argnames, expand_variadic,
100 expand_defaults, missing_ok);
101#endif
102}
103
104/**
105 * @brief Version-agnostic wrapper around @c OpernameGetCandidates().
106 *
107 * PostgreSQL 19 added an @p fgc_flags out-parameter (must not be
108 * @c NULL); it receives a discarded local, as no caller inspects the
109 * lookup-failure flags.
110 */
111static inline FuncCandidateList
112OpernameGetCandidatesCompat(List *names, char oprkind, bool missing_schema_ok)
113{
114#if PG_VERSION_NUM >= 190000
115 int fgc_flags;
116 return OpernameGetCandidates(names, oprkind, missing_schema_ok, &fgc_flags);
117#else
118 return OpernameGetCandidates(names, oprkind, missing_schema_ok);
119#endif
120}
121
122#if PG_VERSION_NUM < 130000
123/**
124 * @brief Insert @p datum at position @p pos in @p list (PG < 13 backport).
125 *
126 * PostgreSQL 13 introduced @c list_insert_nth() when lists were
127 * reimplemented as arrays. This declaration provides the same function
128 * for older PostgreSQL versions; the implementation lives in
129 * @c compatibility.c.
130 *
131 * @param list The list to insert into (may be @c NIL).
132 * @param pos Zero-based index at which to insert the new element.
133 * @param datum The value to insert.
134 * @return The (possibly reallocated) list.
135 */
136List *list_insert_nth(List *list, int pos, void *datum);
137#endif
138
139#if PG_VERSION_NUM < 140000
140/** @brief OID of @c count(*) / @c count(any) aggregate function (pre-PG 14). */
141#define F_COUNT_ANY 2147
142/** @brief OID of @c count() aggregate function (pre-PG 14). */
143#define F_COUNT_ 2803
144/** @brief OID of @c sum(int4) aggregate function (pre-PG 14). */
145#define F_SUM_INT4 2108
146#endif
147
148#if PG_VERSION_NUM >= 130000 && PG_VERSION_NUM < 140000
149/** @brief Five-element list constructor. The linked-list implementation
150 * (pre-PG 13) had it as a macro; the PG13 array rewrite dropped it; PG14
151 * brought it back. Backport it for the PG13 gap only. */
152#define list_make5(x1, x2, x3, x4, x5) lappend(list_make4(x1, x2, x3, x4), x5)
153#endif
154
155#if PG_VERSION_NUM < 130000
156/** @brief Alignment codes for the array routines (@c construct_array /
157 * @c deconstruct_array). The @c TYPALIGN_* macros (in @c catalog/pg_type.h)
158 * were introduced in PostgreSQL 13; on PG 10-12 the alignment is passed as
159 * the older @c 'i' / @c 'c' characters. */
160#define TYPALIGN_INT 'i'
161#define TYPALIGN_CHAR 'c'
162#endif
163
164#if PG_VERSION_NUM < 140000
165/** @brief OID of the @c array_agg(anynonarray) aggregate (pre-PG 14).
166 * The @c F_ARRAY_AGG_ANYNONARRAY macro only exists since PostgreSQL 14,
167 * when @c fmgroids.h gained overload-disambiguated names for aggregates;
168 * before that, aggregates had no @c fmgroids.h entry at all. Same
169 * stable OID. */
170#define F_ARRAY_AGG_ANYNONARRAY 2335
171#endif
172
173#endif /* COMPATIBILITY_H */
static List * my_list_delete_cell(List *list, ListCell *cell, ListCell *prev)
Version-agnostic wrapper around list_delete_cell().
static ListCell * my_lnext(const List *l, const ListCell *c)
Version-agnostic wrapper around lnext().
static FuncCandidateList OpernameGetCandidatesCompat(List *names, char oprkind, bool missing_schema_ok)
Version-agnostic wrapper around OpernameGetCandidates().
static FuncCandidateList FuncnameGetCandidatesCompat(List *names, int nargs, List *argnames, bool expand_variadic, bool expand_defaults, bool include_out_arguments, bool missing_ok)
Version-agnostic wrapper around FuncnameGetCandidates().
List * list_insert_nth(List *list, int pos, void *datum)
Insert datum at position pos in list (PG < 13 backport).