From f2dc4fe15e2b3b35e8481034c8fae7a1e72f79e9 Mon Sep 17 00:00:00 2001 From: Chip Kent <5250374+chipkent@users.noreply.github.com> Date: Wed, 8 May 2024 10:17:51 -0600 Subject: [PATCH] Fixed problems in cumsum and cumprod where multiple leading null values give incorrect answers. (#5464) Fixed bug in cumsum and cumprod when there are multiple initial null values. Resolves #5462 --- engine/function/src/templates/Numeric.ftl | 20 +++++++++---------- engine/function/src/templates/TestNumeric.ftl | 6 ++++++ 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/engine/function/src/templates/Numeric.ftl b/engine/function/src/templates/Numeric.ftl index bb7c8ca0346..30cfc23084e 100644 --- a/engine/function/src/templates/Numeric.ftl +++ b/engine/function/src/templates/Numeric.ftl @@ -1934,10 +1934,10 @@ public class Numeric { if (isNaN(v) || isNaN(result[i - 1])) { Arrays.fill(result, i, n, Double.NaN); return result; - } else if (isNull(result[i - 1])) { - result[i] = v; } else if (isNull(v)) { result[i] = result[i - 1]; + } else if (isNull(result[i - 1])) { + result[i] = v; } else { result[i] = result[i - 1] + v; } @@ -1969,10 +1969,10 @@ public class Numeric { while (vi.hasNext()) { final ${pt.primitive} v = vi.${pt.iteratorNext}(); - if (isNull(result[i - 1])) { - result[i] = v; - } else if (isNull(v)) { + if (isNull(v)) { result[i] = result[i - 1]; + } else if (isNull(result[i - 1])) { + result[i] = v; } else { result[i] = result[i - 1] + v; } @@ -2055,10 +2055,10 @@ public class Numeric { if (isNaN(v) || isNaN(result[i - 1])) { Arrays.fill(result, i, n, Double.NaN); return result; - } else if (isNull(result[i - 1])) { - result[i] = v; } else if (isNull(v)) { result[i] = result[i - 1]; + } else if (isNull(result[i - 1])) { + result[i] = v; } else { result[i] = result[i - 1] * v; } @@ -2090,10 +2090,10 @@ public class Numeric { while (vi.hasNext()) { final ${pt.primitive} v = vi.${pt.iteratorNext}(); - if (isNull(result[i - 1])) { - result[i] = v; - } else if (isNull(v)) { + if (isNull(v)) { result[i] = result[i - 1]; + } else if (isNull(result[i - 1])) { + result[i] = v; } else { result[i] = result[i - 1] * v; } diff --git a/engine/function/src/templates/TestNumeric.ftl b/engine/function/src/templates/TestNumeric.ftl index 56fcb65d2d4..9bf99f52c0b 100644 --- a/engine/function/src/templates/TestNumeric.ftl +++ b/engine/function/src/templates/TestNumeric.ftl @@ -805,6 +805,7 @@ public class TestNumeric extends BaseArrayTestCase { assertEquals(new double[]{1, 3, 6, 10, 15}, cumsum(new ${pt.primitive}[]{1, 2, 3, 4, 5})); assertEquals(new double[]{1, 3, 6, 6, 11}, cumsum(new ${pt.primitive}[]{1, 2, 3, ${pt.null}, 5})); assertEquals(new double[]{NULL_DOUBLE, 2, 5, 9, 14}, cumsum(new ${pt.primitive}[]{${pt.null}, 2, 3, 4, 5})); + assertEquals(new double[]{NULL_DOUBLE, NULL_DOUBLE, 2, 5, 9, 14}, cumsum(new ${pt.primitive}[]{${pt.null}, ${pt.null}, 2, 3, 4, 5})); assertEquals(new double[0], cumsum(new ${pt.primitive}[0])); assertEquals(new double[0], cumsum(new ${pt.boxed}[0])); assertEquals(null, cumsum((${pt.primitive}[]) null)); @@ -812,6 +813,7 @@ public class TestNumeric extends BaseArrayTestCase { assertEquals(new double[]{1, 3, 6, 10, 15}, cumsum(new ${pt.vectorDirect}(new ${pt.primitive}[]{1, 2, 3, 4, 5}))); assertEquals(new double[]{1, 3, 6, 6, 11}, cumsum(new ${pt.vectorDirect}(new ${pt.primitive}[]{1, 2, 3, ${pt.null}, 5}))); assertEquals(new double[]{NULL_DOUBLE, 2, 5, 9, 14}, cumsum(new ${pt.vectorDirect}(new ${pt.primitive}[]{${pt.null}, 2, 3, 4, 5}))); + assertEquals(new double[]{NULL_DOUBLE, NULL_DOUBLE, 2, 5, 9, 14}, cumsum(new ${pt.vectorDirect}(new ${pt.primitive}[]{${pt.null}, ${pt.null}, 2, 3, 4, 5}))); assertEquals(new double[0], cumsum(new ${pt.vectorDirect}())); assertEquals(null, cumsum((${pt.vector}) null)); @@ -832,6 +834,7 @@ public class TestNumeric extends BaseArrayTestCase { assertEquals(new long[]{1, 3, 6, 10, 15}, cumsum(new ${pt.primitive}[]{1, 2, 3, 4, 5})); assertEquals(new long[]{1, 3, 6, 6, 11}, cumsum(new ${pt.primitive}[]{1, 2, 3, ${pt.null}, 5})); assertEquals(new long[]{NULL_LONG, 2, 5, 9, 14}, cumsum(new ${pt.primitive}[]{${pt.null}, 2, 3, 4, 5})); + assertEquals(new long[]{NULL_LONG, NULL_LONG, 2, 5, 9, 14}, cumsum(new ${pt.primitive}[]{${pt.null}, ${pt.null}, 2, 3, 4, 5})); assertEquals(new long[0], cumsum(new ${pt.primitive}[0])); assertEquals(new long[0], cumsum(new ${pt.boxed}[0])); assertEquals(null, cumsum((${pt.primitive}[]) null)); @@ -839,6 +842,7 @@ public class TestNumeric extends BaseArrayTestCase { assertEquals(new long[]{1, 3, 6, 10, 15}, cumsum(new ${pt.vectorDirect}(new ${pt.primitive}[]{1, 2, 3, 4, 5}))); assertEquals(new long[]{1, 3, 6, 6, 11}, cumsum(new ${pt.vectorDirect}(new ${pt.primitive}[]{1, 2, 3, ${pt.null}, 5}))); assertEquals(new long[]{NULL_LONG, 2, 5, 9, 14}, cumsum(new ${pt.vectorDirect}(new ${pt.primitive}[]{${pt.null}, 2, 3, 4, 5}))); + assertEquals(new long[]{NULL_LONG, NULL_LONG, 2, 5, 9, 14}, cumsum(new ${pt.vectorDirect}(new ${pt.primitive}[]{${pt.null}, ${pt.null}, 2, 3, 4, 5}))); assertEquals(new long[0], cumsum(new ${pt.vectorDirect}())); assertEquals(null, cumsum((${pt.vector}) null)); @@ -852,6 +856,7 @@ public class TestNumeric extends BaseArrayTestCase { assertEquals(new double[]{1, 2, 6, 24, 120}, cumprod(new ${pt.primitive}[]{1, 2, 3, 4, 5})); assertEquals(new double[]{1, 2, 6, 6, 30}, cumprod(new ${pt.primitive}[]{1, 2, 3, ${pt.null}, 5})); assertEquals(new double[]{NULL_DOUBLE, 2, 6, 24, 120}, cumprod(new ${pt.primitive}[]{${pt.null}, 2, 3, 4, 5})); + assertEquals(new double[]{NULL_DOUBLE, NULL_DOUBLE, 2, 6, 24, 120}, cumprod(new ${pt.primitive}[]{${pt.null}, ${pt.null}, 2, 3, 4, 5})); assertEquals(new double[0], cumprod(new ${pt.primitive}[0])); assertEquals(new double[0], cumprod(new ${pt.boxed}[0])); assertEquals(null, cumprod((${pt.primitive}[]) null)); @@ -860,6 +865,7 @@ public class TestNumeric extends BaseArrayTestCase { assertEquals(new double[]{1, 2, 6, 24, 120}, cumprod(new ${pt.vectorDirect}(new ${pt.primitive}[]{1, 2, 3, 4, 5}))); assertEquals(new double[]{1, 2, 6, 6, 30}, cumprod(new ${pt.vectorDirect}(new ${pt.primitive}[]{1, 2, 3, ${pt.null}, 5}))); assertEquals(new double[]{NULL_DOUBLE, 2, 6, 24, 120}, cumprod(new ${pt.vectorDirect}(new ${pt.primitive}[]{${pt.null}, 2, 3, 4, 5}))); + assertEquals(new double[]{NULL_DOUBLE, NULL_DOUBLE, 2, 6, 24, 120}, cumprod(new ${pt.vectorDirect}(new ${pt.primitive}[]{${pt.null}, ${pt.null}, 2, 3, 4, 5}))); assertEquals(new double[0], cumprod(new ${pt.vectorDirect}())); assertEquals(null, cumprod((${pt.vector}) null)); assertEquals(new double[]{1, Double.NaN, Double.NaN, Double.NaN, Double.NaN}, cumprod(new ${pt.vectorDirect}(new ${pt.primitive}[]{1, Float.NaN, 3, 4, 5})));