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