This is an automated email from the ASF dual-hosted git repository.
duanzhengqiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shardingsphere.git
The following commit(s) were added to refs/heads/master by this push:
new 51f76fe9a0f Support handling show create view result decoration in
encrypt. (#37299)
51f76fe9a0f is described below
commit 51f76fe9a0f60d7d357037d6f1c3f99dec9411b0
Author: Cong Hu <[email protected]>
AuthorDate: Tue Dec 9 09:04:18 2025 +0800
Support handling show create view result decoration in encrypt. (#37299)
* Support handling show create view result decoration in encrypt.
* Add release note.
---
RELEASE-NOTES.md | 1 +
.../merge/EncryptResultDecoratorEngine.java | 2 +-
.../merge/dal/EncryptDALResultDecorator.java | 23 ++--
.../show/EncryptShowCreateViewMergedResult.java | 137 +++++++++++++++++++++
.../merge/dql/EncryptDQLResultDecorator.java | 6 +-
.../merge/dal/EncryptDALResultDecoratorTest.java | 22 +++-
.../merge/dql/EncryptDQLResultDecoratorTest.java | 4 +-
.../mask/merge/dql/MaskDQLResultDecorator.java | 6 +-
.../mask/merge/dql/MaskDQLResultDecoratorTest.java | 4 +-
.../shardingsphere/infra/merge/MergeEngine.java | 4 +-
.../merge/engine/decorator/ResultDecorator.java | 10 +-
.../decorator/impl/TransparentResultDecorator.java | 6 +-
.../impl/TransparentResultDecoratorTest.java | 4 +-
.../fixture/decorator/ResultDecoratorFixture.java | 5 +-
.../statement/type/MySQLDALStatementVisitor.java | 2 +-
.../ViewInResultSetSQLStatementAttribute.java} | 18 ++-
.../show/view/MySQLShowCreateViewStatement.java | 8 ++
.../test/e2e/sql/it/sql/dal/DALE2EIT.java | 30 +++++
18 files changed, 234 insertions(+), 58 deletions(-)
diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md
index 78407b4545b..3bc4649cf15 100644
--- a/RELEASE-NOTES.md
+++ b/RELEASE-NOTES.md
@@ -65,6 +65,7 @@
1. Pipeline: InventoryDumper reuse table inventory calculator for better
function and performance -
[#36830](https://github.com/apache/shardingsphere/pull/36830)
1. Pipeline: Improve "alter transmission rule": verify STREAM_CHANNEL TYPE
NAME - [#36864](https://github.com/apache/shardingsphere/pull/36864)
1. Pipeline: InventoryDumperContextSplitter supports multi-columns unique key
first integer column splitting -
[#36935](https://github.com/apache/shardingsphere/pull/36935)
+1. Encrypt: Support handling show create view result decoration in encrypt -
[#37299](https://github.com/apache/shardingsphere/pull/37299)
### Bug Fixes
diff --git
a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/merge/EncryptResultDecoratorEngine.java
b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/merge/EncryptResultDecoratorEngine.java
index a92e82a587f..5c4c11dff6c 100644
---
a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/merge/EncryptResultDecoratorEngine.java
+++
b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/merge/EncryptResultDecoratorEngine.java
@@ -44,7 +44,7 @@ public final class EncryptResultDecoratorEngine implements
ResultDecoratorEngine
return Optional.of(new EncryptDQLResultDecorator(database,
metaData, (SelectStatementContext) sqlStatementContext));
}
if (sqlStatementContext.getSqlStatement() instanceof DALStatement) {
- return Optional.of(new
EncryptDALResultDecorator(metaData.getGlobalRuleMetaData()));
+ return Optional.of(new EncryptDALResultDecorator(metaData));
}
return Optional.empty();
}
diff --git
a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/merge/dal/EncryptDALResultDecorator.java
b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/merge/dal/EncryptDALResultDecorator.java
index 155ac930f54..910e127fb76 100644
---
a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/merge/dal/EncryptDALResultDecorator.java
+++
b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/merge/dal/EncryptDALResultDecorator.java
@@ -17,19 +17,21 @@
package org.apache.shardingsphere.encrypt.merge.dal;
+import
com.sphereex.dbplusengine.sql.parser.statement.core.statement.attribute.type.ViewInResultSetSQLStatementAttribute;
import lombok.RequiredArgsConstructor;
import
org.apache.shardingsphere.encrypt.merge.dal.show.EncryptShowColumnsMergedResult;
import
org.apache.shardingsphere.encrypt.merge.dal.show.EncryptShowCreateTableMergedResult;
+import
org.apache.shardingsphere.encrypt.merge.dal.show.EncryptShowCreateViewMergedResult;
import org.apache.shardingsphere.encrypt.rule.EncryptRule;
-import
org.apache.shardingsphere.infra.binder.context.statement.SQLStatementContext;
import org.apache.shardingsphere.infra.merge.engine.decorator.ResultDecorator;
import org.apache.shardingsphere.infra.merge.result.MergedResult;
-import org.apache.shardingsphere.infra.metadata.database.rule.RuleMetaData;
+import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
+import org.apache.shardingsphere.infra.session.query.QueryContext;
import
org.apache.shardingsphere.sql.parser.statement.core.statement.SQLStatement;
import
org.apache.shardingsphere.sql.parser.statement.core.statement.attribute.type.ColumnInResultSetSQLStatementAttribute;
import
org.apache.shardingsphere.sql.parser.statement.core.statement.attribute.type.TableInResultSetSQLStatementAttribute;
-import java.util.List;
+import java.util.Optional;
/**
* DAL result decorator for encrypt.
@@ -37,16 +39,21 @@ import java.util.List;
@RequiredArgsConstructor
public final class EncryptDALResultDecorator implements
ResultDecorator<EncryptRule> {
- private final RuleMetaData globalRuleMetaData;
+ private final ShardingSphereMetaData metaData;
@Override
- public MergedResult decorate(final MergedResult mergedResult, final
SQLStatementContext sqlStatementContext, final List<Object> parameters, final
EncryptRule rule) {
- SQLStatement sqlStatement = sqlStatementContext.getSqlStatement();
+ public MergedResult decorate(final MergedResult mergedResult, final
QueryContext queryContext, final EncryptRule rule) {
+ SQLStatement sqlStatement =
queryContext.getSqlStatementContext().getSqlStatement();
if
(sqlStatement.getAttributes().findAttribute(ColumnInResultSetSQLStatementAttribute.class).isPresent())
{
- return new EncryptShowColumnsMergedResult(mergedResult,
sqlStatementContext, rule);
+ return new EncryptShowColumnsMergedResult(mergedResult,
queryContext.getSqlStatementContext(), rule);
}
if
(sqlStatement.getAttributes().findAttribute(TableInResultSetSQLStatementAttribute.class).isPresent())
{
- return new EncryptShowCreateTableMergedResult(globalRuleMetaData,
mergedResult, sqlStatementContext, rule);
+ return new
EncryptShowCreateTableMergedResult(metaData.getGlobalRuleMetaData(),
mergedResult, queryContext.getSqlStatementContext(), rule);
+ }
+ Optional<ViewInResultSetSQLStatementAttribute>
viewInResultSetSQLStatementAttribute =
sqlStatement.getAttributes().findAttribute(ViewInResultSetSQLStatementAttribute.class);
+ if (viewInResultSetSQLStatementAttribute.isPresent()) {
+ String currentDatabaseName =
queryContext.getConnectionContext().getCurrentDatabaseName().orElse(null);
+ return new EncryptShowCreateViewMergedResult(metaData,
mergedResult, viewInResultSetSQLStatementAttribute.get().getViewName(), rule,
currentDatabaseName);
}
return mergedResult;
}
diff --git
a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/merge/dal/show/EncryptShowCreateViewMergedResult.java
b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/merge/dal/show/EncryptShowCreateViewMergedResult.java
new file mode 100644
index 00000000000..cb35b255639
--- /dev/null
+++
b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/merge/dal/show/EncryptShowCreateViewMergedResult.java
@@ -0,0 +1,137 @@
+/*
+ * 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.encrypt.merge.dal.show;
+
+import
org.apache.shardingsphere.database.connector.core.metadata.database.metadata.DialectDatabaseMetaData;
+import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
+import
org.apache.shardingsphere.database.connector.core.type.DatabaseTypeRegistry;
+import org.apache.shardingsphere.encrypt.rule.EncryptRule;
+import org.apache.shardingsphere.encrypt.rule.table.EncryptTable;
+import org.apache.shardingsphere.infra.merge.result.MergedResult;
+import
org.apache.shardingsphere.infra.merge.result.impl.decorator.DecoratorMergedResult;
+import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
+import org.apache.shardingsphere.infra.parser.SQLParserEngine;
+import org.apache.shardingsphere.parser.rule.SQLParserRule;
+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;
+import
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.OwnerSegment;
+import
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.SimpleTableSegment;
+import
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.TableSegment;
+import
org.apache.shardingsphere.sql.parser.statement.core.statement.type.ddl.view.CreateViewStatement;
+import
org.apache.shardingsphere.sql.parser.statement.core.value.identifier.IdentifierValue;
+
+import java.sql.SQLException;
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * Encrypt show create table merged result.
+ */
+public final class EncryptShowCreateViewMergedResult extends
DecoratorMergedResult {
+
+ private static final String COMMA = ", ";
+
+ private static final int CREATE_TABLE_DEFINITION_INDEX = 2;
+
+ private final MergedResult mergedResult;
+
+ private final String viewName;
+
+ private final EncryptRule rule;
+
+ private final ShardingSphereMetaData metaData;
+
+ private final SQLParserEngine sqlParserEngine;
+
+ private final String currentDatabaseName;
+
+ private final DatabaseType databaseType;
+
+ public EncryptShowCreateViewMergedResult(final ShardingSphereMetaData
metaData, final MergedResult mergedResult, final String viewName, final
EncryptRule rule, final String currentDatabaseName) {
+ super(mergedResult);
+ this.mergedResult = mergedResult;
+ this.viewName = viewName;
+ this.rule = rule;
+ this.metaData = metaData;
+ this.currentDatabaseName = currentDatabaseName;
+ databaseType =
metaData.getDatabase(this.currentDatabaseName).getProtocolType();
+ sqlParserEngine =
metaData.getGlobalRuleMetaData().getSingleRule(SQLParserRule.class).getSQLParserEngine(databaseType);
+ }
+
+ @Override
+ public Object getValue(final int columnIndex, final Class<?> type) throws
SQLException {
+ if (CREATE_TABLE_DEFINITION_INDEX != columnIndex) {
+ return mergedResult.getValue(columnIndex, type);
+ }
+ String createViewSQL =
mergedResult.getValue(CREATE_TABLE_DEFINITION_INDEX, type).toString();
+ Optional<EncryptTable> encryptView = rule.findEncryptTable(viewName);
+ if (!encryptView.isPresent()) {
+ return createViewSQL;
+ }
+ CreateViewStatement createViewStatement = (CreateViewStatement)
sqlParserEngine.parse(createViewSQL, false);
+ Optional<TableSegment> from =
createViewStatement.getSelect().getFrom();
+ if (!from.isPresent() || !(from.get() instanceof SimpleTableSegment)) {
+ return createViewSQL;
+ }
+ String tableName = ((SimpleTableSegment)
from.get()).getTableName().getIdentifier().getValue();
+ Optional<EncryptTable> encryptTable =
+ metaData.getDatabase(getDatabaseName((SimpleTableSegment)
from.get(), databaseType,
currentDatabaseName).getValue()).getRuleMetaData().findSingleRule(EncryptRule.class)
+ .flatMap(encryptRule ->
encryptRule.findEncryptTable(tableName));
+ if (!encryptTable.isPresent()) {
+ return createViewSQL;
+ }
+ List<ProjectionSegment> projections =
createViewStatement.getSelect().getProjections().getProjections();
+ StringBuilder result = new StringBuilder(createViewSQL.substring(0,
projections.get(0).getStartIndex()));
+ for (ProjectionSegment each : projections) {
+ findLogicColumnDefinition(each, encryptView.get(),
encryptTable.get(), createViewSQL).ifPresent(optional ->
result.append(optional).append(COMMA));
+ }
+ result.delete(result.length() - COMMA.length(),
result.length()).append(createViewSQL.substring(projections.get(projections.size()
- 1).getStopIndex() + 1));
+ return result.toString();
+ }
+
+ private static IdentifierValue getDatabaseName(final SimpleTableSegment
segment, final DatabaseType databaseType, final String currentDatabaseName) {
+ DialectDatabaseMetaData dialectDatabaseMetaData = new
DatabaseTypeRegistry(databaseType).getDialectDatabaseMetaData();
+ Optional<OwnerSegment> owner =
dialectDatabaseMetaData.getSchemaOption().getDefaultSchema().isPresent() ?
segment.getOwner().flatMap(OwnerSegment::getOwner) : segment.getOwner();
+ return new IdentifierValue(owner.map(optional ->
optional.getIdentifier().getValue()).orElse(currentDatabaseName));
+ }
+
+ private Optional<String> findLogicColumnDefinition(final ProjectionSegment
projectionSegment, final EncryptTable encryptView, final EncryptTable
encryptTable, final String createTableSQL) {
+ if (!(projectionSegment instanceof ColumnProjectionSegment)) {
+ return
Optional.of(createTableSQL.substring(projectionSegment.getStartIndex(),
projectionSegment.getStopIndex() + 1));
+ }
+ ColumnSegment columnSegment = ((ColumnProjectionSegment)
projectionSegment).getColumn();
+ String columnName = ((ColumnProjectionSegment)
projectionSegment).getAliasName().orElse(columnSegment.getIdentifier().getValue());
+ if (encryptView.isCipherColumn(columnName)) {
+ String logicColumn =
encryptView.getLogicColumnByCipherColumn(columnName);
+ String actualColumn =
encryptTable.getLogicColumnByCipherColumn(columnSegment.getIdentifier().getValue());
+ StringBuilder result = new StringBuilder(actualColumn);
+ Optional<IdentifierValue> alias = ((ColumnProjectionSegment)
projectionSegment).getAlias();
+ alias.ifPresent(identifierValue -> result.append(" AS
").append(identifierValue.getQuoteCharacter().wrap(logicColumn)));
+ return Optional.of(result.toString());
+ }
+ if (isDerivedColumn(encryptView, columnName)) {
+ return Optional.empty();
+ }
+ return
Optional.of(createTableSQL.substring(projectionSegment.getStartIndex(),
projectionSegment.getStopIndex() + 1));
+ }
+
+ private boolean isDerivedColumn(final EncryptTable encryptTable, final
String columnName) {
+ return encryptTable.isAssistedQueryColumn(columnName) ||
encryptTable.isLikeQueryColumn(columnName);
+ }
+}
diff --git
a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/merge/dql/EncryptDQLResultDecorator.java
b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/merge/dql/EncryptDQLResultDecorator.java
index eddd29795f4..8ce4f35203b 100644
---
a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/merge/dql/EncryptDQLResultDecorator.java
+++
b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/merge/dql/EncryptDQLResultDecorator.java
@@ -19,14 +19,12 @@ package org.apache.shardingsphere.encrypt.merge.dql;
import lombok.RequiredArgsConstructor;
import org.apache.shardingsphere.encrypt.rule.EncryptRule;
-import
org.apache.shardingsphere.infra.binder.context.statement.SQLStatementContext;
import
org.apache.shardingsphere.infra.binder.context.statement.type.dml.SelectStatementContext;
import org.apache.shardingsphere.infra.merge.engine.decorator.ResultDecorator;
import org.apache.shardingsphere.infra.merge.result.MergedResult;
import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
import
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
-
-import java.util.List;
+import org.apache.shardingsphere.infra.session.query.QueryContext;
/**
* DQL result decorator for encrypt.
@@ -41,7 +39,7 @@ public final class EncryptDQLResultDecorator implements
ResultDecorator<EncryptR
private final SelectStatementContext selectStatementContext;
@Override
- public MergedResult decorate(final MergedResult mergedResult, final
SQLStatementContext sqlStatementContext, final List<Object> parameters, final
EncryptRule rule) {
+ public MergedResult decorate(final MergedResult mergedResult, final
QueryContext queryContext, final EncryptRule rule) {
return new EncryptMergedResult(database, metaData,
selectStatementContext, mergedResult);
}
}
diff --git
a/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/merge/dal/EncryptDALResultDecoratorTest.java
b/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/merge/dal/EncryptDALResultDecoratorTest.java
index e45505e34e2..d141aff2557 100644
---
a/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/merge/dal/EncryptDALResultDecoratorTest.java
+++
b/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/merge/dal/EncryptDALResultDecoratorTest.java
@@ -23,7 +23,9 @@ import
org.apache.shardingsphere.encrypt.merge.dal.show.EncryptShowCreateTableMe
import org.apache.shardingsphere.encrypt.rule.EncryptRule;
import
org.apache.shardingsphere.infra.binder.context.statement.SQLStatementContext;
import org.apache.shardingsphere.infra.merge.result.MergedResult;
+import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
import org.apache.shardingsphere.infra.metadata.database.rule.RuleMetaData;
+import org.apache.shardingsphere.infra.session.query.QueryContext;
import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
import org.apache.shardingsphere.parser.rule.SQLParserRule;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.SimpleTableSegment;
@@ -60,24 +62,32 @@ class EncryptDALResultDecoratorTest {
@Test
void assertMergedResultWithShowColumnsStatement() {
sqlStatementContext =
mockColumnInResultSetSQLStatementAttributeContext();
- EncryptDALResultDecorator decorator = new
EncryptDALResultDecorator(mock(RuleMetaData.class));
- assertThat(decorator.decorate(mock(MergedResult.class),
sqlStatementContext, Collections.emptyList(), rule),
isA(EncryptShowColumnsMergedResult.class));
+ QueryContext queryContext = mock(QueryContext.class);
+
when(queryContext.getSqlStatementContext()).thenReturn(sqlStatementContext);
+ EncryptDALResultDecorator decorator = new
EncryptDALResultDecorator(mock(ShardingSphereMetaData.class));
+ assertThat(decorator.decorate(mock(MergedResult.class), queryContext,
rule), isA(EncryptShowColumnsMergedResult.class));
}
@Test
void assertMergedResultWithShowCreateTableStatement() {
sqlStatementContext =
mockTableInfoInResultSetAvailableStatementContext();
+ QueryContext queryContext = mock(QueryContext.class);
+
when(queryContext.getSqlStatementContext()).thenReturn(sqlStatementContext);
+ ShardingSphereMetaData metaData = mock(ShardingSphereMetaData.class);
RuleMetaData ruleMetaData = mock(RuleMetaData.class);
when(ruleMetaData.getSingleRule(SQLParserRule.class)).thenReturn(mock(SQLParserRule.class));
- EncryptDALResultDecorator decorator = new
EncryptDALResultDecorator(ruleMetaData);
- assertThat(decorator.decorate(mock(MergedResult.class),
sqlStatementContext, Collections.emptyList(), rule),
isA(EncryptShowCreateTableMergedResult.class));
+ when(metaData.getGlobalRuleMetaData()).thenReturn(ruleMetaData);
+ EncryptDALResultDecorator decorator = new
EncryptDALResultDecorator(metaData);
+ assertThat(decorator.decorate(mock(MergedResult.class), queryContext,
rule), isA(EncryptShowCreateTableMergedResult.class));
}
@Test
void assertMergedResultWithOtherStatement() {
sqlStatementContext = mock(SQLStatementContext.class,
RETURNS_DEEP_STUBS);
- EncryptDALResultDecorator decorator = new
EncryptDALResultDecorator(mock(RuleMetaData.class));
- assertThat(decorator.decorate(mock(MergedResult.class),
sqlStatementContext, Collections.emptyList(), rule), isA(MergedResult.class));
+ QueryContext queryContext = mock(QueryContext.class);
+
when(queryContext.getSqlStatementContext()).thenReturn(sqlStatementContext);
+ EncryptDALResultDecorator decorator = new
EncryptDALResultDecorator(mock(ShardingSphereMetaData.class));
+ assertThat(decorator.decorate(mock(MergedResult.class), queryContext,
rule), isA(MergedResult.class));
}
private SQLStatementContext
mockColumnInResultSetSQLStatementAttributeContext() {
diff --git
a/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/merge/dql/EncryptDQLResultDecoratorTest.java
b/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/merge/dql/EncryptDQLResultDecoratorTest.java
index 55bb454e064..030c3deaaad 100644
---
a/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/merge/dql/EncryptDQLResultDecoratorTest.java
+++
b/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/merge/dql/EncryptDQLResultDecoratorTest.java
@@ -18,7 +18,6 @@
package org.apache.shardingsphere.encrypt.merge.dql;
import org.apache.shardingsphere.encrypt.rule.EncryptRule;
-import
org.apache.shardingsphere.infra.binder.context.statement.SQLStatementContext;
import
org.apache.shardingsphere.infra.binder.context.statement.type.dml.SelectStatementContext;
import org.apache.shardingsphere.infra.merge.result.MergedResult;
import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
@@ -26,7 +25,6 @@ import
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
import org.junit.jupiter.api.Test;
import java.sql.SQLException;
-import java.util.Collections;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
@@ -41,7 +39,7 @@ class EncryptDQLResultDecoratorTest {
when(mergedResult.next()).thenReturn(true);
EncryptDQLResultDecorator decorator =
new
EncryptDQLResultDecorator(mock(ShardingSphereDatabase.class),
mock(ShardingSphereMetaData.class), mock(SelectStatementContext.class,
RETURNS_DEEP_STUBS));
- MergedResult actual = decorator.decorate(mergedResult,
mock(SQLStatementContext.class), Collections.emptyList(),
mock(EncryptRule.class));
+ MergedResult actual = decorator.decorate(mergedResult, mock(),
mock(EncryptRule.class));
assertTrue(actual.next());
}
}
diff --git
a/features/mask/core/src/main/java/org/apache/shardingsphere/mask/merge/dql/MaskDQLResultDecorator.java
b/features/mask/core/src/main/java/org/apache/shardingsphere/mask/merge/dql/MaskDQLResultDecorator.java
index 1b681a9e402..24c6a7b8c74 100644
---
a/features/mask/core/src/main/java/org/apache/shardingsphere/mask/merge/dql/MaskDQLResultDecorator.java
+++
b/features/mask/core/src/main/java/org/apache/shardingsphere/mask/merge/dql/MaskDQLResultDecorator.java
@@ -18,16 +18,14 @@
package org.apache.shardingsphere.mask.merge.dql;
import lombok.RequiredArgsConstructor;
-import
org.apache.shardingsphere.infra.binder.context.statement.SQLStatementContext;
import
org.apache.shardingsphere.infra.binder.context.statement.type.dml.SelectStatementContext;
import org.apache.shardingsphere.infra.merge.engine.decorator.ResultDecorator;
import org.apache.shardingsphere.infra.merge.result.MergedResult;
import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
import
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
+import org.apache.shardingsphere.infra.session.query.QueryContext;
import org.apache.shardingsphere.mask.rule.MaskRule;
-import java.util.List;
-
/**
* DQL result decorator for mask.
*/
@@ -41,7 +39,7 @@ public final class MaskDQLResultDecorator implements
ResultDecorator<MaskRule> {
private final SelectStatementContext selectStatementContext;
@Override
- public MergedResult decorate(final MergedResult mergedResult, final
SQLStatementContext sqlStatementContext, final List<Object> parameters, final
MaskRule rule) {
+ public MergedResult decorate(final MergedResult mergedResult, final
QueryContext queryContext, final MaskRule rule) {
return new MaskMergedResult(database, metaData,
selectStatementContext, mergedResult);
}
}
diff --git
a/features/mask/core/src/test/java/org/apache/shardingsphere/mask/merge/dql/MaskDQLResultDecoratorTest.java
b/features/mask/core/src/test/java/org/apache/shardingsphere/mask/merge/dql/MaskDQLResultDecoratorTest.java
index b4d7a9dbb08..82f8f04814f 100644
---
a/features/mask/core/src/test/java/org/apache/shardingsphere/mask/merge/dql/MaskDQLResultDecoratorTest.java
+++
b/features/mask/core/src/test/java/org/apache/shardingsphere/mask/merge/dql/MaskDQLResultDecoratorTest.java
@@ -17,7 +17,6 @@
package org.apache.shardingsphere.mask.merge.dql;
-import
org.apache.shardingsphere.infra.binder.context.statement.SQLStatementContext;
import
org.apache.shardingsphere.infra.binder.context.statement.type.dml.SelectStatementContext;
import org.apache.shardingsphere.infra.merge.result.MergedResult;
import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
@@ -26,7 +25,6 @@ import org.apache.shardingsphere.mask.rule.MaskRule;
import org.junit.jupiter.api.Test;
import java.sql.SQLException;
-import java.util.Collections;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.mock;
@@ -39,7 +37,7 @@ class MaskDQLResultDecoratorTest {
MergedResult mergedResult = mock(MergedResult.class);
when(mergedResult.next()).thenReturn(true);
MaskDQLResultDecorator decorator = new
MaskDQLResultDecorator(mock(ShardingSphereDatabase.class),
mock(ShardingSphereMetaData.class), mock(SelectStatementContext.class));
- MergedResult actual = decorator.decorate(mergedResult,
mock(SQLStatementContext.class), Collections.emptyList(), mock(MaskRule.class));
+ MergedResult actual = decorator.decorate(mergedResult, mock(),
mock(MaskRule.class));
assertTrue(actual.next());
}
}
diff --git
a/infra/merge/src/main/java/org/apache/shardingsphere/infra/merge/MergeEngine.java
b/infra/merge/src/main/java/org/apache/shardingsphere/infra/merge/MergeEngine.java
index 9a1f8d70258..3063946ff12 100644
---
a/infra/merge/src/main/java/org/apache/shardingsphere/infra/merge/MergeEngine.java
+++
b/infra/merge/src/main/java/org/apache/shardingsphere/infra/merge/MergeEngine.java
@@ -98,8 +98,8 @@ public final class MergeEngine {
for (Entry<ShardingSphereRule, ResultProcessEngine> entry :
engines.entrySet()) {
if (entry.getValue() instanceof ResultDecoratorEngine) {
ResultDecorator resultDecorator =
getResultDecorator(queryContext.getSqlStatementContext(), entry.getValue());
- result = null == result ?
resultDecorator.decorate(mergedResult, queryContext.getSqlStatementContext(),
queryContext.getParameters(), entry.getKey())
- : resultDecorator.decorate(result,
queryContext.getSqlStatementContext(), queryContext.getParameters(),
entry.getKey());
+ result = null == result ?
resultDecorator.decorate(mergedResult, queryContext, entry.getKey())
+ : resultDecorator.decorate(result, queryContext,
entry.getKey());
}
}
return null == result ? mergedResult : result;
diff --git
a/infra/merge/src/main/java/org/apache/shardingsphere/infra/merge/engine/decorator/ResultDecorator.java
b/infra/merge/src/main/java/org/apache/shardingsphere/infra/merge/engine/decorator/ResultDecorator.java
index 03f35c48c22..d2d923a9922 100644
---
a/infra/merge/src/main/java/org/apache/shardingsphere/infra/merge/engine/decorator/ResultDecorator.java
+++
b/infra/merge/src/main/java/org/apache/shardingsphere/infra/merge/engine/decorator/ResultDecorator.java
@@ -17,16 +17,15 @@
package org.apache.shardingsphere.infra.merge.engine.decorator;
-import
org.apache.shardingsphere.infra.binder.context.statement.SQLStatementContext;
import org.apache.shardingsphere.infra.merge.result.MergedResult;
import org.apache.shardingsphere.infra.rule.ShardingSphereRule;
+import org.apache.shardingsphere.infra.session.query.QueryContext;
import java.sql.SQLException;
-import java.util.List;
/**
* Result decorator.
- *
+ *
* @param <T> type of ShardingSphere rule
*/
public interface ResultDecorator<T extends ShardingSphereRule> {
@@ -35,11 +34,10 @@ public interface ResultDecorator<T extends
ShardingSphereRule> {
* Decorate merged result.
*
* @param mergedResult merged result
- * @param sqlStatementContext SQL statement context
- * @param parameters parameters
+ * @param queryContext query context
* @param rule ShardingSphere rule
* @return merged result
* @throws SQLException SQL exception
*/
- MergedResult decorate(MergedResult mergedResult, SQLStatementContext
sqlStatementContext, List<Object> parameters, T rule) throws SQLException;
+ MergedResult decorate(MergedResult mergedResult, QueryContext
queryContext, T rule) throws SQLException;
}
diff --git
a/infra/merge/src/main/java/org/apache/shardingsphere/infra/merge/engine/decorator/impl/TransparentResultDecorator.java
b/infra/merge/src/main/java/org/apache/shardingsphere/infra/merge/engine/decorator/impl/TransparentResultDecorator.java
index 78f46ac92e5..a27a6f0299e 100644
---
a/infra/merge/src/main/java/org/apache/shardingsphere/infra/merge/engine/decorator/impl/TransparentResultDecorator.java
+++
b/infra/merge/src/main/java/org/apache/shardingsphere/infra/merge/engine/decorator/impl/TransparentResultDecorator.java
@@ -17,12 +17,10 @@
package org.apache.shardingsphere.infra.merge.engine.decorator.impl;
-import
org.apache.shardingsphere.infra.binder.context.statement.SQLStatementContext;
import org.apache.shardingsphere.infra.merge.engine.decorator.ResultDecorator;
import org.apache.shardingsphere.infra.merge.result.MergedResult;
import org.apache.shardingsphere.infra.rule.ShardingSphereRule;
-
-import java.util.List;
+import org.apache.shardingsphere.infra.session.query.QueryContext;
/**
* Transparent result decorator.
@@ -30,7 +28,7 @@ import java.util.List;
public final class TransparentResultDecorator implements
ResultDecorator<ShardingSphereRule> {
@Override
- public MergedResult decorate(final MergedResult mergedResult, final
SQLStatementContext sqlStatementContext, final List<Object> parameters, final
ShardingSphereRule rule) {
+ public MergedResult decorate(final MergedResult mergedResult, final
QueryContext queryContext, final ShardingSphereRule rule) {
return mergedResult;
}
}
diff --git
a/infra/merge/src/test/java/org/apache/shardingsphere/infra/merge/engine/decorator/impl/TransparentResultDecoratorTest.java
b/infra/merge/src/test/java/org/apache/shardingsphere/infra/merge/engine/decorator/impl/TransparentResultDecoratorTest.java
index 861846c8e78..4caa1af2489 100644
---
a/infra/merge/src/test/java/org/apache/shardingsphere/infra/merge/engine/decorator/impl/TransparentResultDecoratorTest.java
+++
b/infra/merge/src/test/java/org/apache/shardingsphere/infra/merge/engine/decorator/impl/TransparentResultDecoratorTest.java
@@ -17,13 +17,11 @@
package org.apache.shardingsphere.infra.merge.engine.decorator.impl;
-import
org.apache.shardingsphere.infra.binder.context.statement.SQLStatementContext;
import org.apache.shardingsphere.infra.merge.result.MergedResult;
import org.apache.shardingsphere.infra.rule.ShardingSphereRule;
import org.junit.jupiter.api.Test;
import java.sql.SQLException;
-import java.util.Collections;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.mock;
@@ -36,6 +34,6 @@ class TransparentResultDecoratorTest {
MergedResult mergedResult = mock(MergedResult.class);
when(mergedResult.next()).thenReturn(true);
TransparentResultDecorator decorator = new
TransparentResultDecorator();
- assertTrue(decorator.decorate(mergedResult,
mock(SQLStatementContext.class), Collections.emptyList(),
mock(ShardingSphereRule.class)).next());
+ assertTrue(decorator.decorate(mergedResult, mock(),
mock(ShardingSphereRule.class)).next());
}
}
diff --git
a/infra/merge/src/test/java/org/apache/shardingsphere/infra/merge/fixture/decorator/ResultDecoratorFixture.java
b/infra/merge/src/test/java/org/apache/shardingsphere/infra/merge/fixture/decorator/ResultDecoratorFixture.java
index b1fc0c5a34c..69ecb4d28e6 100644
---
a/infra/merge/src/test/java/org/apache/shardingsphere/infra/merge/fixture/decorator/ResultDecoratorFixture.java
+++
b/infra/merge/src/test/java/org/apache/shardingsphere/infra/merge/fixture/decorator/ResultDecoratorFixture.java
@@ -17,16 +17,15 @@
package org.apache.shardingsphere.infra.merge.fixture.decorator;
-import
org.apache.shardingsphere.infra.binder.context.statement.SQLStatementContext;
import
org.apache.shardingsphere.infra.executor.sql.execute.result.query.impl.driver.jdbc.type.stream.JDBCStreamQueryResult;
import org.apache.shardingsphere.infra.merge.engine.decorator.ResultDecorator;
import org.apache.shardingsphere.infra.merge.fixture.rule.DecoratorRuleFixture;
import org.apache.shardingsphere.infra.merge.result.MergedResult;
import
org.apache.shardingsphere.infra.merge.result.impl.transparent.TransparentMergedResult;
+import org.apache.shardingsphere.infra.session.query.QueryContext;
import java.sql.ResultSet;
import java.sql.SQLException;
-import java.util.List;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -34,7 +33,7 @@ import static org.mockito.Mockito.when;
public final class ResultDecoratorFixture implements
ResultDecorator<DecoratorRuleFixture> {
@Override
- public MergedResult decorate(final MergedResult mergedResult, final
SQLStatementContext sqlStatementContext, final List<Object> parameters, final
DecoratorRuleFixture rule) throws SQLException {
+ public MergedResult decorate(final MergedResult mergedResult, final
QueryContext queryContext, final DecoratorRuleFixture rule) throws SQLException
{
ResultSet resultSet = mock(ResultSet.class);
when(resultSet.getString(1)).thenReturn("decorated_merged_value");
return new TransparentMergedResult(new
JDBCStreamQueryResult(resultSet));
diff --git
a/parser/sql/engine/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/engine/mysql/visitor/statement/type/MySQLDALStatementVisitor.java
b/parser/sql/engine/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/engine/mysql/visitor/statement/type/MySQLDALStatementVisitor.java
index 80ae89db8c9..cf067c04ad3 100644
---
a/parser/sql/engine/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/engine/mysql/visitor/statement/type/MySQLDALStatementVisitor.java
+++
b/parser/sql/engine/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/engine/mysql/visitor/statement/type/MySQLDALStatementVisitor.java
@@ -266,7 +266,7 @@ public final class MySQLDALStatementVisitor extends
MySQLStatementVisitor implem
@Override
public ASTNode visitShowCreateView(final ShowCreateViewContext ctx) {
- return new MySQLShowCreateViewStatement(getDatabaseType(), null);
+ return new MySQLShowCreateViewStatement(getDatabaseType(),
((SimpleTableSegment)
visit(ctx.viewName())).getTableName().getIdentifier().getValue());
}
@Override
diff --git
a/parser/sql/statement/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/statement/mysql/dal/show/view/MySQLShowCreateViewStatement.java
b/parser/sql/statement/core/src/main/java/com/sphereex/dbplusengine/sql/parser/statement/core/statement/attribute/type/ViewInResultSetSQLStatementAttribute.java
similarity index 67%
copy from
parser/sql/statement/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/statement/mysql/dal/show/view/MySQLShowCreateViewStatement.java
copy to
parser/sql/statement/core/src/main/java/com/sphereex/dbplusengine/sql/parser/statement/core/statement/attribute/type/ViewInResultSetSQLStatementAttribute.java
index 9aa9e22a3cd..3982bc53ea2 100644
---
a/parser/sql/statement/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/statement/mysql/dal/show/view/MySQLShowCreateViewStatement.java
+++
b/parser/sql/statement/core/src/main/java/com/sphereex/dbplusengine/sql/parser/statement/core/statement/attribute/type/ViewInResultSetSQLStatementAttribute.java
@@ -15,22 +15,20 @@
* limitations under the License.
*/
-package org.apache.shardingsphere.sql.parser.statement.mysql.dal.show.view;
+package
com.sphereex.dbplusengine.sql.parser.statement.core.statement.attribute.type;
import lombok.Getter;
-import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
-import
org.apache.shardingsphere.sql.parser.statement.core.statement.type.dal.DALStatement;
+import lombok.RequiredArgsConstructor;
+import
org.apache.shardingsphere.sql.parser.statement.core.statement.attribute.SQLStatementAttribute;
/**
- * Show create view statement for MySQL.
+ * Table in result set SQL statement attribute.
*/
+@RequiredArgsConstructor
@Getter
-public final class MySQLShowCreateViewStatement extends DALStatement {
+public final class ViewInResultSetSQLStatementAttribute implements
SQLStatementAttribute {
- private final String viewName;
+ private final int nameResultSetIndex;
- public MySQLShowCreateViewStatement(final DatabaseType databaseType, final
String viewName) {
- super(databaseType);
- this.viewName = viewName;
- }
+ private final String viewName;
}
diff --git
a/parser/sql/statement/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/statement/mysql/dal/show/view/MySQLShowCreateViewStatement.java
b/parser/sql/statement/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/statement/mysql/dal/show/view/MySQLShowCreateViewStatement.java
index 9aa9e22a3cd..41970eca33d 100644
---
a/parser/sql/statement/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/statement/mysql/dal/show/view/MySQLShowCreateViewStatement.java
+++
b/parser/sql/statement/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/statement/mysql/dal/show/view/MySQLShowCreateViewStatement.java
@@ -17,8 +17,11 @@
package org.apache.shardingsphere.sql.parser.statement.mysql.dal.show.view;
+import
com.sphereex.dbplusengine.sql.parser.statement.core.statement.attribute.type.ViewInResultSetSQLStatementAttribute;
import lombok.Getter;
import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
+import
org.apache.shardingsphere.sql.parser.statement.core.statement.attribute.SQLStatementAttributes;
+import
org.apache.shardingsphere.sql.parser.statement.core.statement.attribute.type.DatabaseSelectRequiredSQLStatementAttribute;
import
org.apache.shardingsphere.sql.parser.statement.core.statement.type.dal.DALStatement;
/**
@@ -33,4 +36,9 @@ public final class MySQLShowCreateViewStatement extends
DALStatement {
super(databaseType);
this.viewName = viewName;
}
+
+ @Override
+ public SQLStatementAttributes getAttributes() {
+ return new SQLStatementAttributes(new
DatabaseSelectRequiredSQLStatementAttribute(), new
ViewInResultSetSQLStatementAttribute(2, viewName));
+ }
}
diff --git
a/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/it/sql/dal/DALE2EIT.java
b/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/it/sql/dal/DALE2EIT.java
index 425d346ecdf..b52d0df479d 100644
---
a/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/it/sql/dal/DALE2EIT.java
+++
b/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/it/sql/dal/DALE2EIT.java
@@ -17,6 +17,7 @@
package org.apache.shardingsphere.test.e2e.sql.it.sql.dal;
+import com.google.common.base.Splitter;
import lombok.Setter;
import org.apache.shardingsphere.infra.util.datetime.DateTimeFormatterFactory;
import org.apache.shardingsphere.test.e2e.env.runtime.E2ETestEnvironment;
@@ -30,11 +31,13 @@ import
org.apache.shardingsphere.test.e2e.sql.framework.param.model.AssertionTes
import org.apache.shardingsphere.test.e2e.sql.framework.type.SQLCommandType;
import org.apache.shardingsphere.test.e2e.sql.it.SQLE2EIT;
import org.apache.shardingsphere.test.e2e.sql.it.SQLE2EITContext;
+import org.awaitility.Awaitility;
import org.junit.jupiter.api.condition.EnabledIf;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ArgumentsSource;
import java.sql.Connection;
+import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
@@ -43,6 +46,7 @@ import java.sql.Types;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
+import java.util.concurrent.TimeUnit;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
@@ -75,9 +79,35 @@ class DALE2EIT implements SQLE2EIT {
} catch (final InterruptedException ignore) {
Thread.currentThread().interrupt();
}
+ } finally {
+ tearDown(context);
}
}
+ private void tearDown(final SQLE2EITContext context) throws SQLException {
+ if (null != context.getAssertion().getDestroySQL()) {
+ try (Connection connection =
environmentEngine.getTargetDataSource().getConnection()) {
+ executeDestroySQLs(context, connection);
+ }
+ }
+ }
+
+ private void executeDestroySQLs(final SQLE2EITContext context, final
Connection connection) throws SQLException {
+ if (null == context.getAssertion().getDestroySQL().getSql()) {
+ return;
+ }
+ for (String each :
Splitter.on(";").trimResults().omitEmptyStrings().splitToList(context.getAssertion().getDestroySQL().getSql()))
{
+ try (PreparedStatement preparedStatement =
connection.prepareStatement(each)) {
+ preparedStatement.executeUpdate();
+ }
+ waitCompleted();
+ }
+ }
+
+ private void waitCompleted() {
+ Awaitility.await().pollDelay(1500L, TimeUnit.MILLISECONDS).until(() ->
true);
+ }
+
private void assertExecuteResult(final SQLE2EITContext context, final
Statement statement) throws SQLException {
try (ResultSet resultSet = statement.getResultSet()) {
if (null == context.getAssertion().getAssertionSQL()) {