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

jackietien pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb.git


The following commit(s) were added to refs/heads/master by this push:
     new e5d7d558981 Add try_cast function
e5d7d558981 is described below

commit e5d7d55898156bba2cc98dba164d936802b7bbd2
Author: FearfulTomcat27 <[email protected]>
AuthorDate: Fri Oct 25 10:27:16 2024 +0800

    Add try_cast function
---
 .../scalar/IoTDBCastFunctionTableIT.java           | 552 +++++++++++++++++++++
 .../relational/ColumnTransformerBuilder.java       |   6 +-
 .../plan/relational/sql/parser/AstBuilder.java     |   6 +-
 ... => AbstractCastFunctionColumnTransformer.java} |  78 +--
 .../scalar/CastFunctionColumnTransformer.java      | 320 +-----------
 .../scalar/TryCastFunctionColumnTransformer.java   |  75 +++
 .../db/relational/grammar/sql/RelationalSql.g4     |   1 +
 7 files changed, 661 insertions(+), 377 deletions(-)

diff --git 
a/integration-test/src/test/java/org/apache/iotdb/relational/it/query/old/builtinfunction/scalar/IoTDBCastFunctionTableIT.java
 
b/integration-test/src/test/java/org/apache/iotdb/relational/it/query/old/builtinfunction/scalar/IoTDBCastFunctionTableIT.java
index 16075573251..53db1c1ee77 100644
--- 
a/integration-test/src/test/java/org/apache/iotdb/relational/it/query/old/builtinfunction/scalar/IoTDBCastFunctionTableIT.java
+++ 
b/integration-test/src/test/java/org/apache/iotdb/relational/it/query/old/builtinfunction/scalar/IoTDBCastFunctionTableIT.java
@@ -641,6 +641,522 @@ public class IoTDBCastFunctionTableIT {
 
   // endregion
 
+  // region try_cast
+
+  @Test
+  public void testNewTransformerWithIntSourceInTryCast() {
+    // cast to int
+    String[] expectedHeader = new String[] {TIMESTAMP_STR, "cast_s1"};
+    String[] intRetArray =
+        new String[] {
+          "1970-01-01T00:00:00.000Z,0,",
+          "1970-01-01T00:00:00.001Z,1,",
+          "1970-01-01T00:00:00.002Z,2,",
+          "1970-01-01T00:00:00.003Z,3,",
+        };
+    tableResultSetEqualTest(
+        "select Time, TRY_CAST(s1 AS INT32) as cast_s1 from normal where 
device_id='d1'",
+        expectedHeader,
+        intRetArray,
+        DATABASE_NAME);
+
+    // cast to long
+    String[] longRetArray =
+        new String[] {
+          "1970-01-01T00:00:00.000Z,0,",
+          "1970-01-01T00:00:00.001Z,1,",
+          "1970-01-01T00:00:00.002Z,2,",
+          "1970-01-01T00:00:00.003Z,3,",
+        };
+    tableResultSetEqualTest(
+        "select Time, TRY_CAST(s1 AS INT64) as cast_s1 from normal where 
device_id='d1'",
+        expectedHeader,
+        longRetArray,
+        DATABASE_NAME);
+
+    // cast to float
+    String[] floatRetArray =
+        new String[] {
+          "1970-01-01T00:00:00.000Z,0.0,",
+          "1970-01-01T00:00:00.001Z,1.0,",
+          "1970-01-01T00:00:00.002Z,2.0,",
+          "1970-01-01T00:00:00.003Z,3.0,",
+        };
+    tableResultSetEqualTest(
+        "select Time, TRY_CAST(s1 AS FLOAT) as cast_s1 from normal where 
device_id='d1'",
+        expectedHeader,
+        floatRetArray,
+        DATABASE_NAME);
+
+    // cast to double
+    String[] doubleRetArray =
+        new String[] {
+          "1970-01-01T00:00:00.000Z,0.0,",
+          "1970-01-01T00:00:00.001Z,1.0,",
+          "1970-01-01T00:00:00.002Z,2.0,",
+          "1970-01-01T00:00:00.003Z,3.0,",
+        };
+    tableResultSetEqualTest(
+        "select Time, TRY_CAST(s1 AS DOUBLE) as cast_s1 from normal where 
device_id='d1'",
+        expectedHeader,
+        doubleRetArray,
+        DATABASE_NAME);
+
+    // cast to boolean
+    String[] booleanRetArray =
+        new String[] {
+          "1970-01-01T00:00:00.000Z,false,",
+          "1970-01-01T00:00:00.001Z,true,",
+          "1970-01-01T00:00:00.002Z,true,",
+          "1970-01-01T00:00:00.003Z,true,",
+        };
+    tableResultSetEqualTest(
+        "select Time, TRY_CAST(s1 AS BOOLEAN) as cast_s1 from normal where 
device_id='d1'",
+        expectedHeader,
+        booleanRetArray,
+        DATABASE_NAME);
+
+    // cast to string
+    String[] stringRetArray =
+        new String[] {
+          "1970-01-01T00:00:00.000Z,0,",
+          "1970-01-01T00:00:00.001Z,1,",
+          "1970-01-01T00:00:00.002Z,2,",
+          "1970-01-01T00:00:00.003Z,3,",
+        };
+    tableResultSetEqualTest(
+        "select Time, TRY_CAST(s1 AS STRING) as cast_s1 from normal where 
device_id='d1'",
+        expectedHeader,
+        stringRetArray,
+        DATABASE_NAME);
+  }
+
+  @Test
+  public void testNewTransformerWithLongSourceInTryCast() {
+    // cast to int
+    String[] expectedHeader = new String[] {TIMESTAMP_STR, "cast_s2"};
+    String[] intRetArray =
+        new String[] {
+          "1970-01-01T00:00:00.000Z,0,",
+          "1970-01-01T00:00:00.001Z,1,",
+          "1970-01-01T00:00:00.002Z,2,",
+          "1970-01-01T00:00:00.003Z,3,",
+        };
+
+    tableResultSetEqualTest(
+        "select Time, TRY_CAST(s2 AS INT32) as cast_s2 from normal where 
device_id='d1'",
+        expectedHeader,
+        intRetArray,
+        DATABASE_NAME);
+
+    // cast to long
+    String[] longRetArray =
+        new String[] {
+          "1970-01-01T00:00:00.000Z,0,",
+          "1970-01-01T00:00:00.001Z,1,",
+          "1970-01-01T00:00:00.002Z,2,",
+          "1970-01-01T00:00:00.003Z,3,",
+        };
+    tableResultSetEqualTest(
+        "select Time, TRY_CAST(s2 AS INT64) as cast_s2 from normal where 
device_id='d1'",
+        expectedHeader,
+        longRetArray,
+        DATABASE_NAME);
+
+    // cast to float
+    String[] floatRetArray =
+        new String[] {
+          "1970-01-01T00:00:00.000Z,0.0,",
+          "1970-01-01T00:00:00.001Z,1.0,",
+          "1970-01-01T00:00:00.002Z,2.0,",
+          "1970-01-01T00:00:00.003Z,3.0,",
+        };
+    tableResultSetEqualTest(
+        "select Time, TRY_CAST(s2 AS FLOAT) as cast_s2 from normal where 
device_id='d1'",
+        expectedHeader,
+        floatRetArray,
+        DATABASE_NAME);
+
+    // cast to double
+    String[] doubleRetArray =
+        new String[] {
+          "1970-01-01T00:00:00.000Z,0.0,",
+          "1970-01-01T00:00:00.001Z,1.0,",
+          "1970-01-01T00:00:00.002Z,2.0,",
+          "1970-01-01T00:00:00.003Z,3.0,",
+        };
+    tableResultSetEqualTest(
+        "select Time, TRY_CAST(s2 AS DOUBLE) as cast_s2 from normal where 
device_id='d1'",
+        expectedHeader,
+        doubleRetArray,
+        DATABASE_NAME);
+
+    // cast to boolean
+    String[] booleanRetArray =
+        new String[] {
+          "1970-01-01T00:00:00.000Z,false,",
+          "1970-01-01T00:00:00.001Z,true,",
+          "1970-01-01T00:00:00.002Z,true,",
+          "1970-01-01T00:00:00.003Z,true,",
+        };
+    tableResultSetEqualTest(
+        "select Time, TRY_CAST(s2 AS BOOLEAN) as cast_s2 from normal where 
device_id='d1'",
+        expectedHeader,
+        booleanRetArray,
+        DATABASE_NAME);
+
+    // cast to text
+    String[] stringRetArray =
+        new String[] {
+          "1970-01-01T00:00:00.000Z,0,",
+          "1970-01-01T00:00:00.001Z,1,",
+          "1970-01-01T00:00:00.002Z,2,",
+          "1970-01-01T00:00:00.003Z,3,",
+        };
+    tableResultSetEqualTest(
+        "select Time, TRY_CAST(s2 AS STRING) as cast_s2 from normal where 
device_id='d1'",
+        expectedHeader,
+        stringRetArray,
+        DATABASE_NAME);
+  }
+
+  @Test
+  public void testNewTransformerWithFloatSourceInTryCast() {
+    // cast to int
+    String[] expectedHeader = new String[] {TIMESTAMP_STR, "cast_s3"};
+    String[] intRetArray =
+        new String[] {
+          "1970-01-01T00:00:00.000Z,0,",
+          "1970-01-01T00:00:00.001Z,1,",
+          "1970-01-01T00:00:00.002Z,3,",
+          "1970-01-01T00:00:00.003Z,3,",
+        };
+    tableResultSetEqualTest(
+        "select Time, TRY_CAST(s3 AS INT32) as cast_s3 from normal where 
device_id='d1'",
+        expectedHeader,
+        intRetArray,
+        DATABASE_NAME);
+
+    // cast to long
+    String[] longRetArray =
+        new String[] {
+          "1970-01-01T00:00:00.000Z,0,",
+          "1970-01-01T00:00:00.001Z,1,",
+          "1970-01-01T00:00:00.002Z,3,",
+          "1970-01-01T00:00:00.003Z,3,",
+        };
+    tableResultSetEqualTest(
+        "select Time, TRY_CAST(s3 AS INT64) as cast_s3 from normal where 
device_id='d1'",
+        expectedHeader,
+        longRetArray,
+        DATABASE_NAME);
+
+    // cast to float
+    String[] floatRetArray =
+        new String[] {
+          "1970-01-01T00:00:00.000Z,0.0,",
+          "1970-01-01T00:00:00.001Z,1.0,",
+          "1970-01-01T00:00:00.002Z,2.7,",
+          "1970-01-01T00:00:00.003Z,3.33,",
+        };
+    tableResultSetEqualTest(
+        "select Time, TRY_CAST(s3 AS FLOAT) as cast_s3 from normal where 
device_id='d1'",
+        expectedHeader,
+        floatRetArray,
+        DATABASE_NAME);
+
+    // cast to double
+    String[] doubleRetArray =
+        new String[] {
+          "1970-01-01T00:00:00.000Z,0.0,",
+          "1970-01-01T00:00:00.001Z,1.0,",
+          "1970-01-01T00:00:00.002Z,2.700000047683716,",
+          "1970-01-01T00:00:00.003Z,3.3299999237060547,",
+        };
+    tableResultSetEqualTest(
+        "select Time, TRY_CAST(s3 AS DOUBLE) as cast_s3 from normal where 
device_id='d1'",
+        expectedHeader,
+        doubleRetArray,
+        DATABASE_NAME);
+
+    // cast to boolean
+    String[] booleanRetArray =
+        new String[] {
+          "1970-01-01T00:00:00.000Z,false,",
+          "1970-01-01T00:00:00.001Z,true,",
+          "1970-01-01T00:00:00.002Z,true,",
+          "1970-01-01T00:00:00.003Z,true,",
+        };
+    tableResultSetEqualTest(
+        "select Time, TRY_CAST(s3 AS BOOLEAN) as cast_s3 from normal where 
device_id='d1'",
+        expectedHeader,
+        booleanRetArray,
+        DATABASE_NAME);
+
+    // cast to text
+    String[] stringRetArray =
+        new String[] {
+          "1970-01-01T00:00:00.000Z,0.0,",
+          "1970-01-01T00:00:00.001Z,1.0,",
+          "1970-01-01T00:00:00.002Z,2.7,",
+          "1970-01-01T00:00:00.003Z,3.33,",
+        };
+    tableResultSetEqualTest(
+        "select Time, TRY_CAST(s3 AS STRING) as cast_s3 from normal where 
device_id='d1'",
+        expectedHeader,
+        stringRetArray,
+        DATABASE_NAME);
+  }
+
+  @Test
+  public void testNewTransformerWithDoubleSourceInTryCast() {
+    // cast to int
+    String[] expectedHeader = new String[] {TIMESTAMP_STR, "cast_s4"};
+    String[] intRetArray =
+        new String[] {
+          "1970-01-01T00:00:00.000Z,0,",
+          "1970-01-01T00:00:00.001Z,1,",
+          "1970-01-01T00:00:00.002Z,3,",
+          "1970-01-01T00:00:00.003Z,3,",
+        };
+    tableResultSetEqualTest(
+        "select Time, TRY_CAST(s4 AS INT32) as cast_s4 from normal where 
device_id='d1'",
+        expectedHeader,
+        intRetArray,
+        DATABASE_NAME);
+
+    // cast to long
+    String[] longRetArray =
+        new String[] {
+          "1970-01-01T00:00:00.000Z,0,",
+          "1970-01-01T00:00:00.001Z,1,",
+          "1970-01-01T00:00:00.002Z,3,",
+          "1970-01-01T00:00:00.003Z,3,",
+        };
+    tableResultSetEqualTest(
+        "select Time, TRY_CAST(s4 AS INT64) as cast_s4 from normal where 
device_id='d1'",
+        expectedHeader,
+        longRetArray,
+        DATABASE_NAME);
+
+    // cast to float
+    String[] floatRetArray =
+        new String[] {
+          "1970-01-01T00:00:00.000Z,0.0,",
+          "1970-01-01T00:00:00.001Z,1.0,",
+          "1970-01-01T00:00:00.002Z,2.7,",
+          "1970-01-01T00:00:00.003Z,3.33,",
+        };
+    tableResultSetEqualTest(
+        "select Time, TRY_CAST(s4 AS FLOAT) as cast_s4 from normal where 
device_id='d1'",
+        expectedHeader,
+        floatRetArray,
+        DATABASE_NAME);
+
+    // cast to double
+    String[] doubleRetArray =
+        new String[] {
+          "1970-01-01T00:00:00.000Z,0.0,",
+          "1970-01-01T00:00:00.001Z,1.0,",
+          "1970-01-01T00:00:00.002Z,2.7,",
+          "1970-01-01T00:00:00.003Z,3.33,",
+        };
+    tableResultSetEqualTest(
+        "select Time, TRY_CAST(s4 AS DOUBLE) as cast_s4 from normal where 
device_id='d1'",
+        expectedHeader,
+        doubleRetArray,
+        DATABASE_NAME);
+
+    // cast to boolean
+    String[] booleanRetArray =
+        new String[] {
+          "1970-01-01T00:00:00.000Z,false,",
+          "1970-01-01T00:00:00.001Z,true,",
+          "1970-01-01T00:00:00.002Z,true,",
+          "1970-01-01T00:00:00.003Z,true,",
+        };
+    tableResultSetEqualTest(
+        "select Time, TRY_CAST(s4 AS BOOLEAN) as cast_s4 from normal where 
device_id='d1'",
+        expectedHeader,
+        booleanRetArray,
+        DATABASE_NAME);
+
+    // cast to string
+    String[] stringRetArray =
+        new String[] {
+          "1970-01-01T00:00:00.000Z,0.0,",
+          "1970-01-01T00:00:00.001Z,1.0,",
+          "1970-01-01T00:00:00.002Z,2.7,",
+          "1970-01-01T00:00:00.003Z,3.33,",
+        };
+    tableResultSetEqualTest(
+        "select Time, TRY_CAST(s4 AS STRING) as cast_s4 from normal where 
device_id='d1'",
+        expectedHeader,
+        stringRetArray,
+        DATABASE_NAME);
+  }
+
+  @Test
+  public void testNewTransformerWithBooleanSourceInTryCast() {
+    // cast to int
+    String[] expectedHeader = new String[] {TIMESTAMP_STR, "cast_s5"};
+    String[] intRetArray =
+        new String[] {
+          "1970-01-01T00:00:00.000Z,0,",
+          "1970-01-01T00:00:00.001Z,0,",
+          "1970-01-01T00:00:00.002Z,1,",
+          "1970-01-01T00:00:00.003Z,1,",
+        };
+    tableResultSetEqualTest(
+        "select Time, TRY_CAST(s5 AS INT32) as cast_s5 from normal where 
device_id='d1'",
+        expectedHeader,
+        intRetArray,
+        DATABASE_NAME);
+
+    // cast to long
+    String[] longRetArray =
+        new String[] {
+          "1970-01-01T00:00:00.000Z,0,",
+          "1970-01-01T00:00:00.001Z,0,",
+          "1970-01-01T00:00:00.002Z,1,",
+          "1970-01-01T00:00:00.003Z,1,",
+        };
+    tableResultSetEqualTest(
+        "select Time, TRY_CAST(s5 AS INT64) as cast_s5 from normal where 
device_id='d1'",
+        expectedHeader,
+        longRetArray,
+        DATABASE_NAME);
+
+    // cast to float
+    String[] floatRetArray =
+        new String[] {
+          "1970-01-01T00:00:00.000Z,0.0,",
+          "1970-01-01T00:00:00.001Z,0.0,",
+          "1970-01-01T00:00:00.002Z,1.0,",
+          "1970-01-01T00:00:00.003Z,1.0,",
+        };
+    tableResultSetEqualTest(
+        "select Time, TRY_CAST(s5 AS FLOAT) as cast_s5 from normal where 
device_id='d1'",
+        expectedHeader,
+        floatRetArray,
+        DATABASE_NAME);
+
+    // cast to double
+    String[] doubleRetArray =
+        new String[] {
+          "1970-01-01T00:00:00.000Z,0.0,",
+          "1970-01-01T00:00:00.001Z,0.0,",
+          "1970-01-01T00:00:00.002Z,1.0,",
+          "1970-01-01T00:00:00.003Z,1.0,",
+        };
+    tableResultSetEqualTest(
+        "select Time, TRY_CAST(s5 AS DOUBLE) as cast_s5 from normal where 
device_id='d1'",
+        expectedHeader,
+        doubleRetArray,
+        DATABASE_NAME);
+
+    // cast to boolean
+    String[] booleanRetArray =
+        new String[] {
+          "1970-01-01T00:00:00.000Z,false,",
+          "1970-01-01T00:00:00.001Z,false,",
+          "1970-01-01T00:00:00.002Z,true,",
+          "1970-01-01T00:00:00.003Z,true,",
+        };
+    tableResultSetEqualTest(
+        "select Time, TRY_CAST(s5 AS BOOLEAN) as cast_s5 from normal where 
device_id='d1'",
+        expectedHeader,
+        booleanRetArray,
+        DATABASE_NAME);
+
+    // cast to text
+    String[] stringRetArray =
+        new String[] {
+          "1970-01-01T00:00:00.000Z,false,",
+          "1970-01-01T00:00:00.001Z,false,",
+          "1970-01-01T00:00:00.002Z,true,",
+          "1970-01-01T00:00:00.003Z,true,",
+        };
+    tableResultSetEqualTest(
+        "select Time, TRY_CAST(s5 AS STRING) as cast_s5 from normal where 
device_id='d1'",
+        expectedHeader,
+        stringRetArray,
+        DATABASE_NAME);
+  }
+
+  @Test
+  public void testNewTransformerWithTextSourceInTryCast() {
+    // cast to int
+    String[] expectedHeader = new String[] {TIMESTAMP_STR, "cast_s6"};
+    String[] intRetArray =
+        new String[] {
+          "1970-01-01T00:00:00.000Z,10000,", "1970-01-01T00:00:00.001Z,3,",
+        };
+    tableResultSetEqualTest(
+        "select Time, TRY_CAST(s6 AS INT32) as cast_s6 from normal where 
device_id='d1' and Time < 2",
+        expectedHeader,
+        intRetArray,
+        DATABASE_NAME);
+
+    // cast to long
+    String[] longRetArray =
+        new String[] {
+          "1970-01-01T00:00:00.000Z,10000,", "1970-01-01T00:00:00.001Z,3,",
+        };
+    tableResultSetEqualTest(
+        "select Time, TRY_CAST(s6 AS INT64) as cast_s6 from normal where 
device_id='d1' and Time < 2",
+        expectedHeader,
+        longRetArray,
+        DATABASE_NAME);
+
+    // cast to float
+    String[] floatRetArray =
+        new String[] {
+          "1970-01-01T00:00:00.000Z,10000.0,", "1970-01-01T00:00:00.001Z,3.0,",
+        };
+    tableResultSetEqualTest(
+        "select Time, TRY_CAST(s6 AS FLOAT) as cast_s6 from normal where 
device_id='d1' and Time < 2",
+        expectedHeader,
+        floatRetArray,
+        DATABASE_NAME);
+
+    // cast to double
+    String[] doubleRetArray =
+        new String[] {
+          "1970-01-01T00:00:00.000Z,10000.0,", "1970-01-01T00:00:00.001Z,3.0,",
+        };
+    tableResultSetEqualTest(
+        "select Time, TRY_CAST(s6 AS DOUBLE) as cast_s6 from normal where 
device_id='d1' and Time < 2",
+        expectedHeader,
+        doubleRetArray,
+        DATABASE_NAME);
+
+    // cast to boolean
+    String[] booleanRetArray =
+        new String[] {
+          "1970-01-01T00:00:00.002Z,true,", "1970-01-01T00:00:00.003Z,false,",
+        };
+    tableResultSetEqualTest(
+        "select Time, TRY_CAST(s6 AS BOOLEAN) as cast_s6 from normal where 
device_id='d1' and Time >= 2",
+        expectedHeader,
+        booleanRetArray,
+        DATABASE_NAME);
+
+    // cast to text
+    String[] stringRetArray =
+        new String[] {
+          "1970-01-01T00:00:00.000Z,10000,", "1970-01-01T00:00:00.001Z,3,",
+          "1970-01-01T00:00:00.002Z,TRue,", "1970-01-01T00:00:00.003Z,faLse,",
+        };
+    tableResultSetEqualTest(
+        "select Time, TRY_CAST(s6 AS STRING) as cast_s6 from normal where 
device_id='d1'",
+        expectedHeader,
+        stringRetArray,
+        DATABASE_NAME);
+  }
+
+  // endregion
+
   // region special cases
 
   @Test
@@ -659,6 +1175,16 @@ public class IoTDBCastFunctionTableIT {
     }
   }
 
+  @Test
+  public void testTryCastWithLongSource() {
+    String sql = "select TRY_CAST(s2 AS INT32) from special where 
device_id='d1'";
+    tableResultSetEqualTest(
+        sql,
+        new String[] {"_col0"},
+        new String[] {"null,", "null,", "null,", "null,"},
+        DATABASE_NAME);
+  }
+
   @Test
   public void testCastWithFloatSource() {
     try (Connection connection = 
EnvFactory.getEnv().getConnection(BaseEnv.TABLE_SQL_DIALECT);
@@ -682,6 +1208,16 @@ public class IoTDBCastFunctionTableIT {
     }
   }
 
+  @Test
+  public void testTryCastWithFloatSource() {
+    String sql = "select TRY_CAST(s3 AS INT32) from special where 
device_id='d1'";
+    tableResultSetEqualTest(
+        sql,
+        new String[] {"_col0"},
+        new String[] {"2147483647,", "null,", "null,", "null,"},
+        DATABASE_NAME);
+  }
+
   @Test
   public void testCastWithDoubleSource() {
     try (Connection connection = 
EnvFactory.getEnv().getConnection(BaseEnv.TABLE_SQL_DIALECT);
@@ -712,6 +1248,16 @@ public class IoTDBCastFunctionTableIT {
     }
   }
 
+  @Test
+  public void testTryCastWithDoubleSource() {
+    String sql = "select TRY_CAST(s4 AS Float) from special where 
device_id='d1'";
+    tableResultSetEqualTest(
+        sql,
+        new String[] {"_col0"},
+        new String[] {"null,", "null,", "null,", "null,"},
+        DATABASE_NAME);
+  }
+
   @Test
   public void testCastWithTextSource() {
     try (Connection connection = 
EnvFactory.getEnv().getConnection(BaseEnv.TABLE_SQL_DIALECT);
@@ -784,6 +1330,12 @@ public class IoTDBCastFunctionTableIT {
     }
   }
 
+  @Test
+  public void testTryCastWithTextSource() {
+    String sql = "select TRY_CAST(s6 AS INT32) from special where 
device_id='d1' and time = 1";
+    tableResultSetEqualTest(sql, new String[] {"_col0"}, new String[] 
{"null,"}, DATABASE_NAME);
+  }
+
   @Test
   public void testDateOutOfRange() {
     tableAssertTestFail(
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/relational/ColumnTransformerBuilder.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/relational/ColumnTransformerBuilder.java
index 6fa27f8ba3c..f2df4aab0ff 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/relational/ColumnTransformerBuilder.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/relational/ColumnTransformerBuilder.java
@@ -150,6 +150,7 @@ import 
org.apache.iotdb.db.queryengine.transformation.dag.column.unary.scalar.Ta
 import 
org.apache.iotdb.db.queryengine.transformation.dag.column.unary.scalar.TanhColumnTransformer;
 import 
org.apache.iotdb.db.queryengine.transformation.dag.column.unary.scalar.Trim2ColumnTransformer;
 import 
org.apache.iotdb.db.queryengine.transformation.dag.column.unary.scalar.TrimColumnTransformer;
+import 
org.apache.iotdb.db.queryengine.transformation.dag.column.unary.scalar.TryCastFunctionColumnTransformer;
 import 
org.apache.iotdb.db.queryengine.transformation.dag.column.unary.scalar.UpperColumnTransformer;
 
 import org.apache.tsfile.common.conf.TSFileConfig;
@@ -353,7 +354,10 @@ public class ColumnTransformerBuilder
           throw new SemanticException(String.format("Unknown type: %s", 
node.getType()));
         }
         context.cache.put(
-            node, new CastFunctionColumnTransformer(type, child, 
context.sessionInfo.getZoneId()));
+            node,
+            node.isSafe()
+                ? new TryCastFunctionColumnTransformer(type, child, 
context.sessionInfo.getZoneId())
+                : new CastFunctionColumnTransformer(type, child, 
context.sessionInfo.getZoneId()));
       }
     }
     ColumnTransformer res = context.cache.get(node);
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/parser/AstBuilder.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/parser/AstBuilder.java
index e95a8633d43..42adb9e49ea 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/parser/AstBuilder.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/parser/AstBuilder.java
@@ -1695,8 +1695,12 @@ public class AstBuilder extends 
RelationalSqlBaseVisitor<Node> {
 
   @Override
   public Node visitCast(RelationalSqlParser.CastContext ctx) {
+    boolean isTryCast = ctx.TRY_CAST() != null;
     return new Cast(
-        getLocation(ctx), (Expression) visit(ctx.expression()), (DataType) 
visit(ctx.type()));
+        getLocation(ctx),
+        (Expression) visit(ctx.expression()),
+        (DataType) visit(ctx.type()),
+        isTryCast);
   }
 
   @Override
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/CastFunctionColumnTransformer.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/AbstractCastFunctionColumnTransformer.java
similarity index 82%
copy from 
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/CastFunctionColumnTransformer.java
copy to 
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/AbstractCastFunctionColumnTransformer.java
index 05b965a202d..19e29bd8c25 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/CastFunctionColumnTransformer.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/AbstractCastFunctionColumnTransformer.java
@@ -1,20 +1,15 @@
 /*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
  *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 package org.apache.iotdb.db.queryengine.transformation.dag.column.unary.scalar;
@@ -41,11 +36,11 @@ import java.time.format.DateTimeParseException;
 import static 
org.apache.iotdb.db.queryengine.plan.expression.multi.builtin.helper.CastFunctionHelper.ERROR_MSG;
 import static org.apache.iotdb.rpc.TSStatusCode.DATE_OUT_OF_RANGE;
 
-public class CastFunctionColumnTransformer extends UnaryColumnTransformer {
+public abstract class AbstractCastFunctionColumnTransformer extends 
UnaryColumnTransformer {
 
   private final ZoneId zoneId;
 
-  public CastFunctionColumnTransformer(
+  protected AbstractCastFunctionColumnTransformer(
       Type returnType, ColumnTransformer childColumnTransformer, ZoneId 
zoneId) {
     super(returnType, childColumnTransformer);
     this.zoneId = zoneId;
@@ -77,43 +72,10 @@ public class CastFunctionColumnTransformer extends 
UnaryColumnTransformer {
     }
   }
 
-  private void transform(
-      Column column, ColumnBuilder columnBuilder, TypeEnum sourceType, Type 
childType, int i) {
-    switch (sourceType) {
-      case INT32:
-        cast(columnBuilder, childType.getInt(column, i));
-        break;
-      case DATE:
-        castDate(columnBuilder, childType.getInt(column, i));
-        break;
-      case INT64:
-        cast(columnBuilder, childType.getLong(column, i));
-        break;
-      case TIMESTAMP:
-        castTimestamp(columnBuilder, childType.getLong(column, i));
-        break;
-      case FLOAT:
-        cast(columnBuilder, childType.getFloat(column, i));
-        break;
-      case DOUBLE:
-        cast(columnBuilder, childType.getDouble(column, i));
-        break;
-      case BOOLEAN:
-        cast(columnBuilder, childType.getBoolean(column, i));
-        break;
-      case TEXT:
-      case STRING:
-      case BLOB:
-        cast(columnBuilder, childType.getBinary(column, i));
-        break;
-      default:
-        throw new UnsupportedOperationException(
-            String.format(
-                "Unsupported source dataType: %s", 
childColumnTransformer.getType().getTypeEnum()));
-    }
-  }
+  protected abstract void transform(
+      Column column, ColumnBuilder columnBuilder, TypeEnum sourceType, Type 
childType, int i);
 
-  private void cast(ColumnBuilder columnBuilder, int value) {
+  protected void cast(ColumnBuilder columnBuilder, int value) {
     switch (returnType.getTypeEnum()) {
       case INT32:
       case DATE:
@@ -144,7 +106,7 @@ public class CastFunctionColumnTransformer extends 
UnaryColumnTransformer {
     }
   }
 
-  private void castDate(ColumnBuilder columnBuilder, int value) {
+  protected void castDate(ColumnBuilder columnBuilder, int value) {
     switch (returnType.getTypeEnum()) {
       case INT32:
       case DATE:
@@ -179,7 +141,7 @@ public class CastFunctionColumnTransformer extends 
UnaryColumnTransformer {
     }
   }
 
-  private void castTimestamp(ColumnBuilder columnBuilder, long value) {
+  protected void castTimestamp(ColumnBuilder columnBuilder, long value) {
     try {
       switch (returnType.getTypeEnum()) {
         case INT32:
@@ -221,7 +183,7 @@ public class CastFunctionColumnTransformer extends 
UnaryColumnTransformer {
     }
   }
 
-  private void cast(ColumnBuilder columnBuilder, long value) {
+  protected void cast(ColumnBuilder columnBuilder, long value) {
     switch (returnType.getTypeEnum()) {
       case INT32:
       case DATE:
@@ -252,7 +214,7 @@ public class CastFunctionColumnTransformer extends 
UnaryColumnTransformer {
     }
   }
 
-  private void cast(ColumnBuilder columnBuilder, float value) {
+  protected void cast(ColumnBuilder columnBuilder, float value) {
     switch (returnType.getTypeEnum()) {
       case INT32:
       case DATE:
@@ -283,7 +245,7 @@ public class CastFunctionColumnTransformer extends 
UnaryColumnTransformer {
     }
   }
 
-  private void cast(ColumnBuilder columnBuilder, double value) {
+  protected void cast(ColumnBuilder columnBuilder, double value) {
     switch (returnType.getTypeEnum()) {
       case INT32:
       case DATE:
@@ -314,7 +276,7 @@ public class CastFunctionColumnTransformer extends 
UnaryColumnTransformer {
     }
   }
 
-  private void cast(ColumnBuilder columnBuilder, boolean value) {
+  protected void cast(ColumnBuilder columnBuilder, boolean value) {
     switch (returnType.getTypeEnum()) {
       case INT32:
       case DATE:
@@ -345,7 +307,7 @@ public class CastFunctionColumnTransformer extends 
UnaryColumnTransformer {
     }
   }
 
-  private void cast(ColumnBuilder columnBuilder, Binary value) {
+  protected void cast(ColumnBuilder columnBuilder, Binary value) {
     String stringValue = value.getStringValue(TSFileConfig.STRING_CHARSET);
     try {
       switch (returnType.getTypeEnum()) {
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/CastFunctionColumnTransformer.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/CastFunctionColumnTransformer.java
index 05b965a202d..3412246eea0 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/CastFunctionColumnTransformer.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/CastFunctionColumnTransformer.java
@@ -19,65 +19,24 @@
 
 package org.apache.iotdb.db.queryengine.transformation.dag.column.unary.scalar;
 
-import org.apache.iotdb.commons.exception.IoTDBRuntimeException;
-import org.apache.iotdb.db.exception.sql.SemanticException;
-import 
org.apache.iotdb.db.queryengine.plan.expression.multi.builtin.helper.CastFunctionHelper;
 import 
org.apache.iotdb.db.queryengine.transformation.dag.column.ColumnTransformer;
-import 
org.apache.iotdb.db.queryengine.transformation.dag.column.unary.UnaryColumnTransformer;
-import org.apache.iotdb.db.utils.DateTimeUtils;
 
 import org.apache.tsfile.block.column.Column;
 import org.apache.tsfile.block.column.ColumnBuilder;
-import org.apache.tsfile.common.conf.TSFileConfig;
 import org.apache.tsfile.read.common.type.Type;
 import org.apache.tsfile.read.common.type.TypeEnum;
-import org.apache.tsfile.utils.Binary;
-import org.apache.tsfile.utils.BytesUtils;
-import org.apache.tsfile.utils.DateUtils;
 
 import java.time.ZoneId;
-import java.time.format.DateTimeParseException;
 
-import static 
org.apache.iotdb.db.queryengine.plan.expression.multi.builtin.helper.CastFunctionHelper.ERROR_MSG;
-import static org.apache.iotdb.rpc.TSStatusCode.DATE_OUT_OF_RANGE;
-
-public class CastFunctionColumnTransformer extends UnaryColumnTransformer {
-
-  private final ZoneId zoneId;
+public class CastFunctionColumnTransformer extends 
AbstractCastFunctionColumnTransformer {
 
   public CastFunctionColumnTransformer(
       Type returnType, ColumnTransformer childColumnTransformer, ZoneId 
zoneId) {
-    super(returnType, childColumnTransformer);
-    this.zoneId = zoneId;
+    super(returnType, childColumnTransformer, zoneId);
   }
 
   @Override
-  protected void doTransform(Column column, ColumnBuilder columnBuilder) {
-    TypeEnum sourceType = childColumnTransformer.getType().getTypeEnum();
-    Type childType = childColumnTransformer.getType();
-    for (int i = 0, n = column.getPositionCount(); i < n; i++) {
-      if (!column.isNull(i)) {
-        transform(column, columnBuilder, sourceType, childType, i);
-      } else {
-        columnBuilder.appendNull();
-      }
-    }
-  }
-
-  @Override
-  protected void doTransform(Column column, ColumnBuilder columnBuilder, 
boolean[] selection) {
-    TypeEnum sourceType = childColumnTransformer.getType().getTypeEnum();
-    Type childType = childColumnTransformer.getType();
-    for (int i = 0, n = column.getPositionCount(); i < n; i++) {
-      if (selection[i] && !column.isNull(i)) {
-        transform(column, columnBuilder, sourceType, childType, i);
-      } else {
-        columnBuilder.appendNull();
-      }
-    }
-  }
-
-  private void transform(
+  protected void transform(
       Column column, ColumnBuilder columnBuilder, TypeEnum sourceType, Type 
childType, int i) {
     switch (sourceType) {
       case INT32:
@@ -112,277 +71,4 @@ public class CastFunctionColumnTransformer extends 
UnaryColumnTransformer {
                 "Unsupported source dataType: %s", 
childColumnTransformer.getType().getTypeEnum()));
     }
   }
-
-  private void cast(ColumnBuilder columnBuilder, int value) {
-    switch (returnType.getTypeEnum()) {
-      case INT32:
-      case DATE:
-        returnType.writeInt(columnBuilder, value);
-        break;
-      case INT64:
-      case TIMESTAMP:
-        returnType.writeLong(columnBuilder, value);
-        break;
-      case FLOAT:
-        returnType.writeFloat(columnBuilder, value);
-        break;
-      case DOUBLE:
-        returnType.writeDouble(columnBuilder, value);
-        break;
-      case BOOLEAN:
-        returnType.writeBoolean(columnBuilder, value != 0);
-        break;
-      case TEXT:
-      case STRING:
-        returnType.writeBinary(columnBuilder, 
BytesUtils.valueOf(String.valueOf(value)));
-        break;
-      case BLOB:
-        returnType.writeBinary(columnBuilder, new 
Binary(BytesUtils.intToBytes(value)));
-        break;
-      default:
-        throw new UnsupportedOperationException(String.format(ERROR_MSG, 
returnType.getTypeEnum()));
-    }
-  }
-
-  private void castDate(ColumnBuilder columnBuilder, int value) {
-    switch (returnType.getTypeEnum()) {
-      case INT32:
-      case DATE:
-        returnType.writeInt(columnBuilder, value);
-        break;
-      case INT64:
-        returnType.writeLong(columnBuilder, value);
-        break;
-      case TIMESTAMP:
-        returnType.writeLong(
-            columnBuilder,
-            
DateTimeUtils.correctPrecision(DateUtils.parseIntToTimestamp(value, zoneId)));
-        break;
-      case FLOAT:
-        returnType.writeFloat(columnBuilder, value);
-        break;
-      case DOUBLE:
-        returnType.writeDouble(columnBuilder, value);
-        break;
-      case BOOLEAN:
-        returnType.writeBoolean(columnBuilder, value != 0);
-        break;
-      case TEXT:
-      case STRING:
-        returnType.writeBinary(columnBuilder, 
BytesUtils.valueOf(DateUtils.formatDate(value)));
-        break;
-      case BLOB:
-        returnType.writeBinary(columnBuilder, new 
Binary(BytesUtils.intToBytes(value)));
-        break;
-      default:
-        throw new UnsupportedOperationException(String.format(ERROR_MSG, 
returnType.getTypeEnum()));
-    }
-  }
-
-  private void castTimestamp(ColumnBuilder columnBuilder, long value) {
-    try {
-      switch (returnType.getTypeEnum()) {
-        case INT32:
-          returnType.writeInt(columnBuilder, 
(CastFunctionHelper.castLongToInt(value)));
-          break;
-        case DATE:
-          returnType.writeInt(
-              columnBuilder,
-              
DateUtils.parseDateExpressionToInt(DateTimeUtils.convertToLocalDate(value, 
zoneId)));
-          break;
-        case INT64:
-        case TIMESTAMP:
-          returnType.writeLong(columnBuilder, value);
-          break;
-        case FLOAT:
-          returnType.writeFloat(columnBuilder, value);
-          break;
-        case DOUBLE:
-          returnType.writeDouble(columnBuilder, value);
-          break;
-        case BOOLEAN:
-          returnType.writeBoolean(columnBuilder, value != 0L);
-          break;
-        case TEXT:
-        case STRING:
-          returnType.writeBinary(
-              columnBuilder, 
BytesUtils.valueOf(DateTimeUtils.convertLongToDate(value, zoneId)));
-          break;
-        case BLOB:
-          returnType.writeBinary(columnBuilder, new 
Binary(BytesUtils.longToBytes(value)));
-          break;
-        default:
-          throw new UnsupportedOperationException(
-              String.format(ERROR_MSG, returnType.getTypeEnum()));
-      }
-    } catch (DateTimeParseException e) {
-      throw new IoTDBRuntimeException(
-          "Year must be between 1000 and 9999.", 
DATE_OUT_OF_RANGE.getStatusCode(), true);
-    }
-  }
-
-  private void cast(ColumnBuilder columnBuilder, long value) {
-    switch (returnType.getTypeEnum()) {
-      case INT32:
-      case DATE:
-        returnType.writeInt(columnBuilder, 
(CastFunctionHelper.castLongToInt(value)));
-        break;
-      case INT64:
-      case TIMESTAMP:
-        returnType.writeLong(columnBuilder, value);
-        break;
-      case FLOAT:
-        returnType.writeFloat(columnBuilder, value);
-        break;
-      case DOUBLE:
-        returnType.writeDouble(columnBuilder, value);
-        break;
-      case BOOLEAN:
-        returnType.writeBoolean(columnBuilder, value != 0L);
-        break;
-      case TEXT:
-      case STRING:
-        returnType.writeBinary(columnBuilder, 
BytesUtils.valueOf(String.valueOf(value)));
-        break;
-      case BLOB:
-        returnType.writeBinary(columnBuilder, new 
Binary(BytesUtils.longToBytes(value)));
-        break;
-      default:
-        throw new UnsupportedOperationException(String.format(ERROR_MSG, 
returnType.getTypeEnum()));
-    }
-  }
-
-  private void cast(ColumnBuilder columnBuilder, float value) {
-    switch (returnType.getTypeEnum()) {
-      case INT32:
-      case DATE:
-        returnType.writeInt(columnBuilder, 
CastFunctionHelper.castFloatToInt(value));
-        break;
-      case INT64:
-      case TIMESTAMP:
-        returnType.writeLong(columnBuilder, 
CastFunctionHelper.castFloatToLong(value));
-        break;
-      case FLOAT:
-        returnType.writeFloat(columnBuilder, value);
-        break;
-      case DOUBLE:
-        returnType.writeDouble(columnBuilder, value);
-        break;
-      case BOOLEAN:
-        returnType.writeBoolean(columnBuilder, value != 0.0f);
-        break;
-      case TEXT:
-      case STRING:
-        returnType.writeBinary(columnBuilder, 
BytesUtils.valueOf(String.valueOf(value)));
-        break;
-      case BLOB:
-        returnType.writeBinary(columnBuilder, new 
Binary(BytesUtils.floatToBytes(value)));
-        break;
-      default:
-        throw new UnsupportedOperationException(String.format(ERROR_MSG, 
returnType.getTypeEnum()));
-    }
-  }
-
-  private void cast(ColumnBuilder columnBuilder, double value) {
-    switch (returnType.getTypeEnum()) {
-      case INT32:
-      case DATE:
-        returnType.writeInt(columnBuilder, 
CastFunctionHelper.castDoubleToInt(value));
-        break;
-      case INT64:
-      case TIMESTAMP:
-        returnType.writeLong(columnBuilder, 
CastFunctionHelper.castDoubleToLong(value));
-        break;
-      case FLOAT:
-        returnType.writeFloat(columnBuilder, 
CastFunctionHelper.castDoubleToFloat(value));
-        break;
-      case DOUBLE:
-        returnType.writeDouble(columnBuilder, value);
-        break;
-      case BOOLEAN:
-        returnType.writeBoolean(columnBuilder, value != 0.0);
-        break;
-      case TEXT:
-      case STRING:
-        returnType.writeBinary(columnBuilder, 
BytesUtils.valueOf(String.valueOf(value)));
-        break;
-      case BLOB:
-        returnType.writeBinary(columnBuilder, new 
Binary(BytesUtils.doubleToBytes(value)));
-        break;
-      default:
-        throw new UnsupportedOperationException(String.format(ERROR_MSG, 
returnType.getTypeEnum()));
-    }
-  }
-
-  private void cast(ColumnBuilder columnBuilder, boolean value) {
-    switch (returnType.getTypeEnum()) {
-      case INT32:
-      case DATE:
-        returnType.writeInt(columnBuilder, value ? 1 : 0);
-        break;
-      case INT64:
-      case TIMESTAMP:
-        returnType.writeLong(columnBuilder, value ? 1L : 0);
-        break;
-      case FLOAT:
-        returnType.writeFloat(columnBuilder, value ? 1.0f : 0);
-        break;
-      case DOUBLE:
-        returnType.writeDouble(columnBuilder, value ? 1.0 : 0);
-        break;
-      case BOOLEAN:
-        returnType.writeBoolean(columnBuilder, value);
-        break;
-      case TEXT:
-      case STRING:
-        returnType.writeBinary(columnBuilder, 
BytesUtils.valueOf(String.valueOf(value)));
-        break;
-      case BLOB:
-        returnType.writeBinary(columnBuilder, new 
Binary(BytesUtils.boolToBytes(value)));
-        break;
-      default:
-        throw new UnsupportedOperationException(String.format(ERROR_MSG, 
returnType.getTypeEnum()));
-    }
-  }
-
-  private void cast(ColumnBuilder columnBuilder, Binary value) {
-    String stringValue = value.getStringValue(TSFileConfig.STRING_CHARSET);
-    try {
-      switch (returnType.getTypeEnum()) {
-        case INT32:
-          returnType.writeInt(columnBuilder, Integer.parseInt(stringValue));
-          break;
-        case DATE:
-          returnType.writeInt(columnBuilder, 
DateUtils.parseDateExpressionToInt(stringValue));
-          break;
-        case INT64:
-          returnType.writeLong(columnBuilder, Long.parseLong(stringValue));
-          break;
-        case TIMESTAMP:
-          returnType.writeLong(
-              columnBuilder, 
DateTimeUtils.convertDatetimeStrToLong(stringValue, zoneId));
-          break;
-        case FLOAT:
-          returnType.writeFloat(columnBuilder, 
CastFunctionHelper.castTextToFloat(stringValue));
-          break;
-        case DOUBLE:
-          returnType.writeDouble(columnBuilder, 
CastFunctionHelper.castTextToDouble(stringValue));
-          break;
-        case BOOLEAN:
-          returnType.writeBoolean(columnBuilder, 
CastFunctionHelper.castTextToBoolean(stringValue));
-          break;
-        case TEXT:
-        case STRING:
-        case BLOB:
-          returnType.writeBinary(columnBuilder, value);
-          break;
-        default:
-          throw new UnsupportedOperationException(
-              String.format(ERROR_MSG, returnType.getTypeEnum()));
-      }
-    } catch (DateTimeParseException | NumberFormatException e) {
-      throw new SemanticException(
-          String.format("Cannot cast %s to %s type", stringValue, 
returnType.getDisplayName()));
-    }
-  }
 }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/TryCastFunctionColumnTransformer.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/TryCastFunctionColumnTransformer.java
new file mode 100644
index 00000000000..b825c410206
--- /dev/null
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/TryCastFunctionColumnTransformer.java
@@ -0,0 +1,75 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.iotdb.db.queryengine.transformation.dag.column.unary.scalar;
+
+import org.apache.iotdb.commons.exception.IoTDBRuntimeException;
+import 
org.apache.iotdb.db.queryengine.transformation.dag.column.ColumnTransformer;
+
+import org.apache.tsfile.block.column.Column;
+import org.apache.tsfile.block.column.ColumnBuilder;
+import org.apache.tsfile.read.common.type.Type;
+import org.apache.tsfile.read.common.type.TypeEnum;
+
+import java.time.ZoneId;
+
+public class TryCastFunctionColumnTransformer extends 
AbstractCastFunctionColumnTransformer {
+
+  public TryCastFunctionColumnTransformer(
+      Type returnType, ColumnTransformer childColumnTransformer, ZoneId 
zoneId) {
+    super(returnType, childColumnTransformer, zoneId);
+  }
+
+  @Override
+  protected void transform(
+      Column column, ColumnBuilder columnBuilder, TypeEnum sourceType, Type 
childType, int i) {
+    try {
+      switch (sourceType) {
+        case INT32:
+          cast(columnBuilder, childType.getInt(column, i));
+          break;
+        case DATE:
+          castDate(columnBuilder, childType.getInt(column, i));
+          break;
+        case INT64:
+          cast(columnBuilder, childType.getLong(column, i));
+          break;
+        case TIMESTAMP:
+          castTimestamp(columnBuilder, childType.getLong(column, i));
+          break;
+        case FLOAT:
+          cast(columnBuilder, childType.getFloat(column, i));
+          break;
+        case DOUBLE:
+          cast(columnBuilder, childType.getDouble(column, i));
+          break;
+        case BOOLEAN:
+          cast(columnBuilder, childType.getBoolean(column, i));
+          break;
+        case TEXT:
+        case STRING:
+        case BLOB:
+          cast(columnBuilder, childType.getBinary(column, i));
+          break;
+        default:
+          throw new UnsupportedOperationException(
+              String.format(
+                  "Unsupported source dataType: %s",
+                  childColumnTransformer.getType().getTypeEnum()));
+      }
+    } catch (IoTDBRuntimeException e) {
+      columnBuilder.appendNull();
+    }
+  }
+}
diff --git 
a/iotdb-core/relational-grammar/src/main/antlr4/org/apache/iotdb/db/relational/grammar/sql/RelationalSql.g4
 
b/iotdb-core/relational-grammar/src/main/antlr4/org/apache/iotdb/db/relational/grammar/sql/RelationalSql.g4
index 1fd34b1948f..30f57e994c6 100644
--- 
a/iotdb-core/relational-grammar/src/main/antlr4/org/apache/iotdb/db/relational/grammar/sql/RelationalSql.g4
+++ 
b/iotdb-core/relational-grammar/src/main/antlr4/org/apache/iotdb/db/relational/grammar/sql/RelationalSql.g4
@@ -712,6 +712,7 @@ primaryExpression
     | CASE operand=expression whenClause+ (ELSE elseExpression=expression)? 
END           #simpleCase
     | CASE whenClause+ (ELSE elseExpression=expression)? END                   
           #searchedCase
     | CAST '(' expression AS type ')'                                          
           #cast
+    | TRY_CAST '(' expression AS type ')'                                      
           #cast
     | identifier                                                               
           #columnReference
     | base=primaryExpression '.' fieldName=identifier                          
           #dereference
     | name=NOW ('(' ')')?                                                      
           #specialDateTimeFunction


Reply via email to