未验证 提交 a25ce417 编写于 作者: J Juan Pan(Trista) 提交者: GitHub

Merge pull request #6997 from strongduanmu/issue-6939-dev-0822

fix update/delete limit parameterCount parse error
......@@ -31,6 +31,7 @@ import org.apache.shardingsphere.sharding.route.engine.condition.engine.InsertCl
import org.apache.shardingsphere.sharding.route.engine.condition.engine.WhereClauseShardingConditionEngine;
import org.apache.shardingsphere.sharding.route.engine.type.ShardingRouteEngine;
import org.apache.shardingsphere.sharding.route.engine.type.ShardingRouteEngineFactory;
import org.apache.shardingsphere.sharding.route.engine.validator.ShardingStatementValidator;
import org.apache.shardingsphere.sharding.route.engine.validator.ShardingStatementValidatorFactory;
import org.apache.shardingsphere.sharding.rule.BindingTableRule;
import org.apache.shardingsphere.sharding.rule.ShardingRule;
......@@ -60,8 +61,8 @@ public final class ShardingRouteDecorator implements RouteDecorator<ShardingRule
SQLStatementContext sqlStatementContext = routeContext.getSqlStatementContext();
List<Object> parameters = routeContext.getParameters();
SQLStatement sqlStatement = sqlStatementContext.getSqlStatement();
ShardingStatementValidatorFactory.newInstance(
sqlStatement).ifPresent(validator -> validator.validate(shardingRule, sqlStatementContext, parameters));
Optional<ShardingStatementValidator> shardingStatementValidator = ShardingStatementValidatorFactory.newInstance(sqlStatement);
shardingStatementValidator.ifPresent(validator -> validator.preValidate(shardingRule, sqlStatementContext, parameters));
ShardingConditions shardingConditions = getShardingConditions(parameters, sqlStatementContext, metaData.getSchema().getConfiguredSchemaMetaData(), shardingRule);
boolean needMergeShardingValues = isNeedMergeShardingValues(sqlStatementContext, shardingRule);
if (sqlStatement instanceof DMLStatement && needMergeShardingValues) {
......@@ -70,9 +71,10 @@ public final class ShardingRouteDecorator implements RouteDecorator<ShardingRule
}
ShardingRouteEngine shardingRouteEngine = ShardingRouteEngineFactory.newInstance(shardingRule, metaData, sqlStatementContext, shardingConditions, props);
RouteResult routeResult = shardingRouteEngine.route(shardingRule);
shardingStatementValidator.ifPresent(validator -> validator.postValidate(sqlStatement, routeResult));
return new RouteContext(sqlStatementContext, parameters, routeResult);
}
private ShardingConditions getShardingConditions(final List<Object> parameters, final SQLStatementContext sqlStatementContext,
final SchemaMetaData schemaMetaData, final ShardingRule shardingRule) {
if (sqlStatementContext.getSqlStatement() instanceof DMLStatement) {
......
......@@ -17,6 +17,7 @@
package org.apache.shardingsphere.sharding.route.engine.validator;
import org.apache.shardingsphere.infra.route.context.RouteResult;
import org.apache.shardingsphere.sharding.rule.ShardingRule;
import org.apache.shardingsphere.sql.parser.binder.statement.SQLStatementContext;
import org.apache.shardingsphere.sql.parser.sql.statement.SQLStatement;
......@@ -31,11 +32,19 @@ import java.util.List;
public interface ShardingStatementValidator<T extends SQLStatement> {
/**
* Validate whether sharding operation is supported.
* Validate whether sharding operation is supported before route.
*
* @param shardingRule sharding rule
* @param sqlStatementContext SQL statement context
* @param parameters SQL parameters
*/
void validate(ShardingRule shardingRule, SQLStatementContext<T> sqlStatementContext, List<Object> parameters);
void preValidate(ShardingRule shardingRule, SQLStatementContext<T> sqlStatementContext, List<Object> parameters);
/**
* Validate whether sharding operation is supported after route.
*
* @param sqlStatement SQL statement
* @param routeResult route result
*/
void postValidate(SQLStatement sqlStatement, RouteResult routeResult);
}
......@@ -18,10 +18,12 @@
package org.apache.shardingsphere.sharding.route.engine.validator.impl;
import org.apache.shardingsphere.infra.exception.ShardingSphereException;
import org.apache.shardingsphere.infra.route.context.RouteResult;
import org.apache.shardingsphere.sharding.route.engine.validator.ShardingStatementValidator;
import org.apache.shardingsphere.sharding.rule.ShardingRule;
import org.apache.shardingsphere.sql.parser.binder.statement.SQLStatementContext;
import org.apache.shardingsphere.sql.parser.binder.type.TableAvailable;
import org.apache.shardingsphere.sql.parser.sql.statement.SQLStatement;
import org.apache.shardingsphere.sql.parser.sql.statement.dml.DeleteStatement;
import java.util.List;
......@@ -32,9 +34,16 @@ import java.util.List;
public final class ShardingDeleteStatementValidator implements ShardingStatementValidator<DeleteStatement> {
@Override
public void validate(final ShardingRule shardingRule, final SQLStatementContext<DeleteStatement> sqlStatementContext, final List<Object> parameters) {
public void preValidate(final ShardingRule shardingRule, final SQLStatementContext<DeleteStatement> sqlStatementContext, final List<Object> parameters) {
if (1 != ((TableAvailable) sqlStatementContext).getAllTables().size()) {
throw new ShardingSphereException("Cannot support Multiple-Table for '%s'.", sqlStatementContext.getSqlStatement());
}
}
@Override
public void postValidate(final SQLStatement sqlStatement, final RouteResult routeResult) {
if (((DeleteStatement) sqlStatement).getLimit().isPresent() && routeResult.getRouteUnits().size() > 1) {
throw new ShardingSphereException("DELETE ... LIMIT can not support sharding route to multiple data nodes.");
}
}
}
......@@ -18,6 +18,7 @@
package org.apache.shardingsphere.sharding.route.engine.validator.impl;
import org.apache.shardingsphere.infra.exception.ShardingSphereException;
import org.apache.shardingsphere.infra.route.context.RouteResult;
import org.apache.shardingsphere.sharding.route.engine.validator.ShardingStatementValidator;
import org.apache.shardingsphere.sharding.rule.ShardingRule;
import org.apache.shardingsphere.sql.parser.binder.segment.table.TablesContext;
......@@ -28,6 +29,7 @@ import org.apache.shardingsphere.sql.parser.sql.segment.dml.assignment.Assignmen
import org.apache.shardingsphere.sql.parser.sql.segment.dml.column.ColumnSegment;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.column.OnDuplicateKeyColumnsSegment;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.expr.subquery.SubquerySegment;
import org.apache.shardingsphere.sql.parser.sql.statement.SQLStatement;
import org.apache.shardingsphere.sql.parser.sql.statement.dml.InsertStatement;
import java.util.Collection;
......@@ -40,7 +42,7 @@ import java.util.Optional;
public final class ShardingInsertStatementValidator implements ShardingStatementValidator<InsertStatement> {
@Override
public void validate(final ShardingRule shardingRule, final SQLStatementContext<InsertStatement> sqlStatementContext, final List<Object> parameters) {
public void preValidate(final ShardingRule shardingRule, final SQLStatementContext<InsertStatement> sqlStatementContext, final List<Object> parameters) {
if (null == ((InsertStatementContext) sqlStatementContext).getInsertSelectContext() && 1 != ((TableAvailable) sqlStatementContext).getAllTables().size()) {
throw new ShardingSphereException("Cannot support Multiple-Table for '%s'.", sqlStatementContext.getSqlStatement());
}
......@@ -48,19 +50,23 @@ public final class ShardingInsertStatementValidator implements ShardingStatement
Optional<OnDuplicateKeyColumnsSegment> onDuplicateKeyColumnsSegment = sqlStatement.getOnDuplicateKeyColumns();
String tableName = sqlStatement.getTable().getTableName().getIdentifier().getValue();
if (onDuplicateKeyColumnsSegment.isPresent() && isUpdateShardingKey(shardingRule, onDuplicateKeyColumnsSegment.get(), tableName)) {
throw new ShardingSphereException("INSERT INTO .... ON DUPLICATE KEY UPDATE can not support update for sharding column.");
throw new ShardingSphereException("INSERT INTO ... ON DUPLICATE KEY UPDATE can not support update for sharding column.");
}
Optional<SubquerySegment> insertSelectSegment = sqlStatement.getInsertSelect();
if (insertSelectSegment.isPresent() && isContainsKeyGenerateStrategy(shardingRule, tableName)
&& !isContainsKeyGenerateColumn(shardingRule, sqlStatement.getColumns(), tableName)) {
throw new ShardingSphereException("INSERT INTO .... SELECT can not support applying keyGenerator to absent generateKeyColumn.");
throw new ShardingSphereException("INSERT INTO ... SELECT can not support applying keyGenerator to absent generateKeyColumn.");
}
TablesContext tablesContext = sqlStatementContext.getTablesContext();
if (insertSelectSegment.isPresent() && !isAllSameTables(tablesContext.getTableNames()) && !shardingRule.isAllBindingTables(tablesContext.getTableNames())) {
throw new ShardingSphereException("The table inserted and the table selected must be the same or bind tables.");
}
}
@Override
public void postValidate(final SQLStatement sqlStatement, final RouteResult routeResult) {
}
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)) {
......
......@@ -18,6 +18,7 @@
package org.apache.shardingsphere.sharding.route.engine.validator.impl;
import org.apache.shardingsphere.infra.exception.ShardingSphereException;
import org.apache.shardingsphere.infra.route.context.RouteResult;
import org.apache.shardingsphere.sharding.route.engine.validator.ShardingStatementValidator;
import org.apache.shardingsphere.sharding.rule.ShardingRule;
import org.apache.shardingsphere.sql.parser.binder.statement.SQLStatementContext;
......@@ -32,6 +33,7 @@ import org.apache.shardingsphere.sql.parser.sql.segment.dml.predicate.WhereSegme
import org.apache.shardingsphere.sql.parser.sql.segment.dml.predicate.value.PredicateCompareRightValue;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.predicate.value.PredicateInRightValue;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.predicate.value.PredicateRightValue;
import org.apache.shardingsphere.sql.parser.sql.statement.SQLStatement;
import org.apache.shardingsphere.sql.parser.sql.statement.dml.UpdateStatement;
import java.util.Collection;
......@@ -44,7 +46,7 @@ import java.util.Optional;
public final class ShardingUpdateStatementValidator implements ShardingStatementValidator<UpdateStatement> {
@Override
public void validate(final ShardingRule shardingRule, final SQLStatementContext<UpdateStatement> sqlStatementContext, final List<Object> parameters) {
public void preValidate(final ShardingRule shardingRule, final SQLStatementContext<UpdateStatement> sqlStatementContext, final List<Object> parameters) {
if (1 != ((TableAvailable) sqlStatementContext).getAllTables().size()) {
throw new ShardingSphereException("Cannot support Multiple-Table for '%s'.", sqlStatementContext.getSqlStatement());
}
......@@ -66,7 +68,14 @@ public final class ShardingUpdateStatementValidator implements ShardingStatement
}
}
}
@Override
public void postValidate(final SQLStatement sqlStatement, final RouteResult routeResult) {
if (((UpdateStatement) sqlStatement).getLimit().isPresent() && routeResult.getRouteUnits().size() > 1) {
throw new ShardingSphereException("UPDATE ... LIMIT can not support sharding route to multiple data nodes.");
}
}
private Optional<Object> getShardingColumnSetAssignmentValue(final AssignmentSegment assignmentSegment, final List<Object> parameters) {
ExpressionSegment segment = assignmentSegment.getValue();
int shardingSetAssignIndex = -1;
......
......@@ -42,7 +42,7 @@ public final class ShardingDeleteStatementValidatorTest {
DeleteStatement sqlStatement = new DeleteStatement();
sqlStatement.getTables().addAll(createMultiTablesContext().getTables());
SQLStatementContext<DeleteStatement> sqlStatementContext = new DeleteStatementContext(sqlStatement);
new ShardingDeleteStatementValidator().validate(shardingRule, sqlStatementContext, Collections.emptyList());
new ShardingDeleteStatementValidator().preValidate(shardingRule, sqlStatementContext, Collections.emptyList());
}
private TablesContext createMultiTablesContext() {
......
......@@ -57,21 +57,21 @@ public final class ShardingInsertStatementValidatorTest {
public void assertValidateInsertModifyMultiTables() {
SQLStatementContext<InsertStatement> sqlStatementContext = new InsertStatementContext(new SchemaMetaData(Collections.emptyMap()), Collections.singletonList(1), createInsertStatement());
sqlStatementContext.getTablesContext().getTables().addAll(createMultiTablesContext().getTables());
new ShardingInsertStatementValidator().validate(shardingRule, sqlStatementContext, Collections.emptyList());
new ShardingInsertStatementValidator().preValidate(shardingRule, sqlStatementContext, Collections.emptyList());
}
@Test
public void assertValidateOnDuplicateKeyWithoutShardingKey() {
when(shardingRule.isShardingColumn("id", "user")).thenReturn(false);
SQLStatementContext<InsertStatement> sqlStatementContext = new InsertStatementContext(new SchemaMetaData(Collections.emptyMap()), Collections.singletonList(1), createInsertStatement());
new ShardingInsertStatementValidator().validate(shardingRule, sqlStatementContext, Collections.emptyList());
new ShardingInsertStatementValidator().preValidate(shardingRule, sqlStatementContext, Collections.emptyList());
}
@Test(expected = ShardingSphereException.class)
public void assertValidateOnDuplicateKeyWithShardingKey() {
when(shardingRule.isShardingColumn("id", "user")).thenReturn(true);
SQLStatementContext<InsertStatement> sqlStatementContext = new InsertStatementContext(new SchemaMetaData(Collections.emptyMap()), Collections.singletonList(1), createInsertStatement());
new ShardingInsertStatementValidator().validate(shardingRule, sqlStatementContext, Collections.emptyList());
new ShardingInsertStatementValidator().preValidate(shardingRule, sqlStatementContext, Collections.emptyList());
}
@Test(expected = ShardingSphereException.class)
......@@ -80,7 +80,7 @@ public final class ShardingInsertStatementValidatorTest {
when(shardingRule.isGenerateKeyColumn("id", "user")).thenReturn(false);
SQLStatementContext<InsertStatement> sqlStatementContext = new InsertStatementContext(new SchemaMetaData(Collections.emptyMap()), Collections.singletonList(1), createInsertSelectStatement());
sqlStatementContext.getTablesContext().getTables().addAll(createSingleTablesContext().getTables());
new ShardingInsertStatementValidator().validate(shardingRule, sqlStatementContext, Collections.emptyList());
new ShardingInsertStatementValidator().preValidate(shardingRule, sqlStatementContext, Collections.emptyList());
}
@Test
......@@ -89,7 +89,7 @@ public final class ShardingInsertStatementValidatorTest {
when(shardingRule.isGenerateKeyColumn("id", "user")).thenReturn(true);
SQLStatementContext<InsertStatement> sqlStatementContext = new InsertStatementContext(new SchemaMetaData(Collections.emptyMap()), Collections.singletonList(1), createInsertSelectStatement());
sqlStatementContext.getTablesContext().getTables().addAll(createSingleTablesContext().getTables());
new ShardingInsertStatementValidator().validate(shardingRule, sqlStatementContext, Collections.emptyList());
new ShardingInsertStatementValidator().preValidate(shardingRule, sqlStatementContext, Collections.emptyList());
}
@Test(expected = ShardingSphereException.class)
......@@ -100,7 +100,7 @@ public final class ShardingInsertStatementValidatorTest {
when(shardingRule.isAllBindingTables(multiTablesContext.getTableNames())).thenReturn(false);
SQLStatementContext<InsertStatement> sqlStatementContext = new InsertStatementContext(new SchemaMetaData(Collections.emptyMap()), Collections.singletonList(1), createInsertSelectStatement());
sqlStatementContext.getTablesContext().getTables().addAll(multiTablesContext.getTables());
new ShardingInsertStatementValidator().validate(shardingRule, sqlStatementContext, Collections.emptyList());
new ShardingInsertStatementValidator().preValidate(shardingRule, sqlStatementContext, Collections.emptyList());
}
@Test
......@@ -111,7 +111,7 @@ public final class ShardingInsertStatementValidatorTest {
when(shardingRule.isAllBindingTables(multiTablesContext.getTableNames())).thenReturn(true);
SQLStatementContext<InsertStatement> sqlStatementContext = new InsertStatementContext(new SchemaMetaData(Collections.emptyMap()), Collections.singletonList(1), createInsertSelectStatement());
sqlStatementContext.getTablesContext().getTables().addAll(multiTablesContext.getTables());
new ShardingInsertStatementValidator().validate(shardingRule, sqlStatementContext, Collections.emptyList());
new ShardingInsertStatementValidator().preValidate(shardingRule, sqlStatementContext, Collections.emptyList());
}
private InsertStatement createInsertStatement() {
......
......@@ -57,26 +57,26 @@ public final class ShardingUpdateStatementValidatorTest {
public void assertValidateUpdateModifyMultiTables() {
SQLStatementContext<UpdateStatement> sqlStatementContext = new UpdateStatementContext(createUpdateStatement());
sqlStatementContext.getTablesContext().getTables().addAll(createMultiTablesContext().getTables());
new ShardingUpdateStatementValidator().validate(shardingRule, sqlStatementContext, Collections.emptyList());
new ShardingUpdateStatementValidator().preValidate(shardingRule, sqlStatementContext, Collections.emptyList());
}
@Test
public void assertValidateUpdateWithoutShardingKey() {
when(shardingRule.isShardingColumn("id", "user")).thenReturn(false);
new ShardingUpdateStatementValidator().validate(shardingRule, new UpdateStatementContext(createUpdateStatement()), Collections.emptyList());
new ShardingUpdateStatementValidator().preValidate(shardingRule, new UpdateStatementContext(createUpdateStatement()), Collections.emptyList());
}
@Test(expected = ShardingSphereException.class)
public void assertValidateUpdateWithShardingKey() {
when(shardingRule.isShardingColumn("id", "user")).thenReturn(true);
new ShardingUpdateStatementValidator().validate(shardingRule, new UpdateStatementContext(createUpdateStatement()), Collections.emptyList());
new ShardingUpdateStatementValidator().preValidate(shardingRule, new UpdateStatementContext(createUpdateStatement()), Collections.emptyList());
}
@Test
public void assertValidateUpdateWithoutShardingKeyAndParameters() {
when(shardingRule.isShardingColumn("id", "user")).thenReturn(false);
List<Object> parameters = Arrays.asList(1, 1);
new ShardingUpdateStatementValidator().validate(shardingRule, new UpdateStatementContext(createUpdateStatement()), parameters);
new ShardingUpdateStatementValidator().preValidate(shardingRule, new UpdateStatementContext(createUpdateStatement()), parameters);
}
@Test
......@@ -84,7 +84,7 @@ public final class ShardingUpdateStatementValidatorTest {
when(shardingRule.isShardingColumn("id", "user")).thenReturn(true);
List<Object> parameters = Arrays.asList(1, 1);
SQLStatementContext<UpdateStatement> updateStatementContext = new UpdateStatementContext(createUpdateStatementAndParameters(1));
new ShardingUpdateStatementValidator().validate(shardingRule, updateStatementContext, parameters);
new ShardingUpdateStatementValidator().preValidate(shardingRule, updateStatementContext, parameters);
}
@Test(expected = ShardingSphereException.class)
......@@ -92,7 +92,7 @@ public final class ShardingUpdateStatementValidatorTest {
when(shardingRule.isShardingColumn("id", "user")).thenReturn(true);
List<Object> parameters = Arrays.asList(1, 1);
SQLStatementContext<UpdateStatement> updateStatementContext = new UpdateStatementContext(createUpdateStatementAndParameters(2));
new ShardingUpdateStatementValidator().validate(shardingRule, updateStatementContext, parameters);
new ShardingUpdateStatementValidator().preValidate(shardingRule, updateStatementContext, parameters);
}
private UpdateStatement createUpdateStatement() {
......
......@@ -22,6 +22,9 @@ import lombok.ToString;
import org.apache.shardingsphere.sql.parser.binder.statement.CommonSQLStatementContext;
import org.apache.shardingsphere.sql.parser.sql.statement.dml.CallStatement;
/**
* Call statement context.
*/
@Getter
@ToString(callSuper = true)
public final class CallStatementContext extends CommonSQLStatementContext<CallStatement> {
......
......@@ -264,6 +264,12 @@ public final class MySQLDMLVisitor extends MySQLVisitor implements DMLVisitor {
if (null != ctx.whereClause()) {
result.setWhere((WhereSegment) visit(ctx.whereClause()));
}
if (null != ctx.orderByClause()) {
result.setOrderBy((OrderBySegment) visit(ctx.orderByClause()));
}
if (null != ctx.limitClause()) {
result.setLimit((LimitSegment) visit(ctx.limitClause()));
}
result.setParameterCount(getCurrentParameterIndex());
return result;
}
......@@ -324,6 +330,12 @@ public final class MySQLDMLVisitor extends MySQLVisitor implements DMLVisitor {
if (null != ctx.whereClause()) {
result.setWhere((WhereSegment) visit(ctx.whereClause()));
}
if (null != ctx.orderByClause()) {
result.setOrderBy((OrderBySegment) visit(ctx.orderByClause()));
}
if (null != ctx.limitClause()) {
result.setLimit((LimitSegment) visit(ctx.limitClause()));
}
result.setParameterCount(getCurrentParameterIndex());
return result;
}
......
......@@ -19,6 +19,8 @@ package org.apache.shardingsphere.sql.parser.sql.statement.dml;
import lombok.Getter;
import lombok.Setter;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.order.OrderBySegment;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.pagination.limit.LimitSegment;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.predicate.WhereSegment;
import org.apache.shardingsphere.sql.parser.sql.segment.generic.table.SimpleTableSegment;
......@@ -37,6 +39,10 @@ public final class DeleteStatement extends DMLStatement {
private WhereSegment where;
private OrderBySegment orderBy;
private LimitSegment limit;
/**
* Get where.
*
......@@ -45,4 +51,22 @@ public final class DeleteStatement extends DMLStatement {
public Optional<WhereSegment> getWhere() {
return Optional.ofNullable(where);
}
/**
* Get order by segment.
*
* @return order by segment
*/
public Optional<OrderBySegment> getOrderBy() {
return Optional.ofNullable(orderBy);
}
/**
* Get order by segment.
*
* @return order by segment
*/
public Optional<LimitSegment> getLimit() {
return Optional.ofNullable(limit);
}
}
......@@ -20,6 +20,8 @@ package org.apache.shardingsphere.sql.parser.sql.statement.dml;
import lombok.Getter;
import lombok.Setter;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.assignment.SetAssignmentSegment;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.order.OrderBySegment;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.pagination.limit.LimitSegment;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.predicate.WhereSegment;
import org.apache.shardingsphere.sql.parser.sql.segment.generic.table.SimpleTableSegment;
......@@ -39,6 +41,10 @@ public final class UpdateStatement extends DMLStatement {
private SetAssignmentSegment setAssignment;
private WhereSegment where;
private OrderBySegment orderBy;
private LimitSegment limit;
/**
* Get where.
......@@ -48,4 +54,22 @@ public final class UpdateStatement extends DMLStatement {
public Optional<WhereSegment> getWhere() {
return Optional.ofNullable(where);
}
/**
* Get order by segment.
*
* @return order by segment
*/
public Optional<OrderBySegment> getOrderBy() {
return Optional.ofNullable(orderBy);
}
/**
* Get order by segment.
*
* @return order by segment
*/
public Optional<LimitSegment> getLimit() {
return Optional.ofNullable(limit);
}
}
......@@ -19,11 +19,17 @@ package org.apache.shardingsphere.test.sql.parser.parameterized.asserts.statemen
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.pagination.limit.LimitSegment;
import org.apache.shardingsphere.sql.parser.sql.statement.dml.DeleteStatement;
import org.apache.shardingsphere.test.sql.parser.parameterized.asserts.SQLCaseAssertContext;
import org.apache.shardingsphere.test.sql.parser.parameterized.asserts.segment.where.WhereClauseAssert;
import org.apache.shardingsphere.test.sql.parser.parameterized.asserts.segment.SQLSegmentAssert;
import org.apache.shardingsphere.test.sql.parser.parameterized.asserts.segment.limit.LimitClauseAssert;
import org.apache.shardingsphere.test.sql.parser.parameterized.asserts.segment.orderby.OrderByClauseAssert;
import org.apache.shardingsphere.test.sql.parser.parameterized.asserts.segment.table.TableAssert;
import org.apache.shardingsphere.test.sql.parser.parameterized.asserts.segment.where.WhereClauseAssert;
import org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.statement.dml.DeleteStatementTestCase;
import org.apache.shardingsphere.sql.parser.sql.statement.dml.DeleteStatement;
import java.util.Optional;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
......@@ -44,6 +50,8 @@ public final class DeleteStatementAssert {
public static void assertIs(final SQLCaseAssertContext assertContext, final DeleteStatement actual, final DeleteStatementTestCase expected) {
assertTable(assertContext, actual, expected);
assertWhereClause(assertContext, actual, expected);
assertOrderByClause(assertContext, actual, expected);
assertLimitClause(assertContext, actual, expected);
}
private static void assertTable(final SQLCaseAssertContext assertContext, final DeleteStatement actual, final DeleteStatementTestCase expected) {
......@@ -58,4 +66,24 @@ public final class DeleteStatementAssert {
assertFalse(assertContext.getText("Actual where segment should not exist."), actual.getWhere().isPresent());
}
}
private static void assertOrderByClause(final SQLCaseAssertContext assertContext, final DeleteStatement actual, final DeleteStatementTestCase expected) {
if (null != expected.getOrderByClause()) {
assertTrue(assertContext.getText("Actual order by segment should exist."), actual.getOrderBy().isPresent());
OrderByClauseAssert.assertIs(assertContext, actual.getOrderBy().get(), expected.getOrderByClause());
} else {
assertFalse(assertContext.getText("Actual order by segment should not exist."), actual.getOrderBy().isPresent());
}
}
private static void assertLimitClause(final SQLCaseAssertContext assertContext, final DeleteStatement actual, final DeleteStatementTestCase expected) {
Optional<LimitSegment> limitSegment = actual.getLimit();
if (null != expected.getLimitClause()) {
assertTrue(assertContext.getText("Actual limit segment should exist."), limitSegment.isPresent());
LimitClauseAssert.assertRowCount(assertContext, limitSegment.get().getRowCount().orElse(null), expected.getLimitClause().getRowCount());
SQLSegmentAssert.assertIs(assertContext, limitSegment.get(), expected.getLimitClause());
} else {
assertFalse(assertContext.getText("Actual limit segment should not exist."), limitSegment.isPresent());
}
}
}
......@@ -19,12 +19,18 @@ package org.apache.shardingsphere.test.sql.parser.parameterized.asserts.statemen
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.pagination.limit.LimitSegment;
import org.apache.shardingsphere.sql.parser.sql.statement.dml.UpdateStatement;
import org.apache.shardingsphere.test.sql.parser.parameterized.asserts.SQLCaseAssertContext;
import org.apache.shardingsphere.test.sql.parser.parameterized.asserts.segment.where.WhereClauseAssert;
import org.apache.shardingsphere.test.sql.parser.parameterized.asserts.segment.SQLSegmentAssert;
import org.apache.shardingsphere.test.sql.parser.parameterized.asserts.segment.limit.LimitClauseAssert;
import org.apache.shardingsphere.test.sql.parser.parameterized.asserts.segment.orderby.OrderByClauseAssert;
import org.apache.shardingsphere.test.sql.parser.parameterized.asserts.segment.set.SetClauseAssert;
import org.apache.shardingsphere.test.sql.parser.parameterized.asserts.segment.table.TableAssert;
import org.apache.shardingsphere.test.sql.parser.parameterized.asserts.segment.where.WhereClauseAssert;
import org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.statement.dml.UpdateStatementTestCase;
import org.apache.shardingsphere.sql.parser.sql.statement.dml.UpdateStatement;
import java.util.Optional;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
......@@ -46,6 +52,8 @@ public final class UpdateStatementAssert {
assertTable(assertContext, actual, expected);
assertSetClause(assertContext, actual, expected);
assertWhereClause(assertContext, actual, expected);
assertOrderByClause(assertContext, actual, expected);
assertLimitClause(assertContext, actual, expected);
}
private static void assertTable(final SQLCaseAssertContext assertContext, final UpdateStatement actual, final UpdateStatementTestCase expected) {
......@@ -64,4 +72,24 @@ public final class UpdateStatementAssert {
assertFalse(assertContext.getText("Actual where segment should not exist."), actual.getWhere().isPresent());
}
}
private static void assertOrderByClause(final SQLCaseAssertContext assertContext, final UpdateStatement actual, final UpdateStatementTestCase expected) {
if (null != expected.getOrderByClause()) {
assertTrue(assertContext.getText("Actual order by segment should exist."), actual.getOrderBy().isPresent());
OrderByClauseAssert.assertIs(assertContext, actual.getOrderBy().get(), expected.getOrderByClause());
} else {
assertFalse(assertContext.getText("Actual order by segment should not exist."), actual.getOrderBy().isPresent());
}
}
private static void assertLimitClause(final SQLCaseAssertContext assertContext, final UpdateStatement actual, final UpdateStatementTestCase expected) {
Optional<LimitSegment> limitSegment = actual.getLimit();
if (null != expected.getLimitClause()) {
assertTrue(assertContext.getText("Actual limit segment should exist."), limitSegment.isPresent());
LimitClauseAssert.assertRowCount(assertContext, limitSegment.get().getRowCount().orElse(null), expected.getLimitClause().getRowCount());
SQLSegmentAssert.assertIs(assertContext, limitSegment.get(), expected.getLimitClause());
} else {
assertFalse(assertContext.getText("Actual limit segment should not exist."), limitSegment.isPresent());
}
}
}
......@@ -19,6 +19,8 @@ package org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domai
import lombok.Getter;
import lombok.Setter;
import org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.segment.impl.limit.ExpectedLimitClause;
import org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.segment.impl.orderby.ExpectedOrderByClause;
import org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.segment.impl.predicate.ExpectedWhereClause;
import org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.segment.impl.table.ExpectedSimpleTable;
import org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.statement.SQLParserTestCase;
......@@ -39,4 +41,10 @@ public final class DeleteStatementTestCase extends SQLParserTestCase {
@XmlElement(name = "where")
private ExpectedWhereClause whereClause;
@XmlElement(name = "order-by")
private ExpectedOrderByClause orderByClause;
@XmlElement(name = "limit")
private ExpectedLimitClause limitClause;
}
......@@ -19,6 +19,8 @@ package org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domai
import lombok.Getter;
import lombok.Setter;
import org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.segment.impl.limit.ExpectedLimitClause;
import org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.segment.impl.orderby.ExpectedOrderByClause;
import org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.segment.impl.predicate.ExpectedWhereClause;
import org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.segment.impl.set.ExpectedSetClause;
import org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.segment.impl.table.ExpectedSimpleTable;
......@@ -43,4 +45,10 @@ public final class UpdateStatementTestCase extends SQLParserTestCase {
@XmlElement(name = "where")
private ExpectedWhereClause whereClause;
@XmlElement(name = "order-by")
private ExpectedOrderByClause orderByClause;
@XmlElement(name = "limit")
private ExpectedLimitClause limitClause;
}
......@@ -126,4 +126,42 @@
</and-predicate>
</where>
</delete>
<delete sql-case-id="delete_with_order_by_row_count" parameters="1000, 1001, 'init', 10">
<table name="t_order" start-index="12" stop-index="18" />
<where start-index="20" stop-index="66" literal-stop-index="77">
<and-predicate>
<predicate start-index="26" stop-index="37" literal-stop-index="40">
<column-left-value name="order_id" start-index="26" stop-index="33" />
<operator type="=" />
<compare-right-value>
<parameter-marker-expression value="0" start-index="37" stop-index="37" />
<literal-expression value="1000" start-index="37" stop-index="40" />
</compare-right-value>
</predicate>
<predicate start-index="43" stop-index="53" literal-start-index="46" literal-stop-index="59">
<column-left-value name="user_id" start-index="43" stop-index="49" literal-start-index="46" literal-stop-index="52" />
<operator type="=" />
<compare-right-value>
<parameter-marker-expression value="1" start-index="53" stop-index="53" />
<literal-expression value="1001" start-index="56" stop-index="59" />
</compare-right-value>
</predicate>
<predicate start-index="59" stop-index="66" literal-start-index="65" literal-stop-index="77">
<column-left-value name="status" start-index="59" stop-index="64" literal-start-index="65" literal-stop-index="70" />
<operator type="=" />
<compare-right-value>
<parameter-marker-expression value="2" start-index="66" stop-index="66" />
<literal-expression value="init" start-index="72" stop-index="77" />
</compare-right-value>
</predicate>
</and-predicate>
</where>
<order-by>
<column-item name="order_id" start-index="77" stop-index="84" literal-start-index="88" literal-stop-index="95" />
</order-by>
<limit start-index="86" stop-index="92" literal-start-index="97" literal-stop-index="104">
<row-count value="10" parameter-index="3" start-index="92" stop-index="92" literal-start-index="103" literal-stop-index="104" />
</limit>
</delete>
</sql-parser-test-cases>
......@@ -483,4 +483,43 @@
</and-predicate>
</where>
</update>
<update sql-case-id="update_with_order_by_row_count" parameters="'update', 1, 1, 10">
<table name="t_order" start-index="7" stop-index="13" />
<set start-index="15" stop-index="28" literal-stop-index="35">
<assignment start-index="19" stop-index="28" literal-stop-index="35">
<column name="status" start-index="19" stop-index="24" />
<assignment-value>
<parameter-marker-expression value="0" start-index="28" stop-index="28" />
<literal-expression value="update" start-index="28" stop-index="35" />
</assignment-value>
</assignment>
</set>
<where start-index="30" stop-index="63" literal-start-index="43" literal-stop-index="54">
<and-predicate>
<predicate start-index="36" stop-index="47" literal-start-index="43" literal-stop-index="54">
<column-left-value name="order_id" start-index="36" stop-index="43" literal-start-index="43" literal-stop-index="50" />
<operator type="=" />
<compare-right-value>
<parameter-marker-expression value="1" start-index="47" stop-index="47" />
<literal-expression value="1" start-index="54" stop-index="54" />
</compare-right-value>
</predicate>
<predicate start-index="53" stop-index="63" literal-start-index="60" literal-stop-index="70">
<column-left-value name="user_id" start-index="53" stop-index="59" literal-start-index="60" literal-stop-index="66" />
<operator type="=" />
<compare-right-value>
<parameter-marker-expression value="2" start-index="63" stop-index="63" />
<literal-expression value="1" start-index="70" stop-index="70" />
</compare-right-value>
</predicate>
</and-predicate>
</where>
<order-by>
<column-item name="order_id" start-index="74" stop-index="81" literal-start-index="81" literal-stop-index="88"/>
</order-by>
<limit start-index="83" stop-index="89" literal-start-index="90" literal-stop-index="97">
<row-count value="10" parameter-index="3" start-index="89" stop-index="89" literal-start-index="96" literal-stop-index="97" />
</limit>
</update>
</sql-parser-test-cases>
......@@ -23,4 +23,5 @@
<sql-case id="delete_with_special_comments_return_without_sharding_value" value="DELETE /*+ index(status) */ ONLY t_order WHERE status=1 RETURN * LOG ERRORS INTO TABLE_LOG" db-types="Oracle" />
<sql-case id="delete_with_special_comments_returning_without_sharding_value" value="DELETE /*+ index(status) */ ONLY (t_order) WHERE status=1 RETURNING *" db-types="Oracle" />
<sql-case id="delete_with_alias" value="DELETE o FROM t_order AS o WHERE status=?" db-types="MySQL,Oracle,SQLServer"/>
<sql-case id="delete_with_order_by_row_count" value="DELETE FROM t_order WHERE order_id = ? AND user_id = ? AND status=? ORDER BY order_id LIMIT ?" db-types="MySQL"/>
</sql-cases>
......@@ -31,4 +31,5 @@
<sql-case id="update_with_column_equal_column" value="update t_order set order_id = order_id, status = 'init' where order_id = order_id AND order_id = ?" db-types="MySQL"/>
<sql-case id="update_with_case_when" value="update stock_freeze_detail set row_status=case WHEN (id=?) THEN ? WHEN (id=?) THEN ? WHEN (id=?) THEN ? end,
update_user=case WHEN (id=?) THEN ? WHEN (id=?) THEN ? WHEN (id=?) THEN ? end, update_time=case WHEN (id=?) THEN ? end where tenant_id = ?" db-types="MySQL"/>
<sql-case id="update_with_order_by_row_count" value="UPDATE t_order SET status = ? WHERE order_id = ? AND user_id = ? ORDER BY order_id LIMIT ?" db-types="MySQL"/>
</sql-cases>
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册