From eb54abb7a75d23d35ccdac8b41759f0e1a47c6b3 Mon Sep 17 00:00:00 2001 From: duanzhengqiang Date: Wed, 8 Jan 2025 15:57:54 +0800 Subject: [PATCH 1/2] Enhance create view, alter view, drop view sql parser --- .../EncryptProjectionTokenGenerator.java | 2 +- ...ShardingAlterViewSupportedCheckerTest.java | 23 +++++++++-- .../statement/SQLStatementContextFactory.java | 4 +- .../ddl/AlterViewStatementContext.java | 38 ++++++++++++++++--- .../ddl/CreateViewStatementContext.java | 12 +++++- .../from/type/SimpleTableSegmentBinder.java | 8 +++- .../ddl/CreateViewStatementBinder.java | 1 + .../ddl/AlterViewStatementContextTest.java | 13 ++++++- .../ddl/CreateViewStatementContextTest.java | 18 ++++++++- .../type/DorisDDLStatementVisitor.java | 1 + .../type/MySQLDDLStatementVisitor.java | 2 + .../type/OpenGaussDDLStatementVisitor.java | 1 + .../type/OracleDDLStatementVisitor.java | 1 + .../type/PostgreSQLDDLStatementVisitor.java | 1 + .../type/PrestoDDLStatementVisitor.java | 1 + .../type/SQLServerDDLStatementVisitor.java | 1 + .../statement/core/enums/SubqueryType.java | 2 +- .../statement/ddl/CreateViewStatement.java | 2 + .../core/statement/ddl/DropViewStatement.java | 17 +++++++++ .../mysql/ddl/MySQLDropViewStatement.java | 6 +++ 20 files changed, 136 insertions(+), 18 deletions(-) diff --git a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/projection/EncryptProjectionTokenGenerator.java b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/projection/EncryptProjectionTokenGenerator.java index 03bde3d645dd0..5877e355428f7 100644 --- a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/projection/EncryptProjectionTokenGenerator.java +++ b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/projection/EncryptProjectionTokenGenerator.java @@ -162,7 +162,7 @@ private Collection generateProjections(final EncryptColumn encryptCo if (SubqueryType.PREDICATE == subqueryType) { return Collections.singleton(generateProjectionInPredicateSubquery(encryptColumn, columnProjection)); } - if (SubqueryType.INSERT_SELECT == subqueryType) { + if (SubqueryType.INSERT_SELECT == subqueryType || SubqueryType.VIEW_DEFINITION == subqueryType) { return generateProjectionsInInsertSelectSubquery(encryptColumn, columnProjection); } throw new UnsupportedSQLOperationException( diff --git a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/checker/sql/ddl/ShardingAlterViewSupportedCheckerTest.java b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/checker/sql/ddl/ShardingAlterViewSupportedCheckerTest.java index 1acaea3299c45..05dd28156e305 100644 --- a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/checker/sql/ddl/ShardingAlterViewSupportedCheckerTest.java +++ b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/checker/sql/ddl/ShardingAlterViewSupportedCheckerTest.java @@ -18,8 +18,12 @@ package org.apache.shardingsphere.sharding.checker.sql.ddl; import org.apache.shardingsphere.infra.binder.context.statement.ddl.AlterViewStatementContext; +import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData; +import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase; +import org.apache.shardingsphere.infra.rule.attribute.table.TableMapperRuleAttribute; import org.apache.shardingsphere.sharding.exception.metadata.EngagedViewException; import org.apache.shardingsphere.sharding.rule.ShardingRule; +import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.ProjectionsSegment; 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.value.identifier.IdentifierValue; @@ -31,8 +35,11 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; +import java.util.Collections; + import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.Mockito.RETURNS_DEEP_STUBS; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -46,10 +53,15 @@ class ShardingAlterViewSupportedCheckerTest { void assertPreValidateAlterViewForMySQL() { MySQLSelectStatement selectStatement = new MySQLSelectStatement(); selectStatement.setFrom(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_order")))); + selectStatement.setProjections(new ProjectionsSegment(0, 0)); MySQLAlterViewStatement sqlStatement = new MySQLAlterViewStatement(); sqlStatement.setView(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_order_view")))); sqlStatement.setSelect(selectStatement); - AlterViewStatementContext sqlStatementContext = new AlterViewStatementContext(sqlStatement); + ShardingSphereMetaData metaData = mock(ShardingSphereMetaData.class); + ShardingSphereDatabase database = mock(ShardingSphereDatabase.class, RETURNS_DEEP_STUBS); + when(database.getRuleMetaData().getAttributes(TableMapperRuleAttribute.class)).thenReturn(Collections.emptyList()); + when(metaData.getDatabase("foo_db")).thenReturn(database); + AlterViewStatementContext sqlStatementContext = new AlterViewStatementContext(metaData, Collections.emptyList(), sqlStatement, "foo_db"); when(rule.isShardingTable("t_order")).thenReturn(false); assertDoesNotThrow(() -> new ShardingAlterViewSupportedChecker().check(rule, mock(), mock(), sqlStatementContext)); } @@ -58,10 +70,15 @@ void assertPreValidateAlterViewForMySQL() { void assertPreValidateAlterViewWithShardingTableForMySQL() { MySQLSelectStatement selectStatement = new MySQLSelectStatement(); selectStatement.setFrom(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_order")))); + selectStatement.setProjections(new ProjectionsSegment(0, 0)); MySQLAlterViewStatement sqlStatement = new MySQLAlterViewStatement(); sqlStatement.setView(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_order_view")))); sqlStatement.setSelect(selectStatement); - AlterViewStatementContext sqlStatementContext = new AlterViewStatementContext(sqlStatement); + ShardingSphereMetaData metaData = mock(ShardingSphereMetaData.class); + ShardingSphereDatabase database = mock(ShardingSphereDatabase.class, RETURNS_DEEP_STUBS); + when(database.getRuleMetaData().getAttributes(TableMapperRuleAttribute.class)).thenReturn(Collections.emptyList()); + when(metaData.getDatabase("foo_db")).thenReturn(database); + AlterViewStatementContext sqlStatementContext = new AlterViewStatementContext(metaData, Collections.emptyList(), sqlStatement, "foo_db"); when(rule.isShardingTable("t_order")).thenReturn(true); assertThrows(EngagedViewException.class, () -> new ShardingAlterViewSupportedChecker().check(rule, mock(), mock(), sqlStatementContext)); } @@ -71,7 +88,7 @@ void assertPreValidateAlterRenamedView() { OpenGaussAlterViewStatement sqlStatement = new OpenGaussAlterViewStatement(); sqlStatement.setView(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_order_view")))); sqlStatement.setRenameView(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_order_new")))); - AlterViewStatementContext sqlStatementContext = new AlterViewStatementContext(sqlStatement); + AlterViewStatementContext sqlStatementContext = new AlterViewStatementContext(mock(ShardingSphereMetaData.class), Collections.emptyList(), sqlStatement, "foo_db"); assertDoesNotThrow(() -> new ShardingAlterViewSupportedChecker().check(rule, mock(), mock(), sqlStatementContext)); } } diff --git a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/context/statement/SQLStatementContextFactory.java b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/context/statement/SQLStatementContextFactory.java index dce944382f904..1ad34d3cf09b3 100644 --- a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/context/statement/SQLStatementContextFactory.java +++ b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/context/statement/SQLStatementContextFactory.java @@ -205,10 +205,10 @@ private static SQLStatementContext getDDLStatementContext(final ShardingSphereMe return new CreateProcedureStatementContext((CreateProcedureStatement) sqlStatement); } if (sqlStatement instanceof CreateViewStatement) { - return new CreateViewStatementContext((CreateViewStatement) sqlStatement); + return new CreateViewStatementContext(metaData, params, (CreateViewStatement) sqlStatement, currentDatabaseName); } if (sqlStatement instanceof AlterViewStatement) { - return new AlterViewStatementContext((AlterViewStatement) sqlStatement); + return new AlterViewStatementContext(metaData, params, (AlterViewStatement) sqlStatement, currentDatabaseName); } if (sqlStatement instanceof DropViewStatement) { return new DropViewStatementContext((DropViewStatement) sqlStatement); diff --git a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/context/statement/ddl/AlterViewStatementContext.java b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/context/statement/ddl/AlterViewStatementContext.java index 21ed040858f1f..cef5709022630 100644 --- a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/context/statement/ddl/AlterViewStatementContext.java +++ b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/context/statement/ddl/AlterViewStatementContext.java @@ -20,14 +20,19 @@ import lombok.Getter; import org.apache.shardingsphere.infra.binder.context.segment.table.TablesContext; import org.apache.shardingsphere.infra.binder.context.statement.CommonSQLStatementContext; +import org.apache.shardingsphere.infra.binder.context.statement.dml.SelectStatementContext; import org.apache.shardingsphere.infra.binder.context.type.TableAvailable; +import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData; +import org.apache.shardingsphere.sql.parser.statement.core.enums.SubqueryType; import org.apache.shardingsphere.sql.parser.statement.core.extractor.TableExtractor; import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.SimpleTableSegment; import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.AlterViewStatement; import org.apache.shardingsphere.sql.parser.statement.core.statement.dml.SelectStatement; import java.util.Collection; +import java.util.Collections; import java.util.LinkedList; +import java.util.List; import java.util.Optional; /** @@ -38,18 +43,39 @@ public final class AlterViewStatementContext extends CommonSQLStatementContext i private final TablesContext tablesContext; - public AlterViewStatementContext(final AlterViewStatement sqlStatement) { + private final SelectStatementContext selectStatementContext; + + public AlterViewStatementContext(final ShardingSphereMetaData metaData, final List params, final AlterViewStatement sqlStatement, final String currentDatabaseName) { super(sqlStatement); Collection tables = new LinkedList<>(); tables.add(sqlStatement.getView()); Optional selectStatement = sqlStatement.getSelect(); - selectStatement.ifPresent(optional -> { - TableExtractor extractor = new TableExtractor(); - extractor.extractTablesFromSelect(optional); - tables.addAll(extractor.getRewriteTables()); - }); + selectStatement.ifPresent(optional -> extractTables(optional, tables)); sqlStatement.getRenameView().ifPresent(tables::add); tablesContext = new TablesContext(tables); + selectStatementContext = selectStatement.map(optional -> createSelectStatementContext(metaData, params, optional, currentDatabaseName)).orElse(null); + } + + private SelectStatementContext createSelectStatementContext(final ShardingSphereMetaData metaData, final List params, final SelectStatement selectStatement, + final String currentDatabaseName) { + SelectStatementContext result = new SelectStatementContext(metaData, params, selectStatement, currentDatabaseName, Collections.emptyList()); + result.setSubqueryType(SubqueryType.VIEW_DEFINITION); + return result; + } + + private void extractTables(final SelectStatement selectStatement, final Collection tables) { + TableExtractor extractor = new TableExtractor(); + extractor.extractTablesFromSelect(selectStatement); + tables.addAll(extractor.getRewriteTables()); + } + + /** + * Get select statement context. + * + * @return select statement context + */ + public Optional getSelectStatementContext() { + return Optional.ofNullable(selectStatementContext); } @Override diff --git a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/context/statement/ddl/CreateViewStatementContext.java b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/context/statement/ddl/CreateViewStatementContext.java index 730d89b76db23..c829761b25b8a 100644 --- a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/context/statement/ddl/CreateViewStatementContext.java +++ b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/context/statement/ddl/CreateViewStatementContext.java @@ -20,10 +20,16 @@ import lombok.Getter; import org.apache.shardingsphere.infra.binder.context.segment.table.TablesContext; import org.apache.shardingsphere.infra.binder.context.statement.CommonSQLStatementContext; +import org.apache.shardingsphere.infra.binder.context.statement.dml.SelectStatementContext; import org.apache.shardingsphere.infra.binder.context.type.TableAvailable; +import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData; +import org.apache.shardingsphere.sql.parser.statement.core.enums.SubqueryType; import org.apache.shardingsphere.sql.parser.statement.core.extractor.TableExtractor; import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.CreateViewStatement; +import java.util.Collections; +import java.util.List; + /** * Create view statement context. */ @@ -32,11 +38,15 @@ public final class CreateViewStatementContext extends CommonSQLStatementContext private final TablesContext tablesContext; - public CreateViewStatementContext(final CreateViewStatement sqlStatement) { + private final SelectStatementContext selectStatementContext; + + public CreateViewStatementContext(final ShardingSphereMetaData metaData, final List params, final CreateViewStatement sqlStatement, final String currentDatabaseName) { super(sqlStatement); TableExtractor extractor = new TableExtractor(); extractor.extractTablesFromCreateViewStatement(sqlStatement); tablesContext = new TablesContext(extractor.getRewriteTables()); + selectStatementContext = new SelectStatementContext(metaData, params, sqlStatement.getSelect(), currentDatabaseName, Collections.emptyList()); + selectStatementContext.setSubqueryType(SubqueryType.VIEW_DEFINITION); } @Override diff --git a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/dml/from/type/SimpleTableSegmentBinder.java b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/dml/from/type/SimpleTableSegmentBinder.java index 3ed26ac9e9902..ebe77511e21d4 100644 --- a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/dml/from/type/SimpleTableSegmentBinder.java +++ b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/dml/from/type/SimpleTableSegmentBinder.java @@ -55,6 +55,7 @@ import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.CreateTableStatement; import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.CreateViewStatement; import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.DropTableStatement; +import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.DropViewStatement; import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.RenameTableStatement; import org.apache.shardingsphere.sql.parser.statement.core.value.identifier.IdentifierValue; @@ -150,13 +151,18 @@ private static void checkTableExists(final SQLStatementBinderContext binderConte return; } if (binderContext.getSqlStatement() instanceof CreateViewStatement && isCreateTable(((CreateViewStatement) binderContext.getSqlStatement()).getView(), tableName)) { - ShardingSpherePreconditions.checkState(binderContext.getHintValueContext().isSkipMetadataValidate() || !schema.containsTable(tableName), () -> new TableExistsException(tableName)); + ShardingSpherePreconditions.checkState(binderContext.getHintValueContext().isSkipMetadataValidate() + || ((CreateViewStatement) binderContext.getSqlStatement()).isReplaceView() || !schema.containsTable(tableName), () -> new TableExistsException(tableName)); return; } if (binderContext.getSqlStatement() instanceof AlterViewStatement && isRenameView((AlterViewStatement) binderContext.getSqlStatement(), tableName)) { ShardingSpherePreconditions.checkState(binderContext.getHintValueContext().isSkipMetadataValidate() || !schema.containsTable(tableName), () -> new TableExistsException(tableName)); return; } + if (binderContext.getSqlStatement() instanceof DropViewStatement) { + ShardingSpherePreconditions.checkState(((DropViewStatement) binderContext.getSqlStatement()).isIfExists() || schema.containsTable(tableName), () -> new TableNotFoundException(tableName)); + return; + } if ("DUAL".equalsIgnoreCase(tableName)) { return; } diff --git a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/statement/ddl/CreateViewStatementBinder.java b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/statement/ddl/CreateViewStatementBinder.java index 91befad6c2f8f..0526097d9f108 100644 --- a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/statement/ddl/CreateViewStatementBinder.java +++ b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/statement/ddl/CreateViewStatementBinder.java @@ -37,6 +37,7 @@ public final class CreateViewStatementBinder implements SQLStatementBinder tableBinderContexts = LinkedHashMultimap.create(); + result.setReplaceView(sqlStatement.isReplaceView()); result.setView(SimpleTableSegmentBinder.bind(sqlStatement.getView(), binderContext, tableBinderContexts)); result.setSelect(new SelectStatementBinder().bind(sqlStatement.getSelect(), binderContext)); return result; diff --git a/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/context/statement/ddl/AlterViewStatementContextTest.java b/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/context/statement/ddl/AlterViewStatementContextTest.java index 0feea9fbeddb0..c47841bbe5e9d 100644 --- a/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/context/statement/ddl/AlterViewStatementContextTest.java +++ b/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/context/statement/ddl/AlterViewStatementContextTest.java @@ -18,6 +18,10 @@ package org.apache.shardingsphere.infra.binder.context.statement.ddl; import org.apache.shardingsphere.infra.binder.context.statement.CommonSQLStatementContext; +import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData; +import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase; +import org.apache.shardingsphere.infra.rule.attribute.table.TableMapperRuleAttribute; +import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.ProjectionsSegment; 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; @@ -30,11 +34,13 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import java.util.Collections; import java.util.Optional; import static org.hamcrest.CoreMatchers.instanceOf; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; +import static org.mockito.Mockito.RETURNS_DEEP_STUBS; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -53,6 +59,7 @@ void setUp() { void assertMySQLNewInstance() { SelectStatement select = mock(MySQLSelectStatement.class); when(select.getFrom()).thenReturn(Optional.of(view)); + when(select.getProjections()).thenReturn(new ProjectionsSegment(0, 0)); MySQLAlterViewStatement alterViewStatement = new MySQLAlterViewStatement(); alterViewStatement.setView(view); alterViewStatement.setSelect(select); @@ -70,7 +77,11 @@ void assertPostgreSQLNewInstance() { } private void assertNewInstance(final AlterViewStatement alterViewStatement) { - AlterViewStatementContext actual = new AlterViewStatementContext(alterViewStatement); + ShardingSphereMetaData metaData = mock(ShardingSphereMetaData.class); + ShardingSphereDatabase database = mock(ShardingSphereDatabase.class, RETURNS_DEEP_STUBS); + when(database.getRuleMetaData().getAttributes(TableMapperRuleAttribute.class)).thenReturn(Collections.emptyList()); + when(metaData.getDatabase("foo_db")).thenReturn(database); + AlterViewStatementContext actual = new AlterViewStatementContext(metaData, Collections.emptyList(), alterViewStatement, "foo_db"); assertThat(actual, instanceOf(CommonSQLStatementContext.class)); assertThat(actual.getSqlStatement(), is(alterViewStatement)); assertThat(actual.getTablesContext().getSimpleTables().size(), is(2)); diff --git a/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/context/statement/ddl/CreateViewStatementContextTest.java b/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/context/statement/ddl/CreateViewStatementContextTest.java index 5a59b58cc00b9..5741e889c84c4 100644 --- a/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/context/statement/ddl/CreateViewStatementContextTest.java +++ b/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/context/statement/ddl/CreateViewStatementContextTest.java @@ -18,6 +18,10 @@ package org.apache.shardingsphere.infra.binder.context.statement.ddl; import org.apache.shardingsphere.infra.binder.context.statement.CommonSQLStatementContext; +import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData; +import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase; +import org.apache.shardingsphere.infra.rule.attribute.table.TableMapperRuleAttribute; +import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.ProjectionsSegment; 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; @@ -28,10 +32,14 @@ import org.apache.shardingsphere.sql.parser.statement.postgresql.ddl.PostgreSQLCreateViewStatement; import org.junit.jupiter.api.Test; +import java.util.Collections; + import static org.hamcrest.CoreMatchers.instanceOf; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; +import static org.mockito.Mockito.RETURNS_DEEP_STUBS; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; class CreateViewStatementContextTest { @@ -50,8 +58,14 @@ private void assertNewInstance(final CreateViewStatement createViewStatement) { tableNameSegment.setTableBoundInfo(new TableSegmentBoundInfo(new IdentifierValue("foo_db"), new IdentifierValue("foo_schema"))); SimpleTableSegment view = new SimpleTableSegment(tableNameSegment); createViewStatement.setView(view); - createViewStatement.setSelect(mock(SelectStatement.class)); - CreateViewStatementContext actual = new CreateViewStatementContext(createViewStatement); + SelectStatement selectStatement = mock(SelectStatement.class); + when(selectStatement.getProjections()).thenReturn(new ProjectionsSegment(0, 0)); + createViewStatement.setSelect(selectStatement); + ShardingSphereMetaData metaData = mock(ShardingSphereMetaData.class); + ShardingSphereDatabase database = mock(ShardingSphereDatabase.class, RETURNS_DEEP_STUBS); + when(database.getRuleMetaData().getAttributes(TableMapperRuleAttribute.class)).thenReturn(Collections.emptyList()); + when(metaData.getDatabase("foo_db")).thenReturn(database); + CreateViewStatementContext actual = new CreateViewStatementContext(metaData, Collections.emptyList(), createViewStatement, "foo_db"); assertThat(actual, instanceOf(CommonSQLStatementContext.class)); assertThat(actual.getSqlStatement(), is(createViewStatement)); } 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 9c18804dcf91d..5acd3f672be89 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 @@ -206,6 +206,7 @@ public final class DorisDDLStatementVisitor extends DorisStatementVisitor implem @Override public ASTNode visitCreateView(final CreateViewContext ctx) { DorisCreateViewStatement result = new DorisCreateViewStatement(); + result.setReplaceView(null != ctx.REPLACE()); result.setView((SimpleTableSegment) visit(ctx.viewName())); result.setViewDefinition(getOriginalText(ctx.select())); result.setSelect((DorisSelectStatement) visit(ctx.select())); 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 9f6e311a4b56b..550b3e5afd711 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 @@ -207,6 +207,7 @@ public final class MySQLDDLStatementVisitor extends MySQLStatementVisitor implem @Override public ASTNode visitCreateView(final CreateViewContext ctx) { MySQLCreateViewStatement result = new MySQLCreateViewStatement(); + result.setReplaceView(null != ctx.REPLACE()); result.setView((SimpleTableSegment) visit(ctx.viewName())); result.setViewDefinition(getOriginalText(ctx.select())); result.setSelect((MySQLSelectStatement) visit(ctx.select())); @@ -226,6 +227,7 @@ public ASTNode visitAlterView(final AlterViewContext ctx) { @Override public ASTNode visitDropView(final DropViewContext ctx) { MySQLDropViewStatement result = new MySQLDropViewStatement(); + result.setIfExists(null != ctx.ifExists()); result.getViews().addAll(((CollectionValue) visit(ctx.viewNames())).getValue()); return result; } 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 7fad41cc99f7a..cfba7147d0d11 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 @@ -673,6 +673,7 @@ public ASTNode visitDropView(final DropViewContext ctx) { @Override public ASTNode visitCreateView(final CreateViewContext ctx) { OpenGaussCreateViewStatement result = new OpenGaussCreateViewStatement(); + result.setReplaceView(null != ctx.REPLACE()); result.setView((SimpleTableSegment) visit(ctx.qualifiedName())); result.setViewDefinition(getOriginalText(ctx.select())); result.setSelect((SelectStatement) visit(ctx.select())); diff --git a/parser/sql/dialect/oracle/src/main/java/org/apache/shardingsphere/sql/parser/oracle/visitor/statement/type/OracleDDLStatementVisitor.java b/parser/sql/dialect/oracle/src/main/java/org/apache/shardingsphere/sql/parser/oracle/visitor/statement/type/OracleDDLStatementVisitor.java index 422659d4bd168..cc0258fbdcbac 100644 --- a/parser/sql/dialect/oracle/src/main/java/org/apache/shardingsphere/sql/parser/oracle/visitor/statement/type/OracleDDLStatementVisitor.java +++ b/parser/sql/dialect/oracle/src/main/java/org/apache/shardingsphere/sql/parser/oracle/visitor/statement/type/OracleDDLStatementVisitor.java @@ -373,6 +373,7 @@ public final class OracleDDLStatementVisitor extends OracleStatementVisitor impl @Override public ASTNode visitCreateView(final CreateViewContext ctx) { OracleCreateViewStatement result = new OracleCreateViewStatement(); + result.setReplaceView(null != ctx.REPLACE()); OracleDMLStatementVisitor visitor = new OracleDMLStatementVisitor(); getGlobalParameterMarkerSegments().addAll(visitor.getGlobalParameterMarkerSegments()); getStatementParameterMarkerSegments().addAll(visitor.getStatementParameterMarkerSegments()); 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 5bf935cb3ff88..dcc1477fbe0cb 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 @@ -818,6 +818,7 @@ public ASTNode visitDropView(final DropViewContext ctx) { @Override public ASTNode visitCreateView(final CreateViewContext ctx) { PostgreSQLCreateViewStatement result = new PostgreSQLCreateViewStatement(); + result.setReplaceView(null != ctx.REPLACE()); result.setView((SimpleTableSegment) visit(ctx.qualifiedName())); result.setViewDefinition(getOriginalText(ctx.select())); result.setSelect((SelectStatement) visit(ctx.select())); 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 d2b73e1c0be67..f18720967b9d4 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 @@ -56,6 +56,7 @@ public final class PrestoDDLStatementVisitor extends PrestoStatementVisitor impl @Override public ASTNode visitCreateView(final CreateViewContext ctx) { PrestoCreateViewStatement result = new PrestoCreateViewStatement(); + result.setReplaceView(null != ctx.REPLACE()); result.setView((SimpleTableSegment) visit(ctx.viewName())); result.setViewDefinition(getOriginalText(ctx.select())); result.setSelect((PrestoSelectStatement) visit(ctx.select())); diff --git a/parser/sql/dialect/sqlserver/src/main/java/org/apache/shardingsphere/sql/parser/sqlserver/visitor/statement/type/SQLServerDDLStatementVisitor.java b/parser/sql/dialect/sqlserver/src/main/java/org/apache/shardingsphere/sql/parser/sqlserver/visitor/statement/type/SQLServerDDLStatementVisitor.java index 8d589a494af67..f6f6c4e494c5c 100644 --- a/parser/sql/dialect/sqlserver/src/main/java/org/apache/shardingsphere/sql/parser/sqlserver/visitor/statement/type/SQLServerDDLStatementVisitor.java +++ b/parser/sql/dialect/sqlserver/src/main/java/org/apache/shardingsphere/sql/parser/sqlserver/visitor/statement/type/SQLServerDDLStatementVisitor.java @@ -389,6 +389,7 @@ public ASTNode visitCreateProcedure(final CreateProcedureContext ctx) { @Override public ASTNode visitCreateView(final CreateViewContext ctx) { SQLServerCreateViewStatement result = new SQLServerCreateViewStatement(); + result.setReplaceView(null != ctx.ALTER()); result.setView((SimpleTableSegment) visit(ctx.viewName())); result.setViewDefinition(getOriginalText(ctx.createOrAlterViewClause().select())); result.setSelect((SQLServerSelectStatement) visit(ctx.createOrAlterViewClause().select())); diff --git a/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/enums/SubqueryType.java b/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/enums/SubqueryType.java index a0751b0a805b2..5a71167457547 100644 --- a/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/enums/SubqueryType.java +++ b/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/enums/SubqueryType.java @@ -22,5 +22,5 @@ */ public enum SubqueryType { - PROJECTION, TABLE, JOIN, PREDICATE, INSERT_SELECT, EXISTS, WITH + PROJECTION, TABLE, JOIN, PREDICATE, INSERT_SELECT, EXISTS, WITH, VIEW_DEFINITION } diff --git a/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/statement/ddl/CreateViewStatement.java b/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/statement/ddl/CreateViewStatement.java index 0d7b24e0f18c1..66af70cc76251 100644 --- a/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/statement/ddl/CreateViewStatement.java +++ b/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/statement/ddl/CreateViewStatement.java @@ -30,6 +30,8 @@ @Setter public abstract class CreateViewStatement extends AbstractSQLStatement implements DDLStatement { + private boolean replaceView; + private SimpleTableSegment view; private String viewDefinition; diff --git a/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/statement/ddl/DropViewStatement.java b/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/statement/ddl/DropViewStatement.java index 07e6810718224..658bdc4768ffd 100644 --- a/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/statement/ddl/DropViewStatement.java +++ b/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/statement/ddl/DropViewStatement.java @@ -31,4 +31,21 @@ public abstract class DropViewStatement extends AbstractSQLStatement implements DDLStatement { private final Collection views = new LinkedList<>(); + + /** + * Set if exists. + * + * @param ifExists if exists or not + */ + public void setIfExists(final boolean ifExists) { + } + + /** + * Judge whether contains if exists. + * + * @return contains contains if exists or not + */ + public boolean isIfExists() { + return false; + } } diff --git a/parser/sql/statement/type/mysql/src/main/java/org/apache/shardingsphere/sql/parser/statement/mysql/ddl/MySQLDropViewStatement.java b/parser/sql/statement/type/mysql/src/main/java/org/apache/shardingsphere/sql/parser/statement/mysql/ddl/MySQLDropViewStatement.java index 90294988cbe04..4f39ccff41d4e 100644 --- a/parser/sql/statement/type/mysql/src/main/java/org/apache/shardingsphere/sql/parser/statement/mysql/ddl/MySQLDropViewStatement.java +++ b/parser/sql/statement/type/mysql/src/main/java/org/apache/shardingsphere/sql/parser/statement/mysql/ddl/MySQLDropViewStatement.java @@ -17,11 +17,17 @@ package org.apache.shardingsphere.sql.parser.statement.mysql.ddl; +import lombok.Getter; +import lombok.Setter; import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.DropViewStatement; import org.apache.shardingsphere.sql.parser.statement.mysql.MySQLStatement; /** * MySQL drop view statement. */ +@Getter +@Setter public final class MySQLDropViewStatement extends DropViewStatement implements MySQLStatement { + + private boolean ifExists; } From f3322c46368027c449ed5d907aa7460d0fedd375 Mon Sep 17 00:00:00 2001 From: duanzhengqiang Date: Wed, 8 Jan 2025 15:58:54 +0800 Subject: [PATCH 2/2] update release note --- RELEASE-NOTES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index 8c96db616a877..ad0678561dbd7 100644 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -52,6 +52,7 @@ 1. Encrypt: Support insert statement rewrite use quote [#34259](https://github.com/apache/shardingsphere/pull/34259) 1. SQL Binder: Support optimize table sql bind and add test case - [#34242](https://github.com/apache/shardingsphere/pull/34242) 1. SQL Binder: Support show create table, show columns, show index statement bind - [#34271](https://github.com/apache/shardingsphere/pull/34271) +1. SQL Parser: Enhance create view, alter view, drop view sql parser - [#34283](https://github.com/apache/shardingsphere/pull/34283) ### Bug Fixes