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

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


The following commit(s) were added to refs/heads/master by this push:
     new 51561476a08 [FLINK-38565][table] Reduce `TRY_CAST` chain if source and 
target types are same
51561476a08 is described below

commit 51561476a086fac922b363f07708fba6f78aeed5
Author: Sergey Nuyanzin <[email protected]>
AuthorDate: Mon Oct 27 09:35:02 2025 +0100

    [FLINK-38565][table] Reduce `TRY_CAST` chain if source and target types are 
same
---
 .../planner/calcite/FlinkConvertletTable.java      |  2 +-
 .../table/planner/plan/stream/sql/CalcTest.xml     | 68 ++++++++++++++++++++++
 .../table/planner/plan/stream/sql/CalcTest.scala   | 24 ++++++++
 3 files changed, 93 insertions(+), 1 deletion(-)

diff --git 
a/flink-table/flink-table-planner/src/main/java/org/apache/flink/table/planner/calcite/FlinkConvertletTable.java
 
b/flink-table/flink-table-planner/src/main/java/org/apache/flink/table/planner/calcite/FlinkConvertletTable.java
index 569704f1d87..8af320cf673 100644
--- 
a/flink-table/flink-table-planner/src/main/java/org/apache/flink/table/planner/calcite/FlinkConvertletTable.java
+++ 
b/flink-table/flink-table-planner/src/main/java/org/apache/flink/table/planner/calcite/FlinkConvertletTable.java
@@ -101,7 +101,7 @@ public class FlinkConvertletTable implements 
SqlRexConvertletTable {
         }
         type = typeFactory.createTypeWithNullability(type, true);
 
-        if (SqlUtil.isNullLiteral(leftNode, false)) {
+        if (SqlUtil.isNullLiteral(leftNode, false) || 
type.equals(valueRex.getType())) {
             final SqlValidatorImpl validator = (SqlValidatorImpl) 
cx.getValidator();
             validator.setValidatedNodeType(leftNode, type);
             return cx.convertExpression(leftNode);
diff --git 
a/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/stream/sql/CalcTest.xml
 
b/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/stream/sql/CalcTest.xml
index 4a590a1f777..d0ac50c15fc 100644
--- 
a/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/stream/sql/CalcTest.xml
+++ 
b/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/stream/sql/CalcTest.xml
@@ -532,6 +532,74 @@ LogicalProject(EXPR$0=[ROW(1, _UTF-16LE'Hi', $0)])
       <![CDATA[
 Calc(select=[ROW(1, 'Hi', a) AS EXPR$0])
 +- TableSourceScan(table=[[default_catalog, default_database, MyTable]], 
fields=[a, b, c])
+]]>
+    </Resource>
+  </TestCase>
+  <TestCase name="testRepeatedTryCast">
+    <Resource name="sql">
+      <![CDATA[SELECT TRY_CAST(TRY_CAST(a AS STRING) AS STRING) FROM MyTable]]>
+    </Resource>
+    <Resource name="ast">
+      <![CDATA[
+LogicalProject(EXPR$0=[TRY_CAST($0)])
++- LogicalTableScan(table=[[default_catalog, default_database, MyTable]])
+]]>
+    </Resource>
+    <Resource name="optimized exec plan">
+      <![CDATA[
+Calc(select=[TRY_CAST(a AS VARCHAR(2147483647)) AS EXPR$0])
++- TableSourceScan(table=[[default_catalog, default_database, MyTable]], 
fields=[a, b, c])
+]]>
+    </Resource>
+  </TestCase>
+  <TestCase name="testRepeatedTryCastAfterCast">
+    <Resource name="sql">
+      <![CDATA[SELECT TRY_CAST(CAST(a AS STRING) AS STRING) FROM MyTable]]>
+    </Resource>
+    <Resource name="ast">
+      <![CDATA[
+LogicalProject(EXPR$0=[CAST($0):VARCHAR(2147483647) CHARACTER SET "UTF-16LE"])
++- LogicalTableScan(table=[[default_catalog, default_database, MyTable]])
+]]>
+    </Resource>
+    <Resource name="optimized exec plan">
+      <![CDATA[
+Calc(select=[CAST(a AS VARCHAR(2147483647)) AS EXPR$0])
++- TableSourceScan(table=[[default_catalog, default_database, MyTable]], 
fields=[a, b, c])
+]]>
+    </Resource>
+  </TestCase>
+  <TestCase name="testRepeatedTryCastSameType">
+    <Resource name="sql">
+      <![CDATA[SELECT TRY_CAST(a AS BIGINT) FROM MyTable]]>
+    </Resource>
+    <Resource name="ast">
+      <![CDATA[
+LogicalProject(EXPR$0=[$0])
++- LogicalTableScan(table=[[default_catalog, default_database, MyTable]])
+]]>
+    </Resource>
+    <Resource name="optimized exec plan">
+      <![CDATA[
+Calc(select=[a AS EXPR$0])
++- TableSourceScan(table=[[default_catalog, default_database, MyTable]], 
fields=[a, b, c])
+]]>
+    </Resource>
+  </TestCase>
+  <TestCase name="testRepeatedTryCastDifferentType">
+    <Resource name="sql">
+      <![CDATA[SELECT TRY_CAST(TRY_CAST(a AS STRING) AS INTEGER) FROM 
MyTable]]>
+    </Resource>
+    <Resource name="ast">
+      <![CDATA[
+LogicalProject(EXPR$0=[TRY_CAST(TRY_CAST($0))])
++- LogicalTableScan(table=[[default_catalog, default_database, MyTable]])
+]]>
+    </Resource>
+    <Resource name="optimized exec plan">
+      <![CDATA[
+Calc(select=[TRY_CAST(TRY_CAST(a AS VARCHAR(2147483647)) AS INTEGER) AS 
EXPR$0])
++- TableSourceScan(table=[[default_catalog, default_database, MyTable]], 
fields=[a, b, c])
 ]]>
     </Resource>
   </TestCase>
diff --git 
a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/planner/plan/stream/sql/CalcTest.scala
 
b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/planner/plan/stream/sql/CalcTest.scala
index 13b451aea2b..896d2d24e60 100644
--- 
a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/planner/plan/stream/sql/CalcTest.scala
+++ 
b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/planner/plan/stream/sql/CalcTest.scala
@@ -230,4 +230,28 @@ class CalcTest extends TableTestBase {
                            |SELECT my_row = ROW(1, 'str') from src
                            |""".stripMargin)
   }
+
+  @Test
+  def testRepeatedTryCast(): Unit = {
+    val sqlQuery = "SELECT TRY_CAST(TRY_CAST(a AS STRING) AS STRING) FROM 
MyTable"
+    util.verifyExecPlan(sqlQuery)
+  }
+
+  @Test
+  def testRepeatedTryCastAfterCast(): Unit = {
+    val sqlQuery = "SELECT TRY_CAST(CAST(a AS STRING) AS STRING) FROM MyTable"
+    util.verifyExecPlan(sqlQuery)
+  }
+
+  @Test
+  def testRepeatedTryCastSameType(): Unit = {
+    val sqlQuery = "SELECT TRY_CAST(a AS BIGINT) FROM MyTable"
+    util.verifyExecPlan(sqlQuery)
+  }
+
+  @Test
+  def testRepeatedTryCastDifferentType(): Unit = {
+    val sqlQuery = "SELECT TRY_CAST(TRY_CAST(a AS STRING) AS INTEGER) FROM 
MyTable"
+    util.verifyExecPlan(sqlQuery)
+  }
 }

Reply via email to