Skip to content

Commit

Permalink
Support alter table, drop table sql bind and add test case (#34154)
Browse files Browse the repository at this point in the history
* Support sql bind for select with current select projection reference

* update release note

* fix unit test

* fix unit test

* fix unit test

* fix unit test

* Support alter table, drop table sql bind and add test case

* update release note

* fix rewrite it
  • Loading branch information
strongduanmu authored Dec 26, 2024
1 parent bca6f32 commit 8aaa7c7
Show file tree
Hide file tree
Showing 31 changed files with 526 additions and 23 deletions.
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

0 comments on commit 8aaa7c7

Please sign in to comment.