Repository: calcite Updated Branches: refs/heads/branch-1.15 acdf53c37 -> 83a8caf79 (forced update)
[CALCITE-2074] Simplification of point ranges that are open above or below yields wrong results Suppose that R is a point range that is closed at one or both ends, i.e. [x, x), or (x, x] or (x, y). Such a range is empty, but we were wrongly simplifying it to a point. It is only valid to simplify open-open ranges, [x, x], to a point. For example, "5 >= x AND x > 5", described as the closed-open range "[5, 5)", should simplify to false. Project: http://git-wip-us.apache.org/repos/asf/calcite/repo Commit: http://git-wip-us.apache.org/repos/asf/calcite/commit/11da17b5 Tree: http://git-wip-us.apache.org/repos/asf/calcite/tree/11da17b5 Diff: http://git-wip-us.apache.org/repos/asf/calcite/diff/11da17b5 Branch: refs/heads/branch-1.15 Commit: 11da17b59249b4bd1bbd384a53f1cfd9ebaaf888 Parents: 9bb5400 Author: Julian Hyde <[email protected]> Authored: Fri Dec 1 16:13:22 2017 -0800 Committer: Julian Hyde <[email protected]> Committed: Fri Dec 1 16:13:54 2017 -0800 ---------------------------------------------------------------------- .../org/apache/calcite/rex/RexSimplify.java | 6 +++++ .../org/apache/calcite/test/RexProgramTest.java | 24 ++++++++++++++++++++ 2 files changed, 30 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/calcite/blob/11da17b5/core/src/main/java/org/apache/calcite/rex/RexSimplify.java ---------------------------------------------------------------------- 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 464d28f..cd42c81 100644 --- a/core/src/main/java/org/apache/calcite/rex/RexSimplify.java +++ b/core/src/main/java/org/apache/calcite/rex/RexSimplify.java @@ -826,6 +826,12 @@ public class RexSimplify { // Term is always satisfied given these predicates return rexBuilder.makeLiteral(true); } else if (range2.lowerEndpoint().equals(range2.upperEndpoint())) { + if (range2.lowerBoundType() == BoundType.OPEN + || range2.upperBoundType() == BoundType.OPEN) { + // range is a point, but does not include its endpoint, therefore is + // effectively empty + return rexBuilder.makeLiteral(false); + } // range is now a point; it's worth simplifying return rexBuilder.makeCall(SqlStdOperatorTable.EQUALS, comparison.ref, rexBuilder.makeLiteral(range2.lowerEndpoint(), http://git-wip-us.apache.org/repos/asf/calcite/blob/11da17b5/core/src/test/java/org/apache/calcite/test/RexProgramTest.java ---------------------------------------------------------------------- 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 6cc4e44..9501959 100644 --- a/core/src/test/java/org/apache/calcite/test/RexProgramTest.java +++ b/core/src/test/java/org/apache/calcite/test/RexProgramTest.java @@ -1411,6 +1411,30 @@ public class RexProgramTest { RelOptPredicateList.of(rexBuilder, ImmutableList.of(lt(bRef, literal10), ge(aRef, literal5))), ">(?0.a, 5)"); + + // condition "a > 5" + // with pre-condition "a <= 5" + // yields "false" + checkSimplifyFilter(gt(aRef, literal5), + RelOptPredicateList.of(rexBuilder, + ImmutableList.of(le(aRef, literal5))), + "false"); + + // condition "a > 5" + // with pre-condition "a <= 5 and b <= 5" + // yields "false" + checkSimplifyFilter(gt(aRef, literal5), + RelOptPredicateList.of(rexBuilder, + ImmutableList.of(le(aRef, literal5), le(bRef, literal5))), + "false"); + + // condition "a > 5 or b > 5" + // with pre-condition "a <= 5 and b <= 5" + // should yield "false" but yields "a = 5 or b = 5" + checkSimplifyFilter(or(gt(aRef, literal5), gt(bRef, literal5)), + RelOptPredicateList.of(rexBuilder, + ImmutableList.of(le(aRef, literal5), le(bRef, literal5))), + "false"); } /** Unit test for
