You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by jh...@apache.org on 2023/04/16 00:31:44 UTC
[calcite] branch main updated: [CALCITE-5606] Add SqlLibrary.ALL
This is an automated email from the ASF dual-hosted git repository.
jhyde 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 96da5297db [CALCITE-5606] Add SqlLibrary.ALL
96da5297db is described below
commit 96da5297db7695ade251356e8bc0833946624a01
Author: zoudan <zo...@bytedance.com>
AuthorDate: Fri Mar 24 00:03:53 2023 +0800
[CALCITE-5606] Add SqlLibrary.ALL
Functions that belong to ALL (denoted with the symbol `*` in
the SQL reference) will be included in all database-specific
libraries (`bigquery`, `calcite`, `oracle`, `mysql`, etc.)
but not in `standard` or `spatial`.
This gives us a convenient way to define functions that are
widely supported but are not in the SQL standard.
Change the library of `TANH`, `COSH`, `SINH` functions to
ALL.
Close apache/calcite#3128
---
.../config/CalciteConnectionConfigImpl.java | 9 ++-
.../org/apache/calcite/sql/fun/SqlLibrary.java | 73 +++++++++++++++++++---
.../sql/fun/SqlLibraryOperatorTableFactory.java | 15 ++++-
.../calcite/sql/fun/SqlLibraryOperators.java | 7 ++-
.../apache/calcite/sql/test/DocumentationTest.java | 18 ++++--
.../java/org/apache/calcite/util/UtilTest.java | 57 +++++++++++++++++
site/_docs/reference.md | 7 ++-
.../calcite/sql/test/SqlOperatorFixture.java | 2 +-
.../org/apache/calcite/test/SqlOperatorTest.java | 6 +-
9 files changed, 169 insertions(+), 25 deletions(-)
diff --git a/core/src/main/java/org/apache/calcite/config/CalciteConnectionConfigImpl.java b/core/src/main/java/org/apache/calcite/config/CalciteConnectionConfigImpl.java
index 204568b9ca..49521bcb68 100644
--- a/core/src/main/java/org/apache/calcite/config/CalciteConnectionConfigImpl.java
+++ b/core/src/main/java/org/apache/calcite/config/CalciteConnectionConfigImpl.java
@@ -113,10 +113,15 @@ public class CalciteConnectionConfigImpl extends ConnectionConfigImpl
if (fun == null || fun.equals("") || fun.equals("standard")) {
return defaultOperatorTable;
}
+ // Parse the libraries
final List<SqlLibrary> libraryList = SqlLibrary.parse(fun);
+ // Load standard plus the specified libraries. If 'all' is among the
+ // specified libraries, it is expanded to all libraries (except standard,
+ // spatial, all).
+ final List<SqlLibrary> libraryList1 =
+ SqlLibrary.expand(ConsList.of(SqlLibrary.STANDARD, libraryList));
final SqlOperatorTable operatorTable =
- SqlLibraryOperatorTableFactory.INSTANCE.getOperatorTable(
- ConsList.of(SqlLibrary.STANDARD, libraryList));
+ SqlLibraryOperatorTableFactory.INSTANCE.getOperatorTable(libraryList1);
return operatorTableClass.cast(operatorTable);
}
diff --git a/core/src/main/java/org/apache/calcite/sql/fun/SqlLibrary.java b/core/src/main/java/org/apache/calcite/sql/fun/SqlLibrary.java
index ee673c06d2..3b75d1a763 100644
--- a/core/src/main/java/org/apache/calcite/sql/fun/SqlLibrary.java
+++ b/core/src/main/java/org/apache/calcite/sql/fun/SqlLibrary.java
@@ -24,9 +24,11 @@ import com.google.common.collect.ImmutableMap;
import org.checkerframework.checker.nullness.qual.Nullable;
+import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
+import java.util.Set;
import static java.util.Objects.requireNonNull;
@@ -48,6 +50,9 @@ public enum SqlLibrary {
STANDARD("", "standard"),
/** Geospatial operators. */
SPATIAL("s", "spatial"),
+ /** A collection of operators that could be used in all libraries;
+ * does not include STANDARD and SPATIAL. */
+ ALL("*", "all"),
/** A collection of operators that are in Google BigQuery but not in standard
* SQL. */
BIG_QUERY("b", "bigquery"),
@@ -56,11 +61,11 @@ public enum SqlLibrary {
/** A collection of operators that are in Apache Hive but not in standard
* SQL. */
HIVE("h", "hive"),
- /** A collection of operators that are in MySQL but not in standard SQL. */
- MYSQL("m", "mysql"),
/** A collection of operators that are in Microsoft SQL Server (MSSql) but not
* in standard SQL. */
MSSQL("q", "mssql"),
+ /** A collection of operators that are in MySQL but not in standard SQL. */
+ MYSQL("m", "mysql"),
/** A collection of operators that are in Oracle but not in standard SQL. */
ORACLE("o", "oracle"),
/** A collection of operators that are in PostgreSQL but not in standard
@@ -70,6 +75,9 @@ public enum SqlLibrary {
* SQL. */
SPARK("s", "spark");
+ /** Map from {@link Enum#name() name} and {@link #fun} to library. */
+ public static final Map<String, SqlLibrary> MAP;
+
/** Abbreviation for the library used in SQL reference. */
public final String abbrev;
@@ -84,6 +92,17 @@ public enum SqlLibrary {
fun.equals(name().toLowerCase(Locale.ROOT).replace("_", "")));
}
+ @SuppressWarnings("SwitchStatementWithTooFewBranches")
+ public List<SqlLibrary> children() {
+ switch (this) {
+ case ALL:
+ return ImmutableList.of(BIG_QUERY, CALCITE, HIVE, MSSQL, MYSQL, ORACLE,
+ POSTGRESQL, SPARK);
+ default:
+ return ImmutableList.of();
+ }
+ }
+
/** Looks up a value.
* Returns null if not found.
* You can use upper- or lower-case name. */
@@ -94,16 +113,54 @@ public enum SqlLibrary {
/** Parses a comma-separated string such as "standard,oracle". */
public static List<SqlLibrary> parse(String libraryNameList) {
final ImmutableList.Builder<SqlLibrary> list = ImmutableList.builder();
- for (String libraryName : libraryNameList.split(",")) {
- SqlLibrary library =
- requireNonNull(SqlLibrary.of(libraryName),
- () -> "library does not exist: " + libraryName);
- list.add(library);
+ if (!libraryNameList.isEmpty()) {
+ for (String libraryName : libraryNameList.split(",")) {
+ @Nullable SqlLibrary library = SqlLibrary.of(libraryName);
+ if (library == null) {
+ throw new IllegalArgumentException("unknown library '" + libraryName
+ + "'");
+ }
+ list.add(library);
+ }
}
return list.build();
}
- public static final Map<String, SqlLibrary> MAP;
+ /** Expands libraries in place.
+ *
+ * <p>Preserves order, and ensures that no library occurs more than once. */
+ public static List<SqlLibrary> expand(
+ Iterable<? extends SqlLibrary> libraries) {
+ // LinkedHashSet ensures that libraries are added only once, and order is
+ // preserved.
+ final Set<SqlLibrary> set = new LinkedHashSet<>();
+ libraries.forEach(library -> addExpansion(set, library));
+ return ImmutableList.copyOf(set);
+ }
+
+ private static void addExpansion(Set<SqlLibrary> set, SqlLibrary library) {
+ if (set.add(library)) {
+ library.children().forEach(subLibrary -> addExpansion(set, subLibrary));
+ }
+ }
+
+ /** Expands libraries in place. If any library is a child of 'all', ensures
+ * that 'all' is in the list. */
+ public static List<SqlLibrary> expandUp(
+ Iterable<? extends SqlLibrary> libraries) {
+ // LinkedHashSet ensures that libraries are added only once, and order is
+ // preserved.
+ final Set<SqlLibrary> set = new LinkedHashSet<>();
+ libraries.forEach(library -> addParent(set, library));
+ return ImmutableList.copyOf(set);
+ }
+
+ private static void addParent(Set<SqlLibrary> set, SqlLibrary library) {
+ if (ALL.children().contains(library)) {
+ set.add(ALL);
+ }
+ set.add(library);
+ }
static {
final ImmutableMap.Builder<String, SqlLibrary> builder =
diff --git a/core/src/main/java/org/apache/calcite/sql/fun/SqlLibraryOperatorTableFactory.java b/core/src/main/java/org/apache/calcite/sql/fun/SqlLibraryOperatorTableFactory.java
index 6367427e04..52e2e28128 100644
--- a/core/src/main/java/org/apache/calcite/sql/fun/SqlLibraryOperatorTableFactory.java
+++ b/core/src/main/java/org/apache/calcite/sql/fun/SqlLibraryOperatorTableFactory.java
@@ -154,8 +154,21 @@ public class SqlLibraryOperatorTableFactory {
/** Returns a SQL operator table that contains operators in the given set of
* libraries. */
public SqlOperatorTable getOperatorTable(Iterable<SqlLibrary> librarySet) {
+ return getOperatorTable(librarySet, true);
+ }
+
+ /** Returns a SQL operator table that contains operators in the given set of
+ * libraries, optionally inheriting in operators in {@link SqlLibrary#ALL}. */
+ public SqlOperatorTable getOperatorTable(Iterable<SqlLibrary> librarySet,
+ boolean includeAll) {
try {
- return cache.get(ImmutableSet.copyOf(librarySet));
+ // Expand so that 'hive' becomes 'all,hive';
+ // ensures that operators with library=all get loaded.
+ final List<SqlLibrary> expandedLibrarySet =
+ includeAll
+ ? SqlLibrary.expandUp(librarySet)
+ : ImmutableList.copyOf(librarySet);
+ return cache.get(ImmutableSet.copyOf(expandedLibrarySet));
} catch (ExecutionException e) {
throw Util.throwAsRuntime("populating SqlOperatorTable for library "
+ librarySet, Util.causeOrSelf(e));
diff --git a/core/src/main/java/org/apache/calcite/sql/fun/SqlLibraryOperators.java b/core/src/main/java/org/apache/calcite/sql/fun/SqlLibraryOperators.java
index e53ef0cfa7..acf17da9c6 100644
--- a/core/src/main/java/org/apache/calcite/sql/fun/SqlLibraryOperators.java
+++ b/core/src/main/java/org/apache/calcite/sql/fun/SqlLibraryOperators.java
@@ -52,6 +52,7 @@ import org.checkerframework.checker.nullness.qual.Nullable;
import java.util.ArrayList;
import java.util.List;
+import static org.apache.calcite.sql.fun.SqlLibrary.ALL;
import static org.apache.calcite.sql.fun.SqlLibrary.BIG_QUERY;
import static org.apache.calcite.sql.fun.SqlLibrary.CALCITE;
import static org.apache.calcite.sql.fun.SqlLibrary.HIVE;
@@ -1150,21 +1151,21 @@ public abstract class SqlLibraryOperators {
OperandTypes.INTEGER,
SqlFunctionCategory.STRING);
- @LibraryOperator(libraries = {BIG_QUERY, ORACLE})
+ @LibraryOperator(libraries = {ALL})
public static final SqlFunction TANH =
SqlBasicFunction.create("TANH",
ReturnTypes.DOUBLE_NULLABLE,
OperandTypes.NUMERIC,
SqlFunctionCategory.NUMERIC);
- @LibraryOperator(libraries = {BIG_QUERY, ORACLE})
+ @LibraryOperator(libraries = {ALL})
public static final SqlFunction COSH =
SqlBasicFunction.create("COSH",
ReturnTypes.DOUBLE_NULLABLE,
OperandTypes.NUMERIC,
SqlFunctionCategory.NUMERIC);
- @LibraryOperator(libraries = {BIG_QUERY, ORACLE})
+ @LibraryOperator(libraries = {ALL})
public static final SqlFunction SINH =
SqlBasicFunction.create("SINH",
ReturnTypes.DOUBLE_NULLABLE,
diff --git a/core/src/test/java/org/apache/calcite/sql/test/DocumentationTest.java b/core/src/test/java/org/apache/calcite/sql/test/DocumentationTest.java
index 265531d79a..5085a38a68 100644
--- a/core/src/test/java/org/apache/calcite/sql/test/DocumentationTest.java
+++ b/core/src/test/java/org/apache/calcite/sql/test/DocumentationTest.java
@@ -18,6 +18,7 @@ package org.apache.calcite.sql.test;
import org.apache.calcite.sql.SqlFunction;
import org.apache.calcite.sql.SqlOperator;
+import org.apache.calcite.sql.SqlOperatorTable;
import org.apache.calcite.sql.SqlSpecialOperator;
import org.apache.calcite.sql.fun.SqlLibrary;
import org.apache.calcite.sql.fun.SqlLibraryOperatorTableFactory;
@@ -103,16 +104,25 @@ class DocumentationTest {
@Test void testAllFunctionsAreDocumented() throws IOException {
final FileFixture f = new FileFixture();
final Map<String, PatternOp> map = new TreeMap<>();
- addOperators(map, "", SqlStdOperatorTable.instance().getOperatorList());
+
+ final SqlStdOperatorTable standard = SqlStdOperatorTable.instance();
+ addOperators(map, "", standard.getOperatorList());
+
for (SqlLibrary library : SqlLibrary.values()) {
+ final SqlOperatorTable libraryTable =
+ SqlLibraryOperatorTableFactory.INSTANCE
+ .getOperatorTable(EnumSet.of(library), false);
switch (library) {
case STANDARD:
case SPATIAL:
continue;
+ case ALL:
+ addOperators(map, "\\| \\* ", libraryTable.getOperatorList());
+ continue;
+ default:
+ addOperators(map, "\\| [^|]*" + library.abbrev + "[^|]* ",
+ libraryTable.getOperatorList());
}
- addOperators(map, "\\| [^|]*" + library.abbrev + "[^|]* ",
- SqlLibraryOperatorTableFactory.INSTANCE
- .getOperatorTable(EnumSet.of(library)).getOperatorList());
}
final Set<String> regexSeen = new HashSet<>();
try (LineNumberReader r = new LineNumberReader(Util.reader(f.inFile))) {
diff --git a/core/src/test/java/org/apache/calcite/util/UtilTest.java b/core/src/test/java/org/apache/calcite/util/UtilTest.java
index f03eae6cfe..176a601f29 100644
--- a/core/src/test/java/org/apache/calcite/util/UtilTest.java
+++ b/core/src/test/java/org/apache/calcite/util/UtilTest.java
@@ -31,6 +31,7 @@ import org.apache.calcite.runtime.SqlFunctions;
import org.apache.calcite.runtime.Utilities;
import org.apache.calcite.sql.SqlCollation;
import org.apache.calcite.sql.dialect.CalciteSqlDialect;
+import org.apache.calcite.sql.fun.SqlLibrary;
import org.apache.calcite.sql.util.IdPair;
import org.apache.calcite.sql.util.SqlBuilder;
import org.apache.calcite.sql.util.SqlString;
@@ -118,6 +119,7 @@ import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertNotSame;
import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
@@ -919,6 +921,61 @@ class UtilTest {
}
}
+ @Test void testSqlLibrary() {
+ final SqlLibrary a = SqlLibrary.ALL;
+ final SqlLibrary c = SqlLibrary.CALCITE;
+ final SqlLibrary o = SqlLibrary.ORACLE;
+ final SqlLibrary sp = SqlLibrary.SPATIAL;
+ final SqlLibrary st = SqlLibrary.STANDARD;
+
+ assertThat(SqlLibrary.parse("oracle"),
+ is(ImmutableList.of(o)));
+ assertThat(SqlLibrary.parse("oracle,calcite"),
+ is(ImmutableList.of(o, c)));
+ assertThat(SqlLibrary.parse("oracle,calcite,oracle"),
+ is(ImmutableList.of(o, c, o)));
+ assertThat(SqlLibrary.parse("oracle,CALCITE,oracle"),
+ is(ImmutableList.of(o, c, o)));
+ assertThat(SqlLibrary.parse(""),
+ is(ImmutableList.of()));
+ assertThrows(IllegalArgumentException.class,
+ () -> SqlLibrary.parse("oracle,calcite,foo,oracle"));
+ assertThrows(IllegalArgumentException.class,
+ () -> SqlLibrary.parse("oracle,calcite,,oracle"));
+
+ assertThat(SqlLibrary.expand(ImmutableList.of(a)).toString(),
+ is("[ALL, BIG_QUERY, CALCITE, HIVE, MSSQL, MYSQL, ORACLE, POSTGRESQL, "
+ + "SPARK]"));
+ assertThat(SqlLibrary.expand(ImmutableList.of(a, c)).toString(),
+ is("[ALL, BIG_QUERY, CALCITE, HIVE, MSSQL, MYSQL, ORACLE, POSTGRESQL, "
+ + "SPARK]"));
+ assertThat(SqlLibrary.expand(ImmutableList.of(c, a)).toString(),
+ is("[CALCITE, ALL, BIG_QUERY, HIVE, MSSQL, MYSQL, ORACLE, POSTGRESQL, "
+ + "SPARK]"));
+ assertThat(SqlLibrary.expand(ImmutableList.of(c, o, a)).toString(),
+ is("[CALCITE, ORACLE, ALL, BIG_QUERY, HIVE, MSSQL, MYSQL, POSTGRESQL, "
+ + "SPARK]"));
+ assertThat(SqlLibrary.expand(ImmutableList.of(o, c, o)).toString(),
+ is("[ORACLE, CALCITE]"));
+
+ assertThat("all + spatial + standard covers everything",
+ ImmutableSet.copyOf(SqlLibrary.expand(ImmutableList.of(a, sp, st))),
+ is(ImmutableSet.copyOf(SqlLibrary.values())));
+
+ assertThat(SqlLibrary.expandUp(ImmutableList.of(c)).toString(),
+ is("[ALL, CALCITE]"));
+ assertThat(SqlLibrary.expandUp(ImmutableList.of(c, o)).toString(),
+ is("[ALL, CALCITE, ORACLE]"));
+ assertThat(SqlLibrary.expandUp(ImmutableList.of(st, c, o)).toString(),
+ is("[STANDARD, ALL, CALCITE, ORACLE]"));
+ assertThat(SqlLibrary.expandUp(ImmutableList.of(st, sp)).toString(),
+ is("[STANDARD, SPATIAL]"));
+ assertThat(SqlLibrary.expandUp(ImmutableList.of(st, a, sp)).toString(),
+ is("[STANDARD, ALL, SPATIAL]"));
+ assertThat(SqlLibrary.expandUp(ImmutableList.of(a)).toString(),
+ is("[ALL]"));
+ }
+
@Test void testSpaces() {
assertEquals("", Spaces.of(0));
assertEquals(" ", Spaces.of(1));
diff --git a/site/_docs/reference.md b/site/_docs/reference.md
index fa55adc763..eb78d3a4fc 100644
--- a/site/_docs/reference.md
+++ b/site/_docs/reference.md
@@ -2616,6 +2616,7 @@ To enable an operator table, set the
connect string parameter.
The 'C' (compatibility) column contains value:
+* '*' for all libraries,
* 'b' for Google BigQuery ('fun=bigquery' in the connect string),
* 'c' for Apache Calcite ('fun=calcite' in the connect string),
* 'h' for Apache Hive ('fun=hive' in the connect string),
@@ -2648,7 +2649,7 @@ BigQuery's type system uses confusingly different names for types and functions:
| b | ARRAY_REVERSE(array) | Reverses elements of *array*
| m s | CHAR(integer) | Returns the character whose ASCII code is *integer* % 256, or null if *integer* < 0
| b o p | CHR(integer) | Returns the character whose UTF-8 code is *integer*
-| b o | COSH(numeric) | Returns the hyperbolic cosine of *numeric*
+| * | COSH(numeric) | Returns the hyperbolic cosine of *numeric*
| o | CONCAT(string, string) | Concatenates two strings
| b m p | CONCAT(string [, string ]*) | Concatenates two or more strings
| m | COMPRESS(string) | Compresses a string using zlib compression and returns the result as a binary string
@@ -2725,7 +2726,7 @@ BigQuery's type system uses confusingly different names for types and functions:
| b o | RTRIM(string) | Returns *string* with all blanks removed from the end
| b | SAFE_CAST(value AS type) | Converts *value* to *type*, returning NULL if conversion fails
| b m p | SHA1(string) | Calculates a SHA-1 hash value of *string* and returns it as a hex string
-| b o | SINH(numeric) | Returns the hyperbolic sine of *numeric*
+| * | SINH(numeric) | Returns the hyperbolic sine of *numeric*
| b m o p | SOUNDEX(string) | Returns the phonetic representation of *string*; throws if *string* is encoded with multi-byte encoding such as UTF-8
| m | SPACE(integer) | Returns a string of *integer* spaces; returns an empty string if *integer* is less than 1
| b | SPLIT(string [, delimiter ]) | Returns the string array of *string* split at *delimiter* (if omitted, default is comma)
@@ -2733,7 +2734,7 @@ BigQuery's type system uses confusingly different names for types and functions:
| m | STRCMP(string, string) | Returns 0 if both of the strings are same and returns -1 when the first argument is smaller than the second and 1 when the second one is smaller than the first one
| b p | STRPOS(string, substring) | Equivalent to `POSITION(substring IN string)`
| b m o p | SUBSTR(string, position [, substringLength ]) | Returns a portion of *string*, beginning at character *position*, *substringLength* characters long. SUBSTR calculates lengths using characters as defined by the input character set
-| b o | TANH(numeric) | Returns the hyperbolic tangent of *numeric*
+| * | TANH(numeric) | Returns the hyperbolic tangent of *numeric*
| b | TIME(hour, minute, second) | Returns a TIME value *hour*, *minute*, *second* (all of type INTEGER)
| b | TIME(timestamp) | Extracts the TIME from *timestamp* (a local time; BigQuery's DATETIME type)
| b | TIME(instant) | Extracts the TIME from *timestampLtz* (an instant; BigQuery's TIMESTAMP type), assuming UTC
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 70ae0a89b7..164593741e 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
@@ -566,7 +566,7 @@ public interface SqlOperatorFixture extends AutoCloseable {
/** Applies this fixture to some code for each of the given libraries. */
default void forEachLibrary(Iterable<? extends SqlLibrary> libraries,
Consumer<SqlOperatorFixture> consumer) {
- libraries.forEach(library -> {
+ SqlLibrary.expand(libraries).forEach(library -> {
try {
consumer.accept(this.withLibrary(library));
} catch (Exception e) {
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 6538ce665b..f0a61ab7e5 100644
--- a/testkit/src/main/java/org/apache/calcite/test/SqlOperatorTest.java
+++ b/testkit/src/main/java/org/apache/calcite/test/SqlOperatorTest.java
@@ -5387,7 +5387,7 @@ public class SqlOperatorTest {
f.checkNull("cosh(cast(null as integer))");
f.checkNull("cosh(cast(null as double))");
};
- f0.forEachLibrary(list(SqlLibrary.BIG_QUERY, SqlLibrary.ORACLE), consumer);
+ f0.forEachLibrary(list(SqlLibrary.ALL), consumer);
}
@Test void testCotFunc() {
@@ -5565,7 +5565,7 @@ public class SqlOperatorTest {
f.checkNull("sinh(cast(null as integer))");
f.checkNull("sinh(cast(null as double))");
};
- f0.forEachLibrary(list(SqlLibrary.BIG_QUERY, SqlLibrary.ORACLE), consumer);
+ f0.forEachLibrary(list(SqlLibrary.ALL), consumer);
}
@Test void testTanFunc() {
@@ -5606,7 +5606,7 @@ public class SqlOperatorTest {
f.checkNull("tanh(cast(null as integer))");
f.checkNull("tanh(cast(null as double))");
};
- f0.forEachLibrary(list(SqlLibrary.BIG_QUERY, SqlLibrary.ORACLE), consumer);
+ f0.forEachLibrary(list(SqlLibrary.ALL), consumer);
}
@Test void testTruncFunc() {