This is an automated email from the ASF dual-hosted git repository.
duanzhengqiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shardingsphere.git
The following commit(s) were added to refs/heads/master by this push:
new 216da20a3c3 support for update in Merge statements (#28789)
216da20a3c3 is described below
commit 216da20a3c340a885e59278bd8564ce66a09c8ef
Author: kanha gupta <[email protected]>
AuthorDate: Wed Oct 18 05:18:58 2023 +0530
support for update in Merge statements (#28789)
* support for update in Merge statements
* refactor
---
.../statement/merge/MergeStatementConverter.java | 37 +++++++++++++++++++++-
.../src/test/resources/converter/merge.xml | 1 +
2 files changed, 37 insertions(+), 1 deletion(-)
diff --git
a/kernel/sql-federation/optimizer/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/converter/statement/merge/MergeStatementConverter.java
b/kernel/sql-federation/optimizer/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/converter/statement/merge/MergeStatementConverter.java
index f847fa01e73..32c08702481 100644
---
a/kernel/sql-federation/optimizer/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/converter/statement/merge/MergeStatementConverter.java
+++
b/kernel/sql-federation/optimizer/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/converter/statement/merge/MergeStatementConverter.java
@@ -19,12 +19,23 @@ package
org.apache.shardingsphere.sqlfederation.optimizer.converter.statement.me
import org.apache.calcite.sql.SqlMerge;
import org.apache.calcite.sql.SqlNode;
+import org.apache.calcite.sql.SqlNodeList;
+import org.apache.calcite.sql.SqlUpdate;
import org.apache.calcite.sql.parser.SqlParserPos;
+import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.assignment.AssignmentSegment;
+import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.ColumnSegment;
+import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.ExpressionSegment;
import
org.apache.shardingsphere.sql.parser.sql.common.statement.dml.MergeStatement;
+import
org.apache.shardingsphere.sql.parser.sql.common.statement.dml.UpdateStatement;
import
org.apache.shardingsphere.sqlfederation.optimizer.converter.segment.expression.ExpressionConverter;
+import
org.apache.shardingsphere.sqlfederation.optimizer.converter.segment.expression.impl.ColumnConverter;
import
org.apache.shardingsphere.sqlfederation.optimizer.converter.segment.from.TableConverter;
+import
org.apache.shardingsphere.sqlfederation.optimizer.converter.segment.where.WhereConverter;
import
org.apache.shardingsphere.sqlfederation.optimizer.converter.statement.SQLStatementConverter;
+import java.util.List;
+import java.util.stream.Collectors;
+
/**
* Merge statement converter.
*/
@@ -35,6 +46,30 @@ public final class MergeStatementConverter implements
SQLStatementConverter<Merg
SqlNode targetTable = new
TableConverter().convert(mergeStatement.getTarget()).orElseThrow(IllegalStateException::new);
SqlNode condition = new
ExpressionConverter().convert(mergeStatement.getExpression().getExpr()).get();
SqlNode sourceTable = new
TableConverter().convert(mergeStatement.getSource()).orElseThrow(IllegalStateException::new);
- return new SqlMerge(SqlParserPos.ZERO, targetTable, condition,
sourceTable, null, null, null, null);
+ SqlUpdate sqlUpdate = null;
+ if (null != mergeStatement.getUpdate()) {
+ sqlUpdate = convertUpdate(mergeStatement.getUpdate());
+ }
+ return new SqlMerge(SqlParserPos.ZERO, targetTable, condition,
sourceTable, sqlUpdate, null, null, null);
+ }
+
+ private SqlUpdate convertUpdate(final UpdateStatement updateStatement) {
+ SqlNode table = new
TableConverter().convert(updateStatement.getTable()).orElse(SqlNodeList.EMPTY);
+ SqlNode condition = updateStatement.getWhere().flatMap(optional -> new
WhereConverter().convert(optional)).orElse(null);
+ SqlNodeList columns = new SqlNodeList(SqlParserPos.ZERO);
+ SqlNodeList expressions = new SqlNodeList(SqlParserPos.ZERO);
+ for (AssignmentSegment each :
updateStatement.getAssignmentSegment().orElseThrow(IllegalStateException::new).getAssignments())
{
+ columns.addAll(convertColumn(each.getColumns()));
+ expressions.add(convertExpression(each.getValue()));
+ }
+ return new SqlUpdate(SqlParserPos.ZERO, table, columns, expressions,
condition, null, null);
+ }
+
+ private List<SqlNode> convertColumn(final List<ColumnSegment>
columnSegments) {
+ return columnSegments.stream().map(each -> new
ColumnConverter().convert(each).orElseThrow(IllegalStateException::new)).collect(Collectors.toList());
+ }
+
+ private SqlNode convertExpression(final ExpressionSegment
expressionSegment) {
+ return new
ExpressionConverter().convert(expressionSegment).orElseThrow(IllegalStateException::new);
}
}
diff --git a/test/it/optimizer/src/test/resources/converter/merge.xml
b/test/it/optimizer/src/test/resources/converter/merge.xml
index b2d0ca14c7e..d4c3291f09b 100644
--- a/test/it/optimizer/src/test/resources/converter/merge.xml
+++ b/test/it/optimizer/src/test/resources/converter/merge.xml
@@ -19,4 +19,5 @@
<sql-node-converter-test-cases>
<test-cases sql-case-id="merge_into_table_using_table" expected-sql="MERGE
INTO "people_target" USING "people_source" ON
"people_target"."person_id" =
"people_source"."person_id"" db-types="Oracle"
sql-case-types="LITERAL" />
<test-cases sql-case-id="merge_into_table_using_subquery_alias"
expected-sql="MERGE INTO "bonuses" "D" USING (SELECT
"employee_id", "salary", "department_id" FROM
"employees" WHERE "department_id" = 80) "S" ON
"D"."employee_id" = "S"."employee_id""
db-types="Oracle" sql-case-types="LITERAL" />
+ <test-cases sql-case-id="merge_update_table" expected-sql="MERGE INTO
"people_target" "pt" USING "people_source"
"ps" ON "pt"."person_id" =
"ps"."person_id" WHEN MATCHED THEN UPDATE SET
"pt"."first_name" = "ps"."first_name",
"pt"."last_name" = "ps"."last_name",
"pt"."title" = "ps"."title" [...]
</sql-node-converter-test-cases>