diff --git a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/statement/dml/MergeStatementBinder.java b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/statement/dml/MergeStatementBinder.java deleted file mode 100644 index 1b177ffb7108d..0000000000000 --- a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/statement/dml/MergeStatementBinder.java +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.shardingsphere.infra.binder.statement.dml; - -import com.cedarsoftware.util.CaseInsensitiveMap; -import lombok.SneakyThrows; -import org.apache.shardingsphere.infra.binder.segment.SegmentType; -import org.apache.shardingsphere.infra.binder.segment.column.InsertColumnsSegmentBinder; -import org.apache.shardingsphere.infra.binder.segment.expression.ExpressionSegmentBinder; -import org.apache.shardingsphere.infra.binder.segment.expression.impl.ColumnSegmentBinder; -import org.apache.shardingsphere.infra.binder.segment.from.TableSegmentBinder; -import org.apache.shardingsphere.infra.binder.segment.from.TableSegmentBinderContext; -import org.apache.shardingsphere.infra.binder.segment.parameter.ParameterMarkerSegmentBinder; -import org.apache.shardingsphere.infra.binder.segment.where.WhereSegmentBinder; -import org.apache.shardingsphere.infra.binder.statement.SQLStatementBinder; -import org.apache.shardingsphere.infra.binder.statement.SQLStatementBinderContext; -import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData; -import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.assignment.ColumnAssignmentSegment; -import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.assignment.InsertValuesSegment; -import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.assignment.SetAssignmentSegment; -import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.column.ColumnSegment; -import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.column.InsertColumnsSegment; -import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.ExpressionSegment; -import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.ExpressionWithParamsSegment; -import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.simple.ParameterMarkerExpressionSegment; -import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.ColumnProjectionSegment; -import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.ProjectionSegment; -import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.ParameterMarkerSegment; -import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.bounded.ColumnSegmentBoundedInfo; -import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.SimpleTableSegment; -import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.SubqueryTableSegment; -import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.TableSegment; -import org.apache.shardingsphere.sql.parser.statement.core.statement.dml.InsertStatement; -import org.apache.shardingsphere.sql.parser.statement.core.statement.dml.MergeStatement; -import org.apache.shardingsphere.sql.parser.statement.core.statement.dml.UpdateStatement; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -/** - * Merge statement binder. - */ -public final class MergeStatementBinder implements SQLStatementBinder { - - @Override - public MergeStatement bind(final MergeStatement sqlStatement, final ShardingSphereMetaData metaData, final String currentDatabaseName) { - return bind(sqlStatement, metaData, currentDatabaseName, Collections.emptyMap()); - } - - private MergeStatement bind(final MergeStatement sqlStatement, final ShardingSphereMetaData metaData, final String currentDatabaseName, - final Map externalTableBinderContexts) { - MergeStatement result = copy(sqlStatement); - SQLStatementBinderContext statementBinderContext = new SQLStatementBinderContext(sqlStatement, metaData, currentDatabaseName); - statementBinderContext.getExternalTableBinderContexts().putAll(externalTableBinderContexts); - Map targetTableBinderContexts = new CaseInsensitiveMap<>(); - TableSegment boundedTargetTableSegment = TableSegmentBinder.bind(sqlStatement.getTarget(), statementBinderContext, targetTableBinderContexts, Collections.emptyMap()); - Map sourceTableBinderContexts = new CaseInsensitiveMap<>(); - TableSegment boundedSourceTableSegment = TableSegmentBinder.bind(sqlStatement.getSource(), statementBinderContext, sourceTableBinderContexts, Collections.emptyMap()); - result.setTarget(boundedTargetTableSegment); - result.setSource(boundedSourceTableSegment); - Map tableBinderContexts = new LinkedHashMap<>(); - tableBinderContexts.putAll(sourceTableBinderContexts); - tableBinderContexts.putAll(targetTableBinderContexts); - if (null != sqlStatement.getExpression()) { - ExpressionWithParamsSegment expression = new ExpressionWithParamsSegment(sqlStatement.getExpression().getStartIndex(), sqlStatement.getExpression().getStopIndex(), - ExpressionSegmentBinder.bind(sqlStatement.getExpression().getExpr(), SegmentType.JOIN_ON, statementBinderContext, tableBinderContexts, Collections.emptyMap())); - expression.getParameterMarkerSegments().addAll(sqlStatement.getExpression().getParameterMarkerSegments()); - result.setExpression(expression); - } - sqlStatement.getInsert().ifPresent( - optional -> result.setInsert(bindMergeInsert(optional, (SimpleTableSegment) boundedTargetTableSegment, statementBinderContext, targetTableBinderContexts, sourceTableBinderContexts))); - sqlStatement.getUpdate().ifPresent( - optional -> result.setUpdate(bindMergeUpdate(optional, (SimpleTableSegment) boundedTargetTableSegment, statementBinderContext, targetTableBinderContexts, sourceTableBinderContexts))); - addParameterMarkerSegments(result); - return result; - } - - @SneakyThrows(ReflectiveOperationException.class) - private MergeStatement copy(final MergeStatement sqlStatement) { - MergeStatement result = sqlStatement.getClass().getDeclaredConstructor().newInstance(); - result.getCommentSegments().addAll(sqlStatement.getCommentSegments()); - return result; - } - - private void addParameterMarkerSegments(final MergeStatement mergeStatement) { - // TODO bind parameter marker segments for merge statement - mergeStatement.addParameterMarkerSegments(getSourceSubqueryTableProjectionParameterMarkers(mergeStatement.getSource())); - mergeStatement.getInsert().ifPresent(optional -> mergeStatement.addParameterMarkerSegments(optional.getParameterMarkerSegments())); - mergeStatement.getUpdate().ifPresent(optional -> mergeStatement.addParameterMarkerSegments(optional.getParameterMarkerSegments())); - } - - private Collection getSourceSubqueryTableProjectionParameterMarkers(final TableSegment tableSegment) { - if (!(tableSegment instanceof SubqueryTableSegment)) { - return Collections.emptyList(); - } - SubqueryTableSegment subqueryTable = (SubqueryTableSegment) tableSegment; - Collection result = new LinkedList<>(); - for (ProjectionSegment each : subqueryTable.getSubquery().getSelect().getProjections().getProjections()) { - if (each instanceof ParameterMarkerExpressionSegment) { - result.add((ParameterMarkerSegment) each); - } - } - return result; - } - - @SneakyThrows - private InsertStatement bindMergeInsert(final InsertStatement sqlStatement, final SimpleTableSegment tableSegment, final SQLStatementBinderContext statementBinderContext, - final Map targetTableBinderContexts, final Map sourceTableBinderContexts) { - SQLStatementBinderContext insertStatementBinderContext = new SQLStatementBinderContext(statementBinderContext.getMetaData(), statementBinderContext.getCurrentDatabaseName(), - statementBinderContext.getDatabaseType(), statementBinderContext.getVariableNames()); - insertStatementBinderContext.getExternalTableBinderContexts().putAll(statementBinderContext.getExternalTableBinderContexts()); - insertStatementBinderContext.getExternalTableBinderContexts().putAll(sourceTableBinderContexts); - InsertStatement result = sqlStatement.getClass().getDeclaredConstructor().newInstance(); - result.setTable(tableSegment); - sqlStatement.getInsertColumns() - .ifPresent(optional -> result.setInsertColumns(InsertColumnsSegmentBinder.bind(sqlStatement.getInsertColumns().get(), statementBinderContext, targetTableBinderContexts))); - sqlStatement.getInsertSelect().ifPresent(result::setInsertSelect); - Collection insertValues = new LinkedList<>(); - Map parameterMarkerSegmentBoundedInfos = new LinkedHashMap<>(); - List columnSegments = new ArrayList<>(result.getInsertColumns().map(InsertColumnsSegment::getColumns) - .orElseGet(() -> getVisibleColumns(targetTableBinderContexts.values().iterator().next().getProjectionSegments()))); - for (InsertValuesSegment each : sqlStatement.getValues()) { - List values = new LinkedList<>(); - int index = 0; - for (ExpressionSegment expression : each.getValues()) { - values.add(ExpressionSegmentBinder.bind(expression, SegmentType.VALUES, insertStatementBinderContext, targetTableBinderContexts, sourceTableBinderContexts)); - if (expression instanceof ParameterMarkerSegment) { - parameterMarkerSegmentBoundedInfos.put((ParameterMarkerSegment) expression, columnSegments.get(index).getColumnBoundedInfo()); - } - index++; - } - insertValues.add(new InsertValuesSegment(each.getStartIndex(), each.getStopIndex(), values)); - } - result.getValues().addAll(insertValues); - sqlStatement.getOnDuplicateKeyColumns().ifPresent(result::setOnDuplicateKeyColumns); - sqlStatement.getSetAssignment().ifPresent(result::setSetAssignment); - sqlStatement.getWithSegment().ifPresent(result::setWithSegment); - sqlStatement.getOutputSegment().ifPresent(result::setOutputSegment); - sqlStatement.getMultiTableInsertType().ifPresent(result::setMultiTableInsertType); - sqlStatement.getMultiTableInsertIntoSegment().ifPresent(result::setMultiTableInsertIntoSegment); - sqlStatement.getMultiTableConditionalIntoSegment().ifPresent(result::setMultiTableConditionalIntoSegment); - sqlStatement.getReturningSegment().ifPresent(result::setReturningSegment); - sqlStatement.getWhere().ifPresent(optional -> result.setWhere(WhereSegmentBinder.bind(optional, insertStatementBinderContext, targetTableBinderContexts, sourceTableBinderContexts))); - result.addParameterMarkerSegments(ParameterMarkerSegmentBinder.bind(sqlStatement.getParameterMarkerSegments(), parameterMarkerSegmentBoundedInfos)); - result.getCommentSegments().addAll(sqlStatement.getCommentSegments()); - return result; - } - - private Collection getVisibleColumns(final Collection projectionSegments) { - Collection result = new LinkedList<>(); - for (ProjectionSegment each : projectionSegments) { - if (each instanceof ColumnProjectionSegment && each.isVisible()) { - result.add(((ColumnProjectionSegment) each).getColumn()); - } - } - return result; - } - - @SneakyThrows - private UpdateStatement bindMergeUpdate(final UpdateStatement sqlStatement, final SimpleTableSegment tableSegment, final SQLStatementBinderContext statementBinderContext, - final Map targetTableBinderContexts, final Map sourceTableBinderContexts) { - UpdateStatement result = sqlStatement.getClass().getDeclaredConstructor().newInstance(); - result.setTable(tableSegment); - Collection assignments = new LinkedList<>(); - SQLStatementBinderContext updateStatementBinderContext = new SQLStatementBinderContext(statementBinderContext.getMetaData(), statementBinderContext.getCurrentDatabaseName(), - statementBinderContext.getDatabaseType(), statementBinderContext.getVariableNames()); - updateStatementBinderContext.getExternalTableBinderContexts().putAll(statementBinderContext.getExternalTableBinderContexts()); - updateStatementBinderContext.getExternalTableBinderContexts().putAll(sourceTableBinderContexts); - Map parameterMarkerSegmentBoundedInfos = new LinkedHashMap<>(sqlStatement.getSetAssignment().getAssignments().size(), 1F); - for (ColumnAssignmentSegment each : sqlStatement.getSetAssignment().getAssignments()) { - List columnSegments = new ArrayList<>(each.getColumns().size()); - each.getColumns().forEach(column -> columnSegments.add( - ColumnSegmentBinder.bind(column, SegmentType.SET_ASSIGNMENT, updateStatementBinderContext, targetTableBinderContexts, Collections.emptyMap()))); - ExpressionSegment expression = ExpressionSegmentBinder.bind(each.getValue(), SegmentType.SET_ASSIGNMENT, updateStatementBinderContext, targetTableBinderContexts, Collections.emptyMap()); - ColumnAssignmentSegment columnAssignmentSegment = new ColumnAssignmentSegment(each.getStartIndex(), each.getStopIndex(), columnSegments, expression); - assignments.add(columnAssignmentSegment); - if (expression instanceof ParameterMarkerSegment) { - parameterMarkerSegmentBoundedInfos.put((ParameterMarkerSegment) expression, columnAssignmentSegment.getColumns().get(0).getColumnBoundedInfo()); - } - } - SetAssignmentSegment setAssignmentSegment = new SetAssignmentSegment(sqlStatement.getSetAssignment().getStartIndex(), sqlStatement.getSetAssignment().getStopIndex(), assignments); - result.setSetAssignment(setAssignmentSegment); - sqlStatement.getWhere().ifPresent(optional -> result.setWhere(WhereSegmentBinder.bind(optional, updateStatementBinderContext, targetTableBinderContexts, Collections.emptyMap()))); - sqlStatement.getDeleteWhere().ifPresent(optional -> result.setDeleteWhere(WhereSegmentBinder.bind(optional, updateStatementBinderContext, targetTableBinderContexts, Collections.emptyMap()))); - sqlStatement.getOrderBy().ifPresent(result::setOrderBy); - sqlStatement.getLimit().ifPresent(result::setLimit); - sqlStatement.getWithSegment().ifPresent(result::setWithSegment); - result.addParameterMarkerSegments(ParameterMarkerSegmentBinder.bind(sqlStatement.getParameterMarkerSegments(), parameterMarkerSegmentBoundedInfos)); - result.getCommentSegments().addAll(sqlStatement.getCommentSegments()); - return result; - } -} diff --git a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/type/DMLStatementBindEngine.java b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/type/DMLStatementBindEngine.java index a8da53fdf014f..72bbd3fdc654b 100644 --- a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/type/DMLStatementBindEngine.java +++ b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/type/DMLStatementBindEngine.java @@ -20,14 +20,12 @@ import lombok.RequiredArgsConstructor; import org.apache.shardingsphere.infra.binder.statement.dml.DeleteStatementBinder; import org.apache.shardingsphere.infra.binder.statement.dml.InsertStatementBinder; -import org.apache.shardingsphere.infra.binder.statement.dml.MergeStatementBinder; import org.apache.shardingsphere.infra.binder.statement.dml.SelectStatementBinder; import org.apache.shardingsphere.infra.binder.statement.dml.UpdateStatementBinder; import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData; import org.apache.shardingsphere.sql.parser.statement.core.statement.dml.DMLStatement; import org.apache.shardingsphere.sql.parser.statement.core.statement.dml.DeleteStatement; import org.apache.shardingsphere.sql.parser.statement.core.statement.dml.InsertStatement; -import org.apache.shardingsphere.sql.parser.statement.core.statement.dml.MergeStatement; import org.apache.shardingsphere.sql.parser.statement.core.statement.dml.SelectStatement; import org.apache.shardingsphere.sql.parser.statement.core.statement.dml.UpdateStatement; @@ -60,9 +58,6 @@ public DMLStatement bind(final DMLStatement statement) { if (statement instanceof DeleteStatement) { return new DeleteStatementBinder().bind((DeleteStatement) statement, metaData, currentDatabaseName); } - if (statement instanceof MergeStatement) { - return new MergeStatementBinder().bind((MergeStatement) statement, metaData, currentDatabaseName); - } return statement; } } diff --git a/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/statement/MergeStatementBinderTest.java b/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/statement/MergeStatementBinderTest.java deleted file mode 100644 index ba288eaa9533e..0000000000000 --- a/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/statement/MergeStatementBinderTest.java +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.shardingsphere.infra.binder.statement; - -import org.apache.shardingsphere.infra.binder.statement.dml.MergeStatementBinder; -import org.apache.shardingsphere.infra.database.core.DefaultDatabase; -import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData; -import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereColumn; -import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereSchema; -import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.assignment.ColumnAssignmentSegment; -import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.assignment.SetAssignmentSegment; -import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.column.ColumnSegment; -import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.BinaryOperationExpression; -import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.ExpressionWithParamsSegment; -import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.simple.LiteralExpressionSegment; -import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.subquery.SubquerySegment; -import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.ExpressionProjectionSegment; -import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.ProjectionsSegment; -import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.predicate.WhereSegment; -import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.AliasSegment; -import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.OwnerSegment; -import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.SimpleTableSegment; -import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.SubqueryTableSegment; -import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.TableNameSegment; -import org.apache.shardingsphere.sql.parser.statement.core.statement.dml.MergeStatement; -import org.apache.shardingsphere.sql.parser.statement.core.statement.dml.UpdateStatement; -import org.apache.shardingsphere.sql.parser.statement.core.value.identifier.IdentifierValue; -import org.apache.shardingsphere.sql.parser.statement.oracle.dml.OracleMergeStatement; -import org.apache.shardingsphere.sql.parser.statement.oracle.dml.OracleSelectStatement; -import org.apache.shardingsphere.sql.parser.statement.oracle.dml.OracleUpdateStatement; -import org.junit.jupiter.api.Test; - -import java.sql.Types; -import java.util.Arrays; -import java.util.Collections; - -import static org.hamcrest.CoreMatchers.instanceOf; -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.CoreMatchers.not; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.Mockito.RETURNS_DEEP_STUBS; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -class MergeStatementBinderTest { - - @Test - void assertBind() { - MergeStatement mergeStatement = new OracleMergeStatement(); - SimpleTableSegment targetTable = new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_order"))); - targetTable.setAlias(new AliasSegment(0, 0, new IdentifierValue("a"))); - mergeStatement.setTarget(targetTable); - SimpleTableSegment sourceTable = new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_order_item"))); - sourceTable.setAlias(new AliasSegment(0, 0, new IdentifierValue("b"))); - mergeStatement.setSource(sourceTable); - mergeStatement.setExpression(new ExpressionWithParamsSegment(0, 0, new BinaryOperationExpression(0, 0, new ColumnSegment(0, 0, new IdentifierValue("id")), - new ColumnSegment(0, 0, new IdentifierValue("order_id")), "=", "id = order_id"))); - UpdateStatement updateStatement = new OracleUpdateStatement(); - updateStatement.setTable(targetTable); - ColumnSegment targetTableColumn = new ColumnSegment(0, 0, new IdentifierValue("status")); - targetTableColumn.setOwner(new OwnerSegment(0, 0, new IdentifierValue("a"))); - ColumnSegment sourceTableColumn = new ColumnSegment(0, 0, new IdentifierValue("status")); - sourceTableColumn.setOwner(new OwnerSegment(0, 0, new IdentifierValue("b"))); - SetAssignmentSegment setAssignmentSegment = new SetAssignmentSegment(0, 0, - Collections.singletonList(new ColumnAssignmentSegment(0, 0, Collections.singletonList(targetTableColumn), sourceTableColumn))); - updateStatement.setSetAssignment(setAssignmentSegment); - updateStatement.setWhere(new WhereSegment(0, 0, new BinaryOperationExpression(0, 0, new ColumnSegment(0, 0, new IdentifierValue("item_id")), - new LiteralExpressionSegment(0, 0, 1), "=", "item_id = 1"))); - mergeStatement.setUpdate(updateStatement); - MergeStatement actual = new MergeStatementBinder().bind(mergeStatement, createMetaData(), DefaultDatabase.LOGIC_NAME); - assertThat(actual, not(mergeStatement)); - assertThat(actual.getSource(), not(mergeStatement.getSource())); - assertThat(actual.getSource(), instanceOf(SimpleTableSegment.class)); - assertThat(actual.getTarget(), not(mergeStatement.getTarget())); - assertThat(actual.getTarget(), instanceOf(SimpleTableSegment.class)); - assertTrue(actual.getUpdate().isPresent()); - assertThat(actual.getUpdate().get(), not(mergeStatement.getUpdate())); - assertThat(actual.getUpdate().get().getSetAssignment().getAssignments().iterator().next().getValue(), instanceOf(ColumnSegment.class)); - assertThat(((ColumnSegment) actual.getUpdate().get().getSetAssignment().getAssignments().iterator().next().getValue()).getColumnBoundedInfo().getOriginalTable().getValue(), - is("t_order_item")); - } - - private ShardingSphereMetaData createMetaData() { - ShardingSphereSchema schema = mock(ShardingSphereSchema.class, RETURNS_DEEP_STUBS); - when(schema.getTable("t_order").getColumnValues()).thenReturn(Arrays.asList( - new ShardingSphereColumn("id", Types.INTEGER, true, false, false, true, false, false), - new ShardingSphereColumn("user_id", Types.INTEGER, false, false, false, true, false, false), - new ShardingSphereColumn("status", Types.INTEGER, false, false, false, true, false, false))); - when(schema.getTable("t_order_item").getColumnValues()).thenReturn(Arrays.asList( - new ShardingSphereColumn("item_id", Types.INTEGER, true, false, false, true, false, false), - new ShardingSphereColumn("order_id", Types.INTEGER, false, false, false, true, false, false), - new ShardingSphereColumn("status", Types.INTEGER, false, false, false, true, false, false))); - ShardingSphereMetaData result = mock(ShardingSphereMetaData.class, RETURNS_DEEP_STUBS); - when(result.getDatabase(DefaultDatabase.LOGIC_NAME).getSchema(DefaultDatabase.LOGIC_NAME)).thenReturn(schema); - when(result.containsDatabase(DefaultDatabase.LOGIC_NAME)).thenReturn(true); - when(result.getDatabase(DefaultDatabase.LOGIC_NAME).containsSchema(DefaultDatabase.LOGIC_NAME)).thenReturn(true); - when(result.getDatabase(DefaultDatabase.LOGIC_NAME).getSchema(DefaultDatabase.LOGIC_NAME).containsTable("t_order")).thenReturn(true); - when(result.getDatabase(DefaultDatabase.LOGIC_NAME).getSchema(DefaultDatabase.LOGIC_NAME).containsTable("t_order_item")).thenReturn(true); - return result; - } - - @Test - void assertBindWithSubQuery() { - MergeStatement mergeStatement = new OracleMergeStatement(); - SimpleTableSegment targetTable = new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_order"))); - targetTable.setAlias(new AliasSegment(0, 0, new IdentifierValue("a"))); - mergeStatement.setTarget(targetTable); - ProjectionsSegment projectionsSegment = new ProjectionsSegment(0, 0); - ExpressionProjectionSegment expressionProjectionSegment = new ExpressionProjectionSegment(0, 0, "status + 1", new BinaryOperationExpression(0, 0, - new ColumnSegment(0, 0, new IdentifierValue("status")), new LiteralExpressionSegment(0, 0, 1), "+", "status + 1")); - expressionProjectionSegment.setAlias(new AliasSegment(0, 0, new IdentifierValue("new_status"))); - projectionsSegment.getProjections().add(expressionProjectionSegment); - OracleSelectStatement oracleSelectStatement = new OracleSelectStatement(); - oracleSelectStatement.setProjections(projectionsSegment); - oracleSelectStatement.setFrom(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_order_item")))); - SubqueryTableSegment subqueryTableSegment = new SubqueryTableSegment(0, 0, new SubquerySegment(0, 0, oracleSelectStatement, "")); - subqueryTableSegment.setAlias(new AliasSegment(0, 0, new IdentifierValue("b"))); - mergeStatement.setSource(subqueryTableSegment); - UpdateStatement updateStatement = new OracleUpdateStatement(); - ColumnSegment targetTableColumn = new ColumnSegment(0, 0, new IdentifierValue("status")); - targetTableColumn.setOwner(new OwnerSegment(0, 0, new IdentifierValue("a"))); - ColumnSegment sourceTableColumn = new ColumnSegment(0, 0, new IdentifierValue("new_status")); - SetAssignmentSegment setAssignmentSegment = new SetAssignmentSegment(0, 0, - Collections.singletonList(new ColumnAssignmentSegment(0, 0, Collections.singletonList(targetTableColumn), sourceTableColumn))); - updateStatement.setSetAssignment(setAssignmentSegment); - mergeStatement.setUpdate(updateStatement); - MergeStatement actual = new MergeStatementBinder().bind(mergeStatement, createMetaData(), DefaultDatabase.LOGIC_NAME); - assertThat(actual, not(mergeStatement)); - } - - @Test - void assertBindUpdateDeleteWhere() { - MergeStatement mergeStatement = new OracleMergeStatement(); - SimpleTableSegment targetTable = new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_order"))); - targetTable.setAlias(new AliasSegment(0, 0, new IdentifierValue("a"))); - mergeStatement.setTarget(targetTable); - SimpleTableSegment sourceTable = new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_order_item"))); - sourceTable.setAlias(new AliasSegment(0, 0, new IdentifierValue("b"))); - mergeStatement.setSource(sourceTable); - OracleUpdateStatement updateStatement = new OracleUpdateStatement(); - updateStatement.setTable(targetTable); - ColumnSegment targetTableColumn = new ColumnSegment(0, 0, new IdentifierValue("status")); - targetTableColumn.setOwner(new OwnerSegment(0, 0, new IdentifierValue("a"))); - ColumnSegment sourceTableColumn = new ColumnSegment(0, 0, new IdentifierValue("status")); - sourceTableColumn.setOwner(new OwnerSegment(0, 0, new IdentifierValue("b"))); - SetAssignmentSegment setAssignmentSegment = new SetAssignmentSegment(0, 0, - Collections.singletonList(new ColumnAssignmentSegment(0, 0, Collections.singletonList(targetTableColumn), sourceTableColumn))); - updateStatement.setSetAssignment(setAssignmentSegment); - updateStatement.setDeleteWhere(new WhereSegment(0, 0, new BinaryOperationExpression(0, 0, new ColumnSegment(0, 0, new IdentifierValue("item_id")), - new LiteralExpressionSegment(0, 0, 1), "=", "item_id = 1"))); - mergeStatement.setUpdate(updateStatement); - MergeStatement actual = new MergeStatementBinder().bind(mergeStatement, createMetaData(), DefaultDatabase.LOGIC_NAME); - assertTrue(actual.getUpdate().isPresent()); - assertThat(actual.getUpdate().get(), instanceOf(OracleUpdateStatement.class)); - assertTrue(actual.getUpdate().get().getDeleteWhere().isPresent()); - assertThat(actual.getUpdate().get().getDeleteWhere().get().getExpr(), instanceOf(BinaryOperationExpression.class)); - assertThat(((BinaryOperationExpression) actual.getUpdate().get().getDeleteWhere().get().getExpr()).getLeft(), instanceOf(ColumnSegment.class)); - assertThat(((ColumnSegment) ((BinaryOperationExpression) actual.getUpdate().get().getDeleteWhere().get().getExpr()).getLeft()) - .getColumnBoundedInfo().getOriginalTable().getValue(), is("t_order_item")); - } -}