-
Notifications
You must be signed in to change notification settings - Fork 4
/
util.c
133 lines (113 loc) · 4.5 KB
/
util.c
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
/*
* check to see if a float4/8 val has underflowed or overflowed
* (copied from backend/utils/adt/float.c)
*/
#define CHECKFLOATVAL(val, inf_is_valid, zero_is_valid) \
do { \
if (isinf(val) && !(inf_is_valid)) \
ereport(ERROR, \
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), \
errmsg("value out of range: overflow"))); \
\
if ((val) == 0.0 && !(zero_is_valid)) \
ereport(ERROR, \
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), \
errmsg("value out of range: underflow"))); \
} while(0)
// Some compatibility macros for supporting FunctionCallInfo across different PG versions
#if PG_VERSION_NUM < 120000
#define LOCAL_FCINFO(name, nargs) \
union \
{ \
FunctionCallInfoData fcinfo; \
} name##data; \
FunctionCallInfo name = &name##data.fcinfo
/* convenience macro to allocate FunctionCallInfoData on the heap */
#define HEAP_FCINFO(mcontext, nargs) MemoryContextAlloc(mcontext, sizeof(FunctionCallInfoData))
/* getting arguments has a different API, so these macros unify the versions */
#define FC_ARG(fcinfo, n) ((fcinfo)->arg[(n)])
#define FC_NULL(fcinfo, n) ((fcinfo)->argnull[(n)])
#else
/* convenience macro to allocate FunctionCallInfoData on the heap */
#define HEAP_FCINFO(mcontext, nargs) MemoryContextAlloc(mcontext, SizeForFunctionCallInfo(nargs))
/* getting arguments has a different API, so these macros unify the versions */
#define FC_ARG(fcinfo, n) ((fcinfo)->args[(n)].value)
#define FC_NULL(fcinfo, n) ((fcinfo)->args[(n)].isnull)
#endif
typedef union pgnum {
int16 i16;
int32 i32;
int64 i64;
float4 f4;
float8 f8;
Numeric num;
} pgnum;
typedef struct VecArrayBuildState {
ArrayBuildState state;
Oid inputElementType;
pgnum *vecvalues; // The current aggregate result for each position.
uint32 *veccounts; // How many values in this position are not null.
pgnum *vectmpvalues; // Intermediate results if we need them.
} VecArrayBuildState;
VecArrayBuildState *
initVecArrayResultWithNulls(Oid input_element_type, Oid state_element_type, MemoryContext rcontext, int arLen);
VecArrayBuildState *
initVecArrayResultWithNulls(Oid input_element_type, Oid state_element_type, MemoryContext rcontext, int arLen) {
VecArrayBuildState *astate;
int i;
astate = (VecArrayBuildState *)MemoryContextAlloc(rcontext, sizeof(VecArrayBuildState));
astate->state.mcontext = rcontext;
#if PG_VERSION_NUM >= 90500
astate->state.private_cxt = false;
#endif
astate->state.alen = arLen;
astate->state.dvalues = (Datum *)
MemoryContextAlloc(rcontext, astate->state.alen * sizeof(Datum));
astate->state.dnulls = (bool *)
MemoryContextAlloc(rcontext, astate->state.alen * sizeof(bool));
for (i = 0; i < arLen; i++) {
astate->state.dnulls[i] = true;
}
astate->inputElementType = input_element_type;
astate->vecvalues = (pgnum *)
MemoryContextAlloc(rcontext, astate->state.alen * sizeof(pgnum));
astate->veccounts = (uint32 *)
MemoryContextAlloc(rcontext, astate->state.alen * sizeof(uint32));
memset(astate->veccounts, 0, astate->state.alen * sizeof(uint32));
astate->vectmpvalues = (pgnum *)
MemoryContextAlloc(rcontext, astate->state.alen * sizeof(pgnum));
astate->state.nelems = arLen;
astate->state.element_type = state_element_type;
get_typlenbyvalalign(state_element_type,
&astate->state.typlen,
&astate->state.typbyval,
&astate->state.typalign);
return astate;
}
ArrayBuildState *
initArrayResultWithNulls(Oid element_type, MemoryContext rcontext, int arLen);
ArrayBuildState *
initArrayResultWithNulls(Oid element_type, MemoryContext rcontext, int arLen) {
ArrayBuildState *astate;
int i;
astate = (ArrayBuildState *)MemoryContextAlloc(rcontext, sizeof(ArrayBuildState));
astate->mcontext = rcontext;
#if PG_VERSION_NUM >= 90500
astate->private_cxt = false;
#endif
astate->alen = arLen;
astate->dvalues = (Datum *)
MemoryContextAlloc(rcontext, astate->alen * sizeof(Datum));
astate->dnulls = (bool *)
MemoryContextAlloc(rcontext, astate->alen * sizeof(bool));
for (i = 0; i < arLen; i++) {
astate->dnulls[i] = true;
}
astate->nelems = arLen;
astate->element_type = element_type;
get_typlenbyvalalign(element_type,
&astate->typlen,
&astate->typbyval,
&astate->typalign);
return astate;
}