Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support alter table, drop table sql bind and add test case #34154

Merged
merged 10 commits into from
Dec 26, 2024
1 change: 1 addition & 0 deletions RELEASE-NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
1. SQL Binder: Remove TablesContext#findTableNames method and implement select order by, group by bind logic - [#34123](https://github.com/apache/shardingsphere/pull/34123)
1. SQL Binder: Support select with statement sql bind and add bind test case - [#34141](https://github.com/apache/shardingsphere/pull/34141)
1. SQL Binder: Support sql bind for select with current select projection reference - [#34151](https://github.com/apache/shardingsphere/pull/34151)
1. SQL Binder: Support alter table, drop table sql bind and add test case - [#34154](https://github.com/apache/shardingsphere/pull/34154)

### Bug Fixes

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ void init() {

@Test
void assertCheckForMySQL() {
MySQLDropTableStatement sqlStatement = new MySQLDropTableStatement(false);
MySQLDropTableStatement sqlStatement = new MySQLDropTableStatement();
sqlStatement.getTables().add(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_order_item"))));
DropTableStatementContext sqlStatementContext = new DropTableStatementContext(sqlStatement);
ShardingSphereDatabase database = mock(ShardingSphereDatabase.class, RETURNS_DEEP_STUBS);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ void init() {

@Test
void assertCheckWhenDropTableInUsedForMySQL() {
MySQLDropTableStatement sqlStatement = new MySQLDropTableStatement(false);
MySQLDropTableStatement sqlStatement = new MySQLDropTableStatement();
sqlStatement.getTables().add(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_order_item"))));
ShardingSphereDatabase database = mock(ShardingSphereDatabase.class, RETURNS_DEEP_STUBS);
when(database.getName()).thenReturn("db_schema");
Expand Down Expand Up @@ -119,7 +119,7 @@ void clean() {

@Test
void assertCheckWithSameRouteResultShardingTableForPostgreSQL() {
PostgreSQLDropTableStatement sqlStatement = new PostgreSQLDropTableStatement(false, false);
PostgreSQLDropTableStatement sqlStatement = new PostgreSQLDropTableStatement();
sqlStatement.getTables().add(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_order"))));
when(shardingRule.isShardingTable("t_order")).thenReturn(true);
when(shardingRule.getShardingTable("t_order")).thenReturn(new ShardingTable(Arrays.asList("ds_0", "ds_1"), "t_order"));
Expand All @@ -134,7 +134,7 @@ void assertCheckWithSameRouteResultShardingTableForPostgreSQL() {

@Test
void assertCheckWithDifferentRouteResultShardingTableForPostgreSQL() {
PostgreSQLDropTableStatement sqlStatement = new PostgreSQLDropTableStatement(false, false);
PostgreSQLDropTableStatement sqlStatement = new PostgreSQLDropTableStatement();
sqlStatement.getTables().add(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_order"))));
when(shardingRule.isShardingTable("t_order")).thenReturn(true);
when(shardingRule.getShardingTable("t_order")).thenReturn(new ShardingTable(Arrays.asList("ds_0", "ds_1"), "t_order"));
Expand All @@ -148,7 +148,7 @@ void assertCheckWithDifferentRouteResultShardingTableForPostgreSQL() {

@Test
void assertCheckWithSameRouteResultBroadcastTableForPostgreSQL() {
PostgreSQLDropTableStatement sqlStatement = new PostgreSQLDropTableStatement(false, false);
PostgreSQLDropTableStatement sqlStatement = new PostgreSQLDropTableStatement();
sqlStatement.getTables().add(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_config"))));
when(shardingRule.getShardingTable("t_config")).thenReturn(new ShardingTable(Arrays.asList("ds_0", "ds_1"), "t_config"));
Collection<RouteUnit> routeUnits = new LinkedList<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,9 @@
import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.bound.TableSegmentBoundInfo;
import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.SimpleTableSegment;
import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.TableNameSegment;
import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.AlterTableStatement;
import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.CreateTableStatement;
import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.DropTableStatement;
import org.apache.shardingsphere.sql.parser.statement.core.value.identifier.IdentifierValue;

import java.util.Collection;
Expand Down Expand Up @@ -130,6 +132,14 @@ private static void checkTableExists(final SQLStatementBinderContext binderConte
|| ((CreateTableStatement) binderContext.getSqlStatement()).isIfNotExists() || !schema.containsTable(tableName), () -> new TableExistsException(tableName));
return;
}
if (binderContext.getSqlStatement() instanceof AlterTableStatement && isRenameTable((AlterTableStatement) binderContext.getSqlStatement(), tableName)) {
ShardingSpherePreconditions.checkState(binderContext.getHintValueContext().isSkipMetadataValidate() || !schema.containsTable(tableName), () -> new TableExistsException(tableName));
return;
}
if (binderContext.getSqlStatement() instanceof DropTableStatement) {
ShardingSpherePreconditions.checkState(((DropTableStatement) binderContext.getSqlStatement()).isIfExists() || schema.containsTable(tableName), () -> new TableNotFoundException(tableName));
return;
}
if ("DUAL".equalsIgnoreCase(tableName)) {
return;
}
Expand All @@ -142,6 +152,10 @@ private static void checkTableExists(final SQLStatementBinderContext binderConte
ShardingSpherePreconditions.checkState(schema.containsTable(tableName), () -> new TableNotFoundException(tableName));
}

private static boolean isRenameTable(final AlterTableStatement alterTableStatement, final String tableName) {
return alterTableStatement.getRenameTable().isPresent() && alterTableStatement.getRenameTable().get().getTableName().getIdentifier().getValue().equalsIgnoreCase(tableName);
}

private static SimpleTableSegmentBinderContext createSimpleTableBinderContext(final SimpleTableSegment segment, final ShardingSphereSchema schema, final IdentifierValue databaseName,
final IdentifierValue schemaName, final SQLStatementBinderContext binderContext) {
IdentifierValue tableName = segment.getTableName().getIdentifier();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.shardingsphere.infra.binder.engine.statement.ddl;

import com.cedarsoftware.util.CaseInsensitiveMap.CaseInsensitiveString;
import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.Multimap;
import lombok.SneakyThrows;
import org.apache.shardingsphere.infra.binder.engine.segment.from.context.TableSegmentBinderContext;
import org.apache.shardingsphere.infra.binder.engine.segment.from.type.SimpleTableSegmentBinder;
import org.apache.shardingsphere.infra.binder.engine.statement.SQLStatementBinder;
import org.apache.shardingsphere.infra.binder.engine.statement.SQLStatementBinderContext;
import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.AlterTableStatement;

/**
* Alter table statement binder.
*/
public final class AlterTableStatementBinder implements SQLStatementBinder<AlterTableStatement> {

@Override
public AlterTableStatement bind(final AlterTableStatement sqlStatement, final SQLStatementBinderContext binderContext) {
AlterTableStatement result = copy(sqlStatement);
Multimap<CaseInsensitiveString, TableSegmentBinderContext> tableBinderContexts = LinkedHashMultimap.create();
result.setTable(SimpleTableSegmentBinder.bind(sqlStatement.getTable(), binderContext, tableBinderContexts));
sqlStatement.getRenameTable().ifPresent(optional -> result.setRenameTable(SimpleTableSegmentBinder.bind(optional, binderContext, tableBinderContexts)));
return result;
}

@SneakyThrows(ReflectiveOperationException.class)
private static AlterTableStatement copy(final AlterTableStatement sqlStatement) {
AlterTableStatement result = sqlStatement.getClass().getDeclaredConstructor().newInstance();
// TODO bind column and reference table if kernel need use them
sqlStatement.getConvertTableDefinition().ifPresent(result::setConvertTableDefinition);
result.getAddColumnDefinitions().addAll(sqlStatement.getAddColumnDefinitions());
result.getModifyColumnDefinitions().addAll(sqlStatement.getModifyColumnDefinitions());
result.getChangeColumnDefinitions().addAll(sqlStatement.getChangeColumnDefinitions());
result.getDropColumnDefinitions().addAll(sqlStatement.getDropColumnDefinitions());
result.getAddConstraintDefinitions().addAll(sqlStatement.getAddConstraintDefinitions());
result.getValidateConstraintDefinitions().addAll(sqlStatement.getValidateConstraintDefinitions());
result.getModifyConstraintDefinitions().addAll(sqlStatement.getModifyConstraintDefinitions());
result.getDropConstraintDefinitions().addAll(sqlStatement.getDropConstraintDefinitions());
result.getDropIndexDefinitions().addAll(sqlStatement.getDropIndexDefinitions());
result.getRenameColumnDefinitions().addAll(sqlStatement.getRenameColumnDefinitions());
result.getRenameIndexDefinitions().addAll(sqlStatement.getRenameIndexDefinitions());
sqlStatement.getModifyCollectionRetrieval().ifPresent(result::setModifyCollectionRetrieval);
result.addParameterMarkerSegments(sqlStatement.getParameterMarkerSegments());
result.getCommentSegments().addAll(sqlStatement.getCommentSegments());
result.getVariableNames().addAll(sqlStatement.getVariableNames());
return result;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.shardingsphere.infra.binder.engine.statement.ddl;

import com.cedarsoftware.util.CaseInsensitiveMap.CaseInsensitiveString;
import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.Multimap;
import lombok.SneakyThrows;
import org.apache.shardingsphere.infra.binder.engine.segment.from.context.TableSegmentBinderContext;
import org.apache.shardingsphere.infra.binder.engine.segment.from.type.SimpleTableSegmentBinder;
import org.apache.shardingsphere.infra.binder.engine.statement.SQLStatementBinder;
import org.apache.shardingsphere.infra.binder.engine.statement.SQLStatementBinderContext;
import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.DropTableStatement;

/**
* Drop table statement binder.
*/
public final class DropTableStatementBinder implements SQLStatementBinder<DropTableStatement> {

@Override
public DropTableStatement bind(final DropTableStatement sqlStatement, final SQLStatementBinderContext binderContext) {
DropTableStatement result = copy(sqlStatement);
Multimap<CaseInsensitiveString, TableSegmentBinderContext> tableBinderContexts = LinkedHashMultimap.create();
sqlStatement.getTables().forEach(each -> result.getTables().add(SimpleTableSegmentBinder.bind(each, binderContext, tableBinderContexts)));
return result;
}

@SneakyThrows(ReflectiveOperationException.class)
private static DropTableStatement copy(final DropTableStatement sqlStatement) {
DropTableStatement result = sqlStatement.getClass().getDeclaredConstructor().newInstance();
result.setIfExists(sqlStatement.isIfExists());
result.setContainsCascade(sqlStatement.isContainsCascade());
result.addParameterMarkerSegments(sqlStatement.getParameterMarkerSegments());
result.getCommentSegments().addAll(sqlStatement.getCommentSegments());
result.getVariableNames().addAll(sqlStatement.getVariableNames());
return result;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,19 @@

import lombok.RequiredArgsConstructor;
import org.apache.shardingsphere.infra.binder.engine.statement.SQLStatementBinderContext;
import org.apache.shardingsphere.infra.binder.engine.statement.ddl.AlterTableStatementBinder;
import org.apache.shardingsphere.infra.binder.engine.statement.ddl.CreateIndexStatementBinder;
import org.apache.shardingsphere.infra.binder.engine.statement.ddl.CreateTableStatementBinder;
import org.apache.shardingsphere.infra.binder.engine.statement.ddl.CursorStatementBinder;
import org.apache.shardingsphere.infra.binder.engine.statement.ddl.DropTableStatementBinder;
import org.apache.shardingsphere.infra.hint.HintValueContext;
import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.AlterTableStatement;
import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.CreateIndexStatement;
import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.CreateTableStatement;
import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.CursorStatement;
import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.DDLStatement;
import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.DropTableStatement;

/**
* DDL statement bind engine.
Expand Down Expand Up @@ -55,6 +59,12 @@ public DDLStatement bind(final DDLStatement statement) {
if (statement instanceof CreateTableStatement) {
return new CreateTableStatementBinder().bind((CreateTableStatement) statement, binderContext);
}
if (statement instanceof AlterTableStatement) {
return new AlterTableStatementBinder().bind((AlterTableStatement) statement, binderContext);
}
if (statement instanceof DropTableStatement) {
return new DropTableStatementBinder().bind((DropTableStatement) statement, binderContext);
}
if (statement instanceof CreateIndexStatement) {
return new CreateIndexStatementBinder().bind((CreateIndexStatement) statement, binderContext);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -664,7 +664,8 @@ public ASTNode visitPlace(final PlaceContext ctx) {
@SuppressWarnings("unchecked")
@Override
public ASTNode visitDropTable(final DropTableContext ctx) {
DorisDropTableStatement result = new DorisDropTableStatement(null != ctx.ifExists());
DorisDropTableStatement result = new DorisDropTableStatement();
result.setIfExists(null != ctx.ifExists());
result.getTables().addAll(((CollectionValue<SimpleTableSegment>) visit(ctx.tableList())).getValue());
return result;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -671,7 +671,8 @@ public ASTNode visitPlace(final PlaceContext ctx) {
@SuppressWarnings("unchecked")
@Override
public ASTNode visitDropTable(final DropTableContext ctx) {
MySQLDropTableStatement result = new MySQLDropTableStatement(null != ctx.ifExists());
MySQLDropTableStatement result = new MySQLDropTableStatement();
result.setIfExists(null != ctx.ifExists());
result.getTables().addAll(((CollectionValue<SimpleTableSegment>) visit(ctx.tableList())).getValue());
return result;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -512,7 +512,9 @@ public ASTNode visitRenameColumnSpecification(final RenameColumnSpecificationCon
@Override
public ASTNode visitDropTable(final DropTableContext ctx) {
boolean containsCascade = null != ctx.dropTableOpt() && null != ctx.dropTableOpt().CASCADE();
OpenGaussDropTableStatement result = new OpenGaussDropTableStatement(null != ctx.ifExists(), containsCascade);
OpenGaussDropTableStatement result = new OpenGaussDropTableStatement();
result.setIfExists(null != ctx.ifExists());
result.setContainsCascade(containsCascade);
result.getTables().addAll(((CollectionValue<SimpleTableSegment>) visit(ctx.tableNames())).getValue());
return result;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -627,7 +627,9 @@ public ASTNode visitRenameColumnSpecification(final RenameColumnSpecificationCon
@Override
public ASTNode visitDropTable(final DropTableContext ctx) {
boolean containsCascade = null != ctx.dropTableOpt() && null != ctx.dropTableOpt().CASCADE();
PostgreSQLDropTableStatement result = new PostgreSQLDropTableStatement(null != ctx.ifExists(), containsCascade);
PostgreSQLDropTableStatement result = new PostgreSQLDropTableStatement();
result.setIfExists(null != ctx.ifExists());
result.setContainsCascade(containsCascade);
result.getTables().addAll(((CollectionValue<SimpleTableSegment>) visit(ctx.tableNames())).getValue());
return result;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,8 @@ private String getText(final ParserRuleContext ctx) {
@SuppressWarnings("unchecked")
@Override
public ASTNode visitDropTable(final DropTableContext ctx) {
PrestoDropTableStatement result = new PrestoDropTableStatement(null != ctx.ifExists());
PrestoDropTableStatement result = new PrestoDropTableStatement();
result.setIfExists(null != ctx.ifExists());
result.getTables().addAll(((CollectionValue<SimpleTableSegment>) visit(ctx.tableList())).getValue());
return result;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,8 @@ public ASTNode visitDropColumnSpecification(final DropColumnSpecificationContext
@SuppressWarnings("unchecked")
@Override
public ASTNode visitDropTable(final DropTableContext ctx) {
SQLServerDropTableStatement result = new SQLServerDropTableStatement(null != ctx.ifExists());
SQLServerDropTableStatement result = new SQLServerDropTableStatement();
result.setContainsCascade(null != ctx.ifExists());
result.getTables().addAll(((CollectionValue<SimpleTableSegment>) visit(ctx.tableNames())).getValue());
return result;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,14 @@ public Optional<ConvertTableDefinitionSegment> getConvertTableDefinition() {
return Optional.ofNullable(convertTableDefinition);
}

/**
* Set modify collection retrieval.
*
* @param modifyCollectionRetrieval modify collection retrieval
*/
public void setModifyCollectionRetrieval(final ModifyCollectionRetrievalSegment modifyCollectionRetrieval) {
}

/**
* Get modify collection retrieval.
*
Expand Down
Loading
Loading