forked from pjungwir/aggs_for_vecs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
util.c
105 lines (92 loc) · 3.38 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
/*
* 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)
typedef union pgnum {
int16 i16;
int32 i32;
int64 i64;
float4 f4;
float8 f8;
} pgnum;
typedef struct VecArrayBuildState {
ArrayBuildState state;
Oid inputElementType;
pgnum *vecvalues; // The current aggregate result for each position.
int *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 = (int *)
MemoryContextAlloc(rcontext, astate->state.alen * sizeof(int));
memset(astate->veccounts, 0, astate->state.alen * sizeof(int));
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;
}