[SPARK-21007][SQL] Add SQL function - RIGHT && LEFT

## What changes were proposed in this pull request?
 Add  SQL function - RIGHT && LEFT, same as MySQL:
https://dev.mysql.com/doc/refman/5.7/en/string-functions.html#function_left
https://dev.mysql.com/doc/refman/5.7/en/string-functions.html#function_right

## How was this patch tested?
unit test

Author: liuxian <liu.xian3@zte.com.cn>

Closes #18228 from 10110346/lx-wip-0607.
This commit is contained in:
liuxian 2017-07-12 18:51:19 +08:00 committed by Wenchen Fan
parent 5ed134ee21
commit aaad34dc2f
4 changed files with 84 additions and 1 deletions

View file

@ -346,6 +346,8 @@ object FunctionRegistry {
expression[StringSplit]("split"),
expression[Substring]("substr"),
expression[Substring]("substring"),
expression[Left]("left"),
expression[Right]("right"),
expression[SubstringIndex]("substring_index"),
expression[StringTranslate]("translate"),
expression[StringTrim]("trim"),

View file

@ -1198,6 +1198,49 @@ case class Substring(str: Expression, pos: Expression, len: Expression)
}
}
/**
* Returns the rightmost n characters from the string.
*/
// scalastyle:off line.size.limit
@ExpressionDescription(
usage = "_FUNC_(str, len) - Returns the rightmost `len`(`len` can be string type) characters from the string `str`,if `len` is less or equal than 0 the result is an empty string.",
extended = """
Examples:
> SELECT _FUNC_('Spark SQL', 3);
SQL
""")
// scalastyle:on line.size.limit
case class Right(str: Expression, len: Expression, child: Expression) extends RuntimeReplaceable {
def this(str: Expression, len: Expression) = {
this(str, len, If(IsNull(str), Literal(null, StringType), If(LessThanOrEqual(len, Literal(0)),
Literal(UTF8String.EMPTY_UTF8, StringType), new Substring(str, UnaryMinus(len)))))
}
override def flatArguments: Iterator[Any] = Iterator(str, len)
override def sql: String = s"$prettyName(${str.sql}, ${len.sql})"
}
/**
* Returns the leftmost n characters from the string.
*/
// scalastyle:off line.size.limit
@ExpressionDescription(
usage = "_FUNC_(str, len) - Returns the leftmost `len`(`len` can be string type) characters from the string `str`,if `len` is less or equal than 0 the result is an empty string.",
extended = """
Examples:
> SELECT _FUNC_('Spark SQL', 3);
Spa
""")
// scalastyle:on line.size.limit
case class Left(str: Expression, len: Expression, child: Expression) extends RuntimeReplaceable {
def this(str: Expression, len: Expression) = {
this(str, len, Substring(str, Literal(1), len))
}
override def flatArguments: Iterator[Any] = Iterator(str, len)
override def sql: String = s"$prettyName(${str.sql}, ${len.sql})"
}
/**
* A function that returns the char length of the given string expression or
* number of bytes of the given binary expression.

View file

@ -18,3 +18,9 @@ select length(uuid()), (uuid() <> uuid());
-- position
select position('bar' in 'foobarbar'), position(null, 'foobarbar'), position('aaads', null);
-- left && right
select left("abcd", 2), left("abcd", 5), left("abcd", '2'), left("abcd", null);
select left(null, -2), left("abcd", -2), left("abcd", 0), left("abcd", 'a');
select right("abcd", 2), right("abcd", 5), right("abcd", '2'), right("abcd", null);
select right(null, -2), right("abcd", -2), right("abcd", 0), right("abcd", 'a');

View file

@ -1,5 +1,5 @@
-- Automatically generated by SQLQueryTestSuite
-- Number of queries: 8
-- Number of queries: 12
-- !query 0
@ -86,3 +86,35 @@ select position('bar' in 'foobarbar'), position(null, 'foobarbar'), position('aa
struct<locate(bar, foobarbar, 1):int,locate(CAST(NULL AS STRING), foobarbar, 1):int,locate(aaads, CAST(NULL AS STRING), 1):int>
-- !query 7 output
4 NULL NULL
-- !query 8
select left("abcd", 2), left("abcd", 5), left("abcd", '2'), left("abcd", null)
-- !query 8 schema
struct<left('abcd', 2):string,left('abcd', 5):string,left('abcd', '2'):string,left('abcd', NULL):string>
-- !query 8 output
ab abcd ab NULL
-- !query 9
select left(null, -2), left("abcd", -2), left("abcd", 0), left("abcd", 'a')
-- !query 9 schema
struct<left(NULL, -2):string,left('abcd', -2):string,left('abcd', 0):string,left('abcd', 'a'):string>
-- !query 9 output
NULL NULL
-- !query 10
select right("abcd", 2), right("abcd", 5), right("abcd", '2'), right("abcd", null)
-- !query 10 schema
struct<right('abcd', 2):string,right('abcd', 5):string,right('abcd', '2'):string,right('abcd', NULL):string>
-- !query 10 output
cd abcd cd NULL
-- !query 11
select right(null, -2), right("abcd", -2), right("abcd", 0), right("abcd", 'a')
-- !query 11 schema
struct<right(NULL, -2):string,right('abcd', -2):string,right('abcd', 0):string,right('abcd', 'a'):string>
-- !query 11 output
NULL NULL