Skip to content

Commit

Permalink
Various minor fixups
Browse files Browse the repository at this point in the history
Rename methods in SqlFunctions to make semantics clearer.

CHAR is semi-strict (sometimes returns null if argument is not null).

Improve descriptions of CHAR, CHR, {fn CHAR}.

Close apache#2878
  • Loading branch information
julianhyde committed Sep 8, 2022
1 parent c6ad750 commit 62aca87
Show file tree
Hide file tree
Showing 6 changed files with 28 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,7 @@ public class RexImpTable {
defineMethod(RIGHT, BuiltInMethod.RIGHT.method, NullPolicy.ANY);
defineMethod(REPLACE, BuiltInMethod.REPLACE.method, NullPolicy.STRICT);
defineMethod(TRANSLATE3, BuiltInMethod.TRANSLATE3.method, NullPolicy.STRICT);
defineMethod(CHR, BuiltInMethod.CHR.method, NullPolicy.STRICT);
defineMethod(CHR, BuiltInMethod.CHAR_FROM_UTF8.method, NullPolicy.STRICT);
defineMethod(CHARACTER_LENGTH, BuiltInMethod.CHAR_LENGTH.method,
NullPolicy.STRICT);
defineMethod(CHAR_LENGTH, BuiltInMethod.CHAR_LENGTH.method,
Expand All @@ -381,7 +381,8 @@ public class RexImpTable {
defineMethod(OVERLAY, BuiltInMethod.OVERLAY.method, NullPolicy.STRICT);
defineMethod(POSITION, BuiltInMethod.POSITION.method, NullPolicy.STRICT);
defineMethod(ASCII, BuiltInMethod.ASCII.method, NullPolicy.STRICT);
defineMethod(CHAR, BuiltInMethod.CHAR.method, NullPolicy.STRICT);
defineMethod(CHAR, BuiltInMethod.CHAR_FROM_ASCII.method,
NullPolicy.SEMI_STRICT);
defineMethod(REPEAT, BuiltInMethod.REPEAT.method, NullPolicy.STRICT);
defineMethod(SPACE, BuiltInMethod.SPACE.method, NullPolicy.STRICT);
defineMethod(STRCMP, BuiltInMethod.STRCMP.method, NullPolicy.STRICT);
Expand Down
24 changes: 11 additions & 13 deletions core/src/main/java/org/apache/calcite/runtime/SqlFunctions.java
Original file line number Diff line number Diff line change
Expand Up @@ -462,24 +462,22 @@ public static ByteString right(ByteString s, int n) {
return s.substring(len - n);
}

/**
* SQL CHAR(long) function.
* Returns the ASCII character having the binary equivalent to long;
* If long is larger than 256 the result is equivalent to char(long % 256).
*/
public static @Nullable String charN(long n) {
/** SQL CHAR(integer) function, as in MySQL and Spark.
*
* <p>Returns the ASCII character of {@code n} modulo 256,
* or null if {@code n} &lt; 0. */
public static @Nullable String charFromAscii(int n) {
if (n < 0) {
return null;
}
return String.valueOf(Character.toChars((int) (n % 256)));
return String.valueOf(Character.toChars(n % 256));
}

/**
* SQL CHR(long) function.
* Returns the UTF-8 character having the binary equivalent to long.
*/
public static String chr(long n) {
return String.valueOf(Character.toChars((int) n));
/** SQL CHR(integer) function, as in Oracle and Postgres.
*
* <p>Returns the UTF-8 character whose code is {@code n}. */
public static String charFromUtf8(int n) {
return String.valueOf(Character.toChars(n));
}

/** SQL OCTET_LENGTH(binary) function. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -650,9 +650,8 @@ private SqlLibraryOperators() {
ReturnTypes.BIGINT_NULLABLE, null, OperandTypes.TIMESTAMP,
SqlFunctionCategory.TIMEDATE);

/**
* The "CHAR(bigint)" function; returns the ASCII character having the binary equivalent
* to bigint; If bigint is larger than 256 the result is equivalent to char(bigint % 256). */
/** The "CHAR(n)" function; returns the character whose ASCII code is
* {@code n} % 256, or null if {@code n} &lt; 0. */
@LibraryOperator(libraries = {MYSQL, SPARK})
public static final SqlFunction CHAR =
new SqlFunction("CHAR",
Expand All @@ -662,9 +661,8 @@ private SqlLibraryOperators() {
OperandTypes.INTEGER,
SqlFunctionCategory.STRING);

/**
* The "CHR(bigint)" function; returns the UTF-8 character
* having the binary equivalent to bigint. */
/** The "CHR(n)" function; returns the character whose UTF-8 code is
* @code n}. */
@LibraryOperator(libraries = {ORACLE, POSTGRESQL})
public static final SqlFunction CHR =
new SqlFunction("CHR",
Expand Down
4 changes: 2 additions & 2 deletions core/src/main/java/org/apache/calcite/util/BuiltInMethod.java
Original file line number Diff line number Diff line change
Expand Up @@ -339,8 +339,8 @@ public enum BuiltInMethod {
UPPER(SqlFunctions.class, "upper", String.class),
LOWER(SqlFunctions.class, "lower", String.class),
ASCII(SqlFunctions.class, "ascii", String.class),
CHAR(SqlFunctions.class, "charN", long.class),
CHR(SqlFunctions.class, "chr", long.class),
CHAR_FROM_ASCII(SqlFunctions.class, "charFromAscii", int.class),
CHAR_FROM_UTF8(SqlFunctions.class, "charFromUtf8", int.class),
REPEAT(SqlFunctions.class, "repeat", String.class, int.class),
SPACE(SqlFunctions.class, "space", int.class),
SOUNDEX(SqlFunctions.class, "soundex", String.class),
Expand Down
7 changes: 4 additions & 3 deletions core/src/test/resources/sql/functions.iq
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ SELECT ExtractValue('<a>c</a>', '//a');
!ok

# STRING Functions
#CHAR

# CHAR
SELECT char(null), char(-1), char(65), char(233), char(256+66);
+--------+--------+--------+--------+--------+
| EXPR$0 | EXPR$1 | EXPR$2 | EXPR$3 | EXPR$4 |
Expand All @@ -66,7 +67,7 @@ SELECT char(null), char(-1), char(65), char(233), char(256+66);

!ok

#CONCAT
# CONCAT
SELECT CONCAT('c', 'h', 'a', 'r');
+--------+
| EXPR$0 |
Expand Down Expand Up @@ -125,7 +126,7 @@ select sinh(1);

!ok

#CONCAT
# CONCAT
select concat('a', 'b');
+--------+
| EXPR$0 |
Expand Down
8 changes: 4 additions & 4 deletions site/_docs/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -1749,7 +1749,7 @@ period:
| Operator syntax | Description
|:--------------- |:-----------
| {fn ASCII(string)} | Returns the ASCII code of the first character of *string*; if the first character is a non-ASCII character, returns its Unicode code point; returns 0 if *string* is empty
| {fn CHAR(integer)} | Returns the ASCII character having the binary equivalent to *integer*; If *integer* is larger than 256 the result is equivalent to char(*integer* % 256)
| {fn CHAR(integer)} | Returns the character whose ASCII code is *integer* % 256, or null if *integer* &lt; 0
| {fn CONCAT(character, character)} | Returns the concatenation of character strings
| {fn INSERT(string1, start, length, string2)} | Inserts *string2* into a slot in *string1*
| {fn LCASE(string)} | Returns a string in which all alphabetic characters in *string* have been converted to lower case
Expand All @@ -1759,7 +1759,7 @@ period:
| {fn LTRIM(string)} | Returns *string* with leading space characters removed
| {fn REPLACE(string, search, replacement)} | Returns a string in which all the occurrences of *search* in *string* are replaced with *replacement*; if *replacement* is the empty string, the occurrences of *search* are removed
| {fn REVERSE(string)} | Returns *string* with the order of the characters reversed
| {fn RIGHT(string, integer)} | Returns the rightmost *length* characters from *string*
| {fn RIGHT(string, length)} | Returns the rightmost *length* characters from *string*
| {fn RTRIM(string)} | Returns *string* with trailing space characters removed
| {fn SUBSTRING(string, offset, length)} | Returns a character string that consists of *length* characters from *string* starting at the *offset* position
| {fn UCASE(string)} | Returns a string in which all alphabetic characters in *string* have been converted to upper case
Expand Down Expand Up @@ -2561,8 +2561,8 @@ semantics.
| b | ARRAY_CONCAT(array [, array ]*) | Concatenates one or more arrays. If any input argument is `NULL` the function returns `NULL`
| b | ARRAY_LENGTH(array) | Synonym for `CARDINALITY`
| b | ARRAY_REVERSE(array) | Reverses elements of *array*
| m s | CHAR(integer) | Returns the ASCII character having the binary equivalent to *integer*; If *integer* is larger than 256 the result is equivalent to char(*integer* % 256)
| o p | CHR(integer) | Returns the UTF-8 character having the binary equivalent to *integer* as a CHAR value
| m s | CHAR(integer) | Returns the character whose ASCII code is *integer* % 256, or null if *integer* &lt; 0
| o p | CHR(integer) | Returns the character whose UTF-8 code is *integer*
| o | COSH(numeric) | Returns the hyperbolic cosine of *numeric*
| o | CONCAT(string, string) | Concatenates two strings
| m p | CONCAT(string [, string ]*) | Concatenates two or more strings
Expand Down

0 comments on commit 62aca87

Please sign in to comment.