This is an automated email from the ASF dual-hosted git repository. jhyde pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/calcite.git
commit 6a9832c14e7c7c02a0176920b87d15dab474300a Author: Julian Hyde <[email protected]> AuthorDate: Mon May 24 22:11:38 2021 -0700 Refactor: Add method SqlOperator.reverse() Deprecate SqlStdOperatorTable.reverse(SqlOperator); remove RexImplicationChecker.reverse(SqlOperator) and SqlImplementor.reverseOperatorDirection(SqlOperator). --- .../java/org/apache/calcite/plan/RelOptUtil.java | 48 +++++++++++----------- .../apache/calcite/plan/RexImplicationChecker.java | 16 ++++---- .../apache/calcite/rel/rel2sql/SqlImplementor.java | 21 +--------- .../java/org/apache/calcite/rex/RexNormalize.java | 12 +++--- .../main/java/org/apache/calcite/rex/RexUtil.java | 5 +-- .../org/apache/calcite/sql/SqlBinaryOperator.java | 26 ++++++++++++ .../java/org/apache/calcite/sql/SqlOperator.java | 23 ++++++++++- .../calcite/sql/fun/SqlStdOperatorTable.java | 4 ++ 8 files changed, 92 insertions(+), 63 deletions(-) diff --git a/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java b/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java index 61fb234..939a8a1 100644 --- a/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java +++ b/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java @@ -129,7 +129,6 @@ import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.NavigableSet; -import java.util.Objects; import java.util.Set; import java.util.TreeSet; import java.util.function.Supplier; @@ -137,6 +136,8 @@ import java.util.stream.Collectors; import static org.apache.calcite.rel.type.RelDataTypeImpl.NON_NULLABLE_SUFFIX; +import static java.util.Objects.requireNonNull; + /** * <code>RelOptUtil</code> defines static utility methods for use in optimizing * {@link RelNode}s. @@ -1264,22 +1265,21 @@ public abstract class RelOptUtil { } } - if (condition instanceof RexCall) { - RexCall call = (RexCall) condition; - if (call.getKind() == SqlKind.AND) { - for (RexNode operand : call.getOperands()) { - splitJoinCondition( - sysFieldList, - inputs, - operand, - joinKeys, - filterNulls, - rangeOp, - nonEquiList); - } - return; + if (condition.getKind() == SqlKind.AND) { + for (RexNode operand : ((RexCall) condition).getOperands()) { + splitJoinCondition( + sysFieldList, + inputs, + operand, + joinKeys, + filterNulls, + rangeOp, + nonEquiList); } + return; + } + if (condition instanceof RexCall) { RexNode leftKey = null; RexNode rightKey = null; int leftInput = 0; @@ -1288,7 +1288,8 @@ public abstract class RelOptUtil { List<RelDataTypeField> rightFields = null; boolean reverse = false; - call = collapseExpandedIsNotDistinctFromExpr(call, rexBuilder); + final RexCall call = + collapseExpandedIsNotDistinctFromExpr((RexCall) condition, rexBuilder); SqlKind kind = call.getKind(); // Only consider range operators if we haven't already seen one @@ -1443,10 +1444,11 @@ public abstract class RelOptUtil { if (rangeOp != null && kind != SqlKind.EQUALS && kind != SqlKind.IS_DISTINCT_FROM) { + SqlOperator op = call.getOperator(); if (reverse) { - kind = kind.reverse(); + op = requireNonNull(op.reverse()); } - rangeOp.add(op(kind, call.getOperator())); + rangeOp.add(op); } return; } // else fall through and add this condition as nonEqui condition @@ -4322,7 +4324,7 @@ public abstract class RelOptUtil { } else if (type instanceof MultisetSqlType) { // E.g. "INTEGER NOT NULL MULTISET NOT NULL" RelDataType componentType = - Objects.requireNonNull( + requireNonNull( type.getComponentType(), () -> "type.getComponentType() for " + type); accept(componentType); @@ -4419,9 +4421,9 @@ public abstract class RelOptUtil { if (call.getOperator() == RexBuilder.GET_OPERATOR) { RexLiteral literal = (RexLiteral) call.getOperands().get(1); if (extraFields != null) { - Objects.requireNonNull(literal, () -> "first operand in " + call); + requireNonNull(literal, () -> "first operand in " + call); String value2 = (String) literal.getValue2(); - Objects.requireNonNull(value2, () -> "value of the first operand in " + call); + requireNonNull(value2, () -> "value of the first operand in " + call); extraFields.add( new RelDataTypeFieldImpl( value2, @@ -4527,11 +4529,11 @@ public abstract class RelOptUtil { type = leftDestFields.get(destIndex).getType(); } else { type = - Objects.requireNonNull(rightDestFields, "rightDestFields") + requireNonNull(rightDestFields, "rightDestFields") .get(destIndex - nLeftDestFields).getType(); } } else { - type = Objects.requireNonNull(srcFields, "srcFields").get(srcIndex).getType(); + type = requireNonNull(srcFields, "srcFields").get(srcIndex).getType(); } if ((adjustments[srcIndex] != 0) || (srcFields == null) diff --git a/core/src/main/java/org/apache/calcite/plan/RexImplicationChecker.java b/core/src/main/java/org/apache/calcite/plan/RexImplicationChecker.java index f8d1028..3dff20b 100644 --- a/core/src/main/java/org/apache/calcite/plan/RexImplicationChecker.java +++ b/core/src/main/java/org/apache/calcite/plan/RexImplicationChecker.java @@ -43,9 +43,10 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Objects; import java.util.Set; +import static java.util.Objects.requireNonNull; + /** * Checks whether one condition logically implies another. * @@ -71,9 +72,9 @@ public class RexImplicationChecker { RexBuilder builder, RexExecutor executor, RelDataType rowType) { - this.builder = Objects.requireNonNull(builder, "builder"); - this.executor = Objects.requireNonNull(executor, "executor"); - this.rowType = Objects.requireNonNull(rowType, "rowType"); + this.builder = requireNonNull(builder, "builder"); + this.executor = requireNonNull(executor, "executor"); + this.rowType = requireNonNull(rowType, "rowType"); } /** @@ -494,14 +495,11 @@ public class RexImplicationChecker { if (first.isA(SqlKind.LITERAL) && second.isA(SqlKind.INPUT_REF)) { - updateUsage(reverse(call.getOperator()), (RexInputRef) second, first); + updateUsage(requireNonNull(call.getOperator().reverse()), + (RexInputRef) second, first); } } - private static SqlOperator reverse(SqlOperator op) { - return RelOptUtil.op(op.getKind().reverse(), op); - } - private void updateUsage(SqlOperator op, RexInputRef inputRef, @Nullable RexNode literal) { final InputRefUsage<SqlOperator, @Nullable RexNode> inputRefUse = diff --git a/core/src/main/java/org/apache/calcite/rel/rel2sql/SqlImplementor.java b/core/src/main/java/org/apache/calcite/rel/rel2sql/SqlImplementor.java index 8d5f965..efc7d5d 100644 --- a/core/src/main/java/org/apache/calcite/rel/rel2sql/SqlImplementor.java +++ b/core/src/main/java/org/apache/calcite/rel/rel2sql/SqlImplementor.java @@ -342,7 +342,7 @@ public abstract class SqlImplementor { if (op1.getIndex() < leftFieldCount && op0.getIndex() >= leftFieldCount) { // Arguments were of form 'op1 = op0' - return reverseOperatorDirection(op).createCall(POS, + return requireNonNull(op.reverse()).createCall(POS, leftContext.field(op1.getIndex()), rightContext.field(op0.getIndex() - leftFieldCount)); } @@ -424,25 +424,6 @@ public abstract class SqlImplementor { return node; } - private static SqlOperator reverseOperatorDirection(SqlOperator op) { - switch (op.kind) { - case GREATER_THAN: - return SqlStdOperatorTable.LESS_THAN; - case GREATER_THAN_OR_EQUAL: - return SqlStdOperatorTable.LESS_THAN_OR_EQUAL; - case LESS_THAN: - return SqlStdOperatorTable.GREATER_THAN; - case LESS_THAN_OR_EQUAL: - return SqlStdOperatorTable.GREATER_THAN_OR_EQUAL; - case EQUALS: - case IS_NOT_DISTINCT_FROM: - case NOT_EQUALS: - return op; - default: - throw new AssertionError(op); - } - } - public static JoinType joinType(JoinRelType joinType) { switch (joinType) { case LEFT: diff --git a/core/src/main/java/org/apache/calcite/rex/RexNormalize.java b/core/src/main/java/org/apache/calcite/rex/RexNormalize.java index c5b9cf9..713a1f7 100644 --- a/core/src/main/java/org/apache/calcite/rex/RexNormalize.java +++ b/core/src/main/java/org/apache/calcite/rex/RexNormalize.java @@ -19,7 +19,6 @@ package org.apache.calcite.rex; import org.apache.calcite.config.CalciteSystemProperty; import org.apache.calcite.sql.SqlKind; import org.apache.calcite.sql.SqlOperator; -import org.apache.calcite.sql.fun.SqlStdOperatorTable; import org.apache.calcite.sql.type.SqlTypeUtil; import org.apache.calcite.util.Pair; @@ -31,6 +30,8 @@ import java.util.Arrays; import java.util.List; import java.util.Objects; +import static java.util.Objects.requireNonNull; + /** * Context required to normalize a row-expression. * @@ -82,8 +83,7 @@ public class RexNormalize { final SqlKind reversedKind = kind.reverse(); final int x = reversedKind.compareTo(kind); if (x < 0) { - return Pair.of( - SqlStdOperatorTable.reverse(operator), + return Pair.of(requireNonNull(operator.reverse()), ImmutableList.of(operand1, operand0)); } if (x > 0) { @@ -99,8 +99,7 @@ public class RexNormalize { // When $1 > $0 is normalized, the operation needs to be flipped // so we sort arguments first, then flip the sign. - return Pair.of( - SqlStdOperatorTable.reverse(operator), + return Pair.of(requireNonNull(operator.reverse()), ImmutableList.of(operand1, operand0)); } return original; @@ -125,8 +124,7 @@ public class RexNormalize { final SqlKind reversedKind = kind.reverse(); final int x = reversedKind.compareTo(kind); if (x < 0) { - return Objects.hash( - SqlStdOperatorTable.reverse(operator), + return Objects.hash(requireNonNull(operator.reverse()), Arrays.asList(operands.get(1), operands.get(0))); } if (isSymmetricalCall(operator, operands.get(0), operands.get(1))) { diff --git a/core/src/main/java/org/apache/calcite/rex/RexUtil.java b/core/src/main/java/org/apache/calcite/rex/RexUtil.java index 4870a82..d5b4bc3 100644 --- a/core/src/main/java/org/apache/calcite/rex/RexUtil.java +++ b/core/src/main/java/org/apache/calcite/rex/RexUtil.java @@ -2090,12 +2090,11 @@ public class RexUtil { case GREATER_THAN: case LESS_THAN_OR_EQUAL: case GREATER_THAN_OR_EQUAL: - final SqlOperator op = op(call.getKind().reverse()); + final SqlOperator op = requireNonNull(call.getOperator().reverse()); return rexBuilder.makeCall(op, Lists.reverse(call.getOperands())); default: - break; + return null; } - return null; } @Deprecated // to be removed before 2.0 diff --git a/core/src/main/java/org/apache/calcite/sql/SqlBinaryOperator.java b/core/src/main/java/org/apache/calcite/sql/SqlBinaryOperator.java index f2de703..96ef1aa 100644 --- a/core/src/main/java/org/apache/calcite/sql/SqlBinaryOperator.java +++ b/core/src/main/java/org/apache/calcite/sql/SqlBinaryOperator.java @@ -99,6 +99,32 @@ public class SqlBinaryOperator extends SqlOperator { return !getName().equals("."); } + @Override public @Nullable SqlOperator reverse() { + switch (kind) { + case EQUALS: + case NOT_EQUALS: + case IS_DISTINCT_FROM: + case IS_NOT_DISTINCT_FROM: + case OR: + case AND: + case PLUS: + case TIMES: + return this; + + case GREATER_THAN: + return SqlStdOperatorTable.LESS_THAN; + case GREATER_THAN_OR_EQUAL: + return SqlStdOperatorTable.LESS_THAN_OR_EQUAL; + case LESS_THAN: + return SqlStdOperatorTable.GREATER_THAN; + case LESS_THAN_OR_EQUAL: + return SqlStdOperatorTable.GREATER_THAN_OR_EQUAL; + + default: + return null; + } + } + @Override protected RelDataType adjustType( SqlValidator validator, final SqlCall call, diff --git a/core/src/main/java/org/apache/calcite/sql/SqlOperator.java b/core/src/main/java/org/apache/calcite/sql/SqlOperator.java index b7e00d8..ece841a 100644 --- a/core/src/main/java/org/apache/calcite/sql/SqlOperator.java +++ b/core/src/main/java/org/apache/calcite/sql/SqlOperator.java @@ -965,11 +965,32 @@ public abstract class SqlOperator { * {@code SqlStdOperatorTable.NOT_LIKE}, and vice versa. * * <p>By default, returns {@code null}, which means there is no inverse - * operator. */ + * operator. + * + * @see #reverse */ public @Nullable SqlOperator not() { return null; } + /** Returns the operator that has the same effect as this operator + * if its arguments are reversed. + * + * <p>For example, {@code SqlStdOperatorTable.GREATER_THAN.reverse()} returns + * {@code SqlStdOperatorTable.LESS_THAN}, and vice versa, + * because {@code a > b} is equivalent to {@code b < a}. + * + * <p>{@code SqlStdOperatorTable.EQUALS.reverse()} returns itself. + * + * <p>By default, returns {@code null}, which means there is no inverse + * operator. + * + * @see SqlOperator#not() + * @see SqlKind#reverse() + */ + public @Nullable SqlOperator reverse() { + return null; + } + /** * Returns the {@link Strong.Policy} strategy for this operator, or null if * there is no particular strategy, in which case this policy will be deducted diff --git a/core/src/main/java/org/apache/calcite/sql/fun/SqlStdOperatorTable.java b/core/src/main/java/org/apache/calcite/sql/fun/SqlStdOperatorTable.java index 76e170d..c228f39 100644 --- a/core/src/main/java/org/apache/calcite/sql/fun/SqlStdOperatorTable.java +++ b/core/src/main/java/org/apache/calcite/sql/fun/SqlStdOperatorTable.java @@ -2611,7 +2611,11 @@ public class SqlStdOperatorTable extends ReflectiveSqlOperatorTable { * direction. Or returns this, if its kind is not reversible. * * <p>For example, {@code reverse(GREATER_THAN)} returns {@link #LESS_THAN}. + * + * @deprecated Use {@link SqlOperator#reverse()}, but beware that it has + * slightly different semantics */ + @Deprecated // to be removed before 2.0 public static SqlOperator reverse(SqlOperator operator) { switch (operator.getKind()) { case GREATER_THAN:
