This is an automated email from the ASF dual-hosted git repository.
mbudiu pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/calcite.git
The following commit(s) were added to refs/heads/main by this push:
new b60598b47e [CALCITE-6518] ClassCastException during validation when
loading multiple libraries
b60598b47e is described below
commit b60598b47e86b2b21639d193b374f1d6d4dcd139
Author: Mihai Budiu <[email protected]>
AuthorDate: Mon Aug 12 23:39:01 2024 -0700
[CALCITE-6518] ClassCastException during validation when loading multiple
libraries
Signed-off-by: Mihai Budiu <[email protected]>
---
.../java/org/apache/calcite/sql/SqlFunction.java | 4 +-
.../main/java/org/apache/calcite/sql/SqlKind.java | 94 +++++++++++++++++++++-
.../main/java/org/apache/calcite/sql/SqlUtil.java | 3 +-
.../main/java/org/apache/calcite/util/Util.java | 2 +-
.../calcite/sql/test/SqlOperatorFixture.java | 15 ++++
.../org/apache/calcite/test/SqlOperatorTest.java | 8 ++
6 files changed, 122 insertions(+), 4 deletions(-)
diff --git a/core/src/main/java/org/apache/calcite/sql/SqlFunction.java
b/core/src/main/java/org/apache/calcite/sql/SqlFunction.java
index 626c28eb07..57e4748563 100644
--- a/core/src/main/java/org/apache/calcite/sql/SqlFunction.java
+++ b/core/src/main/java/org/apache/calcite/sql/SqlFunction.java
@@ -310,7 +310,9 @@ public class SqlFunction extends SqlOperator {
// if we succeed, the arguments would be wrapped with CAST operator.
if (function != null) {
TypeCoercion typeCoercion = validator.getTypeCoercion();
- if (typeCoercion.userDefinedFunctionCoercion(scope, call,
function)) {
+ if ((function.category == SqlFunctionCategory.USER_DEFINED_FUNCTION
+ || function.category ==
SqlFunctionCategory.USER_DEFINED_TABLE_FUNCTION)
+ && typeCoercion.userDefinedFunctionCoercion(scope, call,
function)) {
break validCoercionType;
}
}
diff --git a/core/src/main/java/org/apache/calcite/sql/SqlKind.java
b/core/src/main/java/org/apache/calcite/sql/SqlKind.java
index e292990e47..70094d1b49 100644
--- a/core/src/main/java/org/apache/calcite/sql/SqlKind.java
+++ b/core/src/main/java/org/apache/calcite/sql/SqlKind.java
@@ -29,7 +29,7 @@ import java.util.Set;
* Enumerates the possible types of {@link SqlNode}.
*
* <p>The values are immutable, canonical constants, so you can use Kinds to
- * find particular types of expressions quickly. To identity a call to a common
+ * find particular types of expressions quickly. To identify a call to a common
* operator such as '=', use {@link org.apache.calcite.sql.SqlNode#isA}:
*
* <blockquote>
@@ -1715,6 +1715,98 @@ public enum SqlKind {
return category.contains(this);
}
+ /**
+ * If this kind represents a non-standard function, return OTHER_FUNCTION,
otherwise
+ * return this. Do not add standard functions here.
+ */
+ public SqlKind getFunctionKind() {
+ switch (this) {
+ case CONVERT:
+ case TRANSLATE:
+ case POSITION:
+ case DECODE:
+ case NVL:
+ case NVL2:
+ case GREATEST:
+ case GREATEST_PG:
+ case CONCAT2:
+ case CONCAT_WITH_NULL:
+ case CONCAT_WS_MSSQL:
+ case CONCAT_WS_POSTGRESQL:
+ case CONCAT_WS_SPARK:
+ case IF:
+ case LEAST:
+ case LEAST_PG:
+ case LOG:
+ case DATE_ADD:
+ case DATE_TRUNC:
+ case DATE_SUB:
+ case TIME_ADD:
+ case TIME_SUB:
+ case TIMESTAMP_ADD:
+ case TIMESTAMP_DIFF:
+ case TIMESTAMP_SUB:
+ case SAFE_CAST:
+ case FLOOR:
+ case CEIL:
+ case TRIM:
+ case LTRIM:
+ case RTRIM:
+ case ARRAY_APPEND:
+ case ARRAY_COMPACT:
+ case ARRAY_CONCAT:
+ case ARRAY_CONTAINS:
+ case ARRAY_DISTINCT:
+ case ARRAY_EXCEPT:
+ case ARRAY_INSERT:
+ case ARRAY_INTERSECT:
+ case ARRAY_JOIN:
+ case ARRAY_LENGTH:
+ case ARRAY_MAX:
+ case ARRAY_MIN:
+ case ARRAY_POSITION:
+ case ARRAY_PREPEND:
+ case ARRAY_REMOVE:
+ case ARRAY_REPEAT:
+ case ARRAY_REVERSE:
+ case ARRAY_SIZE:
+ case ARRAY_TO_STRING:
+ case ARRAY_UNION:
+ case ARRAYS_OVERLAP:
+ case ARRAYS_ZIP:
+ case SORT_ARRAY:
+ case MAP_CONCAT:
+ case MAP_ENTRIES:
+ case MAP_KEYS:
+ case MAP_VALUES:
+ case MAP_CONTAINS_KEY:
+ case MAP_FROM_ARRAYS:
+ case MAP_FROM_ENTRIES:
+ case STR_TO_MAP:
+ case REVERSE:
+ case REVERSE_SPARK:
+ case SOUNDEX_SPARK:
+ case SUBSTR_BIG_QUERY:
+ case SUBSTR_MYSQL:
+ case SUBSTR_ORACLE:
+ case SUBSTR_POSTGRESQL:
+ case CHAR_LENGTH:
+ case ENDS_WITH:
+ case STARTS_WITH:
+ case JSON_TYPE:
+ case CONTAINS_SUBSTR:
+ case ST_DWITHIN:
+ case ST_POINT:
+ case ST_POINT3:
+ case ST_MAKE_LINE:
+ case ST_CONTAINS:
+ case HILBERT:
+ return OTHER_FUNCTION;
+ default:
+ return this;
+ }
+ }
+
@SafeVarargs
private static <E extends Enum<E>> EnumSet<E> concat(EnumSet<E> set0,
EnumSet<E>... sets) {
diff --git a/core/src/main/java/org/apache/calcite/sql/SqlUtil.java
b/core/src/main/java/org/apache/calcite/sql/SqlUtil.java
index edb50aac38..d0c9157b56 100644
--- a/core/src/main/java/org/apache/calcite/sql/SqlUtil.java
+++ b/core/src/main/java/org/apache/calcite/sql/SqlUtil.java
@@ -519,7 +519,8 @@ public abstract class SqlUtil {
private static Iterator<SqlOperator> filterOperatorRoutinesByKind(
Iterator<SqlOperator> routines, final SqlKind sqlKind) {
return Iterators.filter(routines,
- operator -> Objects.requireNonNull(operator, "operator").getKind() ==
sqlKind);
+ operator -> Objects.requireNonNull(operator, "operator")
+ .getKind().getFunctionKind() == sqlKind);
}
/**
diff --git a/core/src/main/java/org/apache/calcite/util/Util.java
b/core/src/main/java/org/apache/calcite/util/Util.java
index e08f8f5b75..9e3bfbbc3b 100644
--- a/core/src/main/java/org/apache/calcite/util/Util.java
+++ b/core/src/main/java/org/apache/calcite/util/Util.java
@@ -1075,7 +1075,7 @@ public class Util {
* feature has not been implemented, but should be.
*
* <p>If every 'hole' in our functionality uses this method, it will be
- * easier for us to identity the holes. Throwing a
+ * easier for us to identify the holes. Throwing a
* {@link java.lang.UnsupportedOperationException} isn't as good, because
* sometimes we actually want to partially implement an API.
*
diff --git
a/testkit/src/main/java/org/apache/calcite/sql/test/SqlOperatorFixture.java
b/testkit/src/main/java/org/apache/calcite/sql/test/SqlOperatorFixture.java
index a4e2d0aaab..db200847c5 100644
--- a/testkit/src/main/java/org/apache/calcite/sql/test/SqlOperatorFixture.java
+++ b/testkit/src/main/java/org/apache/calcite/sql/test/SqlOperatorFixture.java
@@ -39,6 +39,8 @@ import org.apache.calcite.util.Bug;
import org.checkerframework.checker.nullness.qual.Nullable;
+import java.util.ArrayList;
+import java.util.List;
import java.util.function.Consumer;
import java.util.function.UnaryOperator;
@@ -568,6 +570,19 @@ public interface SqlOperatorFixture extends AutoCloseable {
.with(CalciteConnectionProperty.FUN, library.fun));
}
+ default SqlOperatorFixture withLibraries(SqlLibrary... libraries) {
+ List<String> names = new ArrayList<>();
+ for (SqlLibrary lib : libraries) {
+ names.add(lib.fun);
+ }
+ return withOperatorTable(
+ SqlLibraryOperatorTableFactory.INSTANCE
+ .getOperatorTable(libraries))
+ .withConnectionFactory(cf ->
+ cf.with(ConnectionFactories.add(CalciteAssert.SchemaSpec.HR))
+ .with(CalciteConnectionProperty.FUN, String.join(",", names)));
+ }
+
/** Applies this fixture to some code for each of the given libraries. */
default void forEachLibrary(Iterable<? extends SqlLibrary> libraries,
Consumer<SqlOperatorFixture> consumer) {
diff --git a/testkit/src/main/java/org/apache/calcite/test/SqlOperatorTest.java
b/testkit/src/main/java/org/apache/calcite/test/SqlOperatorTest.java
index c14b6d0003..d6563f3aff 100644
--- a/testkit/src/main/java/org/apache/calcite/test/SqlOperatorTest.java
+++ b/testkit/src/main/java/org/apache/calcite/test/SqlOperatorTest.java
@@ -2424,6 +2424,14 @@ public class SqlOperatorTest {
f.checkFails("^concat()^", INVALID_ARGUMENTS_NUMBER, false);
}
+ /** Test case for <a
href="https://issues.apache.org/jira/browse/CALCITE-6518">
+ * ClassCastException during validation when loading multiple libraries</a>.
*/
+ @Test void testManyLibraries() {
+ SqlOperatorFixture f =
+ fixture().withLibraries(SqlLibrary.STANDARD, SqlLibrary.MYSQL,
SqlLibrary.POSTGRESQL);
+ f.checkScalar("substr('a', 1, 2)", "a", "VARCHAR(1) NOT NULL");
+ }
+
/** Test case for
* <a
href="https://issues.apache.org/jira/browse/CALCITE-5771">[CALCITE-5771]
* Apply two different NULL semantics for CONCAT function(enabled in MySQL,