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 7f113cc96d1..97719fc5c1b 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 @@ -274,8 +274,13 @@ private static SqlCall transformConvert(SqlValidator validator, SqlCall call) { @LibraryOperator(libraries = {BIG_QUERY}) public static final SqlFunction IFNULL = NVL.withName("IFNULL"); + /** The "LEN(string)" function. */ + @LibraryOperator(libraries = {SNOWFLAKE}) + public static final SqlFunction LEN = + SqlStdOperatorTable.CHAR_LENGTH.withName("LEN"); + /** The "LENGTH(string)" function. */ - @LibraryOperator(libraries = {BIG_QUERY}) + @LibraryOperator(libraries = {BIG_QUERY, SNOWFLAKE}) public static final SqlFunction LENGTH = SqlStdOperatorTable.CHAR_LENGTH.withName("LENGTH"); diff --git a/core/src/main/java/org/apache/calcite/sql2rel/StandardConvertletTable.java b/core/src/main/java/org/apache/calcite/sql2rel/StandardConvertletTable.java index 69666ffd34d..d9bc1d27d5c 100644 --- a/core/src/main/java/org/apache/calcite/sql2rel/StandardConvertletTable.java +++ b/core/src/main/java/org/apache/calcite/sql2rel/StandardConvertletTable.java @@ -120,6 +120,8 @@ private StandardConvertletTable() { // Register aliases (operators which have a different name but // identical behavior to other operators). + addAlias(SqlLibraryOperators.LEN, + SqlStdOperatorTable.CHAR_LENGTH); addAlias(SqlLibraryOperators.LENGTH, SqlStdOperatorTable.CHAR_LENGTH); addAlias(SqlStdOperatorTable.CHARACTER_LENGTH, diff --git a/site/_docs/reference.md b/site/_docs/reference.md index 1bcb076bf16..5f7a99707ef 100644 --- a/site/_docs/reference.md +++ b/site/_docs/reference.md @@ -2765,7 +2765,8 @@ BigQuery's type system uses confusingly different names for types and functions: | m | JSON_STORAGE_SIZE(jsonValue) | Returns the number of bytes used to store the binary representation of *jsonValue* | b o | LEAST(expr [, expr ]* ) | Returns the least of the expressions | b m p | LEFT(string, length) | Returns the leftmost *length* characters from the *string* -| b | LENGTH(string) | Equivalent to `CHAR_LENGTH(string)` +| f | LEN(string) | Equivalent to `CHAR_LENGTH(string)` +| b f | LENGTH(string) | Equivalent to `CHAR_LENGTH(string)` | h s | LEVENSHTEIN(string1, string2) | Returns the Levenshtein distance between *string1* and *string2* | b | LOG(numeric1 [, numeric2 ]) | Returns the logarithm of *numeric1* to base *numeric2*, or base e if *numeric2* is not present | b o | LPAD(string, length [, pattern ]) | Returns a string or bytes value that consists of *string* prepended to *length* with *pattern* 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 f9722692cee..e9daec83fa1 100644 --- a/testkit/src/main/java/org/apache/calcite/test/SqlOperatorTest.java +++ b/testkit/src/main/java/org/apache/calcite/test/SqlOperatorTest.java @@ -4108,6 +4108,19 @@ static void checkRlikeFails(SqlOperatorFixture f) { f.checkNull("CHARACTER_LENGTH(cast(null as varchar(1)))"); } + @Test void testLenFunc() { + final SqlOperatorFixture f0 = fixture().setFor(SqlLibraryOperators.LENGTH); + f0.checkFails("^length('hello')^", + "No match found for function signature LENGTH\\(\\)", + false); + final SqlOperatorFixture f = f0.withLibrary(SqlLibrary.SNOWFLAKE); + f.checkScalar("length('hello')", "5", "INTEGER NOT NULL"); + f.checkScalar("length('')", "0", "INTEGER NOT NULL"); + f.checkScalar("length(CAST('x' as CHAR(3)))", "3", "INTEGER NOT NULL"); + f.checkScalar("length(CAST('x' as VARCHAR(4)))", "1", "INTEGER NOT NULL"); + f.checkNull("length(CAST(NULL as CHAR(5)))"); + } + @Test void testLengthFunc() { final SqlOperatorFixture f0 = fixture().setFor(SqlLibraryOperators.LENGTH); f0.checkFails("^length('hello')^", @@ -4122,7 +4135,7 @@ static void checkRlikeFails(SqlOperatorFixture f) { f.checkNull("length(CAST(NULL as CHAR(5)))"); }; - f0.forEachLibrary(list(SqlLibrary.BIG_QUERY), consumer); + f0.forEachLibrary(list(SqlLibrary.BIG_QUERY, SqlLibrary.SNOWFLAKE), consumer); } @Test void testOctetLengthFunc() {