diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index dcc167c950336..15249fef963f4 100644 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -34,6 +34,7 @@ 1. Proxy Native: Support Seata AT integration under Proxy Native in GraalVM Native Image - [#33889](https://github.com/apache/shardingsphere/pull/33889) 1. Agent: Simplify the use of Agent's Docker Image - [#33356](https://github.com/apache/shardingsphere/pull/33356) 1. Metadata: Add load-table-metadata-batch-size props to concurrent load table metadata - [#34009](https://github.com/apache/shardingsphere/pull/34009) +1. SQL Binder: Add sql bind logic for create table statement - [#34074](https://github.com/apache/shardingsphere/pull/34074) ### Bug Fixes diff --git a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/cache/checker/ShardingRouteCacheableCheckerTest.java b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/cache/checker/ShardingRouteCacheableCheckerTest.java index 4ca1d047cbd63..391c25814ad13 100644 --- a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/cache/checker/ShardingRouteCacheableCheckerTest.java +++ b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/cache/checker/ShardingRouteCacheableCheckerTest.java @@ -178,7 +178,7 @@ public Stream provideArguments(final ExtensionContext exten Arguments.of("update t_warehouse set warehouse_name = ? where id = ?", Arrays.asList("foo", 1), true, Collections.singletonList(1)), Arguments.of("delete from t_warehouse where id = ?", Collections.singletonList(1), true, Collections.singletonList(0))); Collection nonCacheableCases = Arrays.asList( - Arguments.of("create table t_warehouse (id int4 not null primary key)", Collections.emptyList(), false, Collections.emptyList()), + Arguments.of("create table t_warehouse_for_create (id int4 not null primary key)", Collections.emptyList(), false, Collections.emptyList()), Arguments.of("insert into t_warehouse (id) select warehouse_id from t_order", Collections.emptyList(), false, Collections.emptyList()), Arguments.of("insert into t_warehouse (id) values (?), (?)", Arrays.asList(1, 2), false, Collections.emptyList()), Arguments.of("insert into t_non_sharding_table (id) values (?)", Collections.singletonList(1), false, Collections.emptyList()), diff --git a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/checker/sql/ddl/ShardingCreateFunctionSupportedCheckerTest.java b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/checker/sql/ddl/ShardingCreateFunctionSupportedCheckerTest.java index 517500fbdae6c..b9ed9e2000bf8 100644 --- a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/checker/sql/ddl/ShardingCreateFunctionSupportedCheckerTest.java +++ b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/checker/sql/ddl/ShardingCreateFunctionSupportedCheckerTest.java @@ -53,7 +53,8 @@ class ShardingCreateFunctionSupportedCheckerTest { void assertCheckCreateFunctionForMySQL() { MySQLSelectStatement selectStatement = new MySQLSelectStatement(); selectStatement.setFrom(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_order_item")))); - MySQLCreateTableStatement createTableStatement = new MySQLCreateTableStatement(false); + MySQLCreateTableStatement createTableStatement = new MySQLCreateTableStatement(); + createTableStatement.setIfNotExists(false); createTableStatement.setTable(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_order")))); ValidStatementSegment validStatementSegment = new ValidStatementSegment(0, 0); validStatementSegment.setSqlStatement(createTableStatement); @@ -104,7 +105,8 @@ void assertCheckCreateFunctionWithNoSuchTableForMySQL() { @Test void assertCheckCreateFunctionWithTableExistsForMySQL() { - MySQLCreateTableStatement createTableStatement = new MySQLCreateTableStatement(false); + MySQLCreateTableStatement createTableStatement = new MySQLCreateTableStatement(); + createTableStatement.setIfNotExists(false); createTableStatement.setTable(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_order")))); ValidStatementSegment validStatementSegment = new ValidStatementSegment(0, 0); validStatementSegment.setSqlStatement(createTableStatement); diff --git a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/checker/sql/ddl/ShardingCreateProcedureSupportedCheckerTest.java b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/checker/sql/ddl/ShardingCreateProcedureSupportedCheckerTest.java index e48488ffe9472..3713cbb5567bd 100644 --- a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/checker/sql/ddl/ShardingCreateProcedureSupportedCheckerTest.java +++ b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/checker/sql/ddl/ShardingCreateProcedureSupportedCheckerTest.java @@ -53,7 +53,8 @@ class ShardingCreateProcedureSupportedCheckerTest { void assertCheckForMySQL() { MySQLSelectStatement selectStatement = new MySQLSelectStatement(); selectStatement.setFrom(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_order_item")))); - MySQLCreateTableStatement createTableStatement = new MySQLCreateTableStatement(false); + MySQLCreateTableStatement createTableStatement = new MySQLCreateTableStatement(); + createTableStatement.setIfNotExists(false); createTableStatement.setTable(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_order")))); ValidStatementSegment validStatementSegment = new ValidStatementSegment(0, 0); validStatementSegment.setSqlStatement(createTableStatement); @@ -105,7 +106,8 @@ void assertCheckWithNoSuchTableForMySQL() { @Test void assertCheckWithTableExistsForMySQL() { - MySQLCreateTableStatement createTableStatement = new MySQLCreateTableStatement(false); + MySQLCreateTableStatement createTableStatement = new MySQLCreateTableStatement(); + createTableStatement.setIfNotExists(false); createTableStatement.setTable(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_order")))); ValidStatementSegment validStatementSegment = new ValidStatementSegment(0, 0); validStatementSegment.setSqlStatement(createTableStatement); diff --git a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/checker/sql/ddl/ShardingCreateTableSupportedCheckerTest.java b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/checker/sql/ddl/ShardingCreateTableSupportedCheckerTest.java index 6231def67420d..8e6a75b9ead6c 100644 --- a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/checker/sql/ddl/ShardingCreateTableSupportedCheckerTest.java +++ b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/checker/sql/ddl/ShardingCreateTableSupportedCheckerTest.java @@ -49,7 +49,8 @@ class ShardingCreateTableSupportedCheckerTest { @Test void assertCheckForMySQL() { - MySQLCreateTableStatement sqlStatement = new MySQLCreateTableStatement(false); + MySQLCreateTableStatement sqlStatement = new MySQLCreateTableStatement(); + sqlStatement.setIfNotExists(false); sqlStatement.setTable(new SimpleTableSegment(new TableNameSegment(1, 2, new IdentifierValue("t_order")))); assertThrows(TableExistsException.class, () -> assertCheck(sqlStatement)); } @@ -63,7 +64,8 @@ void assertCheckForOracle() { @Test void assertCheckForPostgreSQL() { - PostgreSQLCreateTableStatement sqlStatement = new PostgreSQLCreateTableStatement(false); + PostgreSQLCreateTableStatement sqlStatement = new PostgreSQLCreateTableStatement(); + sqlStatement.setIfNotExists(false); sqlStatement.setTable(new SimpleTableSegment(new TableNameSegment(1, 2, new IdentifierValue("t_order")))); assertThrows(TableExistsException.class, () -> assertCheck(sqlStatement)); } @@ -92,14 +94,16 @@ private void assertCheck(final CreateTableStatement sqlStatement) { @Test void assertCheckIfNotExistsForMySQL() { - MySQLCreateTableStatement sqlStatement = new MySQLCreateTableStatement(true); + MySQLCreateTableStatement sqlStatement = new MySQLCreateTableStatement(); + sqlStatement.setIfNotExists(true); sqlStatement.setTable(new SimpleTableSegment(new TableNameSegment(1, 2, new IdentifierValue("t_order")))); assertCheckIfNotExists(sqlStatement); } @Test void assertCheckIfNotExistsForPostgreSQL() { - PostgreSQLCreateTableStatement sqlStatement = new PostgreSQLCreateTableStatement(true); + PostgreSQLCreateTableStatement sqlStatement = new PostgreSQLCreateTableStatement(); + sqlStatement.setIfNotExists(true); sqlStatement.setTable(new SimpleTableSegment(new TableNameSegment(1, 2, new IdentifierValue("t_order")))); assertCheckIfNotExists(sqlStatement); } diff --git a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/route/engine/checker/ddl/ShardingCreateTableRouteContextCheckerTest.java b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/route/engine/checker/ddl/ShardingCreateTableRouteContextCheckerTest.java index e2f568eb205ae..a5a0bee90c919 100644 --- a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/route/engine/checker/ddl/ShardingCreateTableRouteContextCheckerTest.java +++ b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/route/engine/checker/ddl/ShardingCreateTableRouteContextCheckerTest.java @@ -64,7 +64,8 @@ class ShardingCreateTableRouteContextCheckerTest { @Test void assertCheckWithSameRouteResultShardingTableForPostgreSQL() { - PostgreSQLCreateTableStatement sqlStatement = new PostgreSQLCreateTableStatement(false); + PostgreSQLCreateTableStatement sqlStatement = new PostgreSQLCreateTableStatement(); + sqlStatement.setIfNotExists(false); sqlStatement.setTable(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")); @@ -78,7 +79,8 @@ void assertCheckWithSameRouteResultShardingTableForPostgreSQL() { @Test void assertCheckWithDifferentRouteResultShardingTableForPostgreSQL() { - PostgreSQLCreateTableStatement sqlStatement = new PostgreSQLCreateTableStatement(false); + PostgreSQLCreateTableStatement sqlStatement = new PostgreSQLCreateTableStatement(); + sqlStatement.setIfNotExists(false); sqlStatement.setTable(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")); @@ -92,7 +94,8 @@ void assertCheckWithDifferentRouteResultShardingTableForPostgreSQL() { @Test void assertCheckWithSameRouteResultBroadcastTableForPostgreSQL() { - PostgreSQLCreateTableStatement sqlStatement = new PostgreSQLCreateTableStatement(false); + PostgreSQLCreateTableStatement sqlStatement = new PostgreSQLCreateTableStatement(); + sqlStatement.setIfNotExists(false); sqlStatement.setTable(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_config")))); when(queryContext.getSqlStatementContext()).thenReturn(new CreateTableStatementContext(sqlStatement)); assertDoesNotThrow(() -> new ShardingCreateTableRouteContextChecker().check(shardingRule, queryContext, database, mock(ConfigurationProperties.class), routeContext)); diff --git a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/SegmentType.java b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/SegmentType.java index fb62d9f6ff757..6cd02df131ad0 100644 --- a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/SegmentType.java +++ b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/SegmentType.java @@ -22,5 +22,5 @@ */ public enum SegmentType { - PROJECTION, PREDICATE, JOIN_ON, JOIN_USING, ORDER_BY, GROUP_BY, LOCK, SET_ASSIGNMENT, VALUES, INSERT_COLUMNS + PROJECTION, PREDICATE, JOIN_ON, JOIN_USING, ORDER_BY, GROUP_BY, LOCK, SET_ASSIGNMENT, VALUES, INSERT_COLUMNS, DEFINITION_COLUMNS } diff --git a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/column/ColumnDefinitionSegmentBinder.java b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/column/ColumnDefinitionSegmentBinder.java new file mode 100644 index 0000000000000..633bfd8582171 --- /dev/null +++ b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/column/ColumnDefinitionSegmentBinder.java @@ -0,0 +1,63 @@ +/* + * 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.segment.column; + +import com.cedarsoftware.util.CaseInsensitiveMap.CaseInsensitiveString; +import com.google.common.collect.LinkedHashMultimap; +import com.google.common.collect.Multimap; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import org.apache.shardingsphere.infra.binder.engine.segment.SegmentType; +import org.apache.shardingsphere.infra.binder.engine.segment.expression.type.ColumnSegmentBinder; +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.SQLStatementBinderContext; +import org.apache.shardingsphere.sql.parser.statement.core.segment.ddl.column.ColumnDefinitionSegment; +import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.column.ColumnSegment; + +/** + * Column definition segment binder. + */ +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public final class ColumnDefinitionSegmentBinder { + + /** + * Bind column definition segment. + * + * @param segment column definition segment + * @param binderContext SQL statement binder context + * @param tableBinderContexts table binder contexts + * @return bound column definition segment + */ + public static ColumnDefinitionSegment bind(final ColumnDefinitionSegment segment, final SQLStatementBinderContext binderContext, + final Multimap tableBinderContexts) { + ColumnSegment boundColumnSegment = ColumnSegmentBinder.bind(segment.getColumnName(), SegmentType.DEFINITION_COLUMNS, binderContext, tableBinderContexts, LinkedHashMultimap.create()); + ColumnDefinitionSegment result = + new ColumnDefinitionSegment(segment.getStartIndex(), segment.getStopIndex(), boundColumnSegment, segment.getDataType(), segment.isPrimaryKey(), segment.isNotNull(), segment.getText()); + copy(segment, result); + segment.getReferencedTables().forEach(each -> result.getReferencedTables().add(SimpleTableSegmentBinder.bind(each, binderContext, tableBinderContexts))); + return result; + } + + private static void copy(final ColumnDefinitionSegment result, final ColumnDefinitionSegment segment) { + result.setAutoIncrement(segment.isAutoIncrement()); + result.setRef(segment.isRef()); + result.setCharsetName(segment.getCharsetName()); + result.setCollateName(segment.getCollateName()); + } +} diff --git a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/combine/CombineSegmentBinder.java b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/combine/CombineSegmentBinder.java index a8c9d3538df67..d3d6180de958a 100644 --- a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/combine/CombineSegmentBinder.java +++ b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/combine/CombineSegmentBinder.java @@ -51,7 +51,7 @@ public static CombineSegment bind(final CombineSegment segment, final SQLStateme private static SubquerySegment bindSubquerySegment(final SubquerySegment segment, final SQLStatementBinderContext binderContext, final Multimap outerTableBinderContexts) { SubquerySegment result = new SubquerySegment(segment.getStartIndex(), segment.getStopIndex(), segment.getText()); - SQLStatementBinderContext subqueryBinderContext = new SQLStatementBinderContext(segment.getSelect(), binderContext.getMetaData(), binderContext.getCurrentDatabaseName()); + SQLStatementBinderContext subqueryBinderContext = new SQLStatementBinderContext(binderContext.getMetaData(), binderContext.getCurrentDatabaseName(), segment.getSelect()); subqueryBinderContext.getExternalTableBinderContexts().putAll(binderContext.getExternalTableBinderContexts()); result.setSelect(new SelectStatementBinder(outerTableBinderContexts).bind(segment.getSelect(), subqueryBinderContext)); return result; diff --git a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/expression/type/ColumnSegmentBinder.java b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/expression/type/ColumnSegmentBinder.java index 3e3a894764c12..6020cc3f1bbdf 100644 --- a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/expression/type/ColumnSegmentBinder.java +++ b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/expression/type/ColumnSegmentBinder.java @@ -172,7 +172,7 @@ private static Optional findInputColumnSegment(final ColumnSegmen } } if (!isFindInputColumn) { - result = findInputColumnSegmentByVariables(segment, binderContext.getVariableNames()).orElse(null); + result = findInputColumnSegmentByVariables(segment, binderContext.getSqlStatement().getVariableNames()).orElse(null); isFindInputColumn = null != result; } if (!isFindInputColumn) { diff --git a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/expression/type/SubquerySegmentBinder.java b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/expression/type/SubquerySegmentBinder.java index bcefdbd14f9bc..afaca7dbcdba4 100644 --- a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/expression/type/SubquerySegmentBinder.java +++ b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/expression/type/SubquerySegmentBinder.java @@ -43,7 +43,7 @@ public final class SubquerySegmentBinder { */ public static SubquerySegment bind(final SubquerySegment segment, final SQLStatementBinderContext binderContext, final Multimap outerTableBinderContexts) { - SQLStatementBinderContext selectBinderContext = new SQLStatementBinderContext(segment.getSelect(), binderContext.getMetaData(), binderContext.getCurrentDatabaseName()); + SQLStatementBinderContext selectBinderContext = new SQLStatementBinderContext(binderContext.getMetaData(), binderContext.getCurrentDatabaseName(), segment.getSelect()); selectBinderContext.getExternalTableBinderContexts().putAll(binderContext.getExternalTableBinderContexts()); SelectStatement boundSelectStatement = new SelectStatementBinder(outerTableBinderContexts).bind(segment.getSelect(), selectBinderContext); return new SubquerySegment(segment.getStartIndex(), segment.getStopIndex(), boundSelectStatement, segment.getText()); diff --git a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/from/type/JoinTableSegmentBinder.java b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/from/type/JoinTableSegmentBinder.java index 20af49d943801..455d9d7a4936b 100644 --- a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/from/type/JoinTableSegmentBinder.java +++ b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/from/type/JoinTableSegmentBinder.java @@ -83,7 +83,8 @@ public static JoinTableSegment bind(final JoinTableSegment segment, final SQLSta result.setDerivedUsing(bindUsingColumns(derivedUsingColumns, tableBinderContexts)); result.getDerivedUsing().forEach(each -> binderContext.getUsingColumnNames().add(each.getIdentifier().getValue())); } - result.getDerivedJoinTableProjectionSegments().addAll(getDerivedJoinTableProjectionSegments(result, binderContext.getDatabaseType(), usingColumnsByNaturalJoin, tableBinderContexts)); + result.getDerivedJoinTableProjectionSegments() + .addAll(getDerivedJoinTableProjectionSegments(result, binderContext.getSqlStatement().getDatabaseType(), usingColumnsByNaturalJoin, tableBinderContexts)); binderContext.getJoinTableProjectionSegments().addAll(result.getDerivedJoinTableProjectionSegments()); return result; } diff --git a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/from/type/SimpleTableSegmentBinder.java b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/from/type/SimpleTableSegmentBinder.java index d94ad27e23e16..7c3e9c00a6874 100644 --- a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/from/type/SimpleTableSegmentBinder.java +++ b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/from/type/SimpleTableSegmentBinder.java @@ -32,10 +32,14 @@ import org.apache.shardingsphere.infra.database.postgresql.type.PostgreSQLDatabaseType; import org.apache.shardingsphere.infra.exception.core.ShardingSpherePreconditions; import org.apache.shardingsphere.infra.exception.dialect.exception.syntax.database.NoDatabaseSelectedException; +import org.apache.shardingsphere.infra.exception.dialect.exception.syntax.database.UnknownDatabaseException; +import org.apache.shardingsphere.infra.exception.dialect.exception.syntax.table.TableExistsException; +import org.apache.shardingsphere.infra.exception.kernel.metadata.SchemaNotFoundException; import org.apache.shardingsphere.infra.exception.kernel.metadata.TableNotFoundException; import org.apache.shardingsphere.infra.metadata.database.schema.manager.SystemSchemaManager; import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereColumn; import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereSchema; +import org.apache.shardingsphere.sql.parser.statement.core.segment.ddl.column.ColumnDefinitionSegment; import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.column.ColumnSegment; import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.ColumnProjectionSegment; import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.ProjectionSegment; @@ -44,6 +48,7 @@ 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.CreateTableStatement; import org.apache.shardingsphere.sql.parser.statement.core.value.identifier.IdentifierValue; import java.util.Collection; @@ -71,11 +76,10 @@ public static SimpleTableSegment bind(final SimpleTableSegment segment, final SQ final Multimap tableBinderContexts) { fillPivotColumnNamesInBinderContext(segment, binderContext); IdentifierValue databaseName = getDatabaseName(segment, binderContext); - ShardingSpherePreconditions.checkNotNull(databaseName.getValue(), NoDatabaseSelectedException::new); - IdentifierValue schemaName = getSchemaName(segment, binderContext); + IdentifierValue schemaName = getSchemaName(segment, binderContext, databaseName); IdentifierValue tableName = segment.getTableName().getIdentifier(); - checkTableExists(binderContext, databaseName.getValue(), schemaName.getValue(), tableName.getValue()); ShardingSphereSchema schema = binderContext.getMetaData().getDatabase(databaseName.getValue()).getSchema(schemaName.getValue()); + checkTableExists(binderContext, schema, schemaName.getValue(), tableName.getValue()); tableBinderContexts.put(new CaseInsensitiveString(segment.getAliasName().orElseGet(tableName::getValue)), createSimpleTableBinderContext(segment, schema, databaseName, schemaName, binderContext)); TableNameSegment tableNameSegment = new TableNameSegment(segment.getTableName().getStartIndex(), segment.getTableName().getStopIndex(), tableName); @@ -91,9 +95,19 @@ private static void fillPivotColumnNamesInBinderContext(final SimpleTableSegment } private static IdentifierValue getDatabaseName(final SimpleTableSegment segment, final SQLStatementBinderContext binderContext) { - DialectDatabaseMetaData dialectDatabaseMetaData = new DatabaseTypeRegistry(binderContext.getDatabaseType()).getDialectDatabaseMetaData(); + DialectDatabaseMetaData dialectDatabaseMetaData = new DatabaseTypeRegistry(binderContext.getSqlStatement().getDatabaseType()).getDialectDatabaseMetaData(); Optional owner = dialectDatabaseMetaData.getDefaultSchema().isPresent() ? segment.getOwner().flatMap(OwnerSegment::getOwner) : segment.getOwner(); - return new IdentifierValue(owner.map(optional -> optional.getIdentifier().getValue()).orElse(binderContext.getCurrentDatabaseName())); + IdentifierValue result = new IdentifierValue(owner.map(optional -> optional.getIdentifier().getValue()).orElse(binderContext.getCurrentDatabaseName())); + ShardingSpherePreconditions.checkNotNull(result.getValue(), NoDatabaseSelectedException::new); + ShardingSpherePreconditions.checkState(binderContext.getMetaData().containsDatabase(result.getValue()), () -> new UnknownDatabaseException(result.getValue())); + return result; + } + + private static IdentifierValue getSchemaName(final SimpleTableSegment segment, final SQLStatementBinderContext binderContext, final IdentifierValue databaseName) { + IdentifierValue result = getSchemaName(segment, binderContext); + ShardingSpherePreconditions.checkState(binderContext.getMetaData().getDatabase(databaseName.getValue()).containsSchema(result.getValue()), + () -> new SchemaNotFoundException(result.getValue())); + return result; } private static IdentifierValue getSchemaName(final SimpleTableSegment segment, final SQLStatementBinderContext binderContext) { @@ -101,7 +115,7 @@ private static IdentifierValue getSchemaName(final SimpleTableSegment segment, f return segment.getOwner().get().getIdentifier(); } // TODO getSchemaName according to search path - DatabaseType databaseType = binderContext.getDatabaseType(); + DatabaseType databaseType = binderContext.getSqlStatement().getDatabaseType(); if ((databaseType instanceof PostgreSQLDatabaseType || databaseType instanceof OpenGaussDatabaseType) && SystemSchemaManager.isSystemTable(databaseType.getType(), PG_CATALOG, segment.getTableName().getIdentifier().getValue())) { return new IdentifierValue(PG_CATALOG); @@ -109,8 +123,13 @@ private static IdentifierValue getSchemaName(final SimpleTableSegment segment, f return new IdentifierValue(new DatabaseTypeRegistry(databaseType).getDefaultSchemaName(binderContext.getCurrentDatabaseName())); } - private static void checkTableExists(final SQLStatementBinderContext binderContext, final String databaseName, final String schemaName, final String tableName) { - if ("dual".equalsIgnoreCase(tableName)) { + private static void checkTableExists(final SQLStatementBinderContext binderContext, final ShardingSphereSchema schema, final String schemaName, final String tableName) { + if (binderContext.getSqlStatement() instanceof CreateTableStatement) { + CreateTableStatement sqlStatement = (CreateTableStatement) binderContext.getSqlStatement(); + ShardingSpherePreconditions.checkState(sqlStatement.isIfNotExists() || !schema.containsTable(tableName), () -> new TableExistsException(tableName)); + return; + } + if ("DUAL".equalsIgnoreCase(tableName)) { return; } if (SystemSchemaManager.isSystemTable(schemaName, tableName)) { @@ -119,10 +138,7 @@ private static void checkTableExists(final SQLStatementBinderContext binderConte if (binderContext.getExternalTableBinderContexts().containsKey(new CaseInsensitiveString(tableName))) { return; } - ShardingSpherePreconditions.checkState(binderContext.getMetaData().containsDatabase(databaseName) - && binderContext.getMetaData().getDatabase(databaseName).containsSchema(schemaName) - && binderContext.getMetaData().getDatabase(databaseName).getSchema(schemaName).containsTable(tableName), - () -> new TableNotFoundException(tableName)); + ShardingSpherePreconditions.checkState(schema.containsTable(tableName), () -> new TableNotFoundException(tableName)); } private static SimpleTableSegmentBinderContext createSimpleTableBinderContext(final SimpleTableSegment segment, final ShardingSphereSchema schema, final IdentifierValue databaseName, @@ -131,14 +147,27 @@ private static SimpleTableSegmentBinderContext createSimpleTableBinderContext(fi if (binderContext.getMetaData().getDatabase(databaseName.getValue()).getSchema(schemaName.getValue()).containsTable(tableName.getValue())) { return createSimpleTableSegmentBinderContextWithMetaData(segment, schema, databaseName, schemaName, binderContext, tableName); } + if (binderContext.getSqlStatement() instanceof CreateTableStatement) { + return new SimpleTableSegmentBinderContext(createProjectionSegments((CreateTableStatement) binderContext.getSqlStatement(), databaseName, schemaName, tableName)); + } return new SimpleTableSegmentBinderContext(Collections.emptyList()); } + private static Collection createProjectionSegments(final CreateTableStatement sqlStatement, final IdentifierValue databaseName, + final IdentifierValue schemaName, final IdentifierValue tableName) { + Collection result = new LinkedList<>(); + for (ColumnDefinitionSegment each : sqlStatement.getColumnDefinitions()) { + each.getColumnName().setColumnBoundInfo(new ColumnSegmentBoundInfo(new TableSegmentBoundInfo(databaseName, schemaName), tableName, each.getColumnName().getIdentifier())); + result.add(new ColumnProjectionSegment(each.getColumnName())); + } + return result; + } + private static SimpleTableSegmentBinderContext createSimpleTableSegmentBinderContextWithMetaData(final SimpleTableSegment segment, final ShardingSphereSchema schema, final IdentifierValue databaseName, final IdentifierValue schemaName, final SQLStatementBinderContext binderContext, final IdentifierValue tableName) { Collection projectionSegments = new LinkedList<>(); - QuoteCharacter quoteCharacter = new DatabaseTypeRegistry(binderContext.getDatabaseType()).getDialectDatabaseMetaData().getQuoteCharacter(); + QuoteCharacter quoteCharacter = new DatabaseTypeRegistry(binderContext.getSqlStatement().getDatabaseType()).getDialectDatabaseMetaData().getQuoteCharacter(); for (ShardingSphereColumn each : schema.getTable(tableName.getValue()).getAllColumns()) { ColumnProjectionSegment columnProjectionSegment = new ColumnProjectionSegment(createColumnSegment(segment, databaseName, schemaName, each, quoteCharacter, tableName)); columnProjectionSegment.setVisible(each.isVisible()); diff --git a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/from/type/SubqueryTableSegmentBinder.java b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/from/type/SubqueryTableSegmentBinder.java index fd056f567f1be..bd8b3ae73629f 100644 --- a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/from/type/SubqueryTableSegmentBinder.java +++ b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/from/type/SubqueryTableSegmentBinder.java @@ -51,7 +51,7 @@ public static SubqueryTableSegment bind(final SubqueryTableSegment segment, fina final Multimap tableBinderContexts, final Multimap outerTableBinderContexts) { fillPivotColumnNamesInBinderContext(segment, binderContext); - SQLStatementBinderContext subqueryBinderContext = new SQLStatementBinderContext(segment.getSubquery().getSelect(), binderContext.getMetaData(), binderContext.getCurrentDatabaseName()); + SQLStatementBinderContext subqueryBinderContext = new SQLStatementBinderContext(binderContext.getMetaData(), binderContext.getCurrentDatabaseName(), segment.getSubquery().getSelect()); subqueryBinderContext.getExternalTableBinderContexts().putAll(binderContext.getExternalTableBinderContexts()); SelectStatement boundSubSelect = new SelectStatementBinder(outerTableBinderContexts).bind(segment.getSubquery().getSelect(), subqueryBinderContext); SubquerySegment boundSubquerySegment = new SubquerySegment(segment.getSubquery().getStartIndex(), segment.getSubquery().getStopIndex(), boundSubSelect, segment.getSubquery().getText()); @@ -59,7 +59,7 @@ public static SubqueryTableSegment bind(final SubqueryTableSegment segment, fina SubqueryTableSegment result = new SubqueryTableSegment(segment.getStartIndex(), segment.getStopIndex(), boundSubquerySegment); segment.getAliasSegment().ifPresent(result::setAlias); tableBinderContexts.put(new CaseInsensitiveString(subqueryTableName.getValue()), new SimpleTableSegmentBinderContext( - SubqueryTableBindUtils.createSubqueryProjections(boundSubSelect.getProjections().getProjections(), subqueryTableName, binderContext.getDatabaseType()))); + SubqueryTableBindUtils.createSubqueryProjections(boundSubSelect.getProjections().getProjections(), subqueryTableName, binderContext.getSqlStatement().getDatabaseType()))); return result; } diff --git a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/statement/SQLStatementBinderContext.java b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/statement/SQLStatementBinderContext.java index 10d28175fa81e..172660b6ed5fc 100644 --- a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/statement/SQLStatementBinderContext.java +++ b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/statement/SQLStatementBinderContext.java @@ -24,7 +24,6 @@ import lombok.Getter; import lombok.RequiredArgsConstructor; import org.apache.shardingsphere.infra.binder.engine.segment.from.context.TableSegmentBinderContext; -import org.apache.shardingsphere.infra.database.core.type.DatabaseType; import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData; import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.ProjectionSegment; import org.apache.shardingsphere.sql.parser.statement.core.statement.SQLStatement; @@ -43,9 +42,7 @@ public final class SQLStatementBinderContext { private final String currentDatabaseName; - private final DatabaseType databaseType; - - private final Collection variableNames; + private final SQLStatement sqlStatement; private final Collection usingColumnNames = new CaseInsensitiveSet<>(); @@ -54,11 +51,4 @@ public final class SQLStatementBinderContext { private final Multimap externalTableBinderContexts = LinkedHashMultimap.create(); private final Collection pivotColumnNames = new CaseInsensitiveSet<>(); - - public SQLStatementBinderContext(final SQLStatement sqlStatement, final ShardingSphereMetaData metaData, final String currentDatabaseName) { - this.metaData = metaData; - this.currentDatabaseName = currentDatabaseName; - databaseType = sqlStatement.getDatabaseType(); - variableNames = new CaseInsensitiveSet<>(sqlStatement.getVariableNames()); - } } diff --git a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/statement/ddl/CreateTableStatementBinder.java b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/statement/ddl/CreateTableStatementBinder.java new file mode 100644 index 0000000000000..99960f4fb5409 --- /dev/null +++ b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/statement/ddl/CreateTableStatementBinder.java @@ -0,0 +1,59 @@ +/* + * 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.column.ColumnDefinitionSegmentBinder; +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.infra.binder.engine.statement.dml.SelectStatementBinder; +import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.CreateTableStatement; + +/** + * Create table statement binder. + */ +public final class CreateTableStatementBinder implements SQLStatementBinder { + + @Override + public CreateTableStatement bind(final CreateTableStatement sqlStatement, final SQLStatementBinderContext binderContext) { + CreateTableStatement result = copy(sqlStatement); + Multimap tableBinderContexts = LinkedHashMultimap.create(); + result.setTable(SimpleTableSegmentBinder.bind(sqlStatement.getTable(), binderContext, tableBinderContexts)); + sqlStatement.getSelectStatement().ifPresent(optional -> result.setSelectStatement(new SelectStatementBinder().bind(optional, binderContext))); + sqlStatement.getColumnDefinitions().forEach(each -> result.getColumnDefinitions().add(ColumnDefinitionSegmentBinder.bind(each, binderContext, tableBinderContexts))); + return result; + } + + @SneakyThrows(ReflectiveOperationException.class) + private static CreateTableStatement copy(final CreateTableStatement sqlStatement) { + CreateTableStatement result = sqlStatement.getClass().getDeclaredConstructor().newInstance(); + result.getConstraintDefinitions().addAll(sqlStatement.getConstraintDefinitions()); + result.addParameterMarkerSegments(sqlStatement.getParameterMarkerSegments()); + result.setIfNotExists(sqlStatement.isIfNotExists()); + result.getColumns().addAll(sqlStatement.getColumns()); + sqlStatement.getLikeTable().ifPresent(result::setLikeTable); + sqlStatement.getCreateTableOption().ifPresent(result::setCreateTableOption); + result.getCommentSegments().addAll(sqlStatement.getCommentSegments()); + return result; + } +} diff --git a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/type/DDLStatementBindEngine.java b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/type/DDLStatementBindEngine.java index db899e183b37e..66a5f0215532f 100644 --- a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/type/DDLStatementBindEngine.java +++ b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/type/DDLStatementBindEngine.java @@ -19,8 +19,10 @@ import lombok.RequiredArgsConstructor; import org.apache.shardingsphere.infra.binder.engine.statement.SQLStatementBinderContext; +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.metadata.ShardingSphereMetaData; +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; @@ -41,10 +43,13 @@ public final class DDLStatementBindEngine { * @return bound DDL statement */ public DDLStatement bind(final DDLStatement statement) { - SQLStatementBinderContext binderContext = new SQLStatementBinderContext(statement, metaData, currentDatabaseName); + SQLStatementBinderContext binderContext = new SQLStatementBinderContext(metaData, currentDatabaseName, statement); if (statement instanceof CursorStatement) { return new CursorStatementBinder().bind((CursorStatement) statement, binderContext); } + if (statement instanceof CreateTableStatement) { + return new CreateTableStatementBinder().bind((CreateTableStatement) statement, binderContext); + } return statement; } } diff --git a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/type/DMLStatementBindEngine.java b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/type/DMLStatementBindEngine.java index 4500a020a86d4..00a1688655de2 100644 --- a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/type/DMLStatementBindEngine.java +++ b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/type/DMLStatementBindEngine.java @@ -47,7 +47,7 @@ public final class DMLStatementBindEngine { * @return bound DML statement */ public DMLStatement bind(final DMLStatement statement) { - SQLStatementBinderContext binderContext = new SQLStatementBinderContext(statement, metaData, currentDatabaseName); + SQLStatementBinderContext binderContext = new SQLStatementBinderContext(metaData, currentDatabaseName, statement); if (statement instanceof SelectStatement) { return new SelectStatementBinder().bind((SelectStatement) statement, binderContext); } diff --git a/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/engine/segment/expression/type/ColumnSegmentBinderTest.java b/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/engine/segment/expression/type/ColumnSegmentBinderTest.java index 9952c36f686bf..bfaddcd17ba37 100644 --- a/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/engine/segment/expression/type/ColumnSegmentBinderTest.java +++ b/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/engine/segment/expression/type/ColumnSegmentBinderTest.java @@ -33,6 +33,7 @@ import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.OwnerSegment; import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.bound.ColumnSegmentBoundInfo; import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.bound.TableSegmentBoundInfo; +import org.apache.shardingsphere.sql.parser.statement.core.statement.dml.SelectStatement; import org.apache.shardingsphere.sql.parser.statement.core.value.identifier.IdentifierValue; import org.junit.jupiter.api.Test; @@ -45,6 +46,7 @@ import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; class ColumnSegmentBinderTest { @@ -62,8 +64,9 @@ void assertBindWithMultiTablesJoinAndNoOwner() { new IdentifierValue("t_order_item"), new IdentifierValue("item_id"))); tableBinderContexts.put(new CaseInsensitiveString("t_order_item"), new SimpleTableSegmentBinderContext(Collections.singleton(new ColumnProjectionSegment(boundItemIdColumn)))); ColumnSegment columnSegment = new ColumnSegment(0, 0, new IdentifierValue("order_id")); - SQLStatementBinderContext binderContext = - new SQLStatementBinderContext(mock(ShardingSphereMetaData.class), "foo_db", databaseType, Collections.emptySet()); + SelectStatement selectStatement = mock(SelectStatement.class); + when(selectStatement.getDatabaseType()).thenReturn(databaseType); + SQLStatementBinderContext binderContext = new SQLStatementBinderContext(mock(ShardingSphereMetaData.class), "foo_db", selectStatement); ColumnSegment actual = ColumnSegmentBinder.bind(columnSegment, SegmentType.JOIN_ON, binderContext, tableBinderContexts, LinkedHashMultimap.create()); assertNotNull(actual.getColumnBoundInfo()); assertNull(actual.getOtherUsingColumnBoundInfo()); @@ -84,8 +87,9 @@ void assertBindFromOuterTable() { boundOrderItemStatusColumn.setColumnBoundInfo(new ColumnSegmentBoundInfo(new TableSegmentBoundInfo(new IdentifierValue("foo_db"), new IdentifierValue("foo_schema")), new IdentifierValue("t_order_item"), new IdentifierValue("status"))); outerTableBinderContexts.put(new CaseInsensitiveString("t_order_item"), new SimpleTableSegmentBinderContext(Collections.singleton(new ColumnProjectionSegment(boundOrderItemStatusColumn)))); - SQLStatementBinderContext binderContext = - new SQLStatementBinderContext(mock(ShardingSphereMetaData.class), "foo_db", databaseType, Collections.emptySet()); + SelectStatement selectStatement = mock(SelectStatement.class); + when(selectStatement.getDatabaseType()).thenReturn(databaseType); + SQLStatementBinderContext binderContext = new SQLStatementBinderContext(mock(ShardingSphereMetaData.class), "foo_db", selectStatement); ColumnSegment columnSegment = new ColumnSegment(0, 0, new IdentifierValue("status")); ColumnSegment actual = ColumnSegmentBinder.bind(columnSegment, SegmentType.PROJECTION, binderContext, LinkedHashMultimap.create(), outerTableBinderContexts); assertNotNull(actual.getColumnBoundInfo()); @@ -107,8 +111,9 @@ void assertBindWithSameTableAliasAndSameProjection() { boundOrderItemColumn.setColumnBoundInfo(new ColumnSegmentBoundInfo(new TableSegmentBoundInfo(new IdentifierValue("foo_db"), new IdentifierValue("foo_schema")), new IdentifierValue("t_order_item"), new IdentifierValue("status"))); tableBinderContexts.put(new CaseInsensitiveString("temp"), new SimpleTableSegmentBinderContext(Collections.singleton(new ColumnProjectionSegment(boundOrderItemColumn)))); - SQLStatementBinderContext binderContext = - new SQLStatementBinderContext(mock(ShardingSphereMetaData.class), "foo_db", databaseType, Collections.emptySet()); + SelectStatement selectStatement = mock(SelectStatement.class); + when(selectStatement.getDatabaseType()).thenReturn(databaseType); + SQLStatementBinderContext binderContext = new SQLStatementBinderContext(mock(ShardingSphereMetaData.class), "foo_db", selectStatement); ColumnSegment columnSegment = new ColumnSegment(0, 0, new IdentifierValue("status")); columnSegment.setOwner(new OwnerSegment(0, 0, new IdentifierValue("temp"))); assertThrows(AmbiguousColumnException.class, () -> ColumnSegmentBinder.bind(columnSegment, SegmentType.PROJECTION, binderContext, tableBinderContexts, LinkedHashMultimap.create())); @@ -125,8 +130,9 @@ void assertBindWithSameTableAliasAndDifferentProjection() { boundOrderItemColumn.setColumnBoundInfo(new ColumnSegmentBoundInfo(new TableSegmentBoundInfo(new IdentifierValue("foo_db"), new IdentifierValue("foo_schema")), new IdentifierValue("t_order_item"), new IdentifierValue("status"))); tableBinderContexts.put(new CaseInsensitiveString("temp"), new SimpleTableSegmentBinderContext(Collections.singleton(new ColumnProjectionSegment(boundOrderItemColumn)))); - SQLStatementBinderContext binderContext = - new SQLStatementBinderContext(mock(ShardingSphereMetaData.class), "foo_db", databaseType, Collections.emptySet()); + SelectStatement selectStatement = mock(SelectStatement.class); + when(selectStatement.getDatabaseType()).thenReturn(databaseType); + SQLStatementBinderContext binderContext = new SQLStatementBinderContext(mock(ShardingSphereMetaData.class), "foo_db", selectStatement); ColumnSegment columnSegment = new ColumnSegment(0, 0, new IdentifierValue("status")); columnSegment.setOwner(new OwnerSegment(0, 0, new IdentifierValue("temp"))); ColumnSegment actual = ColumnSegmentBinder.bind(columnSegment, SegmentType.PROJECTION, binderContext, tableBinderContexts, LinkedHashMultimap.create()); @@ -151,8 +157,9 @@ void assertBindOwner() { tableBinderContexts.put(new CaseInsensitiveString("t_order_item"), new SimpleTableSegmentBinderContext(Collections.singleton(new ColumnProjectionSegment(boundItemIdColumn)))); ColumnSegment columnSegment = new ColumnSegment(0, 0, new IdentifierValue("order_id")); columnSegment.setOwner(new OwnerSegment(0, 0, new IdentifierValue("t_order"))); - SQLStatementBinderContext binderContext = - new SQLStatementBinderContext(mock(ShardingSphereMetaData.class), "foo_db", databaseType, Collections.emptySet()); + SelectStatement selectStatement = mock(SelectStatement.class); + when(selectStatement.getDatabaseType()).thenReturn(databaseType); + SQLStatementBinderContext binderContext = new SQLStatementBinderContext(mock(ShardingSphereMetaData.class), "foo_db", selectStatement); ColumnSegment actual = ColumnSegmentBinder.bind(columnSegment, SegmentType.JOIN_ON, binderContext, tableBinderContexts, LinkedHashMultimap.create()); assertTrue(actual.getOwner().isPresent()); assertTrue(actual.getOwner().get().getTableBoundInfo().isPresent()); diff --git a/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/engine/segment/expression/type/ExistsSubqueryExpressionBinderTest.java b/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/engine/segment/expression/type/ExistsSubqueryExpressionBinderTest.java index b8ace4d0b9cac..ce3d1b7b2a28f 100644 --- a/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/engine/segment/expression/type/ExistsSubqueryExpressionBinderTest.java +++ b/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/engine/segment/expression/type/ExistsSubqueryExpressionBinderTest.java @@ -23,12 +23,10 @@ import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.ExistsSubqueryExpression; import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.subquery.SubquerySegment; import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.ProjectionsSegment; +import org.apache.shardingsphere.sql.parser.statement.core.statement.SQLStatement; import org.apache.shardingsphere.sql.parser.statement.mysql.dml.MySQLSelectStatement; -import org.apache.shardingsphere.test.fixture.database.MockedDatabaseType; import org.junit.jupiter.api.Test; -import java.util.Collections; - import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; import static org.mockito.Mockito.mock; @@ -40,7 +38,7 @@ void assertBindExistsSubqueryExpression() { MySQLSelectStatement selectStatement = new MySQLSelectStatement(); selectStatement.setProjections(new ProjectionsSegment(0, 0)); ExistsSubqueryExpression existsSubqueryExpression = new ExistsSubqueryExpression(0, 0, new SubquerySegment(0, 0, selectStatement, "t_test")); - SQLStatementBinderContext binderContext = new SQLStatementBinderContext(mock(ShardingSphereMetaData.class), "foo_db", new MockedDatabaseType(), Collections.emptyList()); + SQLStatementBinderContext binderContext = new SQLStatementBinderContext(mock(ShardingSphereMetaData.class), "foo_db", mock(SQLStatement.class)); ExistsSubqueryExpression actual = ExistsSubqueryExpressionBinder.bind(existsSubqueryExpression, binderContext, LinkedHashMultimap.create()); assertThat(actual.getStartIndex(), is(existsSubqueryExpression.getStartIndex())); assertThat(actual.getStopIndex(), is(existsSubqueryExpression.getStopIndex())); diff --git a/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/engine/segment/expression/type/FunctionExpressionSegmentBinderTest.java b/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/engine/segment/expression/type/FunctionExpressionSegmentBinderTest.java index de1c871ded843..699ad7cc12923 100644 --- a/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/engine/segment/expression/type/FunctionExpressionSegmentBinderTest.java +++ b/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/engine/segment/expression/type/FunctionExpressionSegmentBinderTest.java @@ -22,20 +22,19 @@ import org.apache.shardingsphere.infra.binder.engine.statement.SQLStatementBinderContext; import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData; import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.FunctionSegment; -import org.apache.shardingsphere.test.fixture.database.MockedDatabaseType; +import org.apache.shardingsphere.sql.parser.statement.core.statement.SQLStatement; import org.junit.jupiter.api.Test; -import java.util.Collections; - import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; +import static org.mockito.Mockito.mock; class FunctionExpressionSegmentBinderTest { @Test void assertBindFunctionExpressionSegment() { FunctionSegment functionSegment = new FunctionSegment(0, 0, "CONCAT", "('%','abc','%')"); - SQLStatementBinderContext binderContext = new SQLStatementBinderContext(new ShardingSphereMetaData(), "foo_db", new MockedDatabaseType(), Collections.emptyList()); + SQLStatementBinderContext binderContext = new SQLStatementBinderContext(new ShardingSphereMetaData(), "foo_db", mock(SQLStatement.class)); FunctionSegment actual = FunctionExpressionSegmentBinder.bind(functionSegment, SegmentType.PROJECTION, binderContext, LinkedHashMultimap.create(), LinkedHashMultimap.create()); assertThat(actual.getStartIndex(), is(functionSegment.getStartIndex())); assertThat(actual.getStopIndex(), is(functionSegment.getStopIndex())); diff --git a/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/engine/segment/expression/type/SubquerySegmentBinderTest.java b/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/engine/segment/expression/type/SubquerySegmentBinderTest.java index 96fa3d2005521..f879f813eac35 100644 --- a/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/engine/segment/expression/type/SubquerySegmentBinderTest.java +++ b/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/engine/segment/expression/type/SubquerySegmentBinderTest.java @@ -23,11 +23,9 @@ import org.apache.shardingsphere.infra.binder.engine.segment.from.context.TableSegmentBinderContext; import org.apache.shardingsphere.infra.binder.engine.segment.from.context.type.SimpleTableSegmentBinderContext; import org.apache.shardingsphere.infra.binder.engine.statement.SQLStatementBinderContext; -import org.apache.shardingsphere.infra.database.core.type.DatabaseType; import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData; import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereColumn; import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereSchema; -import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader; import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.column.ColumnSegment; import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.ExpressionSegment; import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.subquery.SubquerySegment; @@ -39,6 +37,7 @@ 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.SQLStatement; import org.apache.shardingsphere.sql.parser.statement.core.value.identifier.IdentifierValue; import org.apache.shardingsphere.sql.parser.statement.mysql.dml.MySQLSelectStatement; import org.junit.jupiter.api.Test; @@ -69,8 +68,7 @@ void assertBind() { ExpressionSegment whereExpressionSegment = new ColumnSegment(86, 91, new IdentifierValue("status")); mysqlSelectStatement.setWhere(new WhereSegment(80, 102, whereExpressionSegment)); SubquerySegment subquerySegment = new SubquerySegment(39, 103, mysqlSelectStatement, "order_id = (SELECT order_id FROM t_order WHERE status = 'SUBMIT')"); - SQLStatementBinderContext sqlStatementBinderContext = new SQLStatementBinderContext( - createMetaData(), "foo_db", TypedSPILoader.getService(DatabaseType.class, "FIXTURE"), Collections.emptySet()); + SQLStatementBinderContext sqlStatementBinderContext = new SQLStatementBinderContext(createMetaData(), "foo_db", mock(SQLStatement.class)); ColumnSegment boundNameColumn = new ColumnSegment(7, 13, new IdentifierValue("user_id")); boundNameColumn.setColumnBoundInfo(new ColumnSegmentBoundInfo(new TableSegmentBoundInfo( new IdentifierValue("foo_db"), new IdentifierValue("foo_db")), new IdentifierValue("t_order_item"), new IdentifierValue("user_id"))); diff --git a/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/engine/segment/from/type/JoinTableSegmentBinderTest.java b/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/engine/segment/from/type/JoinTableSegmentBinderTest.java index be8f8ad761323..785990cce8ef4 100644 --- a/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/engine/segment/from/type/JoinTableSegmentBinderTest.java +++ b/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/engine/segment/from/type/JoinTableSegmentBinderTest.java @@ -35,6 +35,7 @@ import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.JoinTableSegment; 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.dml.SelectStatement; import org.apache.shardingsphere.sql.parser.statement.core.value.identifier.IdentifierValue; import org.junit.jupiter.api.Test; @@ -42,7 +43,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; -import java.util.Collections; import java.util.List; import static org.hamcrest.CoreMatchers.instanceOf; @@ -68,8 +68,9 @@ void assertBindWithAlias() { when(joinTableSegment.getRight()).thenReturn(rightTable); ShardingSphereMetaData metaData = createMetaData(); Multimap tableBinderContexts = LinkedHashMultimap.create(); - JoinTableSegment actual = JoinTableSegmentBinder.bind( - joinTableSegment, new SQLStatementBinderContext(metaData, "foo_db", databaseType, Collections.emptySet()), tableBinderContexts, LinkedHashMultimap.create()); + SelectStatement selectStatement = mock(SelectStatement.class); + when(selectStatement.getDatabaseType()).thenReturn(databaseType); + JoinTableSegment actual = JoinTableSegmentBinder.bind(joinTableSegment, new SQLStatementBinderContext(metaData, "foo_db", selectStatement), tableBinderContexts, LinkedHashMultimap.create()); assertThat(actual.getLeft(), instanceOf(SimpleTableSegment.class)); assertThat(actual.getRight(), instanceOf(SimpleTableSegment.class)); assertJoinTableProjectionSegments(actual.getDerivedJoinTableProjectionSegments()); @@ -106,8 +107,9 @@ void assertBindWithoutAlias() { when(joinTableSegment.getRight()).thenReturn(rightTable); ShardingSphereMetaData metaData = createMetaData(); Multimap tableBinderContexts = LinkedHashMultimap.create(); - JoinTableSegment actual = JoinTableSegmentBinder.bind(joinTableSegment, new SQLStatementBinderContext(metaData, "foo_db", databaseType, Collections.emptySet()), - tableBinderContexts, LinkedHashMultimap.create()); + SelectStatement selectStatement = mock(SelectStatement.class); + when(selectStatement.getDatabaseType()).thenReturn(databaseType); + JoinTableSegment actual = JoinTableSegmentBinder.bind(joinTableSegment, new SQLStatementBinderContext(metaData, "foo_db", selectStatement), tableBinderContexts, LinkedHashMultimap.create()); assertThat(actual.getLeft(), instanceOf(SimpleTableSegment.class)); assertThat(actual.getRight(), instanceOf(SimpleTableSegment.class)); assertJoinTableProjectionSegments(actual.getDerivedJoinTableProjectionSegments()); @@ -128,8 +130,9 @@ void assertBindWithNaturalJoin() { when(joinTableSegment.getJoinType()).thenReturn(JoinType.RIGHT.name()); ShardingSphereMetaData metaData = createMetaData(); Multimap tableBinderContexts = LinkedHashMultimap.create(); - JoinTableSegment actual = JoinTableSegmentBinder.bind(joinTableSegment, new SQLStatementBinderContext(metaData, "foo_db", databaseType, Collections.emptySet()), - tableBinderContexts, LinkedHashMultimap.create()); + SelectStatement selectStatement = mock(SelectStatement.class); + when(selectStatement.getDatabaseType()).thenReturn(databaseType); + JoinTableSegment actual = JoinTableSegmentBinder.bind(joinTableSegment, new SQLStatementBinderContext(metaData, "foo_db", selectStatement), tableBinderContexts, LinkedHashMultimap.create()); assertThat(actual.getLeft(), instanceOf(SimpleTableSegment.class)); assertThat(actual.getRight(), instanceOf(SimpleTableSegment.class)); assertJoinTableProjectionSegmentsWithNaturalJoin(actual.getDerivedJoinTableProjectionSegments()); @@ -164,8 +167,9 @@ void assertBindWithJoinUsing() { when(joinTableSegment.getUsing()).thenReturn(Arrays.asList(new ColumnSegment(0, 0, new IdentifierValue("status")), new ColumnSegment(0, 0, new IdentifierValue("order_id")))); ShardingSphereMetaData metaData = createMetaData(); Multimap tableBinderContexts = LinkedHashMultimap.create(); - JoinTableSegment actual = JoinTableSegmentBinder.bind(joinTableSegment, new SQLStatementBinderContext(metaData, "foo_db", databaseType, Collections.emptySet()), - tableBinderContexts, LinkedHashMultimap.create()); + SelectStatement selectStatement = mock(SelectStatement.class); + when(selectStatement.getDatabaseType()).thenReturn(databaseType); + JoinTableSegment actual = JoinTableSegmentBinder.bind(joinTableSegment, new SQLStatementBinderContext(metaData, "foo_db", selectStatement), tableBinderContexts, LinkedHashMultimap.create()); assertThat(actual.getLeft(), instanceOf(SimpleTableSegment.class)); assertThat(actual.getRight(), instanceOf(SimpleTableSegment.class)); assertJoinTableProjectionSegmentsWithUsing(actual.getDerivedJoinTableProjectionSegments()); @@ -199,8 +203,9 @@ void assertBindWithMultiTableJoin() { when(joinTableSegment.getRight()).thenReturn(rightTable); ShardingSphereMetaData metaData = createMetaData(); Multimap tableBinderContexts = LinkedHashMultimap.create(); - JoinTableSegment actual = JoinTableSegmentBinder.bind(joinTableSegment, - new SQLStatementBinderContext(metaData, "foo_db", databaseType, Collections.emptySet()), tableBinderContexts, LinkedHashMultimap.create()); + SelectStatement selectStatement = mock(SelectStatement.class); + when(selectStatement.getDatabaseType()).thenReturn(databaseType); + JoinTableSegment actual = JoinTableSegmentBinder.bind(joinTableSegment, new SQLStatementBinderContext(metaData, "foo_db", selectStatement), tableBinderContexts, LinkedHashMultimap.create()); assertThat(actual.getLeft(), instanceOf(JoinTableSegment.class)); assertThat(((JoinTableSegment) actual.getLeft()).getLeft(), instanceOf(SimpleTableSegment.class)); assertThat(((JoinTableSegment) actual.getLeft()).getRight(), instanceOf(SimpleTableSegment.class)); diff --git a/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/engine/segment/from/type/SimpleTableSegmentBinderTest.java b/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/engine/segment/from/type/SimpleTableSegmentBinderTest.java index e99a256dfd88a..f49fa42d257bc 100644 --- a/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/engine/segment/from/type/SimpleTableSegmentBinderTest.java +++ b/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/engine/segment/from/type/SimpleTableSegmentBinderTest.java @@ -30,12 +30,12 @@ import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader; 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.dml.SelectStatement; import org.apache.shardingsphere.sql.parser.statement.core.value.identifier.IdentifierValue; import org.junit.jupiter.api.Test; import java.sql.Types; import java.util.Arrays; -import java.util.Collections; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.Mockito.RETURNS_DEEP_STUBS; @@ -51,8 +51,9 @@ void assertBindTableNotExists() { SimpleTableSegment simpleTableSegment = new SimpleTableSegment(new TableNameSegment(0, 10, new IdentifierValue("t_not_exists"))); ShardingSphereMetaData metaData = createMetaData(); Multimap tableBinderContexts = LinkedHashMultimap.create(); - assertThrows(TableNotFoundException.class, () -> SimpleTableSegmentBinder.bind( - simpleTableSegment, new SQLStatementBinderContext(metaData, "foo_db", databaseType, Collections.emptySet()), tableBinderContexts)); + SelectStatement selectStatement = mock(SelectStatement.class); + when(selectStatement.getDatabaseType()).thenReturn(databaseType); + assertThrows(TableNotFoundException.class, () -> SimpleTableSegmentBinder.bind(simpleTableSegment, new SQLStatementBinderContext(metaData, "foo_db", selectStatement), tableBinderContexts)); } private ShardingSphereMetaData createMetaData() { diff --git a/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/engine/segment/from/type/SubqueryTableSegmentBinderTest.java b/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/engine/segment/from/type/SubqueryTableSegmentBinderTest.java index 3fd70d8bbd1bd..8cacd05fe7661 100644 --- a/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/engine/segment/from/type/SubqueryTableSegmentBinderTest.java +++ b/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/engine/segment/from/type/SubqueryTableSegmentBinderTest.java @@ -44,7 +44,6 @@ import java.sql.Types; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; import java.util.List; import java.util.Optional; @@ -73,8 +72,8 @@ void assertBindWithSubqueryTableAlias() { subqueryTableSegment.setAlias(new AliasSegment(0, 0, new IdentifierValue("temp"))); ShardingSphereMetaData metaData = createMetaData(); Multimap tableBinderContexts = LinkedHashMultimap.create(); - SubqueryTableSegment actual = SubqueryTableSegmentBinder.bind(subqueryTableSegment, new SQLStatementBinderContext(metaData, "foo_db", databaseType, Collections.emptySet()), - tableBinderContexts, LinkedHashMultimap.create()); + SubqueryTableSegment actual = + SubqueryTableSegmentBinder.bind(subqueryTableSegment, new SQLStatementBinderContext(metaData, "foo_db", selectStatement), tableBinderContexts, LinkedHashMultimap.create()); assertTrue(actual.getAlias().isPresent()); assertTrue(tableBinderContexts.containsKey(new CaseInsensitiveString("temp"))); List projectionSegments = new ArrayList<>(tableBinderContexts.get(new CaseInsensitiveString("temp")).iterator().next().getProjectionSegments()); @@ -107,8 +106,8 @@ void assertBindWithSubqueryProjectionAlias() { subqueryTableSegment.setAlias(new AliasSegment(0, 0, new IdentifierValue("temp"))); ShardingSphereMetaData metaData = createMetaData(); Multimap tableBinderContexts = LinkedHashMultimap.create(); - SubqueryTableSegment actual = SubqueryTableSegmentBinder.bind(subqueryTableSegment, new SQLStatementBinderContext(metaData, "foo_db", databaseType, Collections.emptySet()), - tableBinderContexts, LinkedHashMultimap.create()); + SubqueryTableSegment actual = + SubqueryTableSegmentBinder.bind(subqueryTableSegment, new SQLStatementBinderContext(metaData, "foo_db", selectStatement), tableBinderContexts, LinkedHashMultimap.create()); assertTrue(actual.getAlias().isPresent()); assertTrue(tableBinderContexts.containsKey(new CaseInsensitiveString("temp"))); List projectionSegments = new ArrayList<>(tableBinderContexts.get(new CaseInsensitiveString("temp")).iterator().next().getProjectionSegments()); @@ -130,8 +129,8 @@ void assertBindWithoutSubqueryTableAlias() { SubqueryTableSegment subqueryTableSegment = new SubqueryTableSegment(0, 0, new SubquerySegment(0, 0, selectStatement, "")); ShardingSphereMetaData metaData = createMetaData(); Multimap tableBinderContexts = LinkedHashMultimap.create(); - SubqueryTableSegment actual = SubqueryTableSegmentBinder.bind(subqueryTableSegment, new SQLStatementBinderContext(metaData, "foo_db", databaseType, Collections.emptySet()), - tableBinderContexts, LinkedHashMultimap.create()); + SubqueryTableSegment actual = + SubqueryTableSegmentBinder.bind(subqueryTableSegment, new SQLStatementBinderContext(metaData, "foo_db", selectStatement), tableBinderContexts, LinkedHashMultimap.create()); assertFalse(actual.getAlias().isPresent()); assertTrue(tableBinderContexts.containsKey(new CaseInsensitiveString(""))); } diff --git a/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/engine/statement/dml/DeleteStatementBinderTest.java b/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/engine/statement/dml/DeleteStatementBinderTest.java index 76f5b0cc1cf6a..8f3dd0b072805 100644 --- a/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/engine/statement/dml/DeleteStatementBinderTest.java +++ b/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/engine/statement/dml/DeleteStatementBinderTest.java @@ -53,7 +53,7 @@ void assertBind() { deleteStatement.setTable(simpleTableSegment); deleteStatement.setWhere(new WhereSegment(0, 0, new BinaryOperationExpression(0, 0, new ColumnSegment(0, 0, new IdentifierValue("status")), new LiteralExpressionSegment(0, 0, 0), "=", "status = 1"))); - DeleteStatement actual = new DeleteStatementBinder().bind(deleteStatement, new SQLStatementBinderContext(deleteStatement, createMetaData(), "foo_db")); + DeleteStatement actual = new DeleteStatementBinder().bind(deleteStatement, new SQLStatementBinderContext(createMetaData(), "foo_db", deleteStatement)); assertThat(actual, not(deleteStatement)); assertThat(actual.getTable(), not(deleteStatement.getTable())); assertThat(actual.getTable(), instanceOf(SimpleTableSegment.class)); diff --git a/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/engine/statement/dml/InsertStatementBinderTest.java b/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/engine/statement/dml/InsertStatementBinderTest.java index f830007032947..afd30cf79758a 100644 --- a/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/engine/statement/dml/InsertStatementBinderTest.java +++ b/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/engine/statement/dml/InsertStatementBinderTest.java @@ -61,7 +61,7 @@ void assertBindInsertValues() { new ColumnSegment(0, 0, new IdentifierValue("user_id")), new ColumnSegment(0, 0, new IdentifierValue("status"))))); insertStatement.getValues().add(new InsertValuesSegment(0, 0, Arrays.asList(new LiteralExpressionSegment(0, 0, 1), new LiteralExpressionSegment(0, 0, 1), new LiteralExpressionSegment(0, 0, "OK")))); - InsertStatement actual = new InsertStatementBinder().bind(insertStatement, new SQLStatementBinderContext(insertStatement, createMetaData(), "foo_db")); + InsertStatement actual = new InsertStatementBinder().bind(insertStatement, new SQLStatementBinderContext(createMetaData(), "foo_db", insertStatement)); assertThat(actual, not(insertStatement)); assertTrue(actual.getTable().isPresent()); assertTrue(insertStatement.getTable().isPresent()); @@ -106,7 +106,7 @@ void assertBindInsertSelectWithColumns() { insertStatement.setInsertSelect(new SubquerySegment(0, 0, subSelectStatement, "")); insertStatement.getValues().add(new InsertValuesSegment(0, 0, Arrays.asList(new LiteralExpressionSegment(0, 0, 1), new LiteralExpressionSegment(0, 0, 1), new LiteralExpressionSegment(0, 0, "OK")))); - InsertStatement actual = new InsertStatementBinder().bind(insertStatement, new SQLStatementBinderContext(insertStatement, createMetaData(), "foo_db")); + InsertStatement actual = new InsertStatementBinder().bind(insertStatement, new SQLStatementBinderContext(createMetaData(), "foo_db", insertStatement)); assertThat(actual, not(insertStatement)); assertTrue(actual.getTable().isPresent()); assertTrue(insertStatement.getTable().isPresent()); @@ -130,7 +130,7 @@ void assertBindInsertSelectWithoutColumns() { insertStatement.setInsertSelect(new SubquerySegment(0, 0, subSelectStatement, "")); insertStatement.getValues().add(new InsertValuesSegment(0, 0, Arrays.asList(new LiteralExpressionSegment(0, 0, 1), new LiteralExpressionSegment(0, 0, 1), new LiteralExpressionSegment(0, 0, "OK")))); - InsertStatement actual = new InsertStatementBinder().bind(insertStatement, new SQLStatementBinderContext(insertStatement, createMetaData(), "foo_db")); + InsertStatement actual = new InsertStatementBinder().bind(insertStatement, new SQLStatementBinderContext(createMetaData(), "foo_db", insertStatement)); assertThat(actual, not(insertStatement)); assertTrue(actual.getTable().isPresent()); assertTrue(insertStatement.getTable().isPresent()); diff --git a/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/engine/statement/dml/SelectStatementBinderTest.java b/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/engine/statement/dml/SelectStatementBinderTest.java index 8e9b71f140ba9..b1c7d2fa2a6db 100644 --- a/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/engine/statement/dml/SelectStatementBinderTest.java +++ b/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/engine/statement/dml/SelectStatementBinderTest.java @@ -66,7 +66,7 @@ void assertBind() { SimpleTableSegment simpleTableSegment = new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_order"))); selectStatement.setFrom(simpleTableSegment); selectStatement.setWhere(mockWhereSegment()); - SelectStatement actual = new SelectStatementBinder().bind(selectStatement, new SQLStatementBinderContext(selectStatement, createMetaData(), "foo_db")); + SelectStatement actual = new SelectStatementBinder().bind(selectStatement, new SQLStatementBinderContext(createMetaData(), "foo_db", selectStatement)); assertThat(actual, not(selectStatement)); assertTrue(actual.getFrom().isPresent()); assertThat(actual.getFrom().get(), not(simpleTableSegment)); diff --git a/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/engine/statement/dml/UpdateStatementBinderTest.java b/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/engine/statement/dml/UpdateStatementBinderTest.java index 1f9ed80ba46f0..d0eddea62c550 100644 --- a/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/engine/statement/dml/UpdateStatementBinderTest.java +++ b/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/engine/statement/dml/UpdateStatementBinderTest.java @@ -53,7 +53,7 @@ void assertBind() { updateStatement.setTable(simpleTableSegment); updateStatement.setWhere(new WhereSegment(0, 0, new BinaryOperationExpression(0, 0, new ColumnSegment(0, 0, new IdentifierValue("status")), new LiteralExpressionSegment(0, 0, 0), "=", "status = 1"))); - UpdateStatement actual = new UpdateStatementBinder().bind(updateStatement, new SQLStatementBinderContext(updateStatement, createMetaData(), "foo_db")); + UpdateStatement actual = new UpdateStatementBinder().bind(updateStatement, new SQLStatementBinderContext(createMetaData(), "foo_db", updateStatement)); assertThat(actual, not(updateStatement)); assertThat(actual.getTable(), not(updateStatement.getTable())); assertThat(actual.getTable(), instanceOf(SimpleTableSegment.class)); diff --git a/kernel/data-pipeline/core/src/main/java/org/apache/shardingsphere/data/pipeline/core/metadata/generator/PipelineDDLGenerator.java b/kernel/data-pipeline/core/src/main/java/org/apache/shardingsphere/data/pipeline/core/metadata/generator/PipelineDDLGenerator.java index d56e58ebc63e2..a0510de5440a6 100644 --- a/kernel/data-pipeline/core/src/main/java/org/apache/shardingsphere/data/pipeline/core/metadata/generator/PipelineDDLGenerator.java +++ b/kernel/data-pipeline/core/src/main/java/org/apache/shardingsphere/data/pipeline/core/metadata/generator/PipelineDDLGenerator.java @@ -18,6 +18,7 @@ package org.apache.shardingsphere.data.pipeline.core.metadata.generator; import com.google.common.base.Strings; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.shardingsphere.data.pipeline.core.sqlbuilder.dialect.DialectPipelineSQLBuilder; import org.apache.shardingsphere.infra.binder.context.statement.SQLStatementContext; @@ -32,6 +33,7 @@ import org.apache.shardingsphere.infra.database.core.spi.DatabaseTypedSPILoader; import org.apache.shardingsphere.infra.database.core.type.DatabaseType; import org.apache.shardingsphere.infra.hint.HintValueContext; +import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData; import org.apache.shardingsphere.infra.metadata.database.schema.util.IndexMetaDataUtils; import org.apache.shardingsphere.infra.parser.SQLParserEngine; import org.apache.shardingsphere.sql.parser.statement.core.segment.SQLSegment; @@ -55,11 +57,14 @@ /** * Pipeline DDL generator. */ +@RequiredArgsConstructor @Slf4j public final class PipelineDDLGenerator { private static final String SET_SEARCH_PATH_PREFIX = "set search_path"; + private final ShardingSphereMetaData metaData; + /** * Generate logic DDL. * @@ -129,7 +134,7 @@ private String decorateActualSQL(final String databaseName, final String targetT } private SQLStatementContext parseSQL(final String currentDatabaseName, final SQLParserEngine parserEngine, final String sql) { - return new SQLBindEngine(null, currentDatabaseName, new HintValueContext()).bind(parserEngine.parse(sql, true), Collections.emptyList()); + return new SQLBindEngine(metaData, currentDatabaseName, new HintValueContext()).bind(parserEngine.parse(sql, true), Collections.emptyList()); } private void appendFromIndexAndConstraint(final Map replaceMap, final String targetTableName, final SQLStatementContext sqlStatementContext) { diff --git a/kernel/data-pipeline/core/src/main/java/org/apache/shardingsphere/data/pipeline/core/preparer/datasource/PipelineJobDataSourcePreparer.java b/kernel/data-pipeline/core/src/main/java/org/apache/shardingsphere/data/pipeline/core/preparer/datasource/PipelineJobDataSourcePreparer.java index 20f9928dd7f40..2901c6164427e 100644 --- a/kernel/data-pipeline/core/src/main/java/org/apache/shardingsphere/data/pipeline/core/preparer/datasource/PipelineJobDataSourcePreparer.java +++ b/kernel/data-pipeline/core/src/main/java/org/apache/shardingsphere/data/pipeline/core/preparer/datasource/PipelineJobDataSourcePreparer.java @@ -31,6 +31,7 @@ import org.apache.shardingsphere.infra.database.core.spi.DatabaseTypedSPILoader; import org.apache.shardingsphere.infra.database.core.type.DatabaseType; import org.apache.shardingsphere.infra.database.core.type.DatabaseTypeRegistry; +import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData; import org.apache.shardingsphere.infra.parser.SQLParserEngine; import javax.sql.DataSource; @@ -110,7 +111,7 @@ public void prepareTargetTables(final PrepareTargetTablesParameter param) throws final long startTimeMillis = System.currentTimeMillis(); PipelineDataSourceManager dataSourceManager = param.getDataSourceManager(); for (CreateTableConfiguration each : param.getCreateTableConfigurations()) { - List createTargetTableSQL = getCreateTargetTableSQL(each, dataSourceManager, param.getSqlParserEngine()); + List createTargetTableSQL = getCreateTargetTableSQL(each, dataSourceManager, param.getSqlParserEngine(), param.getMetaData()); try (Connection targetConnection = dataSourceManager.getDataSource(each.getTargetDataSourceConfig()).getConnection()) { for (String sql : createTargetTableSQL) { executeTargetTableSQL(targetConnection, addIfNotExistsForCreateTableSQL(sql)); @@ -120,14 +121,14 @@ public void prepareTargetTables(final PrepareTargetTablesParameter param) throws log.info("prepareTargetTables cost {} ms", System.currentTimeMillis() - startTimeMillis); } - private List getCreateTargetTableSQL(final CreateTableConfiguration createTableConfig, - final PipelineDataSourceManager dataSourceManager, final SQLParserEngine sqlParserEngine) throws SQLException { + private List getCreateTargetTableSQL(final CreateTableConfiguration createTableConfig, final PipelineDataSourceManager dataSourceManager, + final SQLParserEngine sqlParserEngine, final ShardingSphereMetaData metaData) throws SQLException { DatabaseType databaseType = createTableConfig.getSourceDataSourceConfig().getDatabaseType(); DataSource sourceDataSource = dataSourceManager.getDataSource(createTableConfig.getSourceDataSourceConfig()); String schemaName = createTableConfig.getSourceName().getSchemaName(); String sourceTableName = createTableConfig.getSourceName().getTableName(); String targetTableName = createTableConfig.getTargetName().getTableName(); - return new PipelineDDLGenerator().generateLogicDDL(databaseType, sourceDataSource, schemaName, sourceTableName, targetTableName, sqlParserEngine); + return new PipelineDDLGenerator(metaData).generateLogicDDL(databaseType, sourceDataSource, schemaName, sourceTableName, targetTableName, sqlParserEngine); } private void executeTargetTableSQL(final Connection targetConnection, final String sql) throws SQLException { diff --git a/kernel/data-pipeline/core/src/main/java/org/apache/shardingsphere/data/pipeline/core/preparer/datasource/param/PrepareTargetTablesParameter.java b/kernel/data-pipeline/core/src/main/java/org/apache/shardingsphere/data/pipeline/core/preparer/datasource/param/PrepareTargetTablesParameter.java index 2648729988698..d9be8f69bdb2c 100644 --- a/kernel/data-pipeline/core/src/main/java/org/apache/shardingsphere/data/pipeline/core/preparer/datasource/param/PrepareTargetTablesParameter.java +++ b/kernel/data-pipeline/core/src/main/java/org/apache/shardingsphere/data/pipeline/core/preparer/datasource/param/PrepareTargetTablesParameter.java @@ -20,6 +20,7 @@ import lombok.Getter; import lombok.RequiredArgsConstructor; import org.apache.shardingsphere.data.pipeline.core.datasource.PipelineDataSourceManager; +import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData; import org.apache.shardingsphere.infra.parser.SQLParserEngine; import java.util.Collection; @@ -36,4 +37,6 @@ public final class PrepareTargetTablesParameter { private final PipelineDataSourceManager dataSourceManager; private final SQLParserEngine sqlParserEngine; + + private final ShardingSphereMetaData metaData; } diff --git a/kernel/data-pipeline/core/src/test/java/org/apache/shardingsphere/data/pipeline/core/preparer/datasource/PipelineJobDataSourcePreparerTest.java b/kernel/data-pipeline/core/src/test/java/org/apache/shardingsphere/data/pipeline/core/preparer/datasource/PipelineJobDataSourcePreparerTest.java index 7661cff53cd16..06d26a8cf5e54 100644 --- a/kernel/data-pipeline/core/src/test/java/org/apache/shardingsphere/data/pipeline/core/preparer/datasource/PipelineJobDataSourcePreparerTest.java +++ b/kernel/data-pipeline/core/src/test/java/org/apache/shardingsphere/data/pipeline/core/preparer/datasource/PipelineJobDataSourcePreparerTest.java @@ -22,6 +22,7 @@ import org.apache.shardingsphere.data.pipeline.core.preparer.datasource.param.PrepareTargetSchemasParameter; import org.apache.shardingsphere.data.pipeline.core.preparer.datasource.param.PrepareTargetTablesParameter; import org.apache.shardingsphere.infra.database.core.type.DatabaseType; +import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData; import org.apache.shardingsphere.infra.parser.SQLParserEngine; import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader; import org.junit.jupiter.api.Test; @@ -48,7 +49,7 @@ void assertPrepareTargetTables() { CreateTableConfiguration createTableConfig = mock(CreateTableConfiguration.class, RETURNS_DEEP_STUBS); when(createTableConfig.getSourceDataSourceConfig().getDatabaseType()).thenReturn(databaseType); PrepareTargetTablesParameter parameter = new PrepareTargetTablesParameter( - Collections.singleton(createTableConfig), mock(PipelineDataSourceManager.class, RETURNS_DEEP_STUBS), mock(SQLParserEngine.class)); + Collections.singleton(createTableConfig), mock(PipelineDataSourceManager.class, RETURNS_DEEP_STUBS), mock(SQLParserEngine.class), mock(ShardingSphereMetaData.class)); assertDoesNotThrow(() -> new PipelineJobDataSourcePreparer(databaseType).prepareTargetTables(parameter)); } } diff --git a/kernel/data-pipeline/scenario/migration/src/main/java/org/apache/shardingsphere/data/pipeline/scenario/migration/preparer/MigrationJobPreparer.java b/kernel/data-pipeline/scenario/migration/src/main/java/org/apache/shardingsphere/data/pipeline/scenario/migration/preparer/MigrationJobPreparer.java index a8e7e6c85e628..110ff5ac616a8 100644 --- a/kernel/data-pipeline/scenario/migration/src/main/java/org/apache/shardingsphere/data/pipeline/scenario/migration/preparer/MigrationJobPreparer.java +++ b/kernel/data-pipeline/scenario/migration/src/main/java/org/apache/shardingsphere/data/pipeline/scenario/migration/preparer/MigrationJobPreparer.java @@ -161,7 +161,7 @@ private void prepareTarget(final MigrationJobItemContext jobItemContext, final D ShardingSphereMetaData metaData = contextManager.getMetaDataContexts().getMetaData(); SQLParserEngine sqlParserEngine = metaData.getGlobalRuleMetaData().getSingleRule(SQLParserRule.class) .getSQLParserEngine(metaData.getDatabase(jobConfig.getTargetDatabaseName()).getProtocolType()); - preparer.prepareTargetTables(new PrepareTargetTablesParameter(createTableConfigs, dataSourceManager, sqlParserEngine)); + preparer.prepareTargetTables(new PrepareTargetTablesParameter(createTableConfigs, dataSourceManager, sqlParserEngine, metaData)); } private void prepareIncremental(final MigrationJobItemContext jobItemContext) { diff --git a/kernel/single/core/src/test/java/org/apache/shardingsphere/single/route/SingleSQLRouterTest.java b/kernel/single/core/src/test/java/org/apache/shardingsphere/single/route/SingleSQLRouterTest.java index d14c60b38c4ab..120096ee0723f 100644 --- a/kernel/single/core/src/test/java/org/apache/shardingsphere/single/route/SingleSQLRouterTest.java +++ b/kernel/single/core/src/test/java/org/apache/shardingsphere/single/route/SingleSQLRouterTest.java @@ -215,7 +215,8 @@ void assertDecorateRouteContextWithMultiDataSource() throws SQLException { } private QueryContext createQueryContext() { - CreateTableStatement createTableStatement = new MySQLCreateTableStatement(false); + CreateTableStatement createTableStatement = new MySQLCreateTableStatement(); + createTableStatement.setIfNotExists(false); TableNameSegment tableNameSegment = new TableNameSegment(1, 2, new IdentifierValue("t_order")); tableNameSegment.setTableBoundInfo(new TableSegmentBoundInfo(new IdentifierValue("foo_db"), new IdentifierValue("foo_schema"))); createTableStatement.setTable(new SimpleTableSegment(tableNameSegment)); diff --git a/kernel/single/core/src/test/java/org/apache/shardingsphere/single/route/engine/engine/SingleRouteEngineTest.java b/kernel/single/core/src/test/java/org/apache/shardingsphere/single/route/engine/engine/SingleRouteEngineTest.java index 0882a4dc1d0c0..0ed003fa0b611 100644 --- a/kernel/single/core/src/test/java/org/apache/shardingsphere/single/route/engine/engine/SingleRouteEngineTest.java +++ b/kernel/single/core/src/test/java/org/apache/shardingsphere/single/route/engine/engine/SingleRouteEngineTest.java @@ -95,7 +95,9 @@ private Collection mockQualifiedTables() { @Test void assertRouteWithoutSingleRule() throws SQLException { - SingleRouteEngine engine = new SingleRouteEngine(mockQualifiedTables(), new MySQLCreateTableStatement(false), mock(HintValueContext.class)); + MySQLCreateTableStatement sqlStatement = new MySQLCreateTableStatement(); + sqlStatement.setIfNotExists(false); + SingleRouteEngine engine = new SingleRouteEngine(mockQualifiedTables(), sqlStatement, mock(HintValueContext.class)); SingleRule singleRule = new SingleRule(new SingleRuleConfiguration(), "foo_db", new MySQLDatabaseType(), createDataSourceMap(), Collections.emptyList()); RouteContext routeContext = new RouteContext(); engine.route(routeContext, singleRule); @@ -110,7 +112,9 @@ void assertRouteWithoutSingleRule() throws SQLException { @Test void assertRouteWithDefaultSingleRule() throws SQLException { - SingleRouteEngine engine = new SingleRouteEngine(mockQualifiedTables(), new MySQLCreateTableStatement(false), mock(HintValueContext.class)); + MySQLCreateTableStatement sqlStatement = new MySQLCreateTableStatement(); + sqlStatement.setIfNotExists(false); + SingleRouteEngine engine = new SingleRouteEngine(mockQualifiedTables(), sqlStatement, mock(HintValueContext.class)); SingleRule singleRule = new SingleRule(new SingleRuleConfiguration(Collections.emptyList(), "ds_0"), "foo_db", new MySQLDatabaseType(), createDataSourceMap(), Collections.emptyList()); RouteContext routeContext = new RouteContext(); @@ -149,7 +153,8 @@ void assertRouteIfNotExistsDuplicateSingleTable() { } private SQLStatement mockStatement(final boolean ifNotExists) { - MySQLCreateTableStatement result = new MySQLCreateTableStatement(ifNotExists); + MySQLCreateTableStatement result = new MySQLCreateTableStatement(); + result.setIfNotExists(ifNotExists); result.setTable(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_order")))); return result; } diff --git a/kernel/transaction/core/src/test/java/org/apache/shardingsphere/transaction/util/AutoCommitUtilsTest.java b/kernel/transaction/core/src/test/java/org/apache/shardingsphere/transaction/util/AutoCommitUtilsTest.java index 249c5ec0efc8f..5890c64335935 100644 --- a/kernel/transaction/core/src/test/java/org/apache/shardingsphere/transaction/util/AutoCommitUtilsTest.java +++ b/kernel/transaction/core/src/test/java/org/apache/shardingsphere/transaction/util/AutoCommitUtilsTest.java @@ -41,7 +41,9 @@ void assertNeedOpenTransactionForSelectStatement() { @Test void assertNeedOpenTransactionForDDLOrDMLStatement() { - assertTrue(AutoCommitUtils.needOpenTransaction(new MySQLCreateTableStatement(true))); + MySQLCreateTableStatement sqlStatement = new MySQLCreateTableStatement(); + sqlStatement.setIfNotExists(true); + assertTrue(AutoCommitUtils.needOpenTransaction(sqlStatement)); assertTrue(AutoCommitUtils.needOpenTransaction(new MySQLInsertStatement())); } diff --git a/parser/sql/dialect/doris/src/main/java/org/apache/shardingsphere/sql/parser/doris/visitor/statement/type/DorisDDLStatementVisitor.java b/parser/sql/dialect/doris/src/main/java/org/apache/shardingsphere/sql/parser/doris/visitor/statement/type/DorisDDLStatementVisitor.java index aaaee7b031938..70609a7173230 100644 --- a/parser/sql/dialect/doris/src/main/java/org/apache/shardingsphere/sql/parser/doris/visitor/statement/type/DorisDDLStatementVisitor.java +++ b/parser/sql/dialect/doris/src/main/java/org/apache/shardingsphere/sql/parser/doris/visitor/statement/type/DorisDDLStatementVisitor.java @@ -253,8 +253,9 @@ public ASTNode visitDropDatabase(final DropDatabaseContext ctx) { @SuppressWarnings("unchecked") @Override public ASTNode visitCreateTable(final CreateTableContext ctx) { - DorisCreateTableStatement result = new DorisCreateTableStatement(null != ctx.ifNotExists()); + DorisCreateTableStatement result = new DorisCreateTableStatement(); result.setTable((SimpleTableSegment) visit(ctx.tableName())); + result.setIfNotExists(null != ctx.ifNotExists()); if (null != ctx.createDefinitionClause()) { CollectionValue createDefinitions = (CollectionValue) visit(ctx.createDefinitionClause()); for (CreateDefinitionSegment each : createDefinitions.getValue()) { diff --git a/parser/sql/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/statement/type/MySQLDDLStatementVisitor.java b/parser/sql/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/statement/type/MySQLDDLStatementVisitor.java index cbad47bb37fd2..97188a7353d38 100644 --- a/parser/sql/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/statement/type/MySQLDDLStatementVisitor.java +++ b/parser/sql/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/statement/type/MySQLDDLStatementVisitor.java @@ -17,9 +17,9 @@ package org.apache.shardingsphere.sql.parser.mysql.visitor.statement.type; +import com.google.common.base.Preconditions; import org.antlr.v4.runtime.ParserRuleContext; import org.antlr.v4.runtime.misc.Interval; -import com.google.common.base.Preconditions; import org.apache.shardingsphere.sql.parser.api.ASTNode; import org.apache.shardingsphere.sql.parser.api.visitor.statement.type.DDLStatementVisitor; import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.AddColumnContext; @@ -254,8 +254,9 @@ public ASTNode visitDropDatabase(final DropDatabaseContext ctx) { @SuppressWarnings("unchecked") @Override public ASTNode visitCreateTable(final CreateTableContext ctx) { - MySQLCreateTableStatement result = new MySQLCreateTableStatement(null != ctx.ifNotExists()); + MySQLCreateTableStatement result = new MySQLCreateTableStatement(); result.setTable((SimpleTableSegment) visit(ctx.tableName())); + result.setIfNotExists(null != ctx.ifNotExists()); if (null != ctx.createDefinitionClause()) { CollectionValue createDefinitions = (CollectionValue) visit(ctx.createDefinitionClause()); for (CreateDefinitionSegment each : createDefinitions.getValue()) { diff --git a/parser/sql/dialect/opengauss/src/main/java/org/apache/shardingsphere/sql/parser/opengauss/visitor/statement/type/OpenGaussDDLStatementVisitor.java b/parser/sql/dialect/opengauss/src/main/java/org/apache/shardingsphere/sql/parser/opengauss/visitor/statement/type/OpenGaussDDLStatementVisitor.java index 9561522a39b97..bc873d3a0b221 100644 --- a/parser/sql/dialect/opengauss/src/main/java/org/apache/shardingsphere/sql/parser/opengauss/visitor/statement/type/OpenGaussDDLStatementVisitor.java +++ b/parser/sql/dialect/opengauss/src/main/java/org/apache/shardingsphere/sql/parser/opengauss/visitor/statement/type/OpenGaussDDLStatementVisitor.java @@ -264,8 +264,9 @@ public final class OpenGaussDDLStatementVisitor extends OpenGaussStatementVisito @SuppressWarnings("unchecked") @Override public ASTNode visitCreateTable(final CreateTableContext ctx) { - OpenGaussCreateTableStatement result = new OpenGaussCreateTableStatement(null != ctx.ifNotExists()); + OpenGaussCreateTableStatement result = new OpenGaussCreateTableStatement(); result.setTable((SimpleTableSegment) visit(ctx.tableName())); + result.setIfNotExists(null != ctx.ifNotExists()); if (null != ctx.createDefinitionClause()) { CollectionValue createDefinitions = (CollectionValue) visit(ctx.createDefinitionClause()); for (CreateDefinitionSegment each : createDefinitions.getValue()) { diff --git a/parser/sql/dialect/postgresql/src/main/java/org/apache/shardingsphere/sql/parser/postgresql/visitor/statement/type/PostgreSQLDDLStatementVisitor.java b/parser/sql/dialect/postgresql/src/main/java/org/apache/shardingsphere/sql/parser/postgresql/visitor/statement/type/PostgreSQLDDLStatementVisitor.java index c56f7b62f365a..dd5a0abf893ba 100644 --- a/parser/sql/dialect/postgresql/src/main/java/org/apache/shardingsphere/sql/parser/postgresql/visitor/statement/type/PostgreSQLDDLStatementVisitor.java +++ b/parser/sql/dialect/postgresql/src/main/java/org/apache/shardingsphere/sql/parser/postgresql/visitor/statement/type/PostgreSQLDDLStatementVisitor.java @@ -339,8 +339,9 @@ public final class PostgreSQLDDLStatementVisitor extends PostgreSQLStatementVisi @SuppressWarnings("unchecked") @Override public ASTNode visitCreateTable(final CreateTableContext ctx) { - PostgreSQLCreateTableStatement result = new PostgreSQLCreateTableStatement(null != ctx.ifNotExists()); + PostgreSQLCreateTableStatement result = new PostgreSQLCreateTableStatement(); result.setTable((SimpleTableSegment) visit(ctx.tableName())); + result.setIfNotExists(null != ctx.ifNotExists()); if (null != ctx.createDefinitionClause()) { CollectionValue createDefinitions = (CollectionValue) visit(ctx.createDefinitionClause()); for (CreateDefinitionSegment each : createDefinitions.getValue()) { diff --git a/parser/sql/dialect/presto/src/main/java/org/apache/shardingsphere/sql/parser/presto/visitor/statement/type/PrestoDDLStatementVisitor.java b/parser/sql/dialect/presto/src/main/java/org/apache/shardingsphere/sql/parser/presto/visitor/statement/type/PrestoDDLStatementVisitor.java index 9aa313d94cf3c..2fe88595fb6f2 100644 --- a/parser/sql/dialect/presto/src/main/java/org/apache/shardingsphere/sql/parser/presto/visitor/statement/type/PrestoDDLStatementVisitor.java +++ b/parser/sql/dialect/presto/src/main/java/org/apache/shardingsphere/sql/parser/presto/visitor/statement/type/PrestoDDLStatementVisitor.java @@ -73,8 +73,9 @@ public ASTNode visitDropView(final DropViewContext ctx) { @SuppressWarnings("unchecked") @Override public ASTNode visitCreateTable(final CreateTableContext ctx) { - PrestoCreateTableStatement result = new PrestoCreateTableStatement(null != ctx.ifNotExists()); + PrestoCreateTableStatement result = new PrestoCreateTableStatement(); result.setTable((SimpleTableSegment) visit(ctx.tableName())); + result.setIfNotExists(null != ctx.ifNotExists()); if (null != ctx.createDefinitionClause()) { CollectionValue createDefinitions = (CollectionValue) visit(ctx.createDefinitionClause()); for (CreateDefinitionSegment each : createDefinitions.getValue()) { diff --git a/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/statement/AbstractSQLStatement.java b/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/statement/AbstractSQLStatement.java index 66e9da993bf57..d01c935e48dc8 100644 --- a/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/statement/AbstractSQLStatement.java +++ b/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/statement/AbstractSQLStatement.java @@ -17,6 +17,7 @@ package org.apache.shardingsphere.sql.parser.statement.core.statement; +import com.cedarsoftware.util.CaseInsensitiveSet; import lombok.Getter; import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.CommentSegment; import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.ParameterMarkerSegment; @@ -38,7 +39,7 @@ public abstract class AbstractSQLStatement implements SQLStatement { private final Collection commentSegments = new LinkedList<>(); - private final Collection variableNames = new HashSet<>(); + private final Collection variableNames = new CaseInsensitiveSet<>(); @Override public int getParameterCount() { diff --git a/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/statement/ddl/CreateTableStatement.java b/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/statement/ddl/CreateTableStatement.java index c33091986b029..2b46df95c9b0f 100644 --- a/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/statement/ddl/CreateTableStatement.java +++ b/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/statement/ddl/CreateTableStatement.java @@ -66,6 +66,14 @@ public boolean isIfNotExists() { return false; } + /** + * Set if not exists. + * + * @param ifNotExists if not exists + */ + public void setIfNotExists(final boolean ifNotExists) { + } + /** * Get list of columns. * @@ -84,6 +92,14 @@ public Optional getLikeTable() { return Optional.empty(); } + /** + * Set like table. + * + * @param likeTable like table + */ + public void setLikeTable(final SimpleTableSegment likeTable) { + } + /** * Get create table option. * @@ -92,4 +108,12 @@ public Optional getLikeTable() { public Optional getCreateTableOption() { return Optional.empty(); } + + /** + * Set create table option. + * + * @param createTableOption create table option + */ + public void setCreateTableOption(final CreateTableOptionSegment createTableOption) { + } } diff --git a/parser/sql/statement/type/doris/src/main/java/org/apache/shardingsphere/sql/parser/statement/doris/ddl/DorisCreateTableStatement.java b/parser/sql/statement/type/doris/src/main/java/org/apache/shardingsphere/sql/parser/statement/doris/ddl/DorisCreateTableStatement.java index 0f75e4347dd5a..ec4a2500ec743 100644 --- a/parser/sql/statement/type/doris/src/main/java/org/apache/shardingsphere/sql/parser/statement/doris/ddl/DorisCreateTableStatement.java +++ b/parser/sql/statement/type/doris/src/main/java/org/apache/shardingsphere/sql/parser/statement/doris/ddl/DorisCreateTableStatement.java @@ -35,7 +35,7 @@ @Setter public final class DorisCreateTableStatement extends CreateTableStatement implements DorisStatement { - private final boolean ifNotExists; + private boolean ifNotExists; private SimpleTableSegment likeTable; diff --git a/parser/sql/statement/type/mysql/src/main/java/org/apache/shardingsphere/sql/parser/statement/mysql/ddl/MySQLCreateTableStatement.java b/parser/sql/statement/type/mysql/src/main/java/org/apache/shardingsphere/sql/parser/statement/mysql/ddl/MySQLCreateTableStatement.java index cc13a1e7bd4f6..38aa911998e94 100644 --- a/parser/sql/statement/type/mysql/src/main/java/org/apache/shardingsphere/sql/parser/statement/mysql/ddl/MySQLCreateTableStatement.java +++ b/parser/sql/statement/type/mysql/src/main/java/org/apache/shardingsphere/sql/parser/statement/mysql/ddl/MySQLCreateTableStatement.java @@ -35,7 +35,7 @@ @Setter public final class MySQLCreateTableStatement extends CreateTableStatement implements MySQLStatement { - private final boolean ifNotExists; + private boolean ifNotExists; private SimpleTableSegment likeTable; diff --git a/parser/sql/statement/type/opengauss/src/main/java/org/apache/shardingsphere/sql/parser/statement/opengauss/ddl/OpenGaussCreateTableStatement.java b/parser/sql/statement/type/opengauss/src/main/java/org/apache/shardingsphere/sql/parser/statement/opengauss/ddl/OpenGaussCreateTableStatement.java index f79148b1d5c7f..e8ce0ac457385 100644 --- a/parser/sql/statement/type/opengauss/src/main/java/org/apache/shardingsphere/sql/parser/statement/opengauss/ddl/OpenGaussCreateTableStatement.java +++ b/parser/sql/statement/type/opengauss/src/main/java/org/apache/shardingsphere/sql/parser/statement/opengauss/ddl/OpenGaussCreateTableStatement.java @@ -19,6 +19,7 @@ import lombok.Getter; import lombok.RequiredArgsConstructor; +import lombok.Setter; import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.CreateTableStatement; import org.apache.shardingsphere.sql.parser.statement.opengauss.OpenGaussStatement; @@ -27,7 +28,8 @@ */ @RequiredArgsConstructor @Getter +@Setter public final class OpenGaussCreateTableStatement extends CreateTableStatement implements OpenGaussStatement { - private final boolean ifNotExists; + private boolean ifNotExists; } diff --git a/parser/sql/statement/type/postgresql/src/main/java/org/apache/shardingsphere/sql/parser/statement/postgresql/ddl/PostgreSQLCreateTableStatement.java b/parser/sql/statement/type/postgresql/src/main/java/org/apache/shardingsphere/sql/parser/statement/postgresql/ddl/PostgreSQLCreateTableStatement.java index adc9f08a4621b..821aefa28312b 100644 --- a/parser/sql/statement/type/postgresql/src/main/java/org/apache/shardingsphere/sql/parser/statement/postgresql/ddl/PostgreSQLCreateTableStatement.java +++ b/parser/sql/statement/type/postgresql/src/main/java/org/apache/shardingsphere/sql/parser/statement/postgresql/ddl/PostgreSQLCreateTableStatement.java @@ -19,6 +19,7 @@ import lombok.Getter; import lombok.RequiredArgsConstructor; +import lombok.Setter; import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.CreateTableStatement; import org.apache.shardingsphere.sql.parser.statement.postgresql.PostgreSQLStatement; @@ -27,7 +28,8 @@ */ @RequiredArgsConstructor @Getter +@Setter public final class PostgreSQLCreateTableStatement extends CreateTableStatement implements PostgreSQLStatement { - private final boolean ifNotExists; + private boolean ifNotExists; } diff --git a/parser/sql/statement/type/presto/src/main/java/org/apache/shardingsphere/sql/parser/statement/presto/ddl/PrestoCreateTableStatement.java b/parser/sql/statement/type/presto/src/main/java/org/apache/shardingsphere/sql/parser/statement/presto/ddl/PrestoCreateTableStatement.java index a61a9f6f4e933..c591050c0e750 100644 --- a/parser/sql/statement/type/presto/src/main/java/org/apache/shardingsphere/sql/parser/statement/presto/ddl/PrestoCreateTableStatement.java +++ b/parser/sql/statement/type/presto/src/main/java/org/apache/shardingsphere/sql/parser/statement/presto/ddl/PrestoCreateTableStatement.java @@ -35,7 +35,7 @@ @Setter public final class PrestoCreateTableStatement extends CreateTableStatement implements PrestoStatement { - private final boolean ifNotExists; + private boolean ifNotExists; private SimpleTableSegment likeTable; diff --git a/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/connector/ProxySQLExecutorTest.java b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/connector/ProxySQLExecutorTest.java index b2dbcc146d3fd..87bc4e883ed7a 100644 --- a/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/connector/ProxySQLExecutorTest.java +++ b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/connector/ProxySQLExecutorTest.java @@ -238,7 +238,8 @@ void assertCheckExecutePrerequisitesWhenExecuteDDLNotInPostgreSQLTransaction() { } private CreateTableStatementContext createMySQLCreateTableStatementContext() { - MySQLCreateTableStatement sqlStatement = new MySQLCreateTableStatement(false); + MySQLCreateTableStatement sqlStatement = new MySQLCreateTableStatement(); + sqlStatement.setIfNotExists(false); sqlStatement.setTable(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_order")))); return new CreateTableStatementContext(sqlStatement); } @@ -274,7 +275,8 @@ private InsertStatementContext createMySQLInsertStatementContext() { } private CreateTableStatementContext createPostgreSQLCreateTableStatementContext() { - PostgreSQLCreateTableStatement sqlStatement = new PostgreSQLCreateTableStatement(false); + PostgreSQLCreateTableStatement sqlStatement = new PostgreSQLCreateTableStatement(); + sqlStatement.setIfNotExists(false); sqlStatement.setTable(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_order")))); return new CreateTableStatementContext(sqlStatement); } diff --git a/proxy/frontend/type/mysql/src/test/java/org/apache/shardingsphere/proxy/frontend/mysql/command/query/binary/prepare/MySQLComStmtPrepareCheckerTest.java b/proxy/frontend/type/mysql/src/test/java/org/apache/shardingsphere/proxy/frontend/mysql/command/query/binary/prepare/MySQLComStmtPrepareCheckerTest.java index a572cfe83ae67..223001a592daf 100644 --- a/proxy/frontend/type/mysql/src/test/java/org/apache/shardingsphere/proxy/frontend/mysql/command/query/binary/prepare/MySQLComStmtPrepareCheckerTest.java +++ b/proxy/frontend/type/mysql/src/test/java/org/apache/shardingsphere/proxy/frontend/mysql/command/query/binary/prepare/MySQLComStmtPrepareCheckerTest.java @@ -84,10 +84,12 @@ class MySQLComStmtPrepareCheckerTest { @Test void assertIsStatementAllowed() { + MySQLCreateTableStatement createTableStatement = new MySQLCreateTableStatement(); + createTableStatement.setIfNotExists(false); Collection sqlStatements = Arrays.asList( new MySQLAlterTableStatement(), new MySQLAlterUserStatement(), new MySQLAnalyzeTableStatement(), new MySQLCacheIndexStatement(), new MySQLCallStatement(), new MySQLChangeMasterStatement(), new MySQLChecksumTableStatement(), new MySQLCommitStatement(), new MySQLCreateIndexStatement(), - new MySQLDropIndexStatement(), new MySQLCreateDatabaseStatement(), new MySQLDropDatabaseStatement(), new MySQLCreateTableStatement(false), + new MySQLDropIndexStatement(), new MySQLCreateDatabaseStatement(), new MySQLDropDatabaseStatement(), createTableStatement, new MySQLDropTableStatement(false), new MySQLCreateUserStatement(), new MySQLRenameUserStatement(), new MySQLDropUserStatement(), new MySQLCreateViewStatement(), new MySQLDropViewStatement(), new MySQLDeleteStatement(), new MySQLDoStatement(), new MySQLFlushStatement(), new MySQLGrantStatement(), new MySQLInsertStatement(), new MySQLInstallPluginStatement(), new MySQLKillStatement(), diff --git a/test/it/binder/src/test/resources/cases/ddl/create-table.xml b/test/it/binder/src/test/resources/cases/ddl/create-table.xml new file mode 100644 index 0000000000000..59815b36015b0 --- /dev/null +++ b/test/it/binder/src/test/resources/cases/ddl/create-table.xml @@ -0,0 +1,88 @@ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
diff --git a/test/it/binder/src/test/resources/sqls/ddl/create-table.xml b/test/it/binder/src/test/resources/sqls/ddl/create-table.xml new file mode 100644 index 0000000000000..35e75c68f6121 --- /dev/null +++ b/test/it/binder/src/test/resources/sqls/ddl/create-table.xml @@ -0,0 +1,21 @@ + + + + + + diff --git a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/segment/bound/ColumnBoundAssert.java b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/segment/bound/ColumnBoundAssert.java new file mode 100644 index 0000000000000..55eb5a812176e --- /dev/null +++ b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/segment/bound/ColumnBoundAssert.java @@ -0,0 +1,49 @@ +/* + * 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.test.it.sql.parser.internal.asserts.segment.bound; + +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.bound.ColumnSegmentBoundInfo; +import org.apache.shardingsphere.test.it.sql.parser.internal.asserts.SQLCaseAssertContext; +import org.apache.shardingsphere.test.it.sql.parser.internal.asserts.segment.identifier.IdentifierValueAssert; +import org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.bound.ExpectedColumnBoundInfo; + +/** + * Column bound assert. + */ +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public final class ColumnBoundAssert { + + /** + * Assert actual column bound info is correct with expected column bound info. + * + * @param assertContext assert context + * @param actual actual column bound info + * @param expected expected column bound info + */ + public static void assertIs(final SQLCaseAssertContext assertContext, final ColumnSegmentBoundInfo actual, final ExpectedColumnBoundInfo expected) { + if (null == expected) { + return; + } + IdentifierValueAssert.assertIs(assertContext, actual.getOriginalDatabase(), expected.getOriginalDatabase(), "Bound Database"); + IdentifierValueAssert.assertIs(assertContext, actual.getOriginalSchema(), expected.getOriginalSchema(), "Bound Schema"); + IdentifierValueAssert.assertIs(assertContext, actual.getOriginalTable(), expected.getOriginalTable(), "Bound Table"); + IdentifierValueAssert.assertIs(assertContext, actual.getOriginalColumn(), expected.getOriginalColumn(), "Bound Column"); + } +} diff --git a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/segment/bound/TableBoundAssert.java b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/segment/bound/TableBoundAssert.java new file mode 100644 index 0000000000000..c205660d69eac --- /dev/null +++ b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/segment/bound/TableBoundAssert.java @@ -0,0 +1,52 @@ +/* + * 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.test.it.sql.parser.internal.asserts.segment.bound; + +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.bound.TableSegmentBoundInfo; +import org.apache.shardingsphere.test.it.sql.parser.internal.asserts.SQLCaseAssertContext; +import org.apache.shardingsphere.test.it.sql.parser.internal.asserts.segment.identifier.IdentifierValueAssert; +import org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.bound.ExpectedTableBoundInfo; + +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; + +/** + * Table bound assert. + */ +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public final class TableBoundAssert { + + /** + * Assert actual table bound info is correct with expected table bound info. + * + * @param assertContext assert context + * @param actual actual table bound info + * @param expected expected table bound info + */ + public static void assertIs(final SQLCaseAssertContext assertContext, final TableSegmentBoundInfo actual, final ExpectedTableBoundInfo expected) { + if (null == expected) { + assertNull(actual, assertContext.getText("Actual table bound should not exist.")); + } else { + assertNotNull(actual, assertContext.getText("Actual table bound should exist.")); + IdentifierValueAssert.assertIs(assertContext, actual.getOriginalDatabase(), expected.getOriginalDatabase(), "Bound Database"); + IdentifierValueAssert.assertIs(assertContext, actual.getOriginalSchema(), expected.getOriginalSchema(), "Bound Schema"); + } + } +} diff --git a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/segment/definition/ColumnDefinitionAssert.java b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/segment/definition/ColumnDefinitionAssert.java index fd29c2ea25b59..88670abce61a0 100644 --- a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/segment/definition/ColumnDefinitionAssert.java +++ b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/segment/definition/ColumnDefinitionAssert.java @@ -21,6 +21,7 @@ import lombok.NoArgsConstructor; import org.apache.shardingsphere.sql.parser.statement.core.segment.ddl.column.ColumnDefinitionSegment; import org.apache.shardingsphere.test.it.sql.parser.internal.asserts.SQLCaseAssertContext; +import org.apache.shardingsphere.test.it.sql.parser.internal.asserts.segment.bound.ColumnBoundAssert; import org.apache.shardingsphere.test.it.sql.parser.internal.asserts.segment.generic.DataTypeAssert; import org.apache.shardingsphere.test.it.sql.parser.internal.asserts.segment.table.TableAssert; import org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.definition.ExpectedColumnDefinition; @@ -44,7 +45,7 @@ public final class ColumnDefinitionAssert { * @param expected expected column definition */ public static void assertIs(final SQLCaseAssertContext assertContext, final ColumnDefinitionSegment actual, final ExpectedColumnDefinition expected) { - assertThat(assertContext.getText("Column definition name assertion error: "), actual.getColumnName().getIdentifier().getValue(), is(expected.getColumn().getName())); + assertColumnName(assertContext, actual, expected); if (null != expected.getType()) { assertNotNull(actual.getDataType(), assertContext.getText("Column definition data type should exist.")); assertThat(assertContext.getText("Column definition data type assertion error: "), actual.getDataType().getDataTypeName(), is(expected.getType())); @@ -63,4 +64,9 @@ public static void assertIs(final SQLCaseAssertContext assertContext, final Colu assertThat(assertContext.getText("Column definition not null assertion error: "), actual.isNotNull(), is(expected.isNotNull())); } } + + private static void assertColumnName(final SQLCaseAssertContext assertContext, final ColumnDefinitionSegment actual, final ExpectedColumnDefinition expected) { + assertThat(assertContext.getText("Column definition name assertion error: "), actual.getColumnName().getIdentifier().getValue(), is(expected.getColumn().getName())); + ColumnBoundAssert.assertIs(assertContext, actual.getColumnName().getColumnBoundInfo(), expected.getColumn().getColumnBound()); + } } diff --git a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/segment/projection/ProjectionAssert.java b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/segment/projection/ProjectionAssert.java index 1f091e7cec7f3..90b7ee46ea871 100644 --- a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/segment/projection/ProjectionAssert.java +++ b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/segment/projection/ProjectionAssert.java @@ -32,6 +32,7 @@ import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.top.TopProjectionSegment; import org.apache.shardingsphere.test.it.sql.parser.internal.asserts.SQLCaseAssertContext; import org.apache.shardingsphere.test.it.sql.parser.internal.asserts.segment.SQLSegmentAssert; +import org.apache.shardingsphere.test.it.sql.parser.internal.asserts.segment.bound.ColumnBoundAssert; import org.apache.shardingsphere.test.it.sql.parser.internal.asserts.segment.expression.ExpressionAssert; import org.apache.shardingsphere.test.it.sql.parser.internal.asserts.segment.generic.ParenthesesAssert; import org.apache.shardingsphere.test.it.sql.parser.internal.asserts.segment.identifier.IdentifierValueAssert; @@ -164,12 +165,7 @@ private static void assertColumnSegment(final SQLCaseAssertContext assertContext assertThat(assertContext.getText("Nested Object attributes assertion error: "), actual.getColumn().getExpression(), is(expected.getName())); } else { IdentifierValueAssert.assertIs(assertContext, actual.getColumn().getIdentifier(), expected, "Column projection"); - if (null != expected.getColumnBound()) { - IdentifierValueAssert.assertIs(assertContext, actual.getColumn().getColumnBoundInfo().getOriginalDatabase(), expected.getColumnBound().getOriginalDatabase(), "Bound Database"); - IdentifierValueAssert.assertIs(assertContext, actual.getColumn().getColumnBoundInfo().getOriginalSchema(), expected.getColumnBound().getOriginalSchema(), "Bound Schema"); - IdentifierValueAssert.assertIs(assertContext, actual.getColumn().getColumnBoundInfo().getOriginalTable(), expected.getColumnBound().getOriginalTable(), "Bound Table"); - IdentifierValueAssert.assertIs(assertContext, actual.getColumn().getColumnBoundInfo().getOriginalColumn(), expected.getColumnBound().getOriginalColumn(), "Bound Column"); - } + ColumnBoundAssert.assertIs(assertContext, actual.getColumn().getColumnBoundInfo(), expected.getColumnBound()); } } diff --git a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/segment/table/TableAssert.java b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/segment/table/TableAssert.java index a13e50f21a0d6..f2ec4a6b589cd 100644 --- a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/segment/table/TableAssert.java +++ b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/segment/table/TableAssert.java @@ -32,6 +32,7 @@ import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.TableSegment; import org.apache.shardingsphere.test.it.sql.parser.internal.asserts.SQLCaseAssertContext; import org.apache.shardingsphere.test.it.sql.parser.internal.asserts.segment.SQLSegmentAssert; +import org.apache.shardingsphere.test.it.sql.parser.internal.asserts.segment.bound.TableBoundAssert; import org.apache.shardingsphere.test.it.sql.parser.internal.asserts.segment.column.ColumnAssert; import org.apache.shardingsphere.test.it.sql.parser.internal.asserts.segment.expression.ExpressionAssert; import org.apache.shardingsphere.test.it.sql.parser.internal.asserts.segment.identifier.IdentifierValueAssert; @@ -251,12 +252,6 @@ private static void assertTableFunction(final SQLCaseAssertContext assertContext private static void assertTableNameSegment(final SQLCaseAssertContext assertContext, final SimpleTableSegment actual, final ExpectedSimpleTable expected) { IdentifierValueAssert.assertIs(assertContext, actual.getTableName().getIdentifier(), expected, "Table"); - if (null == expected.getTableBound()) { - assertFalse(actual.getTableName().getTableBoundInfo().isPresent(), assertContext.getText("Actual table bound should not exist.")); - } else { - assertTrue(actual.getTableName().getTableBoundInfo().isPresent(), assertContext.getText("Actual table bound should exist.")); - IdentifierValueAssert.assertIs(assertContext, actual.getTableName().getTableBoundInfo().get().getOriginalDatabase(), expected.getTableBound().getOriginalDatabase(), "Bound Database"); - IdentifierValueAssert.assertIs(assertContext, actual.getTableName().getTableBoundInfo().get().getOriginalSchema(), expected.getTableBound().getOriginalSchema(), "Bound Schema"); - } + TableBoundAssert.assertIs(assertContext, actual.getTableName().getTableBoundInfo().orElse(null), expected.getTableBound()); } } diff --git a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/column/ExpectedColumn.java b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/column/ExpectedColumn.java index 1f03ad89c4c15..58bceb1d722bb 100644 --- a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/column/ExpectedColumn.java +++ b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/column/ExpectedColumn.java @@ -20,6 +20,7 @@ import lombok.Getter; import lombok.Setter; import org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.AbstractExpectedIdentifierSQLSegment; +import org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.bound.ExpectedColumnBoundInfo; import org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.expr.ExpectedExpressionSegment; import org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.table.ExpectedOwner; @@ -34,4 +35,7 @@ public final class ExpectedColumn extends AbstractExpectedIdentifierSQLSegment i @XmlElement private ExpectedOwner owner; + + @XmlElement(name = "column-bound") + private ExpectedColumnBoundInfo columnBound; } diff --git a/test/it/rewriter/src/test/resources/scenario/encrypt/case/query-with-cipher/ddl/create/create-table.xml b/test/it/rewriter/src/test/resources/scenario/encrypt/case/query-with-cipher/ddl/create/create-table.xml index efad1b9e6d260..363a17f208d63 100644 --- a/test/it/rewriter/src/test/resources/scenario/encrypt/case/query-with-cipher/ddl/create/create-table.xml +++ b/test/it/rewriter/src/test/resources/scenario/encrypt/case/query-with-cipher/ddl/create/create-table.xml @@ -18,12 +18,12 @@ - - + + - - + + diff --git a/test/it/rewriter/src/test/resources/scenario/encrypt/config/query-with-cipher.yaml b/test/it/rewriter/src/test/resources/scenario/encrypt/config/query-with-cipher.yaml index 7a0a5660d5512..c76e7e776bce9 100644 --- a/test/it/rewriter/src/test/resources/scenario/encrypt/config/query-with-cipher.yaml +++ b/test/it/rewriter/src/test/resources/scenario/encrypt/config/query-with-cipher.yaml @@ -76,6 +76,32 @@ rules: cipher: name: cipher_amount encryptorName: rewrite_normal_fixture + t_account_bak_for_create: + columns: + certificate_number: + cipher: + name: cipher_certificate_number + encryptorName: rewrite_normal_fixture + assistedQuery: + name: assisted_query_certificate_number + encryptorName: rewrite_assisted_query_fixture + likeQuery: + name: like_query_certificate_number + encryptorName: rewrite_like_query_fixture + password: + cipher: + name: cipher_password + encryptorName: rewrite_normal_fixture + assistedQuery: + name: assisted_query_password + encryptorName: rewrite_assisted_query_fixture + likeQuery: + name: like_query_password + encryptorName: rewrite_like_query_fixture + amount: + cipher: + name: cipher_amount + encryptorName: rewrite_normal_fixture t_account_detail: columns: certificate_number: