This is an automated email from the ASF dual-hosted git repository.

wanghailin pushed a commit to branch dev
in repository https://gitbox.apache.org/repos/asf/seatunnel.git


The following commit(s) were added to refs/heads/dev by this push:
     new c99dbf29a0 [Improve][Transform-V2] support try_cast expressions (#9029)
c99dbf29a0 is described below

commit c99dbf29a05ac9de1e472d142c7df458e856966a
Author: corgy-w <[email protected]>
AuthorDate: Tue Apr 1 22:24:46 2025 +0800

    [Improve][Transform-V2] support try_cast expressions (#9029)
---
 docs/en/transform-v2/sql-functions.md                    | 12 ++++++++++++
 docs/zh/transform-v2/sql-functions.md                    | 12 ++++++++++++
 .../src/test/resources/sql_transform/func_system.conf    | 16 ++++++++++++++--
 .../seatunnel/transform/sql/zeta/ZetaSQLFunction.java    | 13 +++++++++++++
 4 files changed, 51 insertions(+), 2 deletions(-)

diff --git a/docs/en/transform-v2/sql-functions.md 
b/docs/en/transform-v2/sql-functions.md
index 3d79ebbccc..a0170d27ca 100644
--- a/docs/en/transform-v2/sql-functions.md
+++ b/docs/en/transform-v2/sql-functions.md
@@ -923,6 +923,18 @@ Example:
 
 CONVERT(NAME AS INT)
 
+### TRY_CAST
+
+```TRY_CAST(value as dataType)```
+
+This function is similar to CAST, but when the conversion fails, it returns 
NULL instead of throwing an exception.
+
+Supported data types: STRING | VARCHAR, INT | INTEGER, LONG | BIGINT, BYTE, 
FLOAT, DOUBLE, DECIMAL(p,s), TIMESTAMP, DATE, TIME, BYTES
+
+Example:
+
+TRY_CAST(NAME AS INT)
+
 ### COALESCE
 
 ```COALESCE(aValue, bValue [,...])```
diff --git a/docs/zh/transform-v2/sql-functions.md 
b/docs/zh/transform-v2/sql-functions.md
index b4b879d27f..55bdf210f2 100644
--- a/docs/zh/transform-v2/sql-functions.md
+++ b/docs/zh/transform-v2/sql-functions.md
@@ -916,6 +916,18 @@ CALL FROM_UNIXTIME(1672502400, 'yyyy-MM-dd 
HH:mm:ss','UTC+6')
 
 CONVERT(NAME AS INT)
 
+### TRY_CAST
+
+```TRY_CAST(value as dataType)```
+
+该函数类似于 CAST,但当转换失败时,它返回 NULL 而不是抛出异常。
+
+支持的数据类型有:STRING | VARCHAR,INT | INTEGER,LONG | 
BIGINT,BYTE,FLOAT,DOUBLE,DECIMAL(p,s),TIMESTAMP,DATE,TIME,BYTES
+
+示例:
+
+TRY_CAST(NAME AS INT)
+
 ### COALESCE
 
 ```COALESCE(aValue, bValue [,...])```
diff --git 
a/seatunnel-e2e/seatunnel-transforms-v2-e2e/seatunnel-transforms-v2-e2e-part-2/src/test/resources/sql_transform/func_system.conf
 
b/seatunnel-e2e/seatunnel-transforms-v2-e2e/seatunnel-transforms-v2-e2e-part-2/src/test/resources/sql_transform/func_system.conf
index 875d485731..75bef984cc 100644
--- 
a/seatunnel-e2e/seatunnel-transforms-v2-e2e/seatunnel-transforms-v2-e2e-part-2/src/test/resources/sql_transform/func_system.conf
+++ 
b/seatunnel-e2e/seatunnel-transforms-v2-e2e/seatunnel-transforms-v2-e2e-part-2/src/test/resources/sql_transform/func_system.conf
@@ -37,10 +37,12 @@ source {
         c4 = "bigint"
         c5 = "int"
         c6 = "int"
+        c7 = "string"
+        c8 = "string"
       }
     }
     rows = [
-      {fields = [1, "Joy Ding", "12.4", "2012-12-21T12:34:56", null, 
1687747869032, 20230625, 235109], kind = INSERT}
+      {fields = [1, "Joy Ding", "12.4", "2012-12-21T12:34:56", null, 
1687747869032, 20230625, 235109,"1","1c"], kind = INSERT}
     ]
   }
 }
@@ -49,7 +51,7 @@ transform {
   Sql {
     plugin_input = "fake"
     plugin_output = "fake1"
-    query = "select cast(id as STRING) as id, cast(id as INT) as id2, cast(id 
as DOUBLE) as id3 , cast(c1 as double) as c1_1, cast(c1 as DECIMAL(10,2)) as 
c1_2, cast(c2 as DATE) as c2_1, coalesce(c3,'Unknown') c3_1, 
ifnull(c3,'Unknown') c3_2, ifnull(nullif(name,'Joy Ding'),'NULL') name1, 
nullif(name,'Joy Ding_') name2, cast(c4 as timestamp) as c4_1, cast(c4 as 
decimal(17,4)) as c4_2, cast(c5 as date) as c5, cast(c6 as time) as c6, 
cast(name as BINARY) as c7, name as `apply` from dual"
+    query = "select cast(id as STRING) as id, cast(id as INT) as id2, cast(id 
as DOUBLE) as id3 , cast(c1 as double) as c1_1, cast(c1 as DECIMAL(10,2)) as 
c1_2, cast(c2 as DATE) as c2_1, coalesce(c3,'Unknown') c3_1, 
ifnull(c3,'Unknown') c3_2, ifnull(nullif(name,'Joy Ding'),'NULL') name1, 
nullif(name,'Joy Ding_') name2, cast(c4 as timestamp) as c4_1, cast(c4 as 
decimal(17,4)) as c4_2, cast(c5 as date) as c5, cast(c6 as time) as c6, 
cast(name as BINARY) as c7,try_cast(c7 AS int) as c8,try_ [...]
   }
 }
 
@@ -165,6 +167,16 @@ sink {
             }
           ]
         },
+        {
+          field_name = "c8"
+          field_type = "int"
+          field_value = [{equals_to = 1}]
+        },
+        {
+          field_name = "c9"
+          field_type = "null"
+          field_value = [{equals_to = null}]
+        },
         {
           field_name = "apply"
           field_type = "string"
diff --git 
a/seatunnel-transforms-v2/src/main/java/org/apache/seatunnel/transform/sql/zeta/ZetaSQLFunction.java
 
b/seatunnel-transforms-v2/src/main/java/org/apache/seatunnel/transform/sql/zeta/ZetaSQLFunction.java
index ae26f12335..4787ada1a4 100644
--- 
a/seatunnel-transforms-v2/src/main/java/org/apache/seatunnel/transform/sql/zeta/ZetaSQLFunction.java
+++ 
b/seatunnel-transforms-v2/src/main/java/org/apache/seatunnel/transform/sql/zeta/ZetaSQLFunction.java
@@ -193,6 +193,8 @@ public class ZetaSQLFunction {
 
     public static final String UUID = "UUID";
 
+    public static final String TRY_CAST = "TRY_CAST";
+
     private final SeaTunnelRowType inputRowType;
 
     private final ZetaSQLType zetaSQLType;
@@ -349,6 +351,9 @@ public class ZetaSQLFunction {
             CastExpression castExpression = (CastExpression) expression;
             Expression leftExpr = castExpression.getLeftExpression();
             Object leftValue = computeForValue(leftExpr, inputFields);
+            if (castExpression.keyword.equalsIgnoreCase(TRY_CAST)) {
+                return executeTryCastExpr(castExpression, leftValue);
+            }
             return executeCastExpr(castExpression, leftValue);
         }
         throw new TransformException(
@@ -604,6 +609,14 @@ public class ZetaSQLFunction {
         return SystemFunction.castAs(args);
     }
 
+    private Object executeTryCastExpr(CastExpression castExpression, Object 
arg) {
+        try {
+            return this.executeCastExpr(castExpression, arg);
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
     private Object executeBinaryExpr(BinaryExpression binaryExpression, 
Object[] inputFields) {
         if (binaryExpression instanceof Concat) {
             Concat concat = (Concat) binaryExpression;

Reply via email to