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 <92207457+kanha-gu...@users.noreply.github.com> 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>