aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/numeric.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2020-06-11 17:38:42 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2020-06-11 17:38:42 -0400
commit77a3be32f7c16538bc4e05edad85560d9f88369b (patch)
tree8ec9514acf4b51a96eba6942d7feb88b8943456b /src/backend/utils/adt/numeric.c
parent92c58fd94801dd5c81ee20e26c5bb71ad64552a8 (diff)
downloadpostgresql-77a3be32f7c16538bc4e05edad85560d9f88369b.tar.gz
postgresql-77a3be32f7c16538bc4e05edad85560d9f88369b.zip
Fix mishandling of NaN counts in numeric_[avg_]combine.
When merging two NumericAggStates, the code missed adding the new state's NaNcount unless its N was also nonzero; since those counts are independent, this is wrong. This would only have visible effect if some partial aggregate scans found only NaNs while earlier ones found only non-NaNs; then we could end up falsely deciding that there were no NaNs and fail to return a NaN final result as expected. That's pretty improbable, so it's no surprise this hasn't been reported from the field. Still, it's a bug. I didn't try to produce a regression test that would show the bug, but I did notice that these functions weren't being reached at all in our regression tests, so I improved the tests to at least exercise them. With these additions, I see pretty complete code coverage on the aggregation-related functions in numeric.c. Back-patch to 9.6 where this code was introduced. (I only added the improved test case as far back as v10, though, since the relevant part of aggregates.sql isn't there at all in 9.6.)
Diffstat (limited to 'src/backend/utils/adt/numeric.c')
-rw-r--r--src/backend/utils/adt/numeric.c12
1 files changed, 6 insertions, 6 deletions
diff --git a/src/backend/utils/adt/numeric.c b/src/backend/utils/adt/numeric.c
index f3a725271e6..553e261ed00 100644
--- a/src/backend/utils/adt/numeric.c
+++ b/src/backend/utils/adt/numeric.c
@@ -3967,11 +3967,11 @@ numeric_combine(PG_FUNCTION_ARGS)
PG_RETURN_POINTER(state1);
}
+ state1->N += state2->N;
+ state1->NaNcount += state2->NaNcount;
+
if (state2->N > 0)
{
- state1->N += state2->N;
- state1->NaNcount += state2->NaNcount;
-
/*
* These are currently only needed for moving aggregates, but let's do
* the right thing anyway...
@@ -4054,11 +4054,11 @@ numeric_avg_combine(PG_FUNCTION_ARGS)
PG_RETURN_POINTER(state1);
}
+ state1->N += state2->N;
+ state1->NaNcount += state2->NaNcount;
+
if (state2->N > 0)
{
- state1->N += state2->N;
- state1->NaNcount += state2->NaNcount;
-
/*
* These are currently only needed for moving aggregates, but let's do
* the right thing anyway...