You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by pa...@apache.org on 2021/08/22 04:23:59 UTC
[shardingsphere] branch master updated: Add Oracle SQL - Update
statement (#11692)
This is an automated email from the ASF dual-hosted git repository.
panjuan 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 3c51144 Add Oracle SQL - Update statement (#11692)
3c51144 is described below
commit 3c51144dafb300617a9a84558b6d87704f826c6a
Author: Thanoshan MV <48...@users.noreply.github.com>
AuthorDate: Sun Aug 22 09:53:28 2021 +0530
Add Oracle SQL - Update statement (#11692)
* add oracle update definition
* add multi-column in an assignment
* make AssignmentSegment into abstract, define new ColumnAssignmentSegment and refactor AssignmentSegment related code.
* utilize ColumnAssignmentSegment to create an instance type of AssignmentSegment
* set ColumnAssignmentSegment's columns field to final and uninitialize it
* remove commented code
---
.../impl/EncryptAssignmentParameterRewriter.java | 4 +-
.../impl/EncryptAssignmentTokenGenerator.java | 18 +-
.../impl/EncryptInsertOnUpdateTokenGenerator.java | 19 +-
.../impl/ShadowUpdateValueParameterRewriter.java | 4 +-
.../impl/ShadowUpdateColumnTokenGenerator.java | 4 +-
.../ShadowUpdateValueParameterRewriterTest.java | 8 +-
.../impl/ShadowUpdateColumnTokenGeneratorTest.java | 7 +-
.../dml/impl/ShardingInsertStatementValidator.java | 2 +-
.../dml/impl/ShardingUpdateStatementValidator.java | 2 +-
.../dml/ShardingInsertStatementValidatorTest.java | 5 +-
.../dml/ShardingUpdateStatementValidatorTest.java | 13 +-
.../insert/values/OnDuplicateUpdateContext.java | 2 +-
.../statement/dml/InsertStatementContext.java | 2 +-
.../values/OnDuplicateUpdateContextTest.java | 9 +-
.../statement/SQLStatementContextFactoryTest.java | 8 +-
.../statement/impl/InsertStatementContextTest.java | 26 +-
.../statement/impl/MySQLStatementSQLVisitor.java | 6 +-
.../src/main/antlr4/imports/oracle/DMLStatement.g4 | 21 +-
.../impl/OracleDMLStatementSQLVisitor.java | 117 +++++++--
.../impl/PostgreSQLStatementSQLVisitor.java | 6 +-
.../impl/SQL92DMLStatementSQLVisitor.java | 7 +-
.../impl/SQLServerDMLStatementSQLVisitor.java | 7 +-
.../sql/common/extractor/TableExtractor.java | 2 +-
.../segment/dml/assignment/AssignmentSegment.java | 28 ++-
...ntSegment.java => ColumnAssignmentSegment.java} | 9 +-
.../segment/assignment/AssignmentAssert.java | 21 +-
.../segment/assignment/AssignmentValueAssert.java | 3 +
.../impl/assignment/ExpectedAssignment.java | 4 +
.../impl/assignment/ExpectedAssignmentValue.java | 4 +
.../src/main/resources/case/dml/update.xml | 273 +++++++++++++++++----
.../main/resources/sql/supported/dml/update.xml | 6 +-
31 files changed, 509 insertions(+), 138 deletions(-)
diff --git a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/parameter/impl/EncryptAssignmentParameterRewriter.java b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/parameter/impl/EncryptAssignmentParameterRewriter.java
index 6762a08..68117a9 100644
--- a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/parameter/impl/EncryptAssignmentParameterRewriter.java
+++ b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/parameter/impl/EncryptAssignmentParameterRewriter.java
@@ -60,7 +60,7 @@ public final class EncryptAssignmentParameterRewriter extends EncryptParameterRe
public void rewrite(final ParameterBuilder parameterBuilder, final SQLStatementContext sqlStatementContext, final List<Object> parameters) {
String tableName = ((TableAvailable) sqlStatementContext).getAllTables().iterator().next().getTableName().getIdentifier().getValue();
for (AssignmentSegment each : getSetAssignmentSegment(sqlStatementContext.getSqlStatement()).getAssignments()) {
- if (each.getValue() instanceof ParameterMarkerExpressionSegment && getEncryptRule().findEncryptor(tableName, each.getColumn().getIdentifier().getValue()).isPresent()) {
+ if (each.getValue() instanceof ParameterMarkerExpressionSegment && getEncryptRule().findEncryptor(tableName, each.getColumns().get(0).getIdentifier().getValue()).isPresent()) {
StandardParameterBuilder standardParameterBuilder = parameterBuilder instanceof StandardParameterBuilder
? (StandardParameterBuilder) parameterBuilder : ((GroupedParameterBuilder) parameterBuilder).getParameterBuilders().get(0);
encryptParameters(standardParameterBuilder, tableName, each, parameters);
@@ -78,7 +78,7 @@ public final class EncryptAssignmentParameterRewriter extends EncryptParameterRe
}
private void encryptParameters(final StandardParameterBuilder parameterBuilder, final String tableName, final AssignmentSegment assignmentSegment, final List<Object> parameters) {
- String columnName = assignmentSegment.getColumn().getIdentifier().getValue();
+ String columnName = assignmentSegment.getColumns().get(0).getIdentifier().getValue();
int parameterMarkerIndex = ((ParameterMarkerExpressionSegment) assignmentSegment.getValue()).getParameterMarkerIndex();
Object originalValue = parameters.get(parameterMarkerIndex);
Object cipherValue = getEncryptRule().getEncryptValues(tableName, columnName, Collections.singletonList(originalValue)).iterator().next();
diff --git a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/impl/EncryptAssignmentTokenGenerator.java b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/impl/EncryptAssignmentTokenGenerator.java
index 55931b6..c9898d8 100644
--- a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/impl/EncryptAssignmentTokenGenerator.java
+++ b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/impl/EncryptAssignmentTokenGenerator.java
@@ -57,7 +57,7 @@ public final class EncryptAssignmentTokenGenerator extends BaseEncryptSQLTokenGe
Collection<EncryptAssignmentToken> result = new LinkedList<>();
String tableName = ((TableAvailable) sqlStatementContext).getAllTables().iterator().next().getTableName().getIdentifier().getValue();
for (AssignmentSegment each : getSetAssignmentSegment(sqlStatementContext.getSqlStatement()).getAssignments()) {
- if (getEncryptRule().findEncryptor(tableName, each.getColumn().getIdentifier().getValue()).isPresent()) {
+ if (getEncryptRule().findEncryptor(tableName, each.getColumns().get(0).getIdentifier().getValue()).isPresent()) {
generateSQLToken(tableName, each).ifPresent(result::add);
}
}
@@ -84,8 +84,8 @@ public final class EncryptAssignmentTokenGenerator extends BaseEncryptSQLTokenGe
}
private EncryptAssignmentToken generateParameterSQLToken(final String tableName, final AssignmentSegment assignmentSegment) {
- EncryptParameterAssignmentToken result = new EncryptParameterAssignmentToken(assignmentSegment.getColumn().getStartIndex(), assignmentSegment.getStopIndex());
- String columnName = assignmentSegment.getColumn().getIdentifier().getValue();
+ EncryptParameterAssignmentToken result = new EncryptParameterAssignmentToken(assignmentSegment.getColumns().get(0).getStartIndex(), assignmentSegment.getStopIndex());
+ String columnName = assignmentSegment.getColumns().get(0).getIdentifier().getValue();
addCipherColumn(tableName, columnName, result);
addAssistedQueryColumn(tableName, columnName, result);
addPlainColumn(tableName, columnName, result);
@@ -105,7 +105,7 @@ public final class EncryptAssignmentTokenGenerator extends BaseEncryptSQLTokenGe
}
private EncryptAssignmentToken generateLiteralSQLToken(final String tableName, final AssignmentSegment assignmentSegment) {
- EncryptLiteralAssignmentToken result = new EncryptLiteralAssignmentToken(assignmentSegment.getColumn().getStartIndex(), assignmentSegment.getStopIndex());
+ EncryptLiteralAssignmentToken result = new EncryptLiteralAssignmentToken(assignmentSegment.getColumns().get(0).getStartIndex(), assignmentSegment.getStopIndex());
addCipherAssignment(tableName, assignmentSegment, result);
addAssistedQueryAssignment(tableName, assignmentSegment, result);
addPlainAssignment(tableName, assignmentSegment, result);
@@ -114,22 +114,22 @@ public final class EncryptAssignmentTokenGenerator extends BaseEncryptSQLTokenGe
private void addCipherAssignment(final String tableName, final AssignmentSegment assignmentSegment, final EncryptLiteralAssignmentToken token) {
Object originalValue = ((LiteralExpressionSegment) assignmentSegment.getValue()).getLiterals();
- Object cipherValue = getEncryptRule().getEncryptValues(tableName, assignmentSegment.getColumn().getIdentifier().getValue(), Collections.singletonList(originalValue)).iterator().next();
- token.addAssignment(getEncryptRule().getCipherColumn(tableName, assignmentSegment.getColumn().getIdentifier().getValue()), cipherValue);
+ Object cipherValue = getEncryptRule().getEncryptValues(tableName, assignmentSegment.getColumns().get(0).getIdentifier().getValue(), Collections.singletonList(originalValue)).iterator().next();
+ token.addAssignment(getEncryptRule().getCipherColumn(tableName, assignmentSegment.getColumns().get(0).getIdentifier().getValue()), cipherValue);
}
private void addAssistedQueryAssignment(final String tableName, final AssignmentSegment assignmentSegment, final EncryptLiteralAssignmentToken token) {
Object originalValue = ((LiteralExpressionSegment) assignmentSegment.getValue()).getLiterals();
- Optional<String> assistedQueryColumn = getEncryptRule().findAssistedQueryColumn(tableName, assignmentSegment.getColumn().getIdentifier().getValue());
+ Optional<String> assistedQueryColumn = getEncryptRule().findAssistedQueryColumn(tableName, assignmentSegment.getColumns().get(0).getIdentifier().getValue());
assistedQueryColumn.ifPresent(s -> {
Object assistedQueryValue = getEncryptRule().getEncryptAssistedQueryValues(
- tableName, assignmentSegment.getColumn().getIdentifier().getValue(), Collections.singletonList(originalValue)).iterator().next();
+ tableName, assignmentSegment.getColumns().get(0).getIdentifier().getValue(), Collections.singletonList(originalValue)).iterator().next();
token.addAssignment(s, assistedQueryValue);
});
}
private void addPlainAssignment(final String tableName, final AssignmentSegment assignmentSegment, final EncryptLiteralAssignmentToken token) {
Object originalValue = ((LiteralExpressionSegment) assignmentSegment.getValue()).getLiterals();
- getEncryptRule().findPlainColumn(tableName, assignmentSegment.getColumn().getIdentifier().getValue()).ifPresent(plainColumn -> token.addAssignment(plainColumn, originalValue));
+ getEncryptRule().findPlainColumn(tableName, assignmentSegment.getColumns().get(0).getIdentifier().getValue()).ifPresent(plainColumn -> token.addAssignment(plainColumn, originalValue));
}
}
diff --git a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/impl/EncryptInsertOnUpdateTokenGenerator.java b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/impl/EncryptInsertOnUpdateTokenGenerator.java
index a140ca2..66ca4ee 100644
--- a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/impl/EncryptInsertOnUpdateTokenGenerator.java
+++ b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/impl/EncryptInsertOnUpdateTokenGenerator.java
@@ -60,7 +60,7 @@ public final class EncryptInsertOnUpdateTokenGenerator extends BaseEncryptSQLTok
return result;
}
for (AssignmentSegment each : onDuplicateKeyColumnsSegments) {
- if (getEncryptRule().findEncryptor(tableName, each.getColumn().getIdentifier().getValue()).isPresent()) {
+ if (getEncryptRule().findEncryptor(tableName, each.getColumns().get(0).getIdentifier().getValue()).isPresent()) {
generateSQLToken(tableName, each).ifPresent(result::add);
}
}
@@ -78,8 +78,8 @@ public final class EncryptInsertOnUpdateTokenGenerator extends BaseEncryptSQLTok
}
private EncryptAssignmentToken generateParameterSQLToken(final String tableName, final AssignmentSegment assignmentSegment) {
- EncryptParameterAssignmentToken result = new EncryptParameterAssignmentToken(assignmentSegment.getColumn().getStartIndex(), assignmentSegment.getStopIndex());
- String columnName = assignmentSegment.getColumn().getIdentifier().getValue();
+ EncryptParameterAssignmentToken result = new EncryptParameterAssignmentToken(assignmentSegment.getColumns().get(0).getStartIndex(), assignmentSegment.getStopIndex());
+ String columnName = assignmentSegment.getColumns().get(0).getIdentifier().getValue();
addCipherColumn(tableName, columnName, result);
addAssistedQueryColumn(tableName, columnName, result);
addPlainColumn(tableName, columnName, result);
@@ -87,7 +87,7 @@ public final class EncryptInsertOnUpdateTokenGenerator extends BaseEncryptSQLTok
}
private EncryptAssignmentToken generateLiteralSQLToken(final String tableName, final AssignmentSegment assignmentSegment) {
- EncryptLiteralAssignmentToken result = new EncryptLiteralAssignmentToken(assignmentSegment.getColumn().getStartIndex(), assignmentSegment.getStopIndex());
+ EncryptLiteralAssignmentToken result = new EncryptLiteralAssignmentToken(assignmentSegment.getColumns().get(0).getStartIndex(), assignmentSegment.getStopIndex());
addCipherAssignment(tableName, assignmentSegment, result);
addAssistedQueryAssignment(tableName, assignmentSegment, result);
addPlainAssignment(tableName, assignmentSegment, result);
@@ -108,14 +108,15 @@ public final class EncryptInsertOnUpdateTokenGenerator extends BaseEncryptSQLTok
private void addCipherAssignment(final String tableName, final AssignmentSegment assignmentSegment, final EncryptLiteralAssignmentToken token) {
Object originalValue = ((LiteralExpressionSegment) assignmentSegment.getValue()).getLiterals();
- Object cipherValue = getEncryptRule().getEncryptValues(tableName, assignmentSegment.getColumn().getIdentifier().getValue(), Collections.singletonList(originalValue)).iterator().next();
- token.addAssignment(getEncryptRule().getCipherColumn(tableName, assignmentSegment.getColumn().getIdentifier().getValue()), cipherValue);
+ Object cipherValue = getEncryptRule().getEncryptValues(tableName, assignmentSegment.getColumns().get(0).getIdentifier().getValue(), Collections.singletonList(originalValue)).iterator().next();
+ token.addAssignment(getEncryptRule().getCipherColumn(tableName, assignmentSegment.getColumns().get(0).getIdentifier().getValue()), cipherValue);
}
private void addAssistedQueryAssignment(final String tableName, final AssignmentSegment assignmentSegment, final EncryptLiteralAssignmentToken token) {
- getEncryptRule().findAssistedQueryColumn(tableName, assignmentSegment.getColumn().getIdentifier().getValue()).ifPresent(assistedQueryColumn -> {
+ getEncryptRule().findAssistedQueryColumn(tableName, assignmentSegment.getColumns().get(0).getIdentifier().getValue()).ifPresent(assistedQueryColumn -> {
Object originalValue = ((LiteralExpressionSegment) assignmentSegment.getValue()).getLiterals();
- Object assistedQueryValue = getEncryptRule().getEncryptAssistedQueryValues(tableName, assignmentSegment.getColumn().getIdentifier().getValue(), Collections.singletonList(originalValue))
+ Object assistedQueryValue = getEncryptRule()
+ .getEncryptAssistedQueryValues(tableName, assignmentSegment.getColumns().get(0).getIdentifier().getValue(), Collections.singletonList(originalValue))
.iterator().next();
token.addAssignment(assistedQueryColumn, assistedQueryValue);
});
@@ -123,6 +124,6 @@ public final class EncryptInsertOnUpdateTokenGenerator extends BaseEncryptSQLTok
private void addPlainAssignment(final String tableName, final AssignmentSegment assignmentSegment, final EncryptLiteralAssignmentToken token) {
Object originalValue = ((LiteralExpressionSegment) assignmentSegment.getValue()).getLiterals();
- getEncryptRule().findPlainColumn(tableName, assignmentSegment.getColumn().getIdentifier().getValue()).ifPresent(plainColumn -> token.addAssignment(plainColumn, originalValue));
+ getEncryptRule().findPlainColumn(tableName, assignmentSegment.getColumns().get(0).getIdentifier().getValue()).ifPresent(plainColumn -> token.addAssignment(plainColumn, originalValue));
}
}
diff --git a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/rewrite/parameter/impl/ShadowUpdateValueParameterRewriter.java b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/rewrite/parameter/impl/ShadowUpdateValueParameterRewriter.java
index 9bd3afd..cd898fa 100644
--- a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/rewrite/parameter/impl/ShadowUpdateValueParameterRewriter.java
+++ b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/rewrite/parameter/impl/ShadowUpdateValueParameterRewriter.java
@@ -38,7 +38,7 @@ public final class ShadowUpdateValueParameterRewriter extends ShadowParameterRew
}
private boolean isContainShadowColumn(final UpdateStatement updateStatement) {
- return updateStatement.getSetAssignment().getAssignments().stream().anyMatch(each -> each.getColumn().getIdentifier().getValue().equals(getShadowColumn()));
+ return updateStatement.getSetAssignment().getAssignments().stream().anyMatch(each -> each.getColumns().get(0).getIdentifier().getValue().equals(getShadowColumn()));
}
@Override
@@ -55,7 +55,7 @@ public final class ShadowUpdateValueParameterRewriter extends ShadowParameterRew
private int getShadowColumnIndex(final UpdateStatement sqlStatement) {
int count = 0;
for (AssignmentSegment each : sqlStatement.getSetAssignment().getAssignments()) {
- if (each.getColumn().getIdentifier().getValue().equals(getShadowColumn())) {
+ if (each.getColumns().get(0).getIdentifier().getValue().equals(getShadowColumn())) {
return count;
}
count++;
diff --git a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/rewrite/token/generator/impl/ShadowUpdateColumnTokenGenerator.java b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/rewrite/token/generator/impl/ShadowUpdateColumnTokenGenerator.java
index 80311f4..7d966b1 100644
--- a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/rewrite/token/generator/impl/ShadowUpdateColumnTokenGenerator.java
+++ b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/rewrite/token/generator/impl/ShadowUpdateColumnTokenGenerator.java
@@ -42,7 +42,7 @@ public final class ShadowUpdateColumnTokenGenerator extends BaseShadowSQLTokenGe
}
private boolean isContainShadowColumn(final Collection<AssignmentSegment> assignments) {
- return assignments.stream().anyMatch(each -> each.getColumn().getIdentifier().getValue().equals(getShadowColumn()));
+ return assignments.stream().anyMatch(each -> each.getColumns().get(0).getIdentifier().getValue().equals(getShadowColumn()));
}
@Override
@@ -52,7 +52,7 @@ public final class ShadowUpdateColumnTokenGenerator extends BaseShadowSQLTokenGe
private Collection<RemoveToken> generateRemoveTokenForShadow(final Collection<AssignmentSegment> assignments) {
List<AssignmentSegment> assignmentSegments = (LinkedList<AssignmentSegment>) assignments;
- return IntStream.range(0, assignmentSegments.size()).filter(i -> getShadowColumn().equals(assignmentSegments.get(i).getColumn().getIdentifier().getValue()))
+ return IntStream.range(0, assignmentSegments.size()).filter(i -> getShadowColumn().equals(assignmentSegments.get(i).getColumns().get(0).getIdentifier().getValue()))
.mapToObj(i -> createRemoveToken(assignmentSegments, i)).collect(Collectors.toCollection(LinkedList::new));
}
diff --git a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/test/java/org/apache/shardingsphere/shadow/rewrite/parameter/impl/ShadowUpdateValueParameterRewriterTest.java b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/test/java/org/apache/shardingsphere/shadow/rewrite/parameter/impl/ShadowUpdateValueParameterRewriterTest.java
index 6b4176d..f85d099 100644
--- a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/test/java/org/apache/shardingsphere/shadow/rewrite/parameter/impl/ShadowUpdateValueParameterRewriterTest.java
+++ b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/test/java/org/apache/shardingsphere/shadow/rewrite/parameter/impl/ShadowUpdateValueParameterRewriterTest.java
@@ -21,6 +21,7 @@ import org.apache.shardingsphere.infra.binder.statement.dml.UpdateStatementConte
import org.apache.shardingsphere.infra.rewrite.parameter.builder.impl.GroupedParameterBuilder;
import org.apache.shardingsphere.shadow.rule.ShadowRule;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.assignment.AssignmentSegment;
+import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.assignment.ColumnAssignmentSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.assignment.SetAssignmentSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.ColumnSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.ExpressionSegment;
@@ -31,6 +32,8 @@ import org.junit.Before;
import org.junit.Test;
import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
@@ -56,7 +59,10 @@ public final class ShadowUpdateValueParameterRewriterTest {
}
private SetAssignmentSegment createSetAssignmentSegment(final String shadowColumn) {
- return new SetAssignmentSegment(0, 20, Collections.singletonList(new AssignmentSegment(0, 15, new ColumnSegment(0, 15, new IdentifierValue(shadowColumn)), mock(ExpressionSegment.class))));
+ List<ColumnSegment> columns = new LinkedList<>();
+ columns.add(new ColumnSegment(0, 15, new IdentifierValue(shadowColumn)));
+ AssignmentSegment assignment = new ColumnAssignmentSegment(0, 15, columns, mock(ExpressionSegment.class));
+ return new SetAssignmentSegment(0, 20, Collections.singletonList(assignment));
}
private void initShadowUpdateValueParameterRewriter(final String shadowColumn) {
diff --git a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/test/java/org/apache/shardingsphere/shadow/rewrite/token/generator/impl/ShadowUpdateColumnTokenGeneratorTest.java b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/test/java/org/apache/shardingsphere/shadow/rewrite/token/generator/impl/ShadowUpdateColumnTokenGeneratorTest.java
index 8b10ae0..e65b771 100644
--- a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/test/java/org/apache/shardingsphere/shadow/rewrite/token/generator/impl/ShadowUpdateColumnTokenGeneratorTest.java
+++ b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/test/java/org/apache/shardingsphere/shadow/rewrite/token/generator/impl/ShadowUpdateColumnTokenGeneratorTest.java
@@ -20,6 +20,7 @@ package org.apache.shardingsphere.shadow.rewrite.token.generator.impl;
import org.apache.shardingsphere.infra.binder.statement.dml.UpdateStatementContext;
import org.apache.shardingsphere.shadow.rule.ShadowRule;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.assignment.AssignmentSegment;
+import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.assignment.ColumnAssignmentSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.assignment.SetAssignmentSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.ColumnSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.ExpressionSegment;
@@ -31,6 +32,7 @@ import org.junit.Test;
import java.util.Collection;
import java.util.LinkedList;
+import java.util.List;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
@@ -65,7 +67,10 @@ public final class ShadowUpdateColumnTokenGeneratorTest {
}
private AssignmentSegment createAssignmentSegment(final int startIndex, final int stopIndex, final IdentifierValue identifierValue) {
- return new AssignmentSegment(startIndex, stopIndex, new ColumnSegment(startIndex, stopIndex, identifierValue), mock(ExpressionSegment.class));
+ List<ColumnSegment> columns = new LinkedList<>();
+ columns.add(new ColumnSegment(startIndex, stopIndex, identifierValue));
+ AssignmentSegment result = new ColumnAssignmentSegment(startIndex, stopIndex, columns, mock(ExpressionSegment.class));
+ return result;
}
private void initShadowUpdateColumnTokenGenerator(final String shadowColumn) {
diff --git a/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/main/java/org/apache/shardingsphere/sharding/route/engine/validator/dml/impl/ShardingInsertStatementValidator.java b/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/main/java/org/apache/shardingsphere/sharding/route/engine/validator/dml/impl/ShardingInsertStatementValidator.java
index 69a502f..3eff253 100644
--- a/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/main/java/org/apache/shardingsphere/sharding/route/engine/validator/dml/impl/ShardingInsertStatementValidator.java
+++ b/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/main/java/org/apache/shardingsphere/sharding/route/engine/validator/dml/impl/ShardingInsertStatementValidator.java
@@ -72,7 +72,7 @@ public final class ShardingInsertStatementValidator extends ShardingDMLStatement
private boolean isUpdateShardingKey(final ShardingRule shardingRule, final OnDuplicateKeyColumnsSegment onDuplicateKeyColumnsSegment, final String tableName) {
for (AssignmentSegment each : onDuplicateKeyColumnsSegment.getColumns()) {
- if (shardingRule.isShardingColumn(each.getColumn().getIdentifier().getValue(), tableName)) {
+ if (shardingRule.isShardingColumn(each.getColumns().get(0).getIdentifier().getValue(), tableName)) {
return true;
}
}
diff --git a/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/main/java/org/apache/shardingsphere/sharding/route/engine/validator/dml/impl/ShardingUpdateStatementValidator.java b/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/main/java/org/apache/shardingsphere/sharding/route/engine/validator/dml/impl/ShardingUpdateStatementValidator.java
index 2f95141..4d23ec8 100644
--- a/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/main/java/org/apache/shardingsphere/sharding/route/engine/validator/dml/impl/ShardingUpdateStatementValidator.java
+++ b/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/main/java/org/apache/shardingsphere/sharding/route/engine/validator/dml/impl/ShardingUpdateStatementValidator.java
@@ -50,7 +50,7 @@ public final class ShardingUpdateStatementValidator extends ShardingDMLStatement
UpdateStatement sqlStatement = sqlStatementContext.getSqlStatement();
String tableName = sqlStatementContext.getTablesContext().getTables().iterator().next().getTableName().getIdentifier().getValue();
for (AssignmentSegment each : sqlStatement.getSetAssignment().getAssignments()) {
- String shardingColumn = each.getColumn().getIdentifier().getValue();
+ String shardingColumn = each.getColumns().get(0).getIdentifier().getValue();
if (shardingRule.isShardingColumn(shardingColumn, tableName)) {
Optional<Object> shardingColumnSetAssignmentValue = getShardingColumnSetAssignmentValue(each, parameters);
Optional<Object> shardingValue = Optional.empty();
diff --git a/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/test/java/org/apache/shardingsphere/sharding/route/engine/validator/dml/ShardingInsertStatementValidatorTest.java b/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/test/java/org/apache/shardingsphere/sharding/route/engine/validator/dml/ShardingInsertStatementValidatorTest.java
index b29dac8..0ea8fda 100644
--- a/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/test/java/org/apache/shardingsphere/sharding/route/engine/validator/dml/ShardingInsertStatementValidatorTest.java
+++ b/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/test/java/org/apache/shardingsphere/sharding/route/engine/validator/dml/ShardingInsertStatementValidatorTest.java
@@ -30,6 +30,7 @@ import org.apache.shardingsphere.sharding.route.engine.condition.ShardingConditi
import org.apache.shardingsphere.sharding.route.engine.validator.dml.impl.ShardingInsertStatementValidator;
import org.apache.shardingsphere.sharding.rule.ShardingRule;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.assignment.AssignmentSegment;
+import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.assignment.ColumnAssignmentSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.ColumnSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.InsertColumnsSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.OnDuplicateKeyColumnsSegment;
@@ -198,7 +199,9 @@ public final class ShardingInsertStatementValidatorTest {
MySQLInsertStatement result = new MySQLInsertStatement();
result.setTable(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("user"))));
ColumnSegment columnSegment = new ColumnSegment(0, 0, new IdentifierValue("id"));
- AssignmentSegment assignmentSegment = new AssignmentSegment(0, 0, columnSegment, new ParameterMarkerExpressionSegment(0, 0, 1));
+ List<ColumnSegment> columnSegments = new LinkedList<>();
+ columnSegments.add(columnSegment);
+ AssignmentSegment assignmentSegment = new ColumnAssignmentSegment(0, 0, columnSegments, new ParameterMarkerExpressionSegment(0, 0, 1));
result.setOnDuplicateKeyColumns(new OnDuplicateKeyColumnsSegment(0, 0, Collections.singletonList(assignmentSegment)));
Collection<ColumnSegment> columns = new LinkedList<>();
columns.add(columnSegment);
diff --git a/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/test/java/org/apache/shardingsphere/sharding/route/engine/validator/dml/ShardingUpdateStatementValidatorTest.java b/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/test/java/org/apache/shardingsphere/sharding/route/engine/validator/dml/ShardingUpdateStatementValidatorTest.java
index 19a3141..cfb54ef 100644
--- a/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/test/java/org/apache/shardingsphere/sharding/route/engine/validator/dml/ShardingUpdateStatementValidatorTest.java
+++ b/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/test/java/org/apache/shardingsphere/sharding/route/engine/validator/dml/ShardingUpdateStatementValidatorTest.java
@@ -24,6 +24,7 @@ import org.apache.shardingsphere.infra.metadata.schema.ShardingSphereSchema;
import org.apache.shardingsphere.sharding.route.engine.validator.dml.impl.ShardingUpdateStatementValidator;
import org.apache.shardingsphere.sharding.rule.ShardingRule;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.assignment.AssignmentSegment;
+import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.assignment.ColumnAssignmentSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.assignment.SetAssignmentSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.ColumnSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.BinaryOperationExpression;
@@ -44,6 +45,7 @@ import org.mockito.junit.MockitoJUnitRunner;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
+import java.util.LinkedList;
import java.util.List;
import static org.mockito.Mockito.mock;
@@ -105,16 +107,21 @@ public final class ShardingUpdateStatementValidatorTest {
private UpdateStatement createUpdateStatement() {
UpdateStatement result = new MySQLUpdateStatement();
result.setTableSegment(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("user"))));
+ List<ColumnSegment> columns = new LinkedList<>();
+ columns.add(new ColumnSegment(0, 0, new IdentifierValue("id")));
+ AssignmentSegment assignment = new ColumnAssignmentSegment(0, 0, columns, new LiteralExpressionSegment(0, 0, ""));
result.setSetAssignment(
- new SetAssignmentSegment(0, 0, Collections.singletonList(new AssignmentSegment(0, 0, new ColumnSegment(0, 0, new IdentifierValue("id")), new LiteralExpressionSegment(0, 0, "")))));
+ new SetAssignmentSegment(0, 0, Collections.singletonList(assignment)));
return result;
}
private UpdateStatement createUpdateStatementAndParameters(final Object shardingColumnParameter) {
UpdateStatement result = new MySQLUpdateStatement();
result.setTableSegment(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("user"))));
- Collection<AssignmentSegment> assignments = Collections.singletonList(
- new AssignmentSegment(0, 0, new ColumnSegment(0, 0, new IdentifierValue("id")), new LiteralExpressionSegment(0, 0, shardingColumnParameter)));
+ List<ColumnSegment> columns = new LinkedList<>();
+ columns.add(new ColumnSegment(0, 0, new IdentifierValue("id")));
+ AssignmentSegment assignment = new ColumnAssignmentSegment(0, 0, columns, new LiteralExpressionSegment(0, 0, shardingColumnParameter));
+ Collection<AssignmentSegment> assignments = Collections.singletonList(assignment);
SetAssignmentSegment setAssignmentSegment = new SetAssignmentSegment(0, 0, assignments);
result.setSetAssignment(setAssignmentSegment);
ColumnSegment left = new ColumnSegment(0, 0, new IdentifierValue("id"));
diff --git a/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/insert/values/OnDuplicateUpdateContext.java b/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/insert/values/OnDuplicateUpdateContext.java
index b961fbe..b70a105 100644
--- a/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/insert/values/OnDuplicateUpdateContext.java
+++ b/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/insert/values/OnDuplicateUpdateContext.java
@@ -48,7 +48,7 @@ public final class OnDuplicateUpdateContext {
parameterCount = calculateParameterCount(expressionSegments);
valueExpressions = getValueExpressions(expressionSegments);
this.parameters = getParameters(parameters, parametersOffset);
- columns = assignments.stream().map(AssignmentSegment::getColumn).collect(Collectors.toList());
+ columns = assignments.stream().map(assignment -> assignment.getColumns().get(0)).collect(Collectors.toList());
}
private int calculateParameterCount(final Collection<ExpressionSegment> assignments) {
diff --git a/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/statement/dml/InsertStatementContext.java b/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/statement/dml/InsertStatementContext.java
index 1ddd6b9..7b50aa9 100644
--- a/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/statement/dml/InsertStatementContext.java
+++ b/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/statement/dml/InsertStatementContext.java
@@ -218,7 +218,7 @@ public final class InsertStatementContext extends CommonSQLStatementContext<Inse
private List<String> getColumnNamesForSetAssignment(final SetAssignmentSegment setAssignment) {
List<String> result = new LinkedList<>();
for (AssignmentSegment each : setAssignment.getAssignments()) {
- result.add(each.getColumn().getIdentifier().getValue().toLowerCase());
+ result.add(each.getColumns().get(0).getIdentifier().getValue().toLowerCase());
}
return result;
}
diff --git a/shardingsphere-infra/shardingsphere-infra-binder/src/test/java/org/apache/shardingsphere/infra/binder/segment/insert/values/OnDuplicateUpdateContextTest.java b/shardingsphere-infra/shardingsphere-infra-binder/src/test/java/org/apache/shardingsphere/infra/binder/segment/insert/values/OnDuplicateUpdateContextTest.java
index 006eb8d..afc7055 100644
--- a/shardingsphere-infra/shardingsphere-infra-binder/src/test/java/org/apache/shardingsphere/infra/binder/segment/insert/values/OnDuplicateUpdateContextTest.java
+++ b/shardingsphere-infra/shardingsphere-infra-binder/src/test/java/org/apache/shardingsphere/infra/binder/segment/insert/values/OnDuplicateUpdateContextTest.java
@@ -18,6 +18,7 @@
package org.apache.shardingsphere.infra.binder.segment.insert.values;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.assignment.AssignmentSegment;
+import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.assignment.ColumnAssignmentSegment;
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.segment.dml.expr.simple.LiteralExpressionSegment;
@@ -31,6 +32,7 @@ import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
+import java.util.LinkedList;
import java.util.List;
import static org.hamcrest.CoreMatchers.is;
@@ -102,7 +104,10 @@ public final class OnDuplicateUpdateContextTest {
int doesNotMatterLexicalIndex = 0;
String doesNotMatterColumnName = "columnNameStr";
ColumnSegment column = new ColumnSegment(doesNotMatterLexicalIndex, doesNotMatterLexicalIndex, new IdentifierValue(doesNotMatterColumnName));
- return new AssignmentSegment(doesNotMatterLexicalIndex, doesNotMatterLexicalIndex, column, expressionSegment);
+ List<ColumnSegment> columnSegments = new LinkedList<>();
+ columnSegments.add(column);
+ AssignmentSegment result = new ColumnAssignmentSegment(doesNotMatterLexicalIndex, doesNotMatterLexicalIndex, columnSegments, expressionSegment);
+ return result;
}
@Test
@@ -130,6 +135,6 @@ public final class OnDuplicateUpdateContextTest {
List<Object> parameters = Collections.emptyList();
OnDuplicateUpdateContext onDuplicateUpdateContext = new OnDuplicateUpdateContext(assignments, parameters, 0);
ColumnSegment column = onDuplicateUpdateContext.getColumn(0);
- assertThat(column, is(assignments.iterator().next().getColumn()));
+ assertThat(column, is(assignments.iterator().next().getColumns().get(0)));
}
}
diff --git a/shardingsphere-infra/shardingsphere-infra-binder/src/test/java/org/apache/shardingsphere/infra/binder/statement/SQLStatementContextFactoryTest.java b/shardingsphere-infra/shardingsphere-infra-binder/src/test/java/org/apache/shardingsphere/infra/binder/statement/SQLStatementContextFactoryTest.java
index 5108963..bd44fca 100644
--- a/shardingsphere-infra/shardingsphere-infra-binder/src/test/java/org/apache/shardingsphere/infra/binder/statement/SQLStatementContextFactoryTest.java
+++ b/shardingsphere-infra/shardingsphere-infra-binder/src/test/java/org/apache/shardingsphere/infra/binder/statement/SQLStatementContextFactoryTest.java
@@ -23,6 +23,7 @@ import org.apache.shardingsphere.infra.binder.statement.dml.SelectStatementConte
import org.apache.shardingsphere.infra.database.DefaultSchema;
import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.assignment.AssignmentSegment;
+import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.assignment.ColumnAssignmentSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.assignment.SetAssignmentSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.ColumnSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.ProjectionsSegment;
@@ -41,6 +42,8 @@ import org.apache.shardingsphere.sql.parser.sql.dialect.statement.sqlserver.dml.
import org.junit.Test;
import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
import java.util.Map;
import static org.junit.Assert.assertNotNull;
@@ -64,8 +67,11 @@ public final class SQLStatementContextFactoryTest {
@Test
public void assertSQLStatementContextCreatedWhenSQLStatementInstanceOfMySQLInsertStatement() {
MySQLInsertStatement insertStatement = new MySQLInsertStatement();
+ List<ColumnSegment> columnSegments = new LinkedList<>();
+ columnSegments.add(new ColumnSegment(0, 0, new IdentifierValue("IdentifierValue")));
+ AssignmentSegment assignment = new ColumnAssignmentSegment(0, 0, columnSegments, null);
insertStatement.setSetAssignment(new SetAssignmentSegment(0, 0,
- Collections.singleton(new AssignmentSegment(0, 0, new ColumnSegment(0, 0, new IdentifierValue("IdentifierValue")), null))));
+ Collections.singleton(assignment)));
assertSQLStatementContextCreatedWhenSQLStatementInstanceOfInsertStatement(insertStatement);
}
diff --git a/shardingsphere-infra/shardingsphere-infra-binder/src/test/java/org/apache/shardingsphere/infra/binder/statement/impl/InsertStatementContextTest.java b/shardingsphere-infra/shardingsphere-infra-binder/src/test/java/org/apache/shardingsphere/infra/binder/statement/impl/InsertStatementContextTest.java
index 550ea0a..d52c994 100644
--- a/shardingsphere-infra/shardingsphere-infra-binder/src/test/java/org/apache/shardingsphere/infra/binder/statement/impl/InsertStatementContextTest.java
+++ b/shardingsphere-infra/shardingsphere-infra-binder/src/test/java/org/apache/shardingsphere/infra/binder/statement/impl/InsertStatementContextTest.java
@@ -23,6 +23,7 @@ import org.apache.shardingsphere.infra.database.DefaultSchema;
import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
import org.apache.shardingsphere.infra.metadata.schema.ShardingSphereSchema;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.assignment.AssignmentSegment;
+import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.assignment.ColumnAssignmentSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.assignment.InsertValuesSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.assignment.SetAssignmentSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.ColumnSegment;
@@ -48,6 +49,7 @@ import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
+import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
@@ -159,10 +161,14 @@ public final class InsertStatementContextTest {
}
private void setUpOnDuplicateValues(final MySQLInsertStatement insertStatement) {
- AssignmentSegment parameterMarkerExpressionAssignment = new AssignmentSegment(0, 0,
- new ColumnSegment(0, 0, new IdentifierValue("on_duplicate_key_update_column_1")), new ParameterMarkerExpressionSegment(0, 0, 4));
- AssignmentSegment literalExpressionAssignment = new AssignmentSegment(0, 0,
- new ColumnSegment(0, 0, new IdentifierValue("on_duplicate_key_update_column_2")), new LiteralExpressionSegment(0, 0, 5));
+ List<ColumnSegment> parameterMarkerExpressionAssignmentColumns = new LinkedList<>();
+ parameterMarkerExpressionAssignmentColumns.add(new ColumnSegment(0, 0, new IdentifierValue("on_duplicate_key_update_column_1")));
+ AssignmentSegment parameterMarkerExpressionAssignment = new ColumnAssignmentSegment(0, 0, parameterMarkerExpressionAssignmentColumns,
+ new ParameterMarkerExpressionSegment(0, 0, 4));
+ List<ColumnSegment> literalExpressionAssignmentColumns = new LinkedList<>();
+ literalExpressionAssignmentColumns.add(new ColumnSegment(0, 0, new IdentifierValue("on_duplicate_key_update_column_2")));
+ AssignmentSegment literalExpressionAssignment = new ColumnAssignmentSegment(0, 0, literalExpressionAssignmentColumns,
+ new LiteralExpressionSegment(0, 0, 5));
OnDuplicateKeyColumnsSegment onDuplicateKeyColumnsSegment = new OnDuplicateKeyColumnsSegment(0, 0, Arrays.asList(parameterMarkerExpressionAssignment, literalExpressionAssignment));
insertStatement.setOnDuplicateKeyColumns(onDuplicateKeyColumnsSegment);
}
@@ -299,8 +305,10 @@ public final class InsertStatementContextTest {
@Test
public void assertGetValueListCountWithSetAssignmentForMySQL() {
MySQLInsertStatement insertStatement = new MySQLInsertStatement();
- insertStatement.setSetAssignment(new SetAssignmentSegment(0, 0, Collections.singletonList(new AssignmentSegment(0, 0,
- new ColumnSegment(0, 0, new IdentifierValue("col")), new LiteralExpressionSegment(0, 0, 1)))));
+ List<ColumnSegment> columns = new LinkedList<>();
+ columns.add(new ColumnSegment(0, 0, new IdentifierValue("col")));
+ AssignmentSegment insertStatementAssignment = new ColumnAssignmentSegment(0, 0, columns, new LiteralExpressionSegment(0, 0, 1));
+ insertStatement.setSetAssignment(new SetAssignmentSegment(0, 0, Collections.singletonList(insertStatementAssignment)));
insertStatement.setTable(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue(""))));
InsertStatementContext insertStatementContext = createInsertStatementContext(Collections.emptyList(), insertStatement);
assertThat(insertStatementContext.getValueListCount(), is(1));
@@ -344,8 +352,10 @@ public final class InsertStatementContextTest {
@Test
public void assertGetInsertColumnNamesForSetAssignmentForMySQL() {
MySQLInsertStatement insertStatement = new MySQLInsertStatement();
- insertStatement.setSetAssignment(new SetAssignmentSegment(0, 0, Collections.singletonList(new AssignmentSegment(0, 0,
- new ColumnSegment(0, 0, new IdentifierValue("col")), new LiteralExpressionSegment(0, 0, 1)))));
+ List<ColumnSegment> columns = new LinkedList<>();
+ columns.add(new ColumnSegment(0, 0, new IdentifierValue("col")));
+ AssignmentSegment insertStatementAssignment = new ColumnAssignmentSegment(0, 0, columns, new LiteralExpressionSegment(0, 0, 1));
+ insertStatement.setSetAssignment(new SetAssignmentSegment(0, 0, Collections.singletonList(insertStatementAssignment)));
insertStatement.setTable(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue(""))));
InsertStatementContext insertStatementContext = createInsertStatementContext(Collections.emptyList(), insertStatement);
List<String> columnNames = insertStatementContext.getInsertColumnNames();
diff --git a/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/statement/impl/MySQLStatementSQLVisitor.java b/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/statement/impl/MySQLStatementSQLVisitor.java
index 8346fbd..267ccdd 100644
--- a/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/statement/impl/MySQLStatementSQLVisitor.java
+++ b/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/statement/impl/MySQLStatementSQLVisitor.java
@@ -127,6 +127,7 @@ import org.apache.shardingsphere.sql.parser.sql.common.constant.UnionType;
import org.apache.shardingsphere.sql.parser.sql.common.segment.ddl.constraint.ConstraintSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.ddl.index.IndexSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.assignment.AssignmentSegment;
+import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.assignment.ColumnAssignmentSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.assignment.InsertValuesSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.assignment.SetAssignmentSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.ColumnSegment;
@@ -1094,7 +1095,10 @@ public abstract class MySQLStatementSQLVisitor extends MySQLStatementBaseVisitor
public ASTNode visitAssignment(final AssignmentContext ctx) {
ColumnSegment column = (ColumnSegment) visit(ctx.columnRef());
ExpressionSegment value = (ExpressionSegment) visit(ctx.assignmentValue());
- return new AssignmentSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), column, value);
+ List<ColumnSegment> columnSegments = new LinkedList<>();
+ columnSegments.add(column);
+ AssignmentSegment result = new ColumnAssignmentSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), columnSegments, value);
+ return result;
}
@Override
diff --git a/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-oracle/src/main/antlr4/imports/oracle/DMLStatement.g4 b/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-oracle/src/main/antlr4/imports/oracle/DMLStatement.g4
index 78ff4da..4478ed1 100644
--- a/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-oracle/src/main/antlr4/imports/oracle/DMLStatement.g4
+++ b/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-oracle/src/main/antlr4/imports/oracle/DMLStatement.g4
@@ -90,19 +90,28 @@ collectionExpr
;
update
- : UPDATE updateSpecification? tableReferences setAssignmentsClause whereClause?
+ : UPDATE hint? updateSpecification alias? updateSetClause whereClause? returningClause? errorLoggingClause?
;
updateSpecification
- : ONLY
+ : dmlTableExprClause | (ONLY LP_ dmlTableExprClause RP_)
;
-assignment
- : columnName EQ_ assignmentValue
+updateSetClause
+ : SET (updateSetColumnList | updateSetValueClause)
;
-setAssignmentsClause
- : SET assignment (COMMA_ assignment)*
+updateSetColumnList
+ : updateSetColumnClause (COMMA_ updateSetColumnClause)*
+ ;
+
+updateSetColumnClause
+ : (LP_ columnName (COMMA_ columnName)* RP_ EQ_ LP_ selectSubquery RP_)
+ | (columnName EQ_ (expr | LP_ selectSubquery RP_ | DEFAULT))
+ ;
+
+updateSetValueClause
+ : VALUE LP_ alias RP_ EQ_ (expr | LP_ selectSubquery RP_)
;
assignmentValues
diff --git a/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-oracle/src/main/java/org/apache/shardingsphere/sql/parser/oracle/visitor/statement/impl/OracleDMLStatementSQLVisitor.java b/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-oracle/src/main/java/org/apache/shardingsphere/sql/parser/oracle/visitor/statement/impl/OracleDMLStatementSQLVisitor.java
index 0f6e7d3..1675bee 100644
--- a/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-oracle/src/main/java/org/apache/shardingsphere/sql/parser/oracle/visitor/statement/impl/OracleDMLStatementSQLVisitor.java
+++ b/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-oracle/src/main/java/org/apache/shardingsphere/sql/parser/oracle/visitor/statement/impl/OracleDMLStatementSQLVisitor.java
@@ -24,7 +24,6 @@ import org.apache.shardingsphere.sql.parser.api.visitor.operation.SQLStatementVi
import org.apache.shardingsphere.sql.parser.api.visitor.type.DMLSQLVisitor;
import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser;
import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.AliasContext;
-import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.AssignmentContext;
import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.AssignmentValueContext;
import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.AssignmentValuesContext;
import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.CellAssignmentContext;
@@ -87,7 +86,6 @@ import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.Select
import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.SelectSubqueryContext;
import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.SelectTableReferenceContext;
import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.SelectUnionClauseContext;
-import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.SetAssignmentsClauseContext;
import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.ShardsClauseContext;
import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.SingleColumnForLoopContext;
import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.SubqueryContext;
@@ -96,11 +94,16 @@ import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.TableC
import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.TableNameContext;
import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.UnionClauseContext;
import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.UpdateContext;
+import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.UpdateSetClauseContext;
+import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.UpdateSetColumnClauseContext;
+import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.UpdateSetValueClauseContext;
+import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.UpdateSpecificationContext;
import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.UsingClauseContext;
import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.WhereClauseContext;
import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.WithClauseContext;
import org.apache.shardingsphere.sql.parser.sql.common.constant.OrderDirection;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.assignment.AssignmentSegment;
+import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.assignment.ColumnAssignmentSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.assignment.InsertValuesSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.assignment.SetAssignmentSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.ColumnSegment;
@@ -312,8 +315,11 @@ public final class OracleDMLStatementSQLVisitor extends OracleStatementSQLVisito
@Override
public ASTNode visitUpdate(final UpdateContext ctx) {
OracleUpdateStatement result = new OracleUpdateStatement();
- result.setTableSegment((TableSegment) visit(ctx.tableReferences()));
- result.setSetAssignment((SetAssignmentSegment) visit(ctx.setAssignmentsClause()));
+ result.setTableSegment((TableSegment) visit(ctx.updateSpecification()));
+ if (null != ctx.alias()) {
+ result.getTableSegment().setAlias((AliasSegment) visit(ctx.alias()));
+ }
+ result.setSetAssignment((SetAssignmentSegment) visit(ctx.updateSetClause()));
if (null != ctx.whereClause()) {
result.setWhere((WhereSegment) visit(ctx.whereClause()));
}
@@ -322,12 +328,95 @@ public final class OracleDMLStatementSQLVisitor extends OracleStatementSQLVisito
}
@Override
- public ASTNode visitSetAssignmentsClause(final SetAssignmentsClauseContext ctx) {
+ public ASTNode visitUpdateSpecification(final UpdateSpecificationContext ctx) {
+ TableSegment result;
+ if (null != ctx.dmlTableExprClause().dmlTableClause()) {
+ result = (TableSegment) visit(ctx.dmlTableExprClause().dmlTableClause());
+ } else if (null != ctx.dmlTableExprClause().dmlSubqueryClause()) {
+ SubquerySegment subquerySegment = (SubquerySegment) visit(ctx.dmlTableExprClause().dmlSubqueryClause());
+ SubqueryTableSegment subqueryTableSegment = new SubqueryTableSegment(subquerySegment);
+ result = (TableSegment) subqueryTableSegment;
+ } else {
+ SubquerySegment subquerySegment = (SubquerySegment) visit(ctx.dmlTableExprClause().tableCollectionExpr());
+ SubqueryTableSegment subqueryTableSegment = new SubqueryTableSegment(subquerySegment);
+ result = (TableSegment) subqueryTableSegment;
+ }
+ return result;
+ }
+
+ @Override
+ public ASTNode visitUpdateSetClause(final UpdateSetClauseContext ctx) {
Collection<AssignmentSegment> assignments = new LinkedList<>();
- for (AssignmentContext each : ctx.assignment()) {
- assignments.add((AssignmentSegment) visit(each));
+ if (null != ctx.updateSetColumnList()) {
+ for (UpdateSetColumnClauseContext each : ctx.updateSetColumnList().updateSetColumnClause()) {
+ assignments.add((AssignmentSegment) visit(each));
+ }
+ } else {
+ assignments.add((AssignmentSegment) visit(ctx.updateSetValueClause()));
+ }
+ SetAssignmentSegment result = new SetAssignmentSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), assignments);
+ return result;
+ }
+
+ @Override
+ public ASTNode visitUpdateSetColumnClause(final UpdateSetColumnClauseContext ctx) {
+ AssignmentSegment result = 1 == ctx.columnName().size() ? createAssignmentSegmentFromSingleColumnAssignment(ctx) : createAssignmentSegmentFromMultiColumnAssignment(ctx);
+ return result;
+ }
+
+ private AssignmentSegment createAssignmentSegmentFromSingleColumnAssignment(final UpdateSetColumnClauseContext ctx) {
+ ColumnSegment column = (ColumnSegment) visitColumnName(ctx.columnName(0));
+ List<ColumnSegment> columnSegments = new LinkedList<>();
+ columnSegments.add(column);
+ if (null != ctx.expr()) {
+ ExpressionSegment value = (ExpressionSegment) visit(ctx.expr());
+ AssignmentSegment result = new ColumnAssignmentSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), columnSegments, value);
+ return result;
+ } else if (null != ctx.selectSubquery()) {
+ SubquerySegment subquerySegment =
+ new SubquerySegment(ctx.selectSubquery().start.getStartIndex(), ctx.selectSubquery().stop.getStopIndex(), (OracleSelectStatement) visit(ctx.selectSubquery()));
+ SubqueryExpressionSegment value = new SubqueryExpressionSegment(subquerySegment);
+ AssignmentSegment result = new ColumnAssignmentSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), columnSegments, value);
+ result.getColumns().add(column);
+ return result;
+ } else {
+ CommonExpressionSegment value = new CommonExpressionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), ctx.DEFAULT().getText());
+ AssignmentSegment result = new ColumnAssignmentSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), columnSegments, value);
+ result.getColumns().add(column);
+ return result;
+ }
+ }
+
+ private AssignmentSegment createAssignmentSegmentFromMultiColumnAssignment(final UpdateSetColumnClauseContext ctx) {
+ List<ColumnSegment> columnSegments = new LinkedList<>();
+ for (ColumnNameContext each : ctx.columnName()) {
+ columnSegments.add((ColumnSegment) visit(each));
+ }
+ SubquerySegment subquerySegment =
+ new SubquerySegment(ctx.selectSubquery().start.getStartIndex(), ctx.selectSubquery().stop.getStopIndex(), (OracleSelectStatement) visit(ctx.selectSubquery()));
+ SubqueryExpressionSegment value = new SubqueryExpressionSegment(subquerySegment);
+ AssignmentSegment result = new ColumnAssignmentSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), columnSegments, value);
+ return result;
+ }
+
+ @Override
+ public ASTNode visitUpdateSetValueClause(final UpdateSetValueClauseContext ctx) {
+ ColumnSegment column = new ColumnSegment(ctx.alias().start.getStartIndex(), ctx.alias().stop.getStopIndex(), (IdentifierValue) visit(ctx.alias().identifier()));
+ List<ColumnSegment> columnSegments = new LinkedList<>();
+ columnSegments.add(column);
+ if (null != ctx.expr()) {
+ ExpressionSegment value = (ExpressionSegment) visit(ctx.expr());
+ AssignmentSegment result = new ColumnAssignmentSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), columnSegments, value);
+ result.getColumns().add(column);
+ return result;
+ } else {
+ SubquerySegment subquerySegment =
+ new SubquerySegment(ctx.selectSubquery().start.getStartIndex(), ctx.selectSubquery().stop.getStopIndex(), (OracleSelectStatement) visit(ctx.selectSubquery()));
+ SubqueryExpressionSegment value = new SubqueryExpressionSegment(subquerySegment);
+ AssignmentSegment result = new ColumnAssignmentSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), columnSegments, value);
+ result.getColumns().add(column);
+ return result;
}
- return new SetAssignmentSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), assignments);
}
@Override
@@ -340,13 +429,6 @@ public final class OracleDMLStatementSQLVisitor extends OracleStatementSQLVisito
}
@Override
- public ASTNode visitAssignment(final AssignmentContext ctx) {
- ColumnSegment column = (ColumnSegment) visitColumnName(ctx.columnName());
- ExpressionSegment value = (ExpressionSegment) visit(ctx.assignmentValue());
- return new AssignmentSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), column, value);
- }
-
- @Override
public ASTNode visitAssignmentValue(final AssignmentValueContext ctx) {
ExprContext expr = ctx.expr();
if (null != expr) {
@@ -1036,7 +1118,10 @@ public final class OracleDMLStatementSQLVisitor extends OracleStatementSQLVisito
public ASTNode visitMergeAssignment(final MergeAssignmentContext ctx) {
ColumnSegment column = (ColumnSegment) visitColumnName(ctx.columnName());
ExpressionSegment value = (ExpressionSegment) visit(ctx.mergeAssignmentValue());
- return new AssignmentSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), column, value);
+ List<ColumnSegment> columnSegments = new LinkedList<>();
+ columnSegments.add(column);
+ AssignmentSegment result = new ColumnAssignmentSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), columnSegments, value);
+ return result;
}
@Override
diff --git a/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-postgresql/src/main/java/org/apache/shardingsphere/sql/parser/postgresql/visitor/statement/impl/PostgreSQLStatementSQLVisitor.java b/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-postgresql/src/main/java/org/apache/shardingsphere/sql/parser/postgresql/visitor/statement/impl/PostgreSQLStatementSQLVisitor.java
index 6bbb920..0f5c040 100644
--- a/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-postgresql/src/main/java/org/apache/shardingsphere/sql/parser/postgresql/visitor/statement/impl/PostgreSQLStatementSQLVisitor.java
+++ b/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-postgresql/src/main/java/org/apache/shardingsphere/sql/parser/postgresql/visitor/statement/impl/PostgreSQLStatementSQLVisitor.java
@@ -101,6 +101,7 @@ import org.apache.shardingsphere.sql.parser.sql.common.constant.OrderDirection;
import org.apache.shardingsphere.sql.parser.sql.common.segment.ddl.constraint.ConstraintSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.ddl.index.IndexSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.assignment.AssignmentSegment;
+import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.assignment.ColumnAssignmentSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.assignment.InsertValuesSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.assignment.SetAssignmentSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.ColumnSegment;
@@ -651,8 +652,11 @@ public abstract class PostgreSQLStatementSQLVisitor extends PostgreSQLStatementB
@Override
public ASTNode visitSetClause(final SetClauseContext ctx) {
ColumnSegment columnSegment = (ColumnSegment) visit(ctx.setTarget());
+ List<ColumnSegment> columnSegments = new LinkedList<>();
+ columnSegments.add(columnSegment);
ExpressionSegment expressionSegment = (ExpressionSegment) visit(ctx.aExpr());
- return new AssignmentSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), columnSegment, expressionSegment);
+ AssignmentSegment result = new ColumnAssignmentSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), columnSegments, expressionSegment);
+ return result;
}
@Override
diff --git a/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-sql92/src/main/java/org/apache/shardingsphere/sql/parser/sql92/visitor/statement/impl/SQL92DMLStatementSQLVisitor.java b/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-sql92/src/main/java/org/apache/shardingsphere/sql/parser/sql92/visitor/statement/impl/SQL92DMLStatementSQLVisitor.java
index b34b770..d9b8f6f 100644
--- a/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-sql92/src/main/java/org/apache/shardingsphere/sql/parser/sql92/visitor/statement/impl/SQL92DMLStatementSQLVisitor.java
+++ b/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-sql92/src/main/java/org/apache/shardingsphere/sql/parser/sql92/visitor/statement/impl/SQL92DMLStatementSQLVisitor.java
@@ -56,6 +56,7 @@ import org.apache.shardingsphere.sql.parser.autogen.SQL92StatementParser.UnionCl
import org.apache.shardingsphere.sql.parser.autogen.SQL92StatementParser.UpdateContext;
import org.apache.shardingsphere.sql.parser.autogen.SQL92StatementParser.WhereClauseContext;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.assignment.AssignmentSegment;
+import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.assignment.ColumnAssignmentSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.assignment.InsertValuesSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.assignment.SetAssignmentSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.ColumnSegment;
@@ -172,8 +173,12 @@ public final class SQL92DMLStatementSQLVisitor extends SQL92StatementSQLVisitor
@Override
public ASTNode visitAssignment(final AssignmentContext ctx) {
ColumnSegment column = (ColumnSegment) visitColumnName(ctx.columnName());
+ List<ColumnSegment> columnSegments = new LinkedList<>();
+ columnSegments.add(column);
ExpressionSegment value = (ExpressionSegment) visit(ctx.assignmentValue());
- return new AssignmentSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), column, value);
+ AssignmentSegment result = new ColumnAssignmentSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), columnSegments, value);
+ result.getColumns().add(column);
+ return result;
}
@Override
diff --git a/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-sqlserver/src/main/java/org/apache/shardingsphere/sql/parser/sqlserver/visitor/statement/impl/SQLServerDMLStatementSQLVisitor.java b/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-sqlserver/src/main/java/org/apache/shardingsphere/sql/parser/sqlserver/visitor/statement/impl/SQLServerDMLStatementSQLVisitor.java
index 4706647..2d3d87d 100644
--- a/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-sqlserver/src/main/java/org/apache/shardingsphere/sql/parser/sqlserver/visitor/statement/impl/SQLServerDMLStatementSQLVisitor.java
+++ b/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-sqlserver/src/main/java/org/apache/shardingsphere/sql/parser/sqlserver/visitor/statement/impl/SQLServerDMLStatementSQLVisitor.java
@@ -67,6 +67,7 @@ import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.Upd
import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.WhereClauseContext;
import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.WithClauseContext;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.assignment.AssignmentSegment;
+import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.assignment.ColumnAssignmentSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.assignment.InsertValuesSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.assignment.SetAssignmentSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.ColumnSegment;
@@ -293,8 +294,12 @@ public final class SQLServerDMLStatementSQLVisitor extends SQLServerStatementSQL
@Override
public ASTNode visitAssignment(final AssignmentContext ctx) {
ColumnSegment column = (ColumnSegment) visitColumnName(ctx.columnName());
+ List<ColumnSegment> columnSegments = new LinkedList<>();
+ columnSegments.add(column);
ExpressionSegment value = (ExpressionSegment) visit(ctx.assignmentValue());
- return new AssignmentSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), column, value);
+ AssignmentSegment result = new ColumnAssignmentSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), columnSegments, value);
+ result.getColumns().add(column);
+ return result;
}
@Override
diff --git a/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/extractor/TableExtractor.java b/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/extractor/TableExtractor.java
index 1743bb7..0a37604 100644
--- a/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/extractor/TableExtractor.java
+++ b/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/extractor/TableExtractor.java
@@ -238,7 +238,7 @@ public final class TableExtractor {
*/
public void extractTablesFromUpdate(final UpdateStatement updateStatement) {
extractTablesFromTableSegment(updateStatement.getTableSegment());
- updateStatement.getSetAssignment().getAssignments().forEach(each -> extractTablesFromExpression(each.getColumn()));
+ updateStatement.getSetAssignment().getAssignments().forEach(each -> extractTablesFromExpression(each.getColumns().get(0)));
if (updateStatement.getWhere().isPresent()) {
extractTablesFromExpression(updateStatement.getWhere().get().getExpr());
}
diff --git a/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/segment/dml/assignment/AssignmentSegment.java b/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/segment/dml/assignment/AssignmentSegment.java
index 211c029..6d2f1c3 100644
--- a/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/segment/dml/assignment/AssignmentSegment.java
+++ b/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/segment/dml/assignment/AssignmentSegment.java
@@ -17,24 +17,28 @@
package org.apache.shardingsphere.sql.parser.sql.common.segment.dml.assignment;
-import lombok.Getter;
-import lombok.RequiredArgsConstructor;
+import org.apache.shardingsphere.sql.parser.sql.common.segment.SQLSegment;
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.segment.SQLSegment;
+
+import java.util.List;
/**
* Assignment segment.
*/
-@RequiredArgsConstructor
-@Getter
-public final class AssignmentSegment implements SQLSegment {
-
- private final int startIndex;
-
- private final int stopIndex;
+public abstract class AssignmentSegment implements SQLSegment {
- private final ColumnSegment column;
+ /**
+ * Get list of column segments.
+ *
+ * @return list of ColumnSegment
+ */
+ public abstract List<ColumnSegment> getColumns();
- private final ExpressionSegment value;
+ /**
+ * Get expression segment value.
+ *
+ * @return ExpressionSegment
+ */
+ public abstract ExpressionSegment getValue();
}
diff --git a/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/segment/dml/assignment/AssignmentSegment.java b/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/segment/dml/assignment/ColumnAssignmentSegment.java
similarity index 86%
copy from shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/segment/dml/assignment/AssignmentSegment.java
copy to shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/segment/dml/assignment/ColumnAssignmentSegment.java
index 211c029..1e3dab1 100644
--- a/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/segment/dml/assignment/AssignmentSegment.java
+++ b/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/segment/dml/assignment/ColumnAssignmentSegment.java
@@ -21,20 +21,21 @@ import lombok.Getter;
import lombok.RequiredArgsConstructor;
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.segment.SQLSegment;
+
+import java.util.List;
/**
- * Assignment segment.
+ * Column Assignment segment.
*/
@RequiredArgsConstructor
@Getter
-public final class AssignmentSegment implements SQLSegment {
+public final class ColumnAssignmentSegment extends AssignmentSegment {
private final int startIndex;
private final int stopIndex;
- private final ColumnSegment column;
+ private final List<ColumnSegment> columns;
private final ExpressionSegment value;
}
diff --git a/shardingsphere-test/shardingsphere-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/asserts/segment/assignment/AssignmentAssert.java b/shardingsphere-test/shardingsphere-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/asserts/segment/assignment/AssignmentAssert.java
index 51836c2..43467d9 100644
--- a/shardingsphere-test/shardingsphere-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/asserts/segment/assignment/AssignmentAssert.java
+++ b/shardingsphere-test/shardingsphere-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/asserts/segment/assignment/AssignmentAssert.java
@@ -19,11 +19,15 @@ package org.apache.shardingsphere.test.sql.parser.parameterized.asserts.segment.
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
+import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.ColumnSegment;
import org.apache.shardingsphere.test.sql.parser.parameterized.asserts.SQLCaseAssertContext;
import org.apache.shardingsphere.test.sql.parser.parameterized.asserts.segment.column.ColumnAssert;
import org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.segment.impl.assignment.ExpectedAssignment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.assignment.AssignmentSegment;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
/**
* Assignment assert.
*/
@@ -38,8 +42,19 @@ public final class AssignmentAssert {
* @param expected expected assignment
*/
public static void assertIs(final SQLCaseAssertContext assertContext, final AssignmentSegment actual, final ExpectedAssignment expected) {
- ColumnAssert.assertIs(assertContext, actual.getColumn(), expected.getColumn());
- // TODO assert assign operator
- AssignmentValueAssert.assertIs(assertContext, actual.getValue(), expected.getAssignmentValue());
+ if (null != expected.getColumns()) {
+ assertThat(assertContext.getText("Assignment columns size assertion error: "), actual.getColumns().size(), is(expected.getColumns().size()));
+ int count = 0;
+ for (ColumnSegment each : actual.getColumns()) {
+ ColumnAssert.assertIs(assertContext, each, expected.getColumns().get(count));
+ count++;
+ }
+ // TODO assert assign operator
+ AssignmentValueAssert.assertIs(assertContext, actual.getValue(), expected.getAssignmentValue());
+ } else {
+ ColumnAssert.assertIs(assertContext, actual.getColumns().get(0), expected.getColumn());
+ // TODO assert assign operator
+ AssignmentValueAssert.assertIs(assertContext, actual.getValue(), expected.getAssignmentValue());
+ }
}
}
diff --git a/shardingsphere-test/shardingsphere-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/asserts/segment/assignment/AssignmentValueAssert.java b/shardingsphere-test/shardingsphere-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/asserts/segment/assignment/AssignmentValueAssert.java
index c682698..ab0c1a5 100644
--- a/shardingsphere-test/shardingsphere-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/asserts/segment/assignment/AssignmentValueAssert.java
+++ b/shardingsphere-test/shardingsphere-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/asserts/segment/assignment/AssignmentValueAssert.java
@@ -23,6 +23,7 @@ import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.Column
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.ExpressionSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.simple.LiteralExpressionSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.simple.ParameterMarkerExpressionSegment;
+import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.subquery.SubqueryExpressionSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.ExpressionProjectionSegment;
import org.apache.shardingsphere.test.sql.parser.parameterized.asserts.SQLCaseAssertContext;
import org.apache.shardingsphere.test.sql.parser.parameterized.asserts.segment.column.ColumnAssert;
@@ -52,6 +53,8 @@ public final class AssignmentValueAssert {
ExpressionAssert.assertCommonExpression(assertContext, (ExpressionProjectionSegment) actual, expected.getCommonExpression());
} else if (actual instanceof ColumnSegment) {
ColumnAssert.assertIs(assertContext, (ColumnSegment) actual, expected.getColumn());
+ } else if (actual instanceof SubqueryExpressionSegment) {
+ ExpressionAssert.assertSubqueryExpression(assertContext, (SubqueryExpressionSegment) actual, expected.getSubquery());
}
}
}
diff --git a/shardingsphere-test/shardingsphere-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/jaxb/cases/domain/segment/impl/assignment/ExpectedAssignment.java b/shardingsphere-test/shardingsphere-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/jaxb/cases/domain/segment/impl/assignment/ExpectedAssignment.java
index 580f073..9b65f88 100644
--- a/shardingsphere-test/shardingsphere-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/jaxb/cases/domain/segment/impl/assignment/ExpectedAssignment.java
+++ b/shardingsphere-test/shardingsphere-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/jaxb/cases/domain/segment/impl/assignment/ExpectedAssignment.java
@@ -23,6 +23,7 @@ import org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain
import org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.segment.impl.column.ExpectedColumn;
import javax.xml.bind.annotation.XmlElement;
+import java.util.List;
/**
* Expected assignment.
@@ -34,6 +35,9 @@ public final class ExpectedAssignment extends AbstractExpectedSQLSegment {
@XmlElement
private ExpectedColumn column;
+ @XmlElement(name = "columns")
+ private List<ExpectedColumn> columns;
+
@XmlElement(name = "assignment-value")
private ExpectedAssignmentValue assignmentValue;
}
diff --git a/shardingsphere-test/shardingsphere-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/jaxb/cases/domain/segment/impl/assignment/ExpectedAssignmentValue.java b/shardingsphere-test/shardingsphere-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/jaxb/cases/domain/segment/impl/assignment/ExpectedAssignmentValue.java
index 6eba0750..0e2ab58 100644
--- a/shardingsphere-test/shardingsphere-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/jaxb/cases/domain/segment/impl/assignment/ExpectedAssignmentValue.java
+++ b/shardingsphere-test/shardingsphere-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/jaxb/cases/domain/segment/impl/assignment/ExpectedAssignmentValue.java
@@ -24,6 +24,7 @@ import org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain
import org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.segment.impl.expr.complex.ExpectedCommonExpression;
import org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.segment.impl.expr.simple.ExpectedLiteralExpression;
import org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.segment.impl.expr.simple.ExpectedParameterMarkerExpression;
+import org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.segment.impl.expr.simple.ExpectedSubquery;
import javax.xml.bind.annotation.XmlElement;
@@ -45,4 +46,7 @@ public final class ExpectedAssignmentValue extends AbstractExpectedSQLSegment {
@XmlElement(name = "column")
private ExpectedColumn column;
+
+ @XmlElement(name = "subquery")
+ private ExpectedSubquery subquery;
}
diff --git a/shardingsphere-test/shardingsphere-parser-test/src/main/resources/case/dml/update.xml b/shardingsphere-test/shardingsphere-parser-test/src/main/resources/case/dml/update.xml
index c999e36..82d3a24 100644
--- a/shardingsphere-test/shardingsphere-parser-test/src/main/resources/case/dml/update.xml
+++ b/shardingsphere-test/shardingsphere-parser-test/src/main/resources/case/dml/update.xml
@@ -302,52 +302,6 @@
</where>
</update>
- <update sql-case-id="update_with_special_comments" parameters="'update', 1, 1">
- <table start-index="33" stop-index="39">
- <simple-table name="t_order" start-index="33" stop-index="39"/>
- </table>
- <set start-index="41" stop-index="52" literal-stop-index="59">
- <assignment start-index="45" stop-index="52" literal-stop-index="59">
- <column name="status" start-index="45" stop-index="50" />
- <assignment-value>
- <parameter-marker-expression value="0" start-index="52" stop-index="52" />
- <literal-expression value="update" start-index="52" stop-index="59" />
- </assignment-value>
- </assignment>
- </set>
- <where start-index="54" stop-index="87" literal-start-index="61" literal-stop-index="94">
- <expr>
- <binary-operation-expression start-index="60" stop-index="87" literal-start-index="67" literal-stop-index="94">
- <left>
- <binary-operation-expression start-index="60" stop-index="71" literal-start-index="67" literal-stop-index="78">
- <left>
- <column name="order_id" start-index="60" stop-index="67" literal-start-index="67" literal-stop-index="74" />
- </left>
- <operator>=</operator>
- <right>
- <literal-expression value="1" start-index="78" stop-index="78" />
- <parameter-marker-expression value="1" start-index="71" stop-index="71" />
- </right>
- </binary-operation-expression>
- </left>
- <operator>AND</operator>
- <right>
- <binary-operation-expression start-index="77" stop-index="87" literal-start-index="84" literal-stop-index="94">
- <left>
- <column name="user_id" start-index="77" stop-index="83" literal-start-index="84" literal-stop-index="90" />
- </left>
- <operator>=</operator>
- <right>
- <literal-expression value="1" start-index="94" stop-index="94" />
- <parameter-marker-expression value="2" start-index="87" stop-index="87" />
- </right>
- </binary-operation-expression>
- </right>
- </binary-operation-expression>
- </expr>
- </where>
- </update>
-
<update sql-case-id="update_without_parameters">
<table start-index="7" stop-index="13">
<simple-table name="t_order" start-index="7" stop-index="13"/>
@@ -863,4 +817,231 @@
</expr>
</where>
</update>
+
+ <update sql-case-id="update_with_set_null">
+ <table start-index="7" stop-index="13">
+ <simple-table name="employees" start-index="7" stop-index="15"/>
+ </table>
+ <set start-index="17" stop-index="41">
+ <assignment start-index="21" stop-index="41">
+ <column name="commission_pct" start-index="21" stop-index="34" />
+ <assignment-value>
+ <literal-expression value="NULL" start-index="38" stop-index="41" />
+ </assignment-value>
+ </assignment>
+ </set>
+ <where start-index="43" stop-index="67">
+ <expr>
+ <binary-operation-expression start-index="49" stop-index="67">
+ <left>
+ <column name="job_id" start-index="49" stop-index="54" />
+ </left>
+ <operator>=</operator>
+ <right>
+ <literal-expression value="SH_CLERK" start-index="58" stop-index="67" />
+ </right>
+ </binary-operation-expression>
+ </expr>
+ </where>
+ </update>
+
+ <update sql-case-id="update_with_set_subquery">
+ <table start-index="7" stop-index="17">
+ <simple-table name="employees" alias="a" start-index="7" stop-index="17"/>
+ </table>
+ <set start-index="19" stop-index="104">
+ <assignment start-index="23" stop-index="104">
+ <column name="department_id" start-index="23" stop-index="35" />
+ <assignment-value>
+ <subquery start-index="39" stop-index="104">
+ <select>
+ <from start-index="66" stop-index="76">
+ <simple-table name="departments" start-index="66" stop-index="76"/>
+ </from>
+ <projections start-index="47" stop-index="59">
+ <column-projection name="department_id" start-index="47" stop-index="59"/>
+ </projections>
+ <where start-index="78" stop-index="103">
+ <expr>
+ <binary-operation-expression start-index="84" stop-index="103">
+ <left>
+ <column name="location_id" start-index="84" stop-index="94"/>
+ </left>
+ <operator>=</operator>
+ <right>
+ <literal-expression value="2100" start-index="98" stop-index="103"/>
+ </right>
+ </binary-operation-expression>
+ </expr>
+ </where>
+ </select>
+ </subquery>
+ </assignment-value>
+ </assignment>
+ </set>
+ </update>
+
+ <update sql-case-id="update_with_multiple_set">
+ <table start-index="7" stop-index="15">
+ <simple-table name="employees" start-index="7" stop-index="15"/>
+ </table>
+ <set start-index="17" stop-index="73">
+ <assignment start-index="21" stop-index="37">
+ <column name="job_id" start-index="21" stop-index="26" />
+ <assignment-value>
+ <literal-expression value="SA_MAN" start-index="30" stop-index="37" />
+ </assignment-value>
+ </assignment>
+ <assignment start-index="40" stop-index="61">
+ <column name="salary" start-index="40" stop-index="45" />
+ <assignment-value>
+ <literal-expression value="1000" start-index="49" stop-index="52" />
+ </assignment-value>
+ </assignment>
+ <assignment start-index="64" stop-index="82">
+ <column name="department_id" start-index="55" stop-index="67" />
+ <assignment-value>
+ <literal-expression value="120" start-index="71" stop-index="73" />
+ </assignment-value>
+ </assignment>
+ </set>
+ <where start-index="75" stop-index="107">
+ <expr>
+ <binary-operation-expression start-index="81" stop-index="107">
+ <left>
+ <column name="last_name" start-index="81" stop-index="89" />
+ </left>
+ <operator>=</operator>
+ <right>
+ <literal-expression value="Douglas Grant" start-index="93" stop-index="107" />
+ </right>
+ </binary-operation-expression>
+ </expr>
+ </where>
+ </update>
+
+ <update sql-case-id="update_with_set_value">
+ <table start-index="7" stop-index="20">
+ <simple-table name="people_demo1" alias="p" start-index="7" stop-index="20"/>
+ </table>
+ <set start-index="22" stop-index="113">
+ <assignment start-index="26" stop-index="113">
+ <column name="p" start-index="32" stop-index="32" />
+ <assignment-value>
+ <subquery start-index="37" stop-index="113">
+ <select>
+ <from start-index="59" stop-index="72">
+ <simple-table name="people_demo2" alias="q" start-index="59" stop-index="72"/>
+ </from>
+ <projections start-index="45" stop-index="52">
+ <expression-projection text="VALUE(q)" start-index="45" stop-index="52"/>
+ </projections>
+ <where start-index="74" stop-index="112">
+ <expr>
+ <binary-operation-expression start-index="80" stop-index="112">
+ <left>
+ <column name="department_id" start-index="80" stop-index="94">
+ <owner name="p" start-index="80" stop-index="80"/>
+ </column>
+ </left>
+ <operator>=</operator>
+ <right>
+ <column name="department_id" start-index="98" stop-index="112">
+ <owner name="q" start-index="98" stop-index="98"/>
+ </column>
+ </right>
+ </binary-operation-expression>
+ </expr>
+ </where>
+ </select>
+ </subquery>
+ </assignment-value>
+ </assignment>
+ </set>
+ <where start-index="115" stop-index="140">
+ <expr>
+ <binary-operation-expression start-index="121" stop-index="140">
+ <left>
+ <column name="department_id" start-index="121" stop-index="135">
+ <owner name="p" start-index="121" stop-index="121"/>
+ </column>
+ </left>
+ <operator>=</operator>
+ <right>
+ <literal-expression value="10" start-index="139" stop-index="140" />
+ </right>
+ </binary-operation-expression>
+ </expr>
+ </where>
+ </update>
+
+ <update sql-case-id="update_with_multi_columns">
+ <table start-index="7" stop-index="17">
+ <simple-table name="employees" alias="a" start-index="7" stop-index="17"/>
+ </table>
+ <set start-index="19" stop-index="239">
+ <assignment start-index="23" stop-index="104">
+ <column name="department_id" start-index="23" stop-index="35" />
+ <assignment-value>
+ <subquery start-index="39" stop-index="104">
+ <select>
+ <from start-index="66" stop-index="76">
+ <simple-table name="departments" start-index="66" stop-index="76"/>
+ </from>
+ <projections start-index="47" stop-index="59">
+ <column-projection name="department_id" start-index="47" stop-index="59"/>
+ </projections>
+ <where start-index="78" stop-index="103">
+ <expr>
+ <binary-operation-expression start-index="84" stop-index="103">
+ <left>
+ <column name="location_id" start-index="84" stop-index="94"/>
+ </left>
+ <operator>=</operator>
+ <right>
+ <literal-expression value="2100" start-index="98" stop-index="103"/>
+ </right>
+ </binary-operation-expression>
+ </expr>
+ </where>
+ </select>
+ </subquery>
+ </assignment-value>
+ </assignment>
+ <assignment start-index="107" stop-index="239">
+ <columns name="salary" start-index="108" stop-index="113"/>
+ <columns name="commission_pct" start-index="116" stop-index="129"/>
+ <assignment-value>
+ <subquery start-index="135" stop-index="238">
+ <select>
+ <from start-index="188" stop-index="198">
+ <simple-table name="employees" alias="b" start-index="188" stop-index="198"/>
+ </from>
+ <projections start-index="142" stop-index="181">
+ <expression-projection text="1.1*AVG(salary)" start-index="142" stop-index="156"/>
+ <expression-projection text="1.5*AVG(commission_pct)" start-index="159" stop-index="181"/>
+ </projections>
+ <where start-index="200" stop-index="238">
+ <expr>
+ <binary-operation-expression start-index="206" stop-index="238">
+ <left>
+ <column name="department_id" start-index="206" stop-index="220">
+ <owner name="a" start-index="206" stop-index="206" />
+ </column>
+ </left>
+ <operator>=</operator>
+ <right>
+ <column name="department_id" start-index="224" stop-index="238">
+ <owner name="b" start-index="224" stop-index="224" />
+ </column>
+ </right>
+ </binary-operation-expression>
+ </expr>
+ </where>
+ </select>
+ </subquery>
+ </assignment-value>
+ </assignment>
+ </set>
+ </update>
</sql-parser-test-cases>
diff --git a/shardingsphere-test/shardingsphere-parser-test/src/main/resources/sql/supported/dml/update.xml b/shardingsphere-test/shardingsphere-parser-test/src/main/resources/sql/supported/dml/update.xml
index 0c21f57..2ddc0a4 100644
--- a/shardingsphere-test/shardingsphere-parser-test/src/main/resources/sql/supported/dml/update.xml
+++ b/shardingsphere-test/shardingsphere-parser-test/src/main/resources/sql/supported/dml/update.xml
@@ -23,7 +23,6 @@
<sql-case id="update_without_condition" value="UPDATE t_order o SET o.status = 'finished'" db-types="MySQL,H2" />
<sql-case id="update_with_extra_keywords" value="UPDATE LOW_PRIORITY IGNORE t_order SET status = ? WHERE order_id = ? AND user_id = ?" db-types="MySQL" />
<sql-case id="update_with_special_character" value="UPDATE `t_order` SET `status` = ? WHERE `order_id` = ? AND user_id = ?" db-types="MySQL" />
- <sql-case id="update_with_special_comments" value="UPDATE /*+ index(field1) */ ONLY t_order SET status=? WHERE order_id = ? AND user_id = ? RETURN * LOG ERRORS INTO TABLE_LOG" db-types="Oracle" />
<sql-case id="update_without_parameters" value="UPDATE t_order SET status = 'update' WHERE order_id = 1000 AND user_id = 10" />
<sql-case id="update_with_or" value="UPDATE t_order SET status = 'update' WHERE (order_id = ? OR order_id = ?) AND user_id = ?" />
<sql-case id="update_with_set_calculation" value="UPDATE t_order SET status = status - ? WHERE order_id = ? AND user_id = ?" />
@@ -37,4 +36,9 @@
<sql-case id="update_with_top" value="UPDATE TOP(10) t_order SET order_id = ? WHERE user_id = ?" db-types="SQLServer" />
<sql-case id="update_with_top_percent" value="UPDATE TOP(10) PERCENT t_order SET order_id = ? WHERE user_id = ?" db-types="SQLServer" />
<sql-case id="update_with_query_hint" value="UPDATE t_order SET status = ? WHERE order_id = ? HASH GROUP" db-types="SQLServer" />
+ <sql-case id="update_with_set_null" value="UPDATE employees SET commission_pct = NULL WHERE job_id = 'SH_CLERK'" db-types="Oracle" />
+ <sql-case id="update_with_set_subquery" value="UPDATE employees a SET department_id = (SELECT department_id FROM departments WHERE location_id = '2100')" db-types="Oracle" />
+ <sql-case id="update_with_multiple_set" value="UPDATE employees SET job_id = 'SA_MAN', salary = 1000, department_id = 120 WHERE last_name = 'Douglas Grant'" db-types="Oracle" />
+ <sql-case id="update_with_set_value" value="UPDATE people_demo1 p SET VALUE(p) = (SELECT VALUE(q) FROM people_demo2 q WHERE p.department_id = q.department_id) WHERE p.department_id = 10" db-types="Oracle" />
+ <sql-case id="update_with_multi_columns" value="UPDATE employees a SET department_id = (SELECT department_id FROM departments WHERE location_id = '2100'), (salary, commission_pct) = (SELECT 1.1*AVG(salary), 1.5*AVG(commission_pct) FROM employees b WHERE a.department_id = b.department_id)" db-types="Oracle" />
</sql-cases>