This is an automated email from the ASF dual-hosted git repository.
chunwei pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/calcite.git
The following commit(s) were added to refs/heads/master by this push:
new ea4293b [CALCITE-4094] Allow SqlOperator of SqlKind#OTHER_FUNCTION to
define a Strong.Policy Follow-up after review comments
ea4293b is described below
commit ea4293b8e3665d5927779db79eb7f9de03f76c83
Author: rubenada <[email protected]>
AuthorDate: Sat Jul 11 14:01:45 2020 +0200
[CALCITE-4094] Allow SqlOperator of SqlKind#OTHER_FUNCTION to define a
Strong.Policy
Follow-up after review comments
---
.../main/java/org/apache/calcite/plan/Strong.java | 35 ++++++--------
.../java/org/apache/calcite/sql/SqlOperator.java | 12 +++++
.../org/apache/calcite/rex/RexProgramTest.java | 8 ++--
.../calcite/sql/test/SqlOperatorBaseTest.java | 53 +++++++++++-----------
4 files changed, 58 insertions(+), 50 deletions(-)
diff --git a/core/src/main/java/org/apache/calcite/plan/Strong.java
b/core/src/main/java/org/apache/calcite/plan/Strong.java
index 745786f..057935e 100644
--- a/core/src/main/java/org/apache/calcite/plan/Strong.java
+++ b/core/src/main/java/org/apache/calcite/plan/Strong.java
@@ -29,13 +29,10 @@ import org.apache.calcite.util.ImmutableBitSet;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
-import org.apiguardian.api.API;
-
import java.util.ArrayList;
import java.util.EnumMap;
import java.util.List;
import java.util.Map;
-import java.util.function.Supplier;
/** Utilities for strong predicates.
*
@@ -92,9 +89,9 @@ public class Strong {
* Returns how to deduce whether a particular kind of expression is null,
* given whether its arguments are null.
*
- * @deprecated Use {@link Strong#policy(RexNode)}
+ * @deprecated Use {@link Strong#policy(RexNode)} or {@link
Strong#policy(SqlOperator)}
*/
- @Deprecated // to be removed before 1.25
+ @Deprecated // to be removed before 2.0
public static Policy policy(SqlKind kind) {
return MAP.getOrDefault(kind, Policy.AS_IS);
}
@@ -104,15 +101,24 @@ public class Strong {
* given whether its arguments are null.
*/
public static Policy policy(RexNode rexNode) {
- if (rexNode instanceof RexCall
- && ((RexCall) rexNode).getOperator() instanceof PolicySupplier) {
- final PolicySupplier supplier = (PolicySupplier) ((RexCall)
rexNode).getOperator();
- return supplier.get();
+ if (rexNode instanceof RexCall) {
+ return policy(((RexCall) rexNode).getOperator());
}
return MAP.getOrDefault(rexNode.getKind(), Policy.AS_IS);
}
/**
+ * Returns how to deduce whether a particular {@link SqlOperator} expression
is null,
+ * given whether its arguments are null.
+ */
+ public static Policy policy(SqlOperator operator) {
+ if (operator.getStrongPolicyInference() != null) {
+ return operator.getStrongPolicyInference().get();
+ }
+ return MAP.getOrDefault(operator.getKind(), Policy.AS_IS);
+ }
+
+ /**
* Returns whether a given expression is strong.
*
* <p>Examples:</p>
@@ -316,15 +322,4 @@ public class Strong {
/** This kind of expression may be null. There is no way to rewrite. */
AS_IS,
}
-
- /**
- * Interface to allow {@link SqlOperator}s to define their own {@link
Policy}.
- * For example, a UDF in a downstream project can implement it and have a
specific policy.
- *
- * @see Strong
- */
- @API(status = API.Status.EXPERIMENTAL, since = "1.24")
- public interface PolicySupplier extends Supplier<Policy> {
- Policy get();
- }
}
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 2506254..199681c 100644
--- a/core/src/main/java/org/apache/calcite/sql/SqlOperator.java
+++ b/core/src/main/java/org/apache/calcite/sql/SqlOperator.java
@@ -17,6 +17,7 @@
package org.apache.calcite.sql;
import org.apache.calcite.linq4j.Ord;
+import org.apache.calcite.plan.Strong;
import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.rel.type.RelDataTypeFactory;
import org.apache.calcite.sql.fun.SqlStdOperatorTable;
@@ -40,6 +41,7 @@ import com.google.common.collect.ImmutableList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
+import java.util.function.Supplier;
import static org.apache.calcite.util.Static.RESOURCE;
@@ -892,6 +894,16 @@ public abstract class SqlOperator {
}
/**
+ * 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 from the operator's
{@link SqlKind}.
+ *
+ * @see Strong
+ */
+ public Supplier<Strong.Policy> getStrongPolicyInference() {
+ return null;
+ }
+
+ /**
* Returns whether this operator is monotonic.
*
* <p>Default implementation returns {@link SqlMonotonicity#NOT_MONOTONIC}.
diff --git a/core/src/test/java/org/apache/calcite/rex/RexProgramTest.java
b/core/src/test/java/org/apache/calcite/rex/RexProgramTest.java
index c255235..0c56498 100644
--- a/core/src/test/java/org/apache/calcite/rex/RexProgramTest.java
+++ b/core/src/test/java/org/apache/calcite/rex/RexProgramTest.java
@@ -56,6 +56,7 @@ import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
+import java.util.function.Supplier;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
@@ -2671,8 +2672,7 @@ class RexProgramTest extends RexProgramTestBase {
checkSimplifyUnchanged(expr);
}
- private static class SqlSpecialOperatorWithPolicy extends SqlSpecialOperator
- implements Strong.PolicySupplier {
+ private static class SqlSpecialOperatorWithPolicy extends SqlSpecialOperator
{
private final Strong.Policy policy;
private SqlSpecialOperatorWithPolicy(String name, SqlKind kind, int prec,
boolean leftAssoc,
SqlReturnTypeInference returnTypeInference, SqlOperandTypeInference
operandTypeInference,
@@ -2681,8 +2681,8 @@ class RexProgramTest extends RexProgramTestBase {
operandTypeChecker);
this.policy = policy;
}
- @Override public Strong.Policy get() {
- return policy;
+ @Override public Supplier<Strong.Policy> getStrongPolicyInference() {
+ return () -> policy;
}
}
diff --git
a/core/src/test/java/org/apache/calcite/sql/test/SqlOperatorBaseTest.java
b/core/src/test/java/org/apache/calcite/sql/test/SqlOperatorBaseTest.java
index 0d2f838..2802373 100644
--- a/core/src/test/java/org/apache/calcite/sql/test/SqlOperatorBaseTest.java
+++ b/core/src/test/java/org/apache/calcite/sql/test/SqlOperatorBaseTest.java
@@ -19,11 +19,13 @@ package org.apache.calcite.sql.test;
import org.apache.calcite.avatica.util.DateTimeUtils;
import org.apache.calcite.config.CalciteConnectionProperty;
import org.apache.calcite.linq4j.Linq4j;
+import org.apache.calcite.plan.Strong;
import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.rel.type.RelDataTypeFactory;
import org.apache.calcite.runtime.CalciteContextException;
import org.apache.calcite.runtime.CalciteException;
import org.apache.calcite.runtime.Hook;
+import org.apache.calcite.sql.SqlAggFunction;
import org.apache.calcite.sql.SqlCall;
import org.apache.calcite.sql.SqlCallBinding;
import org.apache.calcite.sql.SqlIdentifier;
@@ -9420,32 +9422,31 @@ public abstract class SqlOperatorBaseTest {
|| s.matches("MOD\\(.*, 0\\)")) {
continue;
}
- // TODO this part is deactivated because it uses a deprecated method
-// final Strong.Policy policy = Strong.policy(op.kind);
-// try {
-// if (nullCount > 0 && policy == Strong.Policy.ANY) {
-// tester.checkNull(s);
-// } else {
-// final String query;
-// if (op instanceof SqlAggFunction) {
-// if (op.requiresOrder()) {
-// query = "SELECT " + s + " OVER () FROM (VALUES (1))";
-// } else {
-// query = "SELECT " + s + " FROM (VALUES (1))";
-// }
-// } else {
-// query = AbstractSqlTester.buildQuery(s);
-// }
-// tester.check(query, SqlTests.ANY_TYPE_CHECKER,
-// SqlTests.ANY_PARAMETER_CHECKER, result -> { });
-// }
-// } catch (Throwable e) {
-// // Logging the top-level throwable directly makes the message
-// // difficult to read since it either contains too much
information
-// // or very few details.
-// Throwable cause = findMostDescriptiveCause(e);
-// LOGGER.info("Failed: " + s + ": " + cause);
-// }
+ final Strong.Policy policy = Strong.policy(op);
+ try {
+ if (nullCount > 0 && policy == Strong.Policy.ANY) {
+ tester.checkNull(s);
+ } else {
+ final String query;
+ if (op instanceof SqlAggFunction) {
+ if (op.requiresOrder()) {
+ query = "SELECT " + s + " OVER () FROM (VALUES (1))";
+ } else {
+ query = "SELECT " + s + " FROM (VALUES (1))";
+ }
+ } else {
+ query = AbstractSqlTester.buildQuery(s);
+ }
+ tester.check(query, SqlTests.ANY_TYPE_CHECKER,
+ SqlTests.ANY_PARAMETER_CHECKER, result -> { });
+ }
+ } catch (Throwable e) {
+ // Logging the top-level throwable directly makes the message
+ // difficult to read since it either contains too much information
+ // or very few details.
+ Throwable cause = findMostDescriptiveCause(e);
+ LOGGER.info("Failed: " + s + ": " + cause);
+ }
}
}
}