* Generic combine function for numeric aggregates which require sumX2 */
| 4847 | * Generic combine function for numeric aggregates which require sumX2 |
| 4848 | */ |
| 4849 | Datum |
| 4850 | numeric_combine(PG_FUNCTION_ARGS) |
| 4851 | { |
| 4852 | NumericAggState *state1; |
| 4853 | NumericAggState *state2; |
| 4854 | MemoryContext agg_context; |
| 4855 | MemoryContext old_context; |
| 4856 | |
| 4857 | if (!AggCheckCallContext(fcinfo, &agg_context)) |
| 4858 | elog(ERROR, "aggregate function called in non-aggregate context"); |
| 4859 | |
| 4860 | state1 = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0); |
| 4861 | state2 = PG_ARGISNULL(1) ? NULL : (NumericAggState *) PG_GETARG_POINTER(1); |
| 4862 | |
| 4863 | if (state2 == NULL) |
| 4864 | { |
| 4865 | if (state1 == NULL) |
| 4866 | PG_RETURN_NULL(); |
| 4867 | PG_RETURN_POINTER(state1); |
| 4868 | } |
| 4869 | |
| 4870 | /* manually copy all fields from state2 to state1 */ |
| 4871 | if (state1 == NULL) |
| 4872 | { |
| 4873 | old_context = MemoryContextSwitchTo(agg_context); |
| 4874 | |
| 4875 | state1 = makeNumericAggStateCurrentContext(true); |
| 4876 | state1->N = state2->N; |
| 4877 | state1->NaNcount = state2->NaNcount; |
| 4878 | state1->pInfcount = state2->pInfcount; |
| 4879 | state1->nInfcount = state2->nInfcount; |
| 4880 | state1->maxScale = state2->maxScale; |
| 4881 | state1->maxScaleCount = state2->maxScaleCount; |
| 4882 | |
| 4883 | accum_sum_copy(&state1->sumX, &state2->sumX); |
| 4884 | accum_sum_copy(&state1->sumX2, &state2->sumX2); |
| 4885 | |
| 4886 | MemoryContextSwitchTo(old_context); |
| 4887 | |
| 4888 | PG_RETURN_POINTER(state1); |
| 4889 | } |
| 4890 | |
| 4891 | state1->N += state2->N; |
| 4892 | state1->NaNcount += state2->NaNcount; |
| 4893 | state1->pInfcount += state2->pInfcount; |
| 4894 | state1->nInfcount += state2->nInfcount; |
| 4895 | |
| 4896 | if (state2->N > 0) |
| 4897 | { |
| 4898 | /* |
| 4899 | * These are currently only needed for moving aggregates, but let's do |
| 4900 | * the right thing anyway... |
| 4901 | */ |
| 4902 | if (state2->maxScale > state1->maxScale) |
| 4903 | { |
| 4904 | state1->maxScale = state2->maxScale; |
| 4905 | state1->maxScaleCount = state2->maxScaleCount; |
| 4906 | } |
nothing calls this directly
no test coverage detected