From f318595abd54c68603b4c1eb07b2f428184c06d9 Mon Sep 17 00:00:00 2001 From: Haisheng Yuan Date: Mon, 17 Sep 2018 12:03:09 -0500 Subject: [PATCH] [CALCITE-2506] Fix AssertionError in RexSimplify: coalesce(unaryPlus(nullInt), unaryPlus(vInt())) --- .../apache/calcite/rex/RexInterpreter.java | 2 + .../org/apache/calcite/rex/RexSimplify.java | 6 ++- .../calcite/test/RexProgramBuilderBase.java | 2 +- .../apache/calcite/test/RexProgramTest.java | 39 +++++++++++++++---- 4 files changed, 40 insertions(+), 9 deletions(-) diff --git a/core/src/main/java/org/apache/calcite/rex/RexInterpreter.java b/core/src/main/java/org/apache/calcite/rex/RexInterpreter.java index a0455e2fd6a..212ed434efa 100644 --- a/core/src/main/java/org/apache/calcite/rex/RexInterpreter.java +++ b/core/src/main/java/org/apache/calcite/rex/RexInterpreter.java @@ -185,6 +185,8 @@ public Comparable visitCall(RexCall call) { return ceil(call, values); case EXTRACT: return extract(call, values); + case PLUS_PREFIX: + return containsNull(values) ? N : values.get(0); default: throw unbound(call); } diff --git a/core/src/main/java/org/apache/calcite/rex/RexSimplify.java b/core/src/main/java/org/apache/calcite/rex/RexSimplify.java index 1179547cbc3..c0aa0465e29 100644 --- a/core/src/main/java/org/apache/calcite/rex/RexSimplify.java +++ b/core/src/main/java/org/apache/calcite/rex/RexSimplify.java @@ -207,6 +207,8 @@ private RexNode simplify_(RexNode e) { case LESS_THAN_OR_EQUAL: case NOT_EQUALS: return simplifyComparison((RexCall) e); + case PLUS_PREFIX: + return simplify_(((RexCall) e).getOperands().get(0)); default: return e; } @@ -562,7 +564,9 @@ private RexNode simplifyCoalesce(RexCall call) { final List operands = new ArrayList<>(); for (RexNode operand : call.getOperands()) { operand = simplify_(operand); - if (digests.add(operand.digest)) { + // Discard the first few NULL operands + if ((!operands.isEmpty() || !RexUtil.isNull(operand)) + && digests.add(operand.digest)) { operands.add(operand); } if (!operand.getType().isNullable()) { diff --git a/core/src/test/java/org/apache/calcite/test/RexProgramBuilderBase.java b/core/src/test/java/org/apache/calcite/test/RexProgramBuilderBase.java index e3c651fdd11..3a7d980d1f0 100644 --- a/core/src/test/java/org/apache/calcite/test/RexProgramBuilderBase.java +++ b/core/src/test/java/org/apache/calcite/test/RexProgramBuilderBase.java @@ -468,7 +468,7 @@ protected RexNode vBoolNotNull(int arg) { /** * Creates {@code nullable int variable} with index of 0. * If you need several distinct variables, use {@link #vInt(int)}. - * The resulting node would look like {@code ?0.notNullInt0} + * The resulting node would look like {@code ?0.int0} * * @return nullable int variable with index of 0 */ diff --git a/core/src/test/java/org/apache/calcite/test/RexProgramTest.java b/core/src/test/java/org/apache/calcite/test/RexProgramTest.java index b76500a22f2..b14b3d11640 100644 --- a/core/src/test/java/org/apache/calcite/test/RexProgramTest.java +++ b/core/src/test/java/org/apache/calcite/test/RexProgramTest.java @@ -56,7 +56,6 @@ import com.google.common.collect.Multimap; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; import java.math.BigDecimal; @@ -2090,14 +2089,40 @@ private void assertTypeAndToString( "IS DISTINCT FROM(?0.bool0, ?0.bool1)"); } - @Ignore("[CALCITE-2505] java.lang.AssertionError: result mismatch") - @Test public void coalescePlusNull() { - // when applied to {?0.int0=-1}, - // COALESCE(+(null), +(?0.int0)) yielded -1, - // and +(null) yielded NULL + @Test public void coalesceUnaryPlus() { checkSimplify2( coalesce(unaryPlus(nullInt), unaryPlus(vInt())), - "...", "..."); + "?0.int0", "?0.int0"); + + checkSimplify2( + coalesce(unaryPlus(nullInt), unaryPlus(nullInt)), + "null", "null"); + + checkSimplify2( + coalesce(unaryPlus(nullInt), unaryPlus(nullInt), unaryPlus(vInt())), + "?0.int0", "?0.int0"); + + checkSimplify2( + coalesce(unaryPlus(nullInt), unaryPlus(nullInt), + unaryPlus(vInt()), unaryPlus(vInt(1))), + "COALESCE(?0.int0, ?0.int1)", "COALESCE(?0.int0, ?0.int1)"); + + checkSimplify2( + coalesce(unaryPlus(nullInt), unaryPlus(nullInt), + unaryPlus(vIntNotNull()), unaryPlus(vInt(1))), + "?0.notNullInt0", "?0.notNullInt0"); + + checkSimplify2( + coalesce(unaryPlus(vInt(0)), unaryPlus(vInt(1))), + "COALESCE(?0.int0, ?0.int1)", "COALESCE(?0.int0, ?0.int1)"); + + checkSimplify2( + coalesce(unaryPlus(vInt(0)), unaryPlus(nullInt), unaryPlus(vInt(1))), + "COALESCE(?0.int0, null, ?0.int1)", "COALESCE(?0.int0, null, ?0.int1)"); + + checkSimplify2( + coalesce(unaryPlus(vIntNotNull()), unaryPlus(nullInt), unaryPlus(vInt(1))), + "?0.notNullInt0", "?0.notNullInt0"); } /** Converts a map to a string, sorting on the string representation of its