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

Add ShardingCreateTableStatementValidator (#7034)

上级 48ddf2b9
......@@ -62,7 +62,7 @@ public final class ShardingRouteDecorator implements RouteDecorator<ShardingRule
List<Object> parameters = routeContext.getParameters();
SQLStatement sqlStatement = sqlStatementContext.getSqlStatement();
Optional<ShardingStatementValidator> shardingStatementValidator = ShardingStatementValidatorFactory.newInstance(sqlStatement);
shardingStatementValidator.ifPresent(validator -> validator.preValidate(shardingRule, routeContext));
shardingStatementValidator.ifPresent(validator -> validator.preValidate(shardingRule, routeContext, metaData));
ShardingConditions shardingConditions = getShardingConditions(parameters, sqlStatementContext, metaData.getSchema().getConfiguredSchemaMetaData(), shardingRule);
boolean needMergeShardingValues = isNeedMergeShardingValues(sqlStatementContext, shardingRule);
if (sqlStatement instanceof DMLStatement && needMergeShardingValues) {
......
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.shardingsphere.sharding.route.engine.exception;
import org.apache.shardingsphere.infra.exception.ShardingSphereException;
/**
* Table exists exception.
*/
public final class TableExistsException extends ShardingSphereException {
private static final long serialVersionUID = 6056681626545854214L;
public TableExistsException(final String tableName) {
super(String.format("Table '%s' already exists.", tableName));
}
}
......@@ -17,6 +17,7 @@
package org.apache.shardingsphere.sharding.route.engine.validator;
import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
import org.apache.shardingsphere.infra.route.context.RouteContext;
import org.apache.shardingsphere.infra.route.context.RouteResult;
import org.apache.shardingsphere.sharding.rule.ShardingRule;
......@@ -34,8 +35,9 @@ public interface ShardingStatementValidator<T extends SQLStatement> {
*
* @param shardingRule sharding rule
* @param routeContext route context
* @param metaData meta data
*/
void preValidate(ShardingRule shardingRule, RouteContext routeContext);
void preValidate(ShardingRule shardingRule, RouteContext routeContext, ShardingSphereMetaData metaData);
/**
* Validate whether sharding operation is supported after route.
......
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.shardingsphere.sharding.route.engine.validator.impl;
import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
import org.apache.shardingsphere.infra.route.context.RouteContext;
import org.apache.shardingsphere.infra.route.context.RouteResult;
import org.apache.shardingsphere.sharding.route.engine.exception.TableExistsException;
import org.apache.shardingsphere.sharding.route.engine.validator.ShardingStatementValidator;
import org.apache.shardingsphere.sharding.rule.ShardingRule;
import org.apache.shardingsphere.sql.parser.binder.statement.ddl.CreateTableStatementContext;
import org.apache.shardingsphere.sql.parser.sql.statement.SQLStatement;
import org.apache.shardingsphere.sql.parser.sql.statement.ddl.CreateTableStatement;
/**
* Sharding create table statement validator.
*/
public final class ShardingCreateTableStatementValidator implements ShardingStatementValidator<CreateTableStatement> {
@Override
public void preValidate(final ShardingRule shardingRule, final RouteContext routeContext, final ShardingSphereMetaData metaData) {
CreateTableStatementContext sqlStatementContext = (CreateTableStatementContext) routeContext.getSqlStatementContext();
String tableName = sqlStatementContext.getSqlStatement().getTable().getTableName().getIdentifier().getValue();
if (metaData.getSchema().getAllTableNames().contains(tableName)) {
throw new TableExistsException(tableName);
}
}
@Override
public void postValidate(final SQLStatement sqlStatement, final RouteResult routeResult) {
}
}
......@@ -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.metadata.ShardingSphereMetaData;
import org.apache.shardingsphere.infra.route.context.RouteContext;
import org.apache.shardingsphere.infra.route.context.RouteResult;
import org.apache.shardingsphere.sharding.route.engine.validator.ShardingStatementValidator;
......@@ -33,7 +34,7 @@ import org.apache.shardingsphere.sql.parser.sql.statement.dml.DeleteStatement;
public final class ShardingDeleteStatementValidator implements ShardingStatementValidator<DeleteStatement> {
@Override
public void preValidate(final ShardingRule shardingRule, final RouteContext routeContext) {
public void preValidate(final ShardingRule shardingRule, final RouteContext routeContext, final ShardingSphereMetaData metaData) {
SQLStatementContext sqlStatementContext = routeContext.getSqlStatementContext();
if (1 != ((TableAvailable) sqlStatementContext).getAllTables().size()) {
throw new ShardingSphereException("Cannot support Multiple-Table for '%s'.", sqlStatementContext.getSqlStatement());
......
......@@ -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.metadata.ShardingSphereMetaData;
import org.apache.shardingsphere.infra.route.context.RouteContext;
import org.apache.shardingsphere.infra.route.context.RouteResult;
import org.apache.shardingsphere.sharding.route.engine.validator.ShardingStatementValidator;
......@@ -42,7 +43,7 @@ import java.util.Optional;
public final class ShardingInsertStatementValidator implements ShardingStatementValidator<InsertStatement> {
@Override
public void preValidate(final ShardingRule shardingRule, final RouteContext routeContext) {
public void preValidate(final ShardingRule shardingRule, final RouteContext routeContext, final ShardingSphereMetaData metaData) {
SQLStatementContext sqlStatementContext = routeContext.getSqlStatementContext();
if (null == ((InsertStatementContext) sqlStatementContext).getInsertSelectContext() && 1 != ((TableAvailable) sqlStatementContext).getAllTables().size()) {
throw new ShardingSphereException("Cannot support Multiple-Table for '%s'.", sqlStatementContext.getSqlStatement());
......
......@@ -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.metadata.ShardingSphereMetaData;
import org.apache.shardingsphere.infra.route.context.RouteContext;
import org.apache.shardingsphere.infra.route.context.RouteResult;
import org.apache.shardingsphere.sharding.route.engine.validator.ShardingStatementValidator;
......@@ -47,7 +48,7 @@ import java.util.Optional;
public final class ShardingUpdateStatementValidator implements ShardingStatementValidator<UpdateStatement> {
@Override
public void preValidate(final ShardingRule shardingRule, final RouteContext routeContext) {
public void preValidate(final ShardingRule shardingRule, final RouteContext routeContext, final ShardingSphereMetaData metaData) {
SQLStatementContext sqlStatementContext = routeContext.getSqlStatementContext();
if (1 != ((TableAvailable) sqlStatementContext).getAllTables().size()) {
throw new ShardingSphereException("Cannot support Multiple-Table for '%s'.", sqlStatementContext.getSqlStatement());
......
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.shardingsphere.sharding.route.engine.validator.impl;
import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
import org.apache.shardingsphere.infra.metadata.schema.RuleSchemaMetaData;
import org.apache.shardingsphere.infra.route.context.RouteContext;
import org.apache.shardingsphere.infra.route.context.RouteResult;
import org.apache.shardingsphere.sharding.route.engine.exception.TableExistsException;
import org.apache.shardingsphere.sharding.rule.ShardingRule;
import org.apache.shardingsphere.sql.parser.binder.statement.SQLStatementContext;
import org.apache.shardingsphere.sql.parser.binder.statement.ddl.CreateTableStatementContext;
import org.apache.shardingsphere.sql.parser.sql.segment.generic.table.SimpleTableSegment;
import org.apache.shardingsphere.sql.parser.sql.statement.ddl.CreateTableStatement;
import org.apache.shardingsphere.sql.parser.sql.value.identifier.IdentifierValue;
import org.junit.Test;
import org.mockito.Mock;
import java.util.Collections;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public final class ShardingCreateTableStatementValidatorTest {
@Mock
private ShardingRule shardingRule;
@Test(expected = TableExistsException.class)
public void assertValidateCreateTable() {
CreateTableStatement sqlStatement = new CreateTableStatement(new SimpleTableSegment(1, 2, new IdentifierValue("t_order")));
SQLStatementContext<CreateTableStatement> sqlStatementContext = new CreateTableStatementContext(sqlStatement);
RouteContext routeContext = new RouteContext(sqlStatementContext, Collections.emptyList(), new RouteResult());
ShardingSphereMetaData metaData = mock(ShardingSphereMetaData.class);
RuleSchemaMetaData ruleSchemaMetaData = mock(RuleSchemaMetaData.class);
when(ruleSchemaMetaData.getAllTableNames()).thenReturn(Collections.singleton("t_order"));
when(metaData.getSchema()).thenReturn(ruleSchemaMetaData);
new ShardingCreateTableStatementValidator().preValidate(shardingRule, routeContext, metaData);
}
}
......@@ -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.metadata.ShardingSphereMetaData;
import org.apache.shardingsphere.infra.route.context.RouteContext;
import org.apache.shardingsphere.infra.route.context.RouteResult;
import org.apache.shardingsphere.sharding.rule.ShardingRule;
......@@ -34,6 +35,8 @@ import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import static org.mockito.Mockito.mock;
public final class ShardingDeleteStatementValidatorTest {
@Mock
......@@ -45,7 +48,7 @@ public final class ShardingDeleteStatementValidatorTest {
sqlStatement.getTables().addAll(createMultiTablesContext().getTables());
SQLStatementContext<DeleteStatement> sqlStatementContext = new DeleteStatementContext(sqlStatement);
RouteContext routeContext = new RouteContext(sqlStatementContext, Collections.emptyList(), new RouteResult());
new ShardingDeleteStatementValidator().preValidate(shardingRule, routeContext);
new ShardingDeleteStatementValidator().preValidate(shardingRule, routeContext, mock(ShardingSphereMetaData.class));
}
private TablesContext createMultiTablesContext() {
......
......@@ -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.metadata.ShardingSphereMetaData;
import org.apache.shardingsphere.infra.route.context.RouteContext;
import org.apache.shardingsphere.infra.route.context.RouteResult;
import org.apache.shardingsphere.sharding.rule.ShardingRule;
......@@ -47,6 +48,7 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@RunWith(MockitoJUnitRunner.class)
......@@ -60,7 +62,7 @@ public final class ShardingInsertStatementValidatorTest {
SQLStatementContext<InsertStatement> sqlStatementContext = new InsertStatementContext(new SchemaMetaData(Collections.emptyMap()), Collections.singletonList(1), createInsertStatement());
sqlStatementContext.getTablesContext().getTables().addAll(createMultiTablesContext().getTables());
RouteContext routeContext = new RouteContext(sqlStatementContext, Collections.emptyList(), new RouteResult());
new ShardingInsertStatementValidator().preValidate(shardingRule, routeContext);
new ShardingInsertStatementValidator().preValidate(shardingRule, routeContext, mock(ShardingSphereMetaData.class));
}
@Test
......@@ -68,7 +70,7 @@ public final class ShardingInsertStatementValidatorTest {
when(shardingRule.isShardingColumn("id", "user")).thenReturn(false);
SQLStatementContext<InsertStatement> sqlStatementContext = new InsertStatementContext(new SchemaMetaData(Collections.emptyMap()), Collections.singletonList(1), createInsertStatement());
RouteContext routeContext = new RouteContext(sqlStatementContext, Collections.emptyList(), new RouteResult());
new ShardingInsertStatementValidator().preValidate(shardingRule, routeContext);
new ShardingInsertStatementValidator().preValidate(shardingRule, routeContext, mock(ShardingSphereMetaData.class));
}
@Test(expected = ShardingSphereException.class)
......@@ -76,7 +78,7 @@ public final class ShardingInsertStatementValidatorTest {
when(shardingRule.isShardingColumn("id", "user")).thenReturn(true);
SQLStatementContext<InsertStatement> sqlStatementContext = new InsertStatementContext(new SchemaMetaData(Collections.emptyMap()), Collections.singletonList(1), createInsertStatement());
RouteContext routeContext = new RouteContext(sqlStatementContext, Collections.emptyList(), new RouteResult());
new ShardingInsertStatementValidator().preValidate(shardingRule, routeContext);
new ShardingInsertStatementValidator().preValidate(shardingRule, routeContext, mock(ShardingSphereMetaData.class));
}
@Test(expected = ShardingSphereException.class)
......@@ -86,7 +88,7 @@ public final class ShardingInsertStatementValidatorTest {
SQLStatementContext<InsertStatement> sqlStatementContext = new InsertStatementContext(new SchemaMetaData(Collections.emptyMap()), Collections.singletonList(1), createInsertSelectStatement());
sqlStatementContext.getTablesContext().getTables().addAll(createSingleTablesContext().getTables());
RouteContext routeContext = new RouteContext(sqlStatementContext, Collections.emptyList(), new RouteResult());
new ShardingInsertStatementValidator().preValidate(shardingRule, routeContext);
new ShardingInsertStatementValidator().preValidate(shardingRule, routeContext, mock(ShardingSphereMetaData.class));
}
@Test
......@@ -96,7 +98,7 @@ public final class ShardingInsertStatementValidatorTest {
SQLStatementContext<InsertStatement> sqlStatementContext = new InsertStatementContext(new SchemaMetaData(Collections.emptyMap()), Collections.singletonList(1), createInsertSelectStatement());
sqlStatementContext.getTablesContext().getTables().addAll(createSingleTablesContext().getTables());
RouteContext routeContext = new RouteContext(sqlStatementContext, Collections.emptyList(), new RouteResult());
new ShardingInsertStatementValidator().preValidate(shardingRule, routeContext);
new ShardingInsertStatementValidator().preValidate(shardingRule, routeContext, mock(ShardingSphereMetaData.class));
}
@Test(expected = ShardingSphereException.class)
......@@ -108,7 +110,7 @@ public final class ShardingInsertStatementValidatorTest {
SQLStatementContext<InsertStatement> sqlStatementContext = new InsertStatementContext(new SchemaMetaData(Collections.emptyMap()), Collections.singletonList(1), createInsertSelectStatement());
sqlStatementContext.getTablesContext().getTables().addAll(multiTablesContext.getTables());
RouteContext routeContext = new RouteContext(sqlStatementContext, Collections.emptyList(), new RouteResult());
new ShardingInsertStatementValidator().preValidate(shardingRule, routeContext);
new ShardingInsertStatementValidator().preValidate(shardingRule, routeContext, mock(ShardingSphereMetaData.class));
}
@Test
......@@ -120,7 +122,7 @@ public final class ShardingInsertStatementValidatorTest {
SQLStatementContext<InsertStatement> sqlStatementContext = new InsertStatementContext(new SchemaMetaData(Collections.emptyMap()), Collections.singletonList(1), createInsertSelectStatement());
sqlStatementContext.getTablesContext().getTables().addAll(multiTablesContext.getTables());
RouteContext routeContext = new RouteContext(sqlStatementContext, Collections.emptyList(), new RouteResult());
new ShardingInsertStatementValidator().preValidate(shardingRule, routeContext);
new ShardingInsertStatementValidator().preValidate(shardingRule, routeContext, mock(ShardingSphereMetaData.class));
}
private InsertStatement createInsertStatement() {
......
......@@ -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.metadata.ShardingSphereMetaData;
import org.apache.shardingsphere.infra.route.context.RouteContext;
import org.apache.shardingsphere.infra.route.context.RouteResult;
import org.apache.shardingsphere.sharding.rule.ShardingRule;
......@@ -47,6 +48,7 @@ import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@RunWith(MockitoJUnitRunner.class)
......@@ -60,21 +62,21 @@ public final class ShardingUpdateStatementValidatorTest {
SQLStatementContext<UpdateStatement> sqlStatementContext = new UpdateStatementContext(createUpdateStatement());
sqlStatementContext.getTablesContext().getTables().addAll(createMultiTablesContext().getTables());
RouteContext routeContext = new RouteContext(sqlStatementContext, Collections.emptyList(), new RouteResult());
new ShardingUpdateStatementValidator().preValidate(shardingRule, routeContext);
new ShardingUpdateStatementValidator().preValidate(shardingRule, routeContext, mock(ShardingSphereMetaData.class));
}
@Test
public void assertValidateUpdateWithoutShardingKey() {
when(shardingRule.isShardingColumn("id", "user")).thenReturn(false);
RouteContext routeContext = new RouteContext(new UpdateStatementContext(createUpdateStatement()), Collections.emptyList(), new RouteResult());
new ShardingUpdateStatementValidator().preValidate(shardingRule, routeContext);
new ShardingUpdateStatementValidator().preValidate(shardingRule, routeContext, mock(ShardingSphereMetaData.class));
}
@Test(expected = ShardingSphereException.class)
public void assertValidateUpdateWithShardingKey() {
when(shardingRule.isShardingColumn("id", "user")).thenReturn(true);
RouteContext routeContext = new RouteContext(new UpdateStatementContext(createUpdateStatement()), Collections.emptyList(), new RouteResult());
new ShardingUpdateStatementValidator().preValidate(shardingRule, routeContext);
new ShardingUpdateStatementValidator().preValidate(shardingRule, routeContext, mock(ShardingSphereMetaData.class));
}
@Test
......@@ -82,7 +84,7 @@ public final class ShardingUpdateStatementValidatorTest {
when(shardingRule.isShardingColumn("id", "user")).thenReturn(false);
List<Object> parameters = Arrays.asList(1, 1);
RouteContext routeContext = new RouteContext(new UpdateStatementContext(createUpdateStatement()), parameters, new RouteResult());
new ShardingUpdateStatementValidator().preValidate(shardingRule, routeContext);
new ShardingUpdateStatementValidator().preValidate(shardingRule, routeContext, mock(ShardingSphereMetaData.class));
}
@Test
......@@ -91,7 +93,7 @@ public final class ShardingUpdateStatementValidatorTest {
List<Object> parameters = Arrays.asList(1, 1);
SQLStatementContext<UpdateStatement> updateStatementContext = new UpdateStatementContext(createUpdateStatementAndParameters(1));
RouteContext routeContext = new RouteContext(updateStatementContext, parameters, new RouteResult());
new ShardingUpdateStatementValidator().preValidate(shardingRule, routeContext);
new ShardingUpdateStatementValidator().preValidate(shardingRule, routeContext, mock(ShardingSphereMetaData.class));
}
@Test(expected = ShardingSphereException.class)
......@@ -100,7 +102,7 @@ public final class ShardingUpdateStatementValidatorTest {
List<Object> parameters = Arrays.asList(1, 1);
SQLStatementContext<UpdateStatement> updateStatementContext = new UpdateStatementContext(createUpdateStatementAndParameters(2));
RouteContext routeContext = new RouteContext(updateStatementContext, parameters, new RouteResult());
new ShardingUpdateStatementValidator().preValidate(shardingRule, routeContext);
new ShardingUpdateStatementValidator().preValidate(shardingRule, routeContext, mock(ShardingSphereMetaData.class));
}
private UpdateStatement createUpdateStatement() {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册