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

guohongyu pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/calcite.git


The following commit(s) were added to refs/heads/main by this push:
     new cde0fe572c [CALCITE-6968] SqlUpdate#getOperandList omits sourceSelect 
operand
cde0fe572c is described below

commit cde0fe572c928dc91247ca645c4ad86e4a6d80c3
Author: hongyu guo <[email protected]>
AuthorDate: Mon Mar 30 21:59:07 2026 +0800

    [CALCITE-6968] SqlUpdate#getOperandList omits sourceSelect operand
---
 .../java/org/apache/calcite/sql/SqlUpdate.java     |   8 +-
 .../apache/calcite/sql/SqlCallOperandsTest.java    | 141 +++++++++++++++++++++
 2 files changed, 145 insertions(+), 4 deletions(-)

diff --git a/core/src/main/java/org/apache/calcite/sql/SqlUpdate.java 
b/core/src/main/java/org/apache/calcite/sql/SqlUpdate.java
index 3d1ad09c52..82985f2bd7 100644
--- a/core/src/main/java/org/apache/calcite/sql/SqlUpdate.java
+++ b/core/src/main/java/org/apache/calcite/sql/SqlUpdate.java
@@ -47,8 +47,8 @@ public class SqlUpdate extends SqlCall {
               (SqlNodeList) operands[1],
               (SqlNodeList) operands[2],
               operands[3],
-              null,
-              (SqlIdentifier) operands[4]);
+              (SqlSelect) operands[4],
+              (SqlIdentifier) operands[5]);
         }
       };
 
@@ -93,7 +93,7 @@ public SqlUpdate(SqlParserPos pos,
   @SuppressWarnings("nullness")
   @Override public List<@Nullable SqlNode> getOperandList() {
     return ImmutableNullableList.of(targetTable, targetColumnList,
-        sourceExpressionList, condition, alias);
+        sourceExpressionList, condition, sourceSelect, alias);
   }
 
   @SuppressWarnings("assignment.type.incompatible")
@@ -113,7 +113,7 @@ public SqlUpdate(SqlParserPos pos,
       condition = operand;
       break;
     case 4:
-      sourceExpressionList = requireNonNull((SqlNodeList) operand);
+      sourceSelect = (SqlSelect) operand;
       break;
     case 5:
       alias = (SqlIdentifier) operand;
diff --git a/core/src/test/java/org/apache/calcite/sql/SqlCallOperandsTest.java 
b/core/src/test/java/org/apache/calcite/sql/SqlCallOperandsTest.java
index f829b805ce..d987167134 100644
--- a/core/src/test/java/org/apache/calcite/sql/SqlCallOperandsTest.java
+++ b/core/src/test/java/org/apache/calcite/sql/SqlCallOperandsTest.java
@@ -17,6 +17,8 @@
 package org.apache.calcite.sql;
 
 import org.apache.calcite.sql.fun.SqlStdOperatorTable;
+import org.apache.calcite.sql.parser.SqlParseException;
+import org.apache.calcite.sql.parser.SqlParser;
 import org.apache.calcite.sql.parser.SqlParserPos;
 
 import org.junit.jupiter.api.Test;
@@ -24,6 +26,7 @@
 import java.util.List;
 
 import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.containsString;
 import static org.hamcrest.Matchers.equalTo;
 import static org.hamcrest.Matchers.hasSize;
 
@@ -70,4 +73,142 @@ public class SqlCallOperandsTest {
     assertThat(sqlDelete.getSourceSelect(), equalTo(operandList.get(2)));
     assertThat(sqlDelete.getAlias(), equalTo(operandList.get(3)));
   }
+
+  /** Test case for
+   * <a 
href="https://issues.apache.org/jira/browse/CALCITE-6968";>[CALCITE-6968]
+   * SqlUpdate#getOperandList return operands' missing 'sourceSelect'</a>. */
+  @Test void testSqlUpdateGetOperandsMatchWithSetOperand() {
+    SqlUpdate sqlUpdate =
+        new SqlUpdate(SqlParserPos.ZERO, new SqlIdentifier("table1", 
SqlParserPos.ZERO),
+            SqlNodeList.EMPTY,
+            SqlNodeList.EMPTY,
+            null,
+            null,
+            null);
+    SqlNode targetTable = new SqlIdentifier("table2", SqlParserPos.ZERO);
+    final SqlIdentifier field1 = new SqlIdentifier("field1", 
SqlParserPos.ZERO);
+    final SqlIdentifier field2 = new SqlIdentifier("field2", 
SqlParserPos.ZERO);
+    final SqlIdentifier field3 = new SqlIdentifier("field3", 
SqlParserPos.ZERO);
+    final SqlNodeList targetColumnList = SqlNodeList.of(field2);
+    final SqlNodeList sourceExpressionList = SqlNodeList.of(field3);
+    SqlNode condition =
+        SqlStdOperatorTable.EQUALS.createCall(SqlParserPos.ZERO, field1,
+            SqlLiteral.createCharString("field1Value", SqlParserPos.ZERO));
+    SqlSelect sourceSelect =
+        new SqlSelect(SqlParserPos.ZERO, null,
+            SqlNodeList.of(field1),
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null);
+    SqlIdentifier alias = new SqlIdentifier("alias", SqlParserPos.ZERO);
+    sqlUpdate.setOperand(0, targetTable);
+    sqlUpdate.setOperand(1, targetColumnList);
+    sqlUpdate.setOperand(2, sourceExpressionList);
+    sqlUpdate.setOperand(3, condition);
+    sqlUpdate.setOperand(4, sourceSelect);
+    sqlUpdate.setOperand(5, alias);
+    final List<SqlNode> operandList = sqlUpdate.getOperandList();
+    assertThat(operandList, hasSize(6));
+    assertThat(sqlUpdate.getTargetTable(), equalTo(operandList.get(0)));
+    assertThat(sqlUpdate.getTargetColumnList(), equalTo(operandList.get(1)));
+    assertThat(sqlUpdate.getSourceExpressionList(), 
equalTo(operandList.get(2)));
+    assertThat(sqlUpdate.getCondition(), equalTo(operandList.get(3)));
+    assertThat(sqlUpdate.getSourceSelect(), equalTo(operandList.get(4)));
+    assertThat(sqlUpdate.getAlias(), equalTo(operandList.get(5)));
+  }
+
+  /** Test case for
+   * <a 
href="https://issues.apache.org/jira/browse/CALCITE-6968";>[CALCITE-6968]
+   * SqlUpdate#getOperandList return operands' missing 'sourceSelect'</a>. */
+  @Test void testSqlUpdateClonePreservesSourceSelect() {
+    final SqlIdentifier field1 = new SqlIdentifier("field1", 
SqlParserPos.ZERO);
+    final SqlSelect sourceSelect =
+        new SqlSelect(SqlParserPos.ZERO, null,
+            SqlNodeList.of(field1),
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null);
+    final SqlIdentifier alias = new SqlIdentifier("alias", SqlParserPos.ZERO);
+    final SqlUpdate sqlUpdate =
+        new SqlUpdate(SqlParserPos.ZERO, new SqlIdentifier("table1", 
SqlParserPos.ZERO),
+            SqlNodeList.of(field1),
+            SqlNodeList.of(SqlLiteral.createCharString("field1Value", 
SqlParserPos.ZERO)),
+            null,
+            sourceSelect,
+            alias);
+    final SqlUpdate cloned = (SqlUpdate) sqlUpdate.clone(SqlParserPos.ZERO);
+    assertThat(cloned.getOperandList(), hasSize(6));
+    assertThat(cloned.getSourceSelect(), equalTo(sourceSelect));
+    assertThat(cloned.getAlias(), equalTo(alias));
+  }
+
+  /** Test case for
+   * <a 
href="https://issues.apache.org/jira/browse/CALCITE-6968";>[CALCITE-6968]
+   * SqlUpdate#getOperandList return operands' missing 'sourceSelect'</a>. */
+  @Test void testSqlUpdateUnparseIgnoresSourceSelect() {
+    final SqlIdentifier targetColumn = new SqlIdentifier("field1", 
SqlParserPos.ZERO);
+    final SqlSelect sourceSelect =
+        new SqlSelect(SqlParserPos.ZERO, null,
+            SqlNodeList.of(new SqlIdentifier("internalField", 
SqlParserPos.ZERO)),
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null);
+    final SqlUpdate sqlUpdate =
+        new SqlUpdate(SqlParserPos.ZERO, new SqlIdentifier("table1", 
SqlParserPos.ZERO),
+            SqlNodeList.of(targetColumn),
+            SqlNodeList.of(SqlLiteral.createCharString("field1Value", 
SqlParserPos.ZERO)),
+            null,
+            sourceSelect,
+            new SqlIdentifier("alias", SqlParserPos.ZERO));
+    final String sql =
+        sqlUpdate.toSqlString(c -> c.withClauseStartsLine(false)).getSql();
+    assertThat(sql, containsString("UPDATE"));
+    assertThat(sql, containsString("field1Value"));
+    assertThat(sql.contains("internalField"), equalTo(false));
+    assertThat(sql.contains("SELECT"), equalTo(false));
+  }
+
+  /** Test case for
+   * <a 
href="https://issues.apache.org/jira/browse/CALCITE-6968";>[CALCITE-6968]
+   * SqlUpdate#getOperandList return operands' missing 'sourceSelect'</a>. */
+  @Test void testSqlUpdateUnparseIgnoresSourceSelectAfterParsingSql()
+      throws SqlParseException {
+    final SqlUpdate sqlUpdate =
+        (SqlUpdate) SqlParser.create("UPDATE table1 AS alias "
+            + "SET field1 = 'field1Value' "
+            + "WHERE field1 = 'field1Value'")
+            .parseStmt();
+    final SqlSelect sourceSelect =
+        (SqlSelect) SqlParser.create("SELECT INTERNAL_MARKER FROM 
INTERNAL_SOURCE")
+            .parseQuery();
+    sqlUpdate.setSourceSelect(sourceSelect);
+    final String sql =
+        sqlUpdate.toSqlString(c -> c.withClauseStartsLine(false)).getSql();
+    assertThat(sql, containsString("UPDATE"));
+    assertThat(sql, containsString("field1Value"));
+    assertThat(sql.contains("INTERNAL_MARKER"), equalTo(false));
+    assertThat(sql.contains("INTERNAL_SOURCE"), equalTo(false));
+    assertThat(sql.contains("SELECT"), equalTo(false));
+  }
 }

Reply via email to