@@ -188,15 +188,30 @@ static void rewrite_count_histogram(Aggref *aggref, List *aid_refs)
188188 append_aid_args (aggref , aid_refs );
189189}
190190
191- /* Intended for the denominator in the `avg(col)` rewritten to `sum(col) / count(col)`. */
192- static Aggref * make_anon_count_value_aggref (const Aggref * source_aggref )
191+ /*
192+ * Intended for the denominator in the `avg(col)` rewritten to `sum(col) / nullif(count(col), 0)`.
193+ * `nullif` is necessary to handle cases where large negative noise brings `count` down to 0
194+ * during global aggregation.
195+ */
196+ static Expr * make_safe_anon_count_value (const Aggref * source_aggref )
193197{
194198 Aggref * count_aggref = copyObjectImpl (source_aggref );
195199 count_aggref -> aggfnoid = g_oid_cache .anon_count_value ;
196200 count_aggref -> aggtype = INT8OID ;
197201 count_aggref -> aggstar = false;
198202 count_aggref -> aggdistinct = false;
199- return count_aggref ;
203+
204+ NullIfExpr * nullif = makeNode (NullIfExpr );
205+ nullif -> opno = g_oid_cache .op_int8eq ;
206+ nullif -> opfuncid = F_INT8EQ ;
207+ nullif -> opresulttype = count_aggref -> aggtype ;
208+ nullif -> opretset = false;
209+ nullif -> opcollid = 0 ;
210+ nullif -> inputcollid = 0 ;
211+ nullif -> args = list_make2 (count_aggref , make_const_int64 (0L ));
212+ nullif -> location = count_aggref -> location ;
213+
214+ return (Expr * )nullif ;
200215}
201216
202217static FuncExpr * make_i4tod (List * args )
@@ -254,11 +269,9 @@ static Node *rewrite_to_avg_aggregator(Aggref *aggref, List *aid_refs)
254269 aggref -> aggfnoid = g_oid_cache .anon_sum ;
255270 aggref -> aggstar = false;
256271 aggref -> aggdistinct = false;
257-
258- Aggref * count_aggref = make_anon_count_value_aggref (aggref );
259-
260272 append_aid_args (aggref , aid_refs );
261- append_aid_args (count_aggref , aid_refs );
273+
274+ Expr * count_aggref = make_safe_anon_count_value (aggref );
262275
263276 FuncExpr * cast_sum ;
264277 FuncExpr * cast_count ;
@@ -310,11 +323,9 @@ static Node *rewrite_to_avg_noise_aggregator(Aggref *aggref, List *aid_refs)
310323 aggref -> aggtype = FLOAT8OID ;
311324 aggref -> aggstar = false;
312325 aggref -> aggdistinct = false;
313-
314- Aggref * count_aggref = make_anon_count_value_aggref (aggref );
315-
316326 append_aid_args (aggref , aid_refs );
317- append_aid_args (count_aggref , aid_refs );
327+
328+ Expr * count_aggref = make_safe_anon_count_value (aggref );
318329
319330 FuncExpr * cast_count = make_i4tod (list_make1 (count_aggref ));
320331 FuncExpr * division = make_float8div (list_make2 (aggref , cast_count ));
0 commit comments