Datum pg_hll_sketch_combine()

in src/hll_sketch_pg_functions.c [226:283]


Datum pg_hll_sketch_combine(PG_FUNCTION_ARGS) {
  struct hll_agg_state* stateptr1;
  struct hll_agg_state* stateptr2;
  struct hll_agg_state* stateptr;

  MemoryContext oldcontext;
  MemoryContext aggcontext;

  if (PG_ARGISNULL(0) && PG_ARGISNULL(1)) PG_RETURN_NULL();

  if (!AggCheckCallContext(fcinfo, &aggcontext)) {
    elog(ERROR, "hll_sketch_combine called in non-aggregate context");
  }
  oldcontext = MemoryContextSwitchTo(aggcontext);

  stateptr1 = (struct hll_agg_state*) PG_GETARG_POINTER(0);
  stateptr2 = (struct hll_agg_state*) PG_GETARG_POINTER(1);

  stateptr = palloc(sizeof(struct hll_agg_state));
  stateptr->type = SKETCH;
  stateptr->lg_k = stateptr1 ? stateptr1->lg_k : stateptr2->lg_k;
  stateptr->tgt_type = stateptr1 ? stateptr1->tgt_type : stateptr2->tgt_type;
  stateptr->ptr = hll_union_new(stateptr->lg_k);

  if (stateptr1) {
    if (stateptr1->type == UNION) {
      if (stateptr1->tgt_type) {
        stateptr1->ptr = hll_union_get_result_tgt_type(stateptr1->ptr, stateptr1->tgt_type);
      } else {
        stateptr1->ptr = hll_union_get_result(stateptr1->ptr);
      }
    }
    hll_union_update(stateptr->ptr, stateptr1->ptr);
    hll_sketch_delete(stateptr1->ptr);
    pfree(stateptr1);
  }
  if (stateptr2) {
    if (stateptr2->type == UNION) {
      if (stateptr2->tgt_type) {
        stateptr2->ptr = hll_union_get_result_tgt_type(stateptr2->ptr, stateptr2->tgt_type);
      } else {
        stateptr2->ptr = hll_union_get_result(stateptr2->ptr);
      }
    }
    hll_union_update(stateptr->ptr, stateptr2->ptr);
    hll_sketch_delete(stateptr2->ptr);
    pfree(stateptr2);
  }
  if (stateptr->tgt_type) {
    stateptr->ptr = hll_union_get_result_tgt_type(stateptr->ptr, stateptr->tgt_type);
  } else {
    stateptr->ptr = hll_union_get_result(stateptr->ptr);
  }

  MemoryContextSwitchTo(oldcontext);

  PG_RETURN_POINTER(stateptr);
}