-
Notifications
You must be signed in to change notification settings - Fork 150
Expand file tree
/
Copy pathCompatibility.hpp
More file actions
272 lines (232 loc) · 7.24 KB
/
Compatibility.hpp
File metadata and controls
272 lines (232 loc) · 7.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
/* ----------------------------------------------------------------------- *//**
*
* @file Compatibility.hpp
*
*//* ----------------------------------------------------------------------- */
#ifndef MADLIB_POSTGRES_COMPATIBILITY_HPP
#define MADLIB_POSTGRES_COMPATIBILITY_HPP
extern "C" {
#include <access/tupmacs.h>
#include <utils/memutils.h>
#if PG_VERSION_NUM >= 90300
#include <access/htup_details.h>
#endif
// PostgreSQL 16+ compatibility
#if PG_VERSION_NUM >= 160000
#include <varatt.h>
#include <catalog/pg_proc.h>
#endif
}
namespace madlib {
namespace dbconnector {
namespace postgres {
namespace {
// No need to make these function accessible outside of the postgres namespace.
#ifndef FLOAT8ARRAYOID
#define FLOAT8ARRAYOID 1022
#endif
#ifndef INT8ARRAYOID
#define INT8ARRAYOID 1016
#endif
#ifndef PG_GET_COLLATION
// See madlib_InitFunctionCallInfoData()
#define PG_GET_COLLATION() InvalidOid
#endif
#ifndef SearchSysCache1
// See madlib_SearchSysCache1()
#define SearchSysCache1(cacheId, key1) \
SearchSysCache(cacheId, key1, 0, 0, 0)
#endif
/*
* In commit 2d4db3675fa7a2f4831b755bc98242421901042f,
* by Tom Lane <tgl@sss.pgh.pa.us> Wed, 6 Jun 2007 23:00:50 +0000,
* is_array_type was changed to type_is_array
*/
#if defined(is_array_type) && !defined(type_is_array)
#define type_is_array(x) is_array_type(x)
#endif
#if PG_VERSION_NUM < 90000
/**
* The following has existed in PostgresSQL since commit ID
* d5768dce10576c2fb1254c03fb29475d4fac6bb4, by
* Tom Lane <tgl@sss.pgh.pa.us> Mon, 8 Feb 2010 20:39:52 +0000.
*/
/* AggCheckCallContext can return one of the following codes, or 0: */
#define AGG_CONTEXT_AGGREGATE 1 /* regular aggregate */
#define AGG_CONTEXT_WINDOW 2 /* window function */
/**
* @brief Test whether we are currently in an aggregate calling context.
*
* Knowing whether we are in an aggregate calling context is useful, because it
* allows write access to the transition state of the aggregate function.
* At all other time, modifying a pass-by-reference input is strictly forbidden:
* http://developer.postgresql.org/pgdocs/postgres/xaggr.html
*
* This function is essentially a copy of AggCheckCallContext from
* backend/executor/nodeAgg.c, which is part of PostgreSQL >= 9.0.
*/
inline
int
AggCheckCallContext(FunctionCallInfo fcinfo, MemoryContext *aggcontext) {
if (fcinfo->context && IsA(fcinfo->context, AggState)) {
if (aggcontext)
*aggcontext = ((AggState *) fcinfo->context)->aggcontext;
return AGG_CONTEXT_AGGREGATE;
}
/* More recent versions of PostgreSQL also have a window aggregate context.
* However, these changes are not contained in the 8.4 branch (or before).
*
* Reference: See changed file src/include/nodes/execnodes.h from
* commit ec4be2ee6827b6bd85e0813c7a8993cfbb0e6fa7 from
* Fri, 12 Feb 2010 17:33:21 +0000 (17:33 +0000)
* by Tom Lane <tgl@sss.pgh.pa.us> */
/* this is just to prevent "uninitialized variable" warnings */
if (aggcontext)
*aggcontext = NULL;
return 0;
}
#endif // PG_VERSION_NUM < 90000
} // namespace
/**
* @brief construct an array of zero values.
* @note the supported types are: int2, int4, int8, float4 and float8
*
*/
static ArrayType* construct_md_array_zero
(
int ndims,
int* dims,
int* lbs,
Oid elmtype,
int elmlen,
bool elmbyval,
char elmalign
){
ArrayType *result;
size_t nbytes;
int32 dataoffset;
int i;
int nelems;
Datum theDatum = Datum(0);
(void) elmbyval;
if (ndims < 0) /* we do allow zero-dimension arrays */
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("invalid number of dimensions: %d", ndims)));
if (ndims > MAXDIM)
ereport(ERROR,
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)",
ndims, MAXDIM)));
/* fast track for empty array */
if (ndims == 0)
return construct_empty_array(elmtype);
nelems = ArrayGetNItems(ndims, dims);
/* compute required space */
nbytes = 0;
switch (elmtype)
{
case INT2OID:
theDatum = Int16GetDatum(1);
break;
case INT4OID:
theDatum = Int32GetDatum(1);
break;
case INT8OID:
theDatum = Int64GetDatum(1);
break;
case FLOAT4OID:
theDatum = Float4GetDatum(1.0);
break;
case FLOAT8OID:
theDatum = Float8GetDatum(1.0);
break;
default:
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("the support types are INT2, INT4, INT8, FLOAT4 and FLOAT8")));
break;
}
for (i = 0; i < nelems; i++)
{
/* make sure data is not toasted */
if (elmlen == -1)
theDatum = PointerGetDatum(PG_DETOAST_DATUM(theDatum));
nbytes = att_addlength_datum(nbytes, elmlen, theDatum);
nbytes = att_align_nominal(nbytes, elmalign);
/* check for overflow of total request */
if (!AllocSizeIsValid(nbytes))
ereport(ERROR,
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
errmsg("array size exceeds the maximum allowed (%d)",
(int) MaxAllocSize)));
}
dataoffset = 0; /* marker for no null bitmap */
nbytes += ARR_OVERHEAD_NONULLS(ndims);
result = (ArrayType *) palloc0(nbytes);
SET_VARSIZE(result, nbytes);
result->ndim = ndims;
result->dataoffset = dataoffset;
result->elemtype = elmtype;
memcpy(ARR_DIMS(result), dims, ndims * sizeof(int));
memcpy(ARR_LBOUND(result), lbs, ndims * sizeof(int));
return result;
}
/**
* @brief construct an array of zero values.
* @note the supported types are: int2, int4, int8, float4 and float8
*/
static ArrayType* construct_array_zero
(
int nelems,
Oid elmtype,
int elmlen,
bool elmbyval,
char elmalign
)
{
int dims[1];
int lbs[1];
dims[0] = nelems;
lbs[0] = 1;
return
construct_md_array_zero(
1, dims, lbs, elmtype, elmlen, elmbyval, elmalign);
}
inline ArrayType* madlib_construct_md_array
(
Datum* elems,
bool* nulls,
int ndims,
int* dims,
int* lbs,
Oid elmtype,
int elmlen,
bool elmbyval,
char elmalign
){
return
elems ?
construct_md_array(
elems, nulls, ndims, dims, lbs, elmtype, elmlen, elmbyval,
elmalign) :
construct_md_array_zero(
ndims, dims, lbs, elmtype, elmlen, elmbyval, elmalign);
}
inline ArrayType* madlib_construct_array
(
Datum* elems,
int nelems,
Oid elmtype,
int elmlen,
bool elmbyval,
char elmalign
){
return elems ?
construct_array(elems, nelems, elmtype, elmlen, elmbyval, elmalign) :
construct_array_zero(nelems, elmtype, elmlen, elmbyval, elmalign);
}
} // namespace postgres
} // namespace dbconnector
} // namespace madlib
#endif // defined(MADLIB_POSTGRES_COMPATIBILITY_HPP)