Skip to content

Commit 8c7d92f

Browse files
committed
[CALCITE-6869] SqlUpdate#getOperandList omits sourceSelect operand
1 parent 2886ce1 commit 8c7d92f

2 files changed

Lines changed: 145 additions & 4 deletions

File tree

core/src/main/java/org/apache/calcite/sql/SqlUpdate.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@ public class SqlUpdate extends SqlCall {
4747
(SqlNodeList) operands[1],
4848
(SqlNodeList) operands[2],
4949
operands[3],
50-
null,
51-
(SqlIdentifier) operands[4]);
50+
(SqlSelect) operands[4],
51+
(SqlIdentifier) operands[5]);
5252
}
5353
};
5454

@@ -93,7 +93,7 @@ public SqlUpdate(SqlParserPos pos,
9393
@SuppressWarnings("nullness")
9494
@Override public List<@Nullable SqlNode> getOperandList() {
9595
return ImmutableNullableList.of(targetTable, targetColumnList,
96-
sourceExpressionList, condition, alias);
96+
sourceExpressionList, condition, sourceSelect, alias);
9797
}
9898

9999
@SuppressWarnings("assignment.type.incompatible")
@@ -113,7 +113,7 @@ public SqlUpdate(SqlParserPos pos,
113113
condition = operand;
114114
break;
115115
case 4:
116-
sourceExpressionList = requireNonNull((SqlNodeList) operand);
116+
sourceSelect = (SqlSelect) operand;
117117
break;
118118
case 5:
119119
alias = (SqlIdentifier) operand;

core/src/test/java/org/apache/calcite/sql/SqlCallOperandsTest.java

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,16 @@
1717
package org.apache.calcite.sql;
1818

1919
import org.apache.calcite.sql.fun.SqlStdOperatorTable;
20+
import org.apache.calcite.sql.parser.SqlParseException;
21+
import org.apache.calcite.sql.parser.SqlParser;
2022
import org.apache.calcite.sql.parser.SqlParserPos;
2123

2224
import org.junit.jupiter.api.Test;
2325

2426
import java.util.List;
2527

2628
import static org.hamcrest.MatcherAssert.assertThat;
29+
import static org.hamcrest.Matchers.containsString;
2730
import static org.hamcrest.Matchers.equalTo;
2831
import static org.hamcrest.Matchers.hasSize;
2932

@@ -70,4 +73,142 @@ public class SqlCallOperandsTest {
7073
assertThat(sqlDelete.getSourceSelect(), equalTo(operandList.get(2)));
7174
assertThat(sqlDelete.getAlias(), equalTo(operandList.get(3)));
7275
}
76+
77+
/** Test case for
78+
* <a href="https://issues.apache.org/jira/browse/CALCITE-6968">[CALCITE-6968]
79+
* SqlUpdate#getOperandList return operands' missing 'sourceSelect'</a>. */
80+
@Test void testSqlUpdateGetOperandsMatchWithSetOperand() {
81+
SqlUpdate sqlUpdate =
82+
new SqlUpdate(SqlParserPos.ZERO, new SqlIdentifier("table1", SqlParserPos.ZERO),
83+
SqlNodeList.EMPTY,
84+
SqlNodeList.EMPTY,
85+
null,
86+
null,
87+
null);
88+
SqlNode targetTable = new SqlIdentifier("table2", SqlParserPos.ZERO);
89+
final SqlIdentifier field1 = new SqlIdentifier("field1", SqlParserPos.ZERO);
90+
final SqlIdentifier field2 = new SqlIdentifier("field2", SqlParserPos.ZERO);
91+
final SqlIdentifier field3 = new SqlIdentifier("field3", SqlParserPos.ZERO);
92+
final SqlNodeList targetColumnList = SqlNodeList.of(field2);
93+
final SqlNodeList sourceExpressionList = SqlNodeList.of(field3);
94+
SqlNode condition =
95+
SqlStdOperatorTable.EQUALS.createCall(SqlParserPos.ZERO, field1,
96+
SqlLiteral.createCharString("field1Value", SqlParserPos.ZERO));
97+
SqlSelect sourceSelect =
98+
new SqlSelect(SqlParserPos.ZERO, null,
99+
SqlNodeList.of(field1),
100+
null,
101+
null,
102+
null,
103+
null,
104+
null,
105+
null,
106+
null,
107+
null,
108+
null,
109+
null);
110+
SqlIdentifier alias = new SqlIdentifier("alias", SqlParserPos.ZERO);
111+
sqlUpdate.setOperand(0, targetTable);
112+
sqlUpdate.setOperand(1, targetColumnList);
113+
sqlUpdate.setOperand(2, sourceExpressionList);
114+
sqlUpdate.setOperand(3, condition);
115+
sqlUpdate.setOperand(4, sourceSelect);
116+
sqlUpdate.setOperand(5, alias);
117+
final List<SqlNode> operandList = sqlUpdate.getOperandList();
118+
assertThat(operandList, hasSize(6));
119+
assertThat(sqlUpdate.getTargetTable(), equalTo(operandList.get(0)));
120+
assertThat(sqlUpdate.getTargetColumnList(), equalTo(operandList.get(1)));
121+
assertThat(sqlUpdate.getSourceExpressionList(), equalTo(operandList.get(2)));
122+
assertThat(sqlUpdate.getCondition(), equalTo(operandList.get(3)));
123+
assertThat(sqlUpdate.getSourceSelect(), equalTo(operandList.get(4)));
124+
assertThat(sqlUpdate.getAlias(), equalTo(operandList.get(5)));
125+
}
126+
127+
/** Test case for
128+
* <a href="https://issues.apache.org/jira/browse/CALCITE-6968">[CALCITE-6968]
129+
* SqlUpdate#getOperandList return operands' missing 'sourceSelect'</a>. */
130+
@Test void testSqlUpdateClonePreservesSourceSelect() {
131+
final SqlIdentifier field1 = new SqlIdentifier("field1", SqlParserPos.ZERO);
132+
final SqlSelect sourceSelect =
133+
new SqlSelect(SqlParserPos.ZERO, null,
134+
SqlNodeList.of(field1),
135+
null,
136+
null,
137+
null,
138+
null,
139+
null,
140+
null,
141+
null,
142+
null,
143+
null,
144+
null);
145+
final SqlIdentifier alias = new SqlIdentifier("alias", SqlParserPos.ZERO);
146+
final SqlUpdate sqlUpdate =
147+
new SqlUpdate(SqlParserPos.ZERO, new SqlIdentifier("table1", SqlParserPos.ZERO),
148+
SqlNodeList.of(field1),
149+
SqlNodeList.of(SqlLiteral.createCharString("field1Value", SqlParserPos.ZERO)),
150+
null,
151+
sourceSelect,
152+
alias);
153+
final SqlUpdate cloned = (SqlUpdate) sqlUpdate.clone(SqlParserPos.ZERO);
154+
assertThat(cloned.getOperandList(), hasSize(6));
155+
assertThat(cloned.getSourceSelect(), equalTo(sourceSelect));
156+
assertThat(cloned.getAlias(), equalTo(alias));
157+
}
158+
159+
/** Test case for
160+
* <a href="https://issues.apache.org/jira/browse/CALCITE-6968">[CALCITE-6968]
161+
* SqlUpdate#getOperandList return operands' missing 'sourceSelect'</a>. */
162+
@Test void testSqlUpdateUnparseIgnoresSourceSelect() {
163+
final SqlIdentifier targetColumn = new SqlIdentifier("field1", SqlParserPos.ZERO);
164+
final SqlSelect sourceSelect =
165+
new SqlSelect(SqlParserPos.ZERO, null,
166+
SqlNodeList.of(new SqlIdentifier("internalField", SqlParserPos.ZERO)),
167+
null,
168+
null,
169+
null,
170+
null,
171+
null,
172+
null,
173+
null,
174+
null,
175+
null,
176+
null);
177+
final SqlUpdate sqlUpdate =
178+
new SqlUpdate(SqlParserPos.ZERO, new SqlIdentifier("table1", SqlParserPos.ZERO),
179+
SqlNodeList.of(targetColumn),
180+
SqlNodeList.of(SqlLiteral.createCharString("field1Value", SqlParserPos.ZERO)),
181+
null,
182+
sourceSelect,
183+
new SqlIdentifier("alias", SqlParserPos.ZERO));
184+
final String sql =
185+
sqlUpdate.toSqlString(c -> c.withClauseStartsLine(false)).getSql();
186+
assertThat(sql, containsString("UPDATE"));
187+
assertThat(sql, containsString("field1Value"));
188+
assertThat(sql.contains("internalField"), equalTo(false));
189+
assertThat(sql.contains("SELECT"), equalTo(false));
190+
}
191+
192+
/** Test case for
193+
* <a href="https://issues.apache.org/jira/browse/CALCITE-6968">[CALCITE-6968]
194+
* SqlUpdate#getOperandList return operands' missing 'sourceSelect'</a>. */
195+
@Test void testSqlUpdateUnparseIgnoresSourceSelectAfterParsingSql()
196+
throws SqlParseException {
197+
final SqlUpdate sqlUpdate =
198+
(SqlUpdate) SqlParser.create("UPDATE table1 AS alias "
199+
+ "SET field1 = 'field1Value' "
200+
+ "WHERE field1 = 'field1Value'")
201+
.parseStmt();
202+
final SqlSelect sourceSelect =
203+
(SqlSelect) SqlParser.create("SELECT INTERNAL_MARKER FROM INTERNAL_SOURCE")
204+
.parseQuery();
205+
sqlUpdate.setSourceSelect(sourceSelect);
206+
final String sql =
207+
sqlUpdate.toSqlString(c -> c.withClauseStartsLine(false)).getSql();
208+
assertThat(sql, containsString("UPDATE"));
209+
assertThat(sql, containsString("field1Value"));
210+
assertThat(sql.contains("INTERNAL_MARKER"), equalTo(false));
211+
assertThat(sql.contains("INTERNAL_SOURCE"), equalTo(false));
212+
assertThat(sql.contains("SELECT"), equalTo(false));
213+
}
73214
}

0 commit comments

Comments
 (0)