You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flink.apache.org by di...@apache.org on 2022/07/04 02:14:51 UTC
[flink] branch master updated: [FLINK-28298][table][python] Support left and right in Table API (#20104)
This is an automated email from the ASF dual-hosted git repository.
dianfu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/flink.git
The following commit(s) were added to refs/heads/master by this push:
new da720c3b97d [FLINK-28298][table][python] Support left and right in Table API (#20104)
da720c3b97d is described below
commit da720c3b97d5c3e781abb1e910a8337f6a5ee0e4
Author: Luning (Lucas) Wang <wa...@gmail.com>
AuthorDate: Mon Jul 4 10:14:44 2022 +0800
[FLINK-28298][table][python] Support left and right in Table API (#20104)
---
docs/data/sql_functions.yml | 2 ++
docs/data/sql_functions_zh.yml | 2 ++
flink-python/pyflink/table/expression.py | 12 ++++++++++++
.../pyflink/table/tests/test_expression.py | 2 ++
.../flink/table/api/internal/BaseExpressions.java | 12 ++++++++++++
.../functions/BuiltInFunctionDefinitions.java | 22 ++++++++++++++++++++++
.../expressions/converter/DirectConvertRule.java | 2 ++
.../planner/expressions/ScalarFunctionsTest.scala | 7 +++++++
8 files changed, 61 insertions(+)
diff --git a/docs/data/sql_functions.yml b/docs/data/sql_functions.yml
index 2ad4347b20c..7a8795566b0 100644
--- a/docs/data/sql_functions.yml
+++ b/docs/data/sql_functions.yml
@@ -341,8 +341,10 @@ string:
- sql: INSTR(string1, string2)
description: Returns the position of the first occurrence of string2 in string1. Returns NULL if any of arguments is NULL.
- sql: LEFT(string, integer)
+ table: STRING.LEFT(INT)
description: Returns the leftmost integer characters from the string. Returns EMPTY String if integer is negative. Returns NULL if any argument is NULL.
- sql: RIGHT(string, integer)
+ table: STRING.RIGHT(INT)
description: Returns the rightmost integer characters from the string. Returns EMPTY String if integer is negative. Returns NULL if any argument is NULL.
- sql: LOCATE(string1, string2[, integer])
description: Returns the position of the first occurrence of string1 in string2 after position integer. Returns 0 if not found. Returns NULL if any of arguments is NULL.
diff --git a/docs/data/sql_functions_zh.yml b/docs/data/sql_functions_zh.yml
index ad9940b3486..f9056bf62c3 100644
--- a/docs/data/sql_functions_zh.yml
+++ b/docs/data/sql_functions_zh.yml
@@ -434,10 +434,12 @@ string:
- sql: INSTR(string1, string2)
description: 返回 string2 在 string1 中第一次出现的位置。如果有任一参数为 `NULL`,则返回 `NULL`。
- sql: LEFT(string, integer)
+ table: STRING.LEFT(INT)
description: |
返回字符串中最左边的长度为 integer 值的字符串。如果 integer 为负,则返回 `EMPTY` 字符串。如果有任一参数
为 `NULL` 则返回 `NULL`。
- sql: RIGHT(string, integer)
+ table: STRING.RIGHT(INT)
description: |
返回字符串中最右边的长度为 integer 值的字符串。如果 integer 为负,则返回 `EMPTY` 字符串。如果有任一参数
为 `NULL` 则返回 `NULL`。
diff --git a/flink-python/pyflink/table/expression.py b/flink-python/pyflink/table/expression.py
index 1f7e64f9576..b22dd0f02b0 100644
--- a/flink-python/pyflink/table/expression.py
+++ b/flink-python/pyflink/table/expression.py
@@ -1212,6 +1212,18 @@ class Expression(Generic[T]):
"""
return _binary_op("encode")(self, charset)
+ def left(self, length: Union[int, 'Expression[int]']) -> 'Expression[str]':
+ """
+ Returns the leftmost integer characters from the input string.
+ """
+ return _binary_op("left")(self, length)
+
+ def right(self, length: Union[int, 'Expression[int]']) -> 'Expression[str]':
+ """
+ Returns the rightmost integer characters from the input string.
+ """
+ return _binary_op("right")(self, length)
+
@property
def ltrim(self) -> 'Expression[str]':
"""
diff --git a/flink-python/pyflink/table/tests/test_expression.py b/flink-python/pyflink/table/tests/test_expression.py
index dd494cb1cdf..e17f07ba963 100644
--- a/flink-python/pyflink/table/tests/test_expression.py
+++ b/flink-python/pyflink/table/tests/test_expression.py
@@ -147,6 +147,8 @@ class PyFlinkBatchExpressionTests(PyFlinkTestCase):
self.assertEqual('chr(a)', str(expr1.chr))
self.assertEqual("decode(a, 'utf-8')", str(expr1.decode('utf-8')))
self.assertEqual("encode(a, 'utf-8')", str(expr1.encode('utf-8')))
+ self.assertEqual('left(a, 2)', str(expr1.left(2)))
+ self.assertEqual('right(a, 2)', str(expr1.right(2)))
self.assertEqual('ltrim(a)', str(expr1.ltrim))
self.assertEqual('rtrim(a)', str(expr1.rtrim))
self.assertEqual('repeat(a, 3)', str(expr1.repeat(3)))
diff --git a/flink-table/flink-table-api-java/src/main/java/org/apache/flink/table/api/internal/BaseExpressions.java b/flink-table/flink-table-api-java/src/main/java/org/apache/flink/table/api/internal/BaseExpressions.java
index 908a2ab3957..e68fd84c3f3 100644
--- a/flink-table/flink-table-api-java/src/main/java/org/apache/flink/table/api/internal/BaseExpressions.java
+++ b/flink-table/flink-table-api-java/src/main/java/org/apache/flink/table/api/internal/BaseExpressions.java
@@ -103,6 +103,7 @@ import static org.apache.flink.table.functions.BuiltInFunctionDefinitions.JSON_E
import static org.apache.flink.table.functions.BuiltInFunctionDefinitions.JSON_QUERY;
import static org.apache.flink.table.functions.BuiltInFunctionDefinitions.JSON_VALUE;
import static org.apache.flink.table.functions.BuiltInFunctionDefinitions.LAST_VALUE;
+import static org.apache.flink.table.functions.BuiltInFunctionDefinitions.LEFT;
import static org.apache.flink.table.functions.BuiltInFunctionDefinitions.LESS_THAN;
import static org.apache.flink.table.functions.BuiltInFunctionDefinitions.LESS_THAN_OR_EQUAL;
import static org.apache.flink.table.functions.BuiltInFunctionDefinitions.LIKE;
@@ -135,6 +136,7 @@ import static org.apache.flink.table.functions.BuiltInFunctionDefinitions.REGEXP
import static org.apache.flink.table.functions.BuiltInFunctionDefinitions.REGEXP_REPLACE;
import static org.apache.flink.table.functions.BuiltInFunctionDefinitions.REPEAT;
import static org.apache.flink.table.functions.BuiltInFunctionDefinitions.REPLACE;
+import static org.apache.flink.table.functions.BuiltInFunctionDefinitions.RIGHT;
import static org.apache.flink.table.functions.BuiltInFunctionDefinitions.ROUND;
import static org.apache.flink.table.functions.BuiltInFunctionDefinitions.ROWTIME;
import static org.apache.flink.table.functions.BuiltInFunctionDefinitions.RPAD;
@@ -1048,6 +1050,16 @@ public abstract class BaseExpressions<InType, OutType> {
unresolvedCall(ENCODE, toExpr(), objectToExpression(charset)));
}
+ /** Returns the leftmost integer characters from the input string. */
+ public OutType left(InType len) {
+ return toApiSpecificExpression(unresolvedCall(LEFT, toExpr(), objectToExpression(len)));
+ }
+
+ /** Returns the rightmost integer characters from the input string. */
+ public OutType right(InType len) {
+ return toApiSpecificExpression(unresolvedCall(RIGHT, toExpr(), objectToExpression(len)));
+ }
+
/** Returns a string that removes the left whitespaces from the given string. */
public OutType ltrim() {
return toApiSpecificExpression(unresolvedCall(LTRIM, toExpr()));
diff --git a/flink-table/flink-table-common/src/main/java/org/apache/flink/table/functions/BuiltInFunctionDefinitions.java b/flink-table/flink-table-common/src/main/java/org/apache/flink/table/functions/BuiltInFunctionDefinitions.java
index bb00d2e45cb..645d8e5372b 100644
--- a/flink-table/flink-table-common/src/main/java/org/apache/flink/table/functions/BuiltInFunctionDefinitions.java
+++ b/flink-table/flink-table-common/src/main/java/org/apache/flink/table/functions/BuiltInFunctionDefinitions.java
@@ -760,6 +760,28 @@ public final class BuiltInFunctionDefinitions {
.outputTypeStrategy(nullableIfArgs(explicit(DataTypes.BYTES())))
.build();
+ public static final BuiltInFunctionDefinition LEFT =
+ BuiltInFunctionDefinition.newBuilder()
+ .name("left")
+ .kind(SCALAR)
+ .inputTypeStrategy(
+ sequence(
+ logical(LogicalTypeFamily.CHARACTER_STRING),
+ logical(LogicalTypeFamily.INTEGER_NUMERIC)))
+ .outputTypeStrategy(nullableIfArgs(varyingString(argument(0))))
+ .build();
+
+ public static final BuiltInFunctionDefinition RIGHT =
+ BuiltInFunctionDefinition.newBuilder()
+ .name("right")
+ .kind(SCALAR)
+ .inputTypeStrategy(
+ sequence(
+ logical(LogicalTypeFamily.CHARACTER_STRING),
+ logical(LogicalTypeFamily.INTEGER_NUMERIC)))
+ .outputTypeStrategy(nullableIfArgs(varyingString(argument(0))))
+ .build();
+
public static final BuiltInFunctionDefinition UUID =
BuiltInFunctionDefinition.newBuilder()
.name("uuid")
diff --git a/flink-table/flink-table-planner/src/main/java/org/apache/flink/table/planner/expressions/converter/DirectConvertRule.java b/flink-table/flink-table-planner/src/main/java/org/apache/flink/table/planner/expressions/converter/DirectConvertRule.java
index 010a0d062c2..5410191f5cd 100644
--- a/flink-table/flink-table-planner/src/main/java/org/apache/flink/table/planner/expressions/converter/DirectConvertRule.java
+++ b/flink-table/flink-table-planner/src/main/java/org/apache/flink/table/planner/expressions/converter/DirectConvertRule.java
@@ -116,6 +116,8 @@ public class DirectConvertRule implements CallExpressionConvertRule {
BuiltInFunctionDefinitions.DECODE, FlinkSqlOperatorTable.DECODE);
DEFINITION_OPERATOR_MAP.put(
BuiltInFunctionDefinitions.ENCODE, FlinkSqlOperatorTable.ENCODE);
+ DEFINITION_OPERATOR_MAP.put(BuiltInFunctionDefinitions.LEFT, FlinkSqlOperatorTable.LEFT);
+ DEFINITION_OPERATOR_MAP.put(BuiltInFunctionDefinitions.RIGHT, FlinkSqlOperatorTable.RIGHT);
DEFINITION_OPERATOR_MAP.put(BuiltInFunctionDefinitions.UUID, FlinkSqlOperatorTable.UUID);
DEFINITION_OPERATOR_MAP.put(BuiltInFunctionDefinitions.LTRIM, FlinkSqlOperatorTable.LTRIM);
DEFINITION_OPERATOR_MAP.put(BuiltInFunctionDefinitions.RTRIM, FlinkSqlOperatorTable.RTRIM);
diff --git a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/planner/expressions/ScalarFunctionsTest.scala b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/planner/expressions/ScalarFunctionsTest.scala
index 9136e9162f7..5e1995265fa 100644
--- a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/planner/expressions/ScalarFunctionsTest.scala
+++ b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/planner/expressions/ScalarFunctionsTest.scala
@@ -195,6 +195,13 @@ class ScalarFunctionsTest extends ScalarTypesTestBase {
)
}
+ @Test
+ def testLeftAndRight(): Unit = {
+ val str = "Hello"
+ testAllApis(str.left(3), s"LEFT('$str', 3)", "Hel")
+ testAllApis(str.right(3), s"RIGHT('$str', 3)", "llo")
+ }
+
@Test
def testInstr(): Unit = {
testSqlApi("instr('Corporate Floor', 'or', 3, 2)", "14")