Skip to content

Commit aaad34d

Browse files
10110346cloud-fan
authored andcommitted
[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 <[email protected]> Closes apache#18228 from 10110346/lx-wip-0607.
1 parent 5ed134e commit aaad34d

File tree

4 files changed

+84
-1
lines changed

4 files changed

+84
-1
lines changed

sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/FunctionRegistry.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,8 @@ object FunctionRegistry {
346346
expression[StringSplit]("split"),
347347
expression[Substring]("substr"),
348348
expression[Substring]("substring"),
349+
expression[Left]("left"),
350+
expression[Right]("right"),
349351
expression[SubstringIndex]("substring_index"),
350352
expression[StringTranslate]("translate"),
351353
expression[StringTrim]("trim"),

sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/stringExpressions.scala

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1198,6 +1198,49 @@ case class Substring(str: Expression, pos: Expression, len: Expression)
11981198
}
11991199
}
12001200

1201+
/**
1202+
* Returns the rightmost n characters from the string.
1203+
*/
1204+
// scalastyle:off line.size.limit
1205+
@ExpressionDescription(
1206+
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.",
1207+
extended = """
1208+
Examples:
1209+
> SELECT _FUNC_('Spark SQL', 3);
1210+
SQL
1211+
""")
1212+
// scalastyle:on line.size.limit
1213+
case class Right(str: Expression, len: Expression, child: Expression) extends RuntimeReplaceable {
1214+
def this(str: Expression, len: Expression) = {
1215+
this(str, len, If(IsNull(str), Literal(null, StringType), If(LessThanOrEqual(len, Literal(0)),
1216+
Literal(UTF8String.EMPTY_UTF8, StringType), new Substring(str, UnaryMinus(len)))))
1217+
}
1218+
1219+
override def flatArguments: Iterator[Any] = Iterator(str, len)
1220+
override def sql: String = s"$prettyName(${str.sql}, ${len.sql})"
1221+
}
1222+
1223+
/**
1224+
* Returns the leftmost n characters from the string.
1225+
*/
1226+
// scalastyle:off line.size.limit
1227+
@ExpressionDescription(
1228+
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.",
1229+
extended = """
1230+
Examples:
1231+
> SELECT _FUNC_('Spark SQL', 3);
1232+
Spa
1233+
""")
1234+
// scalastyle:on line.size.limit
1235+
case class Left(str: Expression, len: Expression, child: Expression) extends RuntimeReplaceable {
1236+
def this(str: Expression, len: Expression) = {
1237+
this(str, len, Substring(str, Literal(1), len))
1238+
}
1239+
1240+
override def flatArguments: Iterator[Any] = Iterator(str, len)
1241+
override def sql: String = s"$prettyName(${str.sql}, ${len.sql})"
1242+
}
1243+
12011244
/**
12021245
* A function that returns the char length of the given string expression or
12031246
* number of bytes of the given binary expression.

sql/core/src/test/resources/sql-tests/inputs/string-functions.sql

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,9 @@ select length(uuid()), (uuid() <> uuid());
1818

1919
-- position
2020
select position('bar' in 'foobarbar'), position(null, 'foobarbar'), position('aaads', null);
21+
22+
-- left && right
23+
select left("abcd", 2), left("abcd", 5), left("abcd", '2'), left("abcd", null);
24+
select left(null, -2), left("abcd", -2), left("abcd", 0), left("abcd", 'a');
25+
select right("abcd", 2), right("abcd", 5), right("abcd", '2'), right("abcd", null);
26+
select right(null, -2), right("abcd", -2), right("abcd", 0), right("abcd", 'a');

sql/core/src/test/resources/sql-tests/results/string-functions.sql.out

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
-- Automatically generated by SQLQueryTestSuite
2-
-- Number of queries: 8
2+
-- Number of queries: 12
33

44

55
-- !query 0
@@ -86,3 +86,35 @@ select position('bar' in 'foobarbar'), position(null, 'foobarbar'), position('aa
8686
struct<locate(bar, foobarbar, 1):int,locate(CAST(NULL AS STRING), foobarbar, 1):int,locate(aaads, CAST(NULL AS STRING), 1):int>
8787
-- !query 7 output
8888
4 NULL NULL
89+
90+
91+
-- !query 8
92+
select left("abcd", 2), left("abcd", 5), left("abcd", '2'), left("abcd", null)
93+
-- !query 8 schema
94+
struct<left('abcd', 2):string,left('abcd', 5):string,left('abcd', '2'):string,left('abcd', NULL):string>
95+
-- !query 8 output
96+
ab abcd ab NULL
97+
98+
99+
-- !query 9
100+
select left(null, -2), left("abcd", -2), left("abcd", 0), left("abcd", 'a')
101+
-- !query 9 schema
102+
struct<left(NULL, -2):string,left('abcd', -2):string,left('abcd', 0):string,left('abcd', 'a'):string>
103+
-- !query 9 output
104+
NULL NULL
105+
106+
107+
-- !query 10
108+
select right("abcd", 2), right("abcd", 5), right("abcd", '2'), right("abcd", null)
109+
-- !query 10 schema
110+
struct<right('abcd', 2):string,right('abcd', 5):string,right('abcd', '2'):string,right('abcd', NULL):string>
111+
-- !query 10 output
112+
cd abcd cd NULL
113+
114+
115+
-- !query 11
116+
select right(null, -2), right("abcd", -2), right("abcd", 0), right("abcd", 'a')
117+
-- !query 11 schema
118+
struct<right(NULL, -2):string,right('abcd', -2):string,right('abcd', 0):string,right('abcd', 'a'):string>
119+
-- !query 11 output
120+
NULL NULL

0 commit comments

Comments
 (0)