in src/aod_sketch_pg_functions.c [161:198]
Datum pg_aod_sketch_union_agg(PG_FUNCTION_ARGS) {
struct aod_agg_state* stateptr;
bytea* sketch_bytes;
void* sketchptr;
MemoryContext oldcontext;
MemoryContext aggcontext;
if (PG_ARGISNULL(0) && PG_ARGISNULL(1)) {
PG_RETURN_NULL();
} else if (PG_ARGISNULL(1)) {
PG_RETURN_POINTER(PG_GETARG_POINTER(0)); // no update value. return unmodified state
}
if (!AggCheckCallContext(fcinfo, &aggcontext)) {
elog(ERROR, "aod_sketch_union_agg called in non-aggregate context");
}
oldcontext = MemoryContextSwitchTo(aggcontext);
if (PG_ARGISNULL(0)) {
stateptr = palloc(sizeof(struct aod_agg_state));
stateptr->type = UNION;
stateptr->num_values = PG_NARGS() > 2 ? PG_GETARG_INT32(2) : 1;
stateptr->lg_k = PG_NARGS() > 3 ? PG_GETARG_INT32(3) : 0;
stateptr->ptr = stateptr->lg_k ? aod_union_new_lgk(stateptr->num_values, stateptr->lg_k) : aod_union_new(stateptr->num_values);
} else {
stateptr = (struct aod_agg_state*) PG_GETARG_POINTER(0);
}
sketch_bytes = PG_GETARG_BYTEA_P(1);
sketchptr = aod_sketch_deserialize(VARDATA(sketch_bytes), VARSIZE(sketch_bytes) - VARHDRSZ);
aod_union_update(stateptr->ptr, sketchptr);
compact_aod_sketch_delete(sketchptr);
MemoryContextSwitchTo(oldcontext);
PG_RETURN_POINTER(stateptr);
}