-
Notifications
You must be signed in to change notification settings - Fork 29
/
aggregates.c
63 lines (54 loc) · 1.55 KB
/
aggregates.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
#include <postgres.h>
#include <fmgr.h>
#include "uint.h"
#include <utils/array.h>
#define make_sum_func(argtype, ARGTYPE, RETTYPE) \
PG_FUNCTION_INFO_V1(argtype##_sum); \
Datum \
argtype##_sum(PG_FUNCTION_ARGS) \
{ \
if (PG_ARGISNULL(0) && PG_ARGISNULL(1)) \
PG_RETURN_NULL(); \
\
PG_RETURN_##RETTYPE((PG_ARGISNULL(0) ? 0 : PG_GETARG_##RETTYPE(0)) + \
(PG_ARGISNULL(1) ? 0 : PG_GETARG_##ARGTYPE(1))); \
} \
extern int no_such_variable
make_sum_func(int1, INT8, INT32);
make_sum_func(uint1, UINT8, UINT32);
make_sum_func(uint2, UINT16, UINT64);
make_sum_func(uint4, UINT32, UINT64);
make_sum_func(uint8, UINT64, UINT64); // FIXME: should use numeric
typedef struct Int8TransTypeData
{
int64 count;
int64 sum;
} Int8TransTypeData;
#define make_avg_func(argtype, ARGTYPE) \
PG_FUNCTION_INFO_V1(argtype##_avg_accum); \
Datum \
argtype##_avg_accum(PG_FUNCTION_ARGS) \
{ \
ArrayType *transarray; \
Int8TransTypeData *transdata; \
\
transarray = (AggCheckCallContext(fcinfo, NULL)) \
? PG_GETARG_ARRAYTYPE_P(0) \
: PG_GETARG_ARRAYTYPE_P_COPY(0); \
\
if (ARR_HASNULL(transarray) || \
ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData)) \
elog(ERROR, "expected 2-element int8 array"); \
\
transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray); \
transdata->count++; \
transdata->sum += PG_GETARG_##ARGTYPE(1); \
\
PG_RETURN_ARRAYTYPE_P(transarray); \
} \
extern int no_such_variable
make_avg_func(int1, INT8);
make_avg_func(uint1, UINT8);
make_avg_func(uint2, UINT16);
make_avg_func(uint4, UINT32);
make_avg_func(uint8, UINT64);