You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by zh...@apache.org on 2023/06/12 09:24:25 UTC
[shardingsphere] branch master updated: Add MetaDataHeldRule for SQLFederationRule to refresh plannerContext when metadata change (#26301)
This is an automated email from the ASF dual-hosted git repository.
zhaojinchao 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 92cbe9f2fed Add MetaDataHeldRule for SQLFederationRule to refresh plannerContext when metadata change (#26301)
92cbe9f2fed is described below
commit 92cbe9f2fedf8f53a76d98792bed10a38cff50fb
Author: Zhengqiang Duan <du...@apache.org>
AuthorDate: Mon Jun 12 17:24:17 2023 +0800
Add MetaDataHeldRule for SQLFederationRule to refresh plannerContext when metadata change (#26301)
* Add MetaDataHeldRule for SQLFederationRule to refresh plannerContext when metadata change
* modify javadoc
* add alterMetaDataHeldRule in reloadDatabaseMetaData
---
.../rule/identifier/type/MetaDataHeldRule.java | 41 ++++++++++++++++++++++
.../rule/identifier/type/MutableDataNodeRule.java | 6 ++--
.../single/decider/SingleSQLFederationDecider.java | 4 +--
.../route/engine/SingleStandardRouteEngine.java | 4 +--
.../shardingsphere/single/rule/SingleRule.java | 6 ++--
.../decider/SingleSQLFederationDeciderTest.java | 4 +--
.../engine/SingleStandardRouteEngineTest.java | 2 +-
.../shardingsphere/single/rule/SingleRuleTest.java | 4 +--
.../optimizer/SQLFederationCompiler.java | 4 +--
.../optimizer/context/OptimizerContext.java | 19 ++++++++++
.../sqlfederation/rule/SQLFederationRule.java | 16 ++++++++-
.../mode/manager/ContextManager.java | 32 +++++++++++++----
.../mode/manager/ContextManagerTest.java | 2 +-
.../standalone/StandaloneModeContextManager.java | 12 ++++++-
14 files changed, 129 insertions(+), 27 deletions(-)
diff --git a/infra/common/src/main/java/org/apache/shardingsphere/infra/rule/identifier/type/MetaDataHeldRule.java b/infra/common/src/main/java/org/apache/shardingsphere/infra/rule/identifier/type/MetaDataHeldRule.java
new file mode 100644
index 00000000000..8f825b3ab32
--- /dev/null
+++ b/infra/common/src/main/java/org/apache/shardingsphere/infra/rule/identifier/type/MetaDataHeldRule.java
@@ -0,0 +1,41 @@
+/*
+ * 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.rule.identifier.type;
+
+import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
+import org.apache.shardingsphere.infra.rule.ShardingSphereRule;
+
+/**
+ * ShardingSphere rule which held metadata.
+ */
+public interface MetaDataHeldRule extends ShardingSphereRule {
+
+ /**
+ * Alter database.
+ *
+ * @param database database
+ */
+ void alterDatabase(ShardingSphereDatabase database);
+
+ /**
+ * Drop database.
+ *
+ * @param databaseName database name
+ */
+ void dropDatabase(String databaseName);
+}
diff --git a/infra/common/src/main/java/org/apache/shardingsphere/infra/rule/identifier/type/MutableDataNodeRule.java b/infra/common/src/main/java/org/apache/shardingsphere/infra/rule/identifier/type/MutableDataNodeRule.java
index f5a9fa8592b..80794b4a9cd 100644
--- a/infra/common/src/main/java/org/apache/shardingsphere/infra/rule/identifier/type/MutableDataNodeRule.java
+++ b/infra/common/src/main/java/org/apache/shardingsphere/infra/rule/identifier/type/MutableDataNodeRule.java
@@ -57,13 +57,13 @@ public interface MutableDataNodeRule extends ShardingSphereRule {
void remove(Collection<String> schemaNames, String tableName);
/**
- * Find single data node.
+ * Find table data node.
*
* @param schemaName schema name
* @param tableName table name
- * @return single table data node
+ * @return table data node
*/
- Optional<DataNode> findSingleTableDataNode(String schemaName, String tableName);
+ Optional<DataNode> findTableDataNode(String schemaName, String tableName);
/**
* Reload single rule.
diff --git a/kernel/single/core/src/main/java/org/apache/shardingsphere/single/decider/SingleSQLFederationDecider.java b/kernel/single/core/src/main/java/org/apache/shardingsphere/single/decider/SingleSQLFederationDecider.java
index 66813c6d1a7..81505878976 100644
--- a/kernel/single/core/src/main/java/org/apache/shardingsphere/single/decider/SingleSQLFederationDecider.java
+++ b/kernel/single/core/src/main/java/org/apache/shardingsphere/single/decider/SingleSQLFederationDecider.java
@@ -91,7 +91,7 @@ public final class SingleSQLFederationDecider implements SQLFederationDecider<Si
return false;
}
QualifiedTable sampleTable = singleTableNames.iterator().next();
- Optional<DataNode> dataNode = rule.findSingleTableDataNode(sampleTable.getSchemaName(), sampleTable.getTableName());
+ Optional<DataNode> dataNode = rule.findTableDataNode(sampleTable.getSchemaName(), sampleTable.getTableName());
if (!dataNode.isPresent()) {
return true;
}
@@ -106,7 +106,7 @@ public final class SingleSQLFederationDecider implements SQLFederationDecider<Si
private Collection<DataNode> getTableDataNodes(final SingleRule rule, final Collection<QualifiedTable> singleTableNames) {
Collection<DataNode> result = new HashSet<>();
for (QualifiedTable each : singleTableNames) {
- rule.findSingleTableDataNode(each.getSchemaName(), each.getTableName()).ifPresent(result::add);
+ rule.findTableDataNode(each.getSchemaName(), each.getTableName()).ifPresent(result::add);
}
return result;
}
diff --git a/kernel/single/core/src/main/java/org/apache/shardingsphere/single/route/engine/SingleStandardRouteEngine.java b/kernel/single/core/src/main/java/org/apache/shardingsphere/single/route/engine/SingleStandardRouteEngine.java
index 88f6d4d2e4f..26cc5edb06f 100644
--- a/kernel/single/core/src/main/java/org/apache/shardingsphere/single/route/engine/SingleStandardRouteEngine.java
+++ b/kernel/single/core/src/main/java/org/apache/shardingsphere/single/route/engine/SingleStandardRouteEngine.java
@@ -77,7 +77,7 @@ public final class SingleStandardRouteEngine implements SingleRouteEngine {
private void route0(final RouteContext routeContext, final SingleRule rule) {
if (sqlStatement instanceof CreateTableStatement) {
QualifiedTable table = singleTableNames.iterator().next();
- Optional<DataNode> dataNodeOptional = rule.findSingleTableDataNode(table.getSchemaName(), table.getTableName());
+ Optional<DataNode> dataNodeOptional = rule.findTableDataNode(table.getSchemaName(), table.getTableName());
boolean containsIfNotExists = CreateTableStatementHandler.ifNotExists((CreateTableStatement) sqlStatement);
if (dataNodeOptional.isPresent() && containsIfNotExists) {
String dataSourceName = dataNodeOptional.map(DataNode::getDataSourceName).orElse(null);
@@ -96,7 +96,7 @@ public final class SingleStandardRouteEngine implements SingleRouteEngine {
private void fillRouteContext(final SingleRule singleRule, final RouteContext routeContext, final Collection<QualifiedTable> logicTables) {
for (QualifiedTable each : logicTables) {
String tableName = each.getTableName();
- Optional<DataNode> dataNode = singleRule.findSingleTableDataNode(each.getSchemaName(), tableName);
+ Optional<DataNode> dataNode = singleRule.findTableDataNode(each.getSchemaName(), tableName);
if (!dataNode.isPresent()) {
throw new SingleTableNotFoundException(tableName);
}
diff --git a/kernel/single/core/src/main/java/org/apache/shardingsphere/single/rule/SingleRule.java b/kernel/single/core/src/main/java/org/apache/shardingsphere/single/rule/SingleRule.java
index 14fb92b46bb..4ceae345101 100644
--- a/kernel/single/core/src/main/java/org/apache/shardingsphere/single/rule/SingleRule.java
+++ b/kernel/single/core/src/main/java/org/apache/shardingsphere/single/rule/SingleRule.java
@@ -131,7 +131,7 @@ public final class SingleRule implements DatabaseRule, DataNodeContainedRule, Ta
public boolean isSingleTablesInSameDataSource(final Collection<QualifiedTable> singleTableNames) {
String firstFoundDataSourceName = null;
for (QualifiedTable each : singleTableNames) {
- Optional<DataNode> dataNode = findSingleTableDataNode(each.getSchemaName(), each.getTableName());
+ Optional<DataNode> dataNode = findTableDataNode(each.getSchemaName(), each.getTableName());
if (!dataNode.isPresent()) {
continue;
}
@@ -158,7 +158,7 @@ public final class SingleRule implements DatabaseRule, DataNodeContainedRule, Ta
return false;
}
QualifiedTable sampleTable = singleTableNames.iterator().next();
- Optional<DataNode> dataNode = findSingleTableDataNode(sampleTable.getSchemaName(), sampleTable.getTableName());
+ Optional<DataNode> dataNode = findTableDataNode(sampleTable.getSchemaName(), sampleTable.getTableName());
if (dataNode.isPresent()) {
for (RouteUnit each : routeContext.getRouteUnits()) {
if (!each.getDataSourceMapper().getLogicName().equals(dataNode.get().getDataSourceName())) {
@@ -225,7 +225,7 @@ public final class SingleRule implements DatabaseRule, DataNodeContainedRule, Ta
}
@Override
- public Optional<DataNode> findSingleTableDataNode(final String schemaName, final String tableName) {
+ public Optional<DataNode> findTableDataNode(final String schemaName, final String tableName) {
Collection<DataNode> dataNodes = singleTableDataNodes.getOrDefault(tableName.toLowerCase(), new LinkedHashSet<>());
for (DataNode each : dataNodes) {
if (schemaName.equalsIgnoreCase(each.getSchemaName())) {
diff --git a/kernel/single/core/src/test/java/org/apache/shardingsphere/single/decider/SingleSQLFederationDeciderTest.java b/kernel/single/core/src/test/java/org/apache/shardingsphere/single/decider/SingleSQLFederationDeciderTest.java
index 72e57550f23..0fc051d7c86 100644
--- a/kernel/single/core/src/test/java/org/apache/shardingsphere/single/decider/SingleSQLFederationDeciderTest.java
+++ b/kernel/single/core/src/test/java/org/apache/shardingsphere/single/decider/SingleSQLFederationDeciderTest.java
@@ -100,8 +100,8 @@ class SingleSQLFederationDeciderTest {
private SingleRule createSingleRule(final Collection<QualifiedTable> qualifiedTables) {
SingleRule result = mock(SingleRule.class);
when(result.getSingleTableNames(any())).thenReturn(qualifiedTables);
- when(result.findSingleTableDataNode(DefaultDatabase.LOGIC_NAME, "t_order")).thenReturn(Optional.of(new DataNode("ds_0", "t_order")));
- when(result.findSingleTableDataNode(DefaultDatabase.LOGIC_NAME, "t_order_item")).thenReturn(Optional.of(new DataNode("ds_0", "t_order_item")));
+ when(result.findTableDataNode(DefaultDatabase.LOGIC_NAME, "t_order")).thenReturn(Optional.of(new DataNode("ds_0", "t_order")));
+ when(result.findTableDataNode(DefaultDatabase.LOGIC_NAME, "t_order_item")).thenReturn(Optional.of(new DataNode("ds_0", "t_order_item")));
return result;
}
diff --git a/kernel/single/core/src/test/java/org/apache/shardingsphere/single/route/engine/SingleStandardRouteEngineTest.java b/kernel/single/core/src/test/java/org/apache/shardingsphere/single/route/engine/SingleStandardRouteEngineTest.java
index b4856a0056c..f9a60cf1ec3 100644
--- a/kernel/single/core/src/test/java/org/apache/shardingsphere/single/route/engine/SingleStandardRouteEngineTest.java
+++ b/kernel/single/core/src/test/java/org/apache/shardingsphere/single/route/engine/SingleStandardRouteEngineTest.java
@@ -149,7 +149,7 @@ class SingleStandardRouteEngineTest {
private SingleRule mockSingleRule() {
SingleRule result = mock(SingleRule.class);
DataNode dataNode = mock(DataNode.class);
- when(result.findSingleTableDataNode(DefaultDatabase.LOGIC_NAME, "t_order")).thenReturn(Optional.of(dataNode));
+ when(result.findTableDataNode(DefaultDatabase.LOGIC_NAME, "t_order")).thenReturn(Optional.of(dataNode));
return result;
}
}
diff --git a/kernel/single/core/src/test/java/org/apache/shardingsphere/single/rule/SingleRuleTest.java b/kernel/single/core/src/test/java/org/apache/shardingsphere/single/rule/SingleRuleTest.java
index 19c93e10e71..61f1c888d26 100644
--- a/kernel/single/core/src/test/java/org/apache/shardingsphere/single/rule/SingleRuleTest.java
+++ b/kernel/single/core/src/test/java/org/apache/shardingsphere/single/rule/SingleRuleTest.java
@@ -121,7 +121,7 @@ class SingleRuleTest {
void assertFindSingleTableDataNode() {
DataNodeContainedRule dataNodeContainedRule = mock(DataNodeContainedRule.class);
SingleRule singleRule = new SingleRule(new SingleRuleConfiguration(), DefaultDatabase.LOGIC_NAME, dataSourceMap, Collections.singleton(dataNodeContainedRule));
- Optional<DataNode> actual = singleRule.findSingleTableDataNode(DefaultDatabase.LOGIC_NAME, "employee");
+ Optional<DataNode> actual = singleRule.findTableDataNode(DefaultDatabase.LOGIC_NAME, "employee");
assertTrue(actual.isPresent());
assertThat(actual.get().getDataSourceName(), is("foo_ds"));
assertThat(actual.get().getTableName(), is("employee"));
@@ -131,7 +131,7 @@ class SingleRuleTest {
void assertFindSingleTableDataNodeWithUpperCase() {
DataNodeContainedRule dataNodeContainedRule = mock(DataNodeContainedRule.class);
SingleRule singleRule = new SingleRule(new SingleRuleConfiguration(), DefaultDatabase.LOGIC_NAME, dataSourceMap, Collections.singleton(dataNodeContainedRule));
- Optional<DataNode> actual = singleRule.findSingleTableDataNode(DefaultDatabase.LOGIC_NAME, "EMPLOYEE");
+ Optional<DataNode> actual = singleRule.findTableDataNode(DefaultDatabase.LOGIC_NAME, "EMPLOYEE");
assertTrue(actual.isPresent());
assertThat(actual.get().getDataSourceName(), is("foo_ds"));
assertThat(actual.get().getTableName(), is("employee"));
diff --git a/kernel/sql-federation/core/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/SQLFederationCompiler.java b/kernel/sql-federation/core/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/SQLFederationCompiler.java
index 9dcffdab4e1..f3e52168028 100644
--- a/kernel/sql-federation/core/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/SQLFederationCompiler.java
+++ b/kernel/sql-federation/core/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/SQLFederationCompiler.java
@@ -22,7 +22,7 @@ import org.apache.calcite.adapter.enumerable.EnumerableConvention;
import org.apache.calcite.plan.RelOptPlanner;
import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.metadata.JaninoRelMetadataProvider;
-import org.apache.calcite.rel.metadata.RelMetadataQuery;
+import org.apache.calcite.rel.metadata.RelMetadataQueryBase;
import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.sql.SqlNode;
import org.apache.calcite.sql2rel.SqlToRelConverter;
@@ -48,7 +48,7 @@ public final class SQLFederationCompiler {
* @return sql federation execution plan
*/
public SQLFederationExecutionPlan compile(final SQLStatement sqlStatement) {
- RelMetadataQuery.THREAD_PROVIDERS.set(JaninoRelMetadataProvider.DEFAULT);
+ RelMetadataQueryBase.THREAD_PROVIDERS.set(JaninoRelMetadataProvider.DEFAULT);
SqlNode sqlNode = SQLNodeConverterEngine.convert(sqlStatement);
RelNode logicPlan = converter.convertQuery(sqlNode, true, true).rel;
RelDataType resultColumnType = Objects.requireNonNull(converter.validator).getValidatedNodeType(sqlNode);
diff --git a/kernel/sql-federation/core/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/context/OptimizerContext.java b/kernel/sql-federation/core/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/context/OptimizerContext.java
index 0e270e35f89..a8d4d6db019 100644
--- a/kernel/sql-federation/core/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/context/OptimizerContext.java
+++ b/kernel/sql-federation/core/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/context/OptimizerContext.java
@@ -57,4 +57,23 @@ public final class OptimizerContext {
public OptimizerPlannerContext getPlannerContext(final String databaseName) {
return plannerContexts.get(databaseName.toLowerCase());
}
+
+ /**
+ * Put planner context.
+ *
+ * @param databaseName database name
+ * @param plannerContext planner context
+ */
+ public void putPlannerContext(final String databaseName, final OptimizerPlannerContext plannerContext) {
+ plannerContexts.put(databaseName.toLowerCase(), plannerContext);
+ }
+
+ /**
+ * Remove planner context.
+ *
+ * @param databaseName database name
+ */
+ public void removePlannerContext(final String databaseName) {
+ plannerContexts.remove(databaseName.toLowerCase());
+ }
}
diff --git a/kernel/sql-federation/core/src/main/java/org/apache/shardingsphere/sqlfederation/rule/SQLFederationRule.java b/kernel/sql-federation/core/src/main/java/org/apache/shardingsphere/sqlfederation/rule/SQLFederationRule.java
index 9af676fce63..e61c695d6b0 100644
--- a/kernel/sql-federation/core/src/main/java/org/apache/shardingsphere/sqlfederation/rule/SQLFederationRule.java
+++ b/kernel/sql-federation/core/src/main/java/org/apache/shardingsphere/sqlfederation/rule/SQLFederationRule.java
@@ -21,10 +21,13 @@ import lombok.Getter;
import org.apache.shardingsphere.infra.config.props.ConfigurationProperties;
import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
import org.apache.shardingsphere.infra.rule.identifier.scope.GlobalRule;
+import org.apache.shardingsphere.infra.rule.identifier.type.MetaDataHeldRule;
import org.apache.shardingsphere.sqlfederation.api.config.SQLFederationRuleConfiguration;
import org.apache.shardingsphere.sqlfederation.executor.SQLFederationExecutor;
import org.apache.shardingsphere.sqlfederation.optimizer.context.OptimizerContext;
import org.apache.shardingsphere.sqlfederation.optimizer.context.OptimizerContextFactory;
+import org.apache.shardingsphere.sqlfederation.optimizer.context.planner.OptimizerPlannerContext;
+import org.apache.shardingsphere.sqlfederation.optimizer.context.planner.OptimizerPlannerContextFactory;
import java.util.Map;
@@ -32,7 +35,7 @@ import java.util.Map;
* SQL federation rule.
*/
@Getter
-public final class SQLFederationRule implements GlobalRule {
+public final class SQLFederationRule implements GlobalRule, MetaDataHeldRule {
private final SQLFederationRuleConfiguration configuration;
@@ -46,6 +49,17 @@ public final class SQLFederationRule implements GlobalRule {
optimizerContext = OptimizerContextFactory.create(databases, props);
}
+ @Override
+ public void alterDatabase(final ShardingSphereDatabase database) {
+ OptimizerPlannerContext plannerContext = OptimizerPlannerContextFactory.create(database, optimizerContext.getParserContext(database.getName()), optimizerContext.getSqlParserRule());
+ optimizerContext.putPlannerContext(database.getName(), plannerContext);
+ }
+
+ @Override
+ public void dropDatabase(final String databaseName) {
+ optimizerContext.removePlannerContext(databaseName);
+ }
+
@Override
public String getType() {
return SQLFederationRule.class.getSimpleName();
diff --git a/mode/core/src/main/java/org/apache/shardingsphere/mode/manager/ContextManager.java b/mode/core/src/main/java/org/apache/shardingsphere/mode/manager/ContextManager.java
index fff537ab4b7..1087f2ad81b 100644
--- a/mode/core/src/main/java/org/apache/shardingsphere/mode/manager/ContextManager.java
+++ b/mode/core/src/main/java/org/apache/shardingsphere/mode/manager/ContextManager.java
@@ -44,6 +44,7 @@ import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSp
import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereTable;
import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereView;
import org.apache.shardingsphere.infra.rule.builder.global.GlobalRulesBuilder;
+import org.apache.shardingsphere.infra.rule.identifier.type.MetaDataHeldRule;
import org.apache.shardingsphere.infra.rule.identifier.type.MutableDataNodeRule;
import org.apache.shardingsphere.infra.rule.identifier.type.ResourceHeldRule;
import org.apache.shardingsphere.infra.rule.identifier.type.TableContainedRule;
@@ -133,6 +134,12 @@ public final class ContextManager implements AutoCloseable {
}
DatabaseType protocolType = DatabaseTypeEngine.getProtocolType(Collections.emptyMap(), metaDataContexts.get().getMetaData().getProps());
metaDataContexts.get().getMetaData().addDatabase(databaseName, protocolType);
+ ShardingSphereDatabase database = metaDataContexts.get().getMetaData().getDatabase(databaseName);
+ alterMetaDataHeldRule(database);
+ }
+
+ private void alterMetaDataHeldRule(final ShardingSphereDatabase database) {
+ metaDataContexts.get().getMetaData().getGlobalRuleMetaData().findRules(MetaDataHeldRule.class).forEach(each -> each.alterDatabase(database));
}
/**
@@ -145,6 +152,7 @@ public final class ContextManager implements AutoCloseable {
return;
}
metaDataContexts.get().getMetaData().dropDatabase(metaDataContexts.get().getMetaData().getDatabase(databaseName).getName());
+ metaDataContexts.get().getMetaData().getGlobalRuleMetaData().findRules(MetaDataHeldRule.class).forEach(each -> each.dropDatabase(databaseName));
}
/**
@@ -154,10 +162,12 @@ public final class ContextManager implements AutoCloseable {
* @param schemaName schema name
*/
public synchronized void addSchema(final String databaseName, final String schemaName) {
- if (metaDataContexts.get().getMetaData().getDatabase(databaseName).containsSchema(schemaName)) {
+ ShardingSphereDatabase database = metaDataContexts.get().getMetaData().getDatabase(databaseName);
+ if (database.containsSchema(schemaName)) {
return;
}
- metaDataContexts.get().getMetaData().getDatabase(databaseName).putSchema(schemaName, new ShardingSphereSchema());
+ database.putSchema(schemaName, new ShardingSphereSchema());
+ alterMetaDataHeldRule(database);
}
/**
@@ -167,10 +177,12 @@ public final class ContextManager implements AutoCloseable {
* @param schemaName schema name
*/
public synchronized void dropSchema(final String databaseName, final String schemaName) {
- if (!metaDataContexts.get().getMetaData().getDatabase(databaseName).containsSchema(schemaName)) {
+ ShardingSphereDatabase database = metaDataContexts.get().getMetaData().getDatabase(databaseName);
+ if (!database.containsSchema(schemaName)) {
return;
}
- metaDataContexts.get().getMetaData().getDatabase(databaseName).removeSchema(schemaName);
+ database.removeSchema(schemaName);
+ alterMetaDataHeldRule(database);
}
/**
@@ -184,6 +196,7 @@ public final class ContextManager implements AutoCloseable {
public synchronized void alterSchema(final String databaseName, final String schemaName, final String toBeDeletedTableName, final String toBeDeletedViewName) {
Optional.ofNullable(toBeDeletedTableName).ifPresent(optional -> dropTable(databaseName, schemaName, optional));
Optional.ofNullable(toBeDeletedViewName).ifPresent(optional -> dropView(databaseName, schemaName, optional));
+ alterMetaDataHeldRule(metaDataContexts.get().getMetaData().getDatabase(databaseName));
}
/**
@@ -200,6 +213,7 @@ public final class ContextManager implements AutoCloseable {
}
Optional.ofNullable(toBeChangedTable).ifPresent(optional -> alterTable(databaseName, schemaName, optional));
Optional.ofNullable(toBeChangedView).ifPresent(optional -> alterView(databaseName, schemaName, optional));
+ alterMetaDataHeldRule(metaDataContexts.get().getMetaData().getDatabase(databaseName));
}
private synchronized void dropTable(final String databaseName, final String schemaName, final String toBeDeletedTableName) {
@@ -467,15 +481,17 @@ public final class ContextManager implements AutoCloseable {
*/
public synchronized void reloadDatabaseMetaData(final String databaseName) {
try {
- ShardingSphereResourceMetaData currentResourceMetaData = metaDataContexts.get().getMetaData().getDatabase(databaseName).getResourceMetaData();
+ ShardingSphereDatabase database = metaDataContexts.get().getMetaData().getDatabase(databaseName);
+ ShardingSphereResourceMetaData currentResourceMetaData = database.getResourceMetaData();
Map<String, DataSourceProperties> dataSourceProps = metaDataContexts.get().getPersistService().getDataSourceService().load(databaseName);
SwitchingResource switchingResource = new ResourceSwitchManager().createByAlterDataSourceProps(currentResourceMetaData, dataSourceProps);
- metaDataContexts.get().getMetaData().getDatabases().putAll(renewDatabase(metaDataContexts.get().getMetaData().getDatabase(databaseName), switchingResource));
+ metaDataContexts.get().getMetaData().getDatabases().putAll(renewDatabase(database, switchingResource));
MetaDataContexts reloadedMetaDataContexts = createMetaDataContexts(databaseName, switchingResource);
- deletedSchemaNames(databaseName, reloadedMetaDataContexts.getMetaData().getDatabase(databaseName), metaDataContexts.get().getMetaData().getDatabase(databaseName));
+ deletedSchemaNames(databaseName, reloadedMetaDataContexts.getMetaData().getDatabase(databaseName), database);
metaDataContexts.set(reloadedMetaDataContexts);
metaDataContexts.get().getMetaData().getDatabases().values().forEach(each -> each.getSchemas()
.forEach((schemaName, schema) -> metaDataContexts.get().getPersistService().getDatabaseMetaDataService().compareAndPersist(each.getName(), schemaName, schema)));
+ alterMetaDataHeldRule(database);
switchingResource.closeStaleDataSources();
} catch (final SQLException ex) {
log.error("Reload database meta data: {} failed", databaseName, ex);
@@ -513,6 +529,7 @@ public final class ContextManager implements AutoCloseable {
metaDataContexts.get().getPersistService().getDatabaseMetaDataService()
.compareAndPersist(metaDataContexts.get().getMetaData().getDatabase(databaseName).getName(), schemaName, reloadedSchema);
}
+ alterMetaDataHeldRule(metaDataContexts.get().getMetaData().getDatabase(databaseName));
} catch (final SQLException ex) {
log.error("Reload meta data of database: {} schema: {} with data source: {} failed", databaseName, schemaName, dataSourceName, ex);
}
@@ -574,6 +591,7 @@ public final class ContextManager implements AutoCloseable {
dropTable(databaseName, schemaName, tableName);
}
metaDataContexts.get().getPersistService().getDatabaseMetaDataService().compareAndPersist(database.getName(), schemaName, database.getSchema(schemaName));
+ alterMetaDataHeldRule(metaDataContexts.get().getMetaData().getDatabase(databaseName));
}
/**
diff --git a/mode/core/src/test/java/org/apache/shardingsphere/mode/manager/ContextManagerTest.java b/mode/core/src/test/java/org/apache/shardingsphere/mode/manager/ContextManagerTest.java
index df32950d568..477324887d6 100644
--- a/mode/core/src/test/java/org/apache/shardingsphere/mode/manager/ContextManagerTest.java
+++ b/mode/core/src/test/java/org/apache/shardingsphere/mode/manager/ContextManagerTest.java
@@ -96,7 +96,7 @@ class ContextManagerTest {
when(result.getProtocolType()).thenReturn(new MySQLDatabaseType());
when(result.getResourceMetaData().getStorageTypes()).thenReturn(Collections.singletonMap("ds_0", new MySQLDatabaseType()));
MutableDataNodeRule mutableDataNodeRule = mock(MutableDataNodeRule.class, RETURNS_DEEP_STUBS);
- when(mutableDataNodeRule.findSingleTableDataNode("foo_schema", "foo_tbl")).thenReturn(Optional.of(mock(DataNode.class)));
+ when(mutableDataNodeRule.findTableDataNode("foo_schema", "foo_tbl")).thenReturn(Optional.of(mock(DataNode.class)));
when(result.getRuleMetaData()).thenReturn(new ShardingSphereRuleMetaData(Collections.singleton(mutableDataNodeRule)));
when(result.getSchemas()).thenReturn(new HashMap<>(Collections.singletonMap("foo_schema", new ShardingSphereSchema())));
return result;
diff --git a/mode/type/standalone/core/src/main/java/org/apache/shardingsphere/mode/manager/standalone/StandaloneModeContextManager.java b/mode/type/standalone/core/src/main/java/org/apache/shardingsphere/mode/manager/standalone/StandaloneModeContextManager.java
index 489b94d59dc..51c7ef73935 100644
--- a/mode/type/standalone/core/src/main/java/org/apache/shardingsphere/mode/manager/standalone/StandaloneModeContextManager.java
+++ b/mode/type/standalone/core/src/main/java/org/apache/shardingsphere/mode/manager/standalone/StandaloneModeContextManager.java
@@ -27,6 +27,7 @@ import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSp
import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereView;
import org.apache.shardingsphere.infra.metadata.database.schema.pojo.AlterSchemaMetaDataPOJO;
import org.apache.shardingsphere.infra.metadata.database.schema.pojo.AlterSchemaPOJO;
+import org.apache.shardingsphere.infra.rule.identifier.type.MetaDataHeldRule;
import org.apache.shardingsphere.infra.rule.identifier.type.MutableDataNodeRule;
import org.apache.shardingsphere.infra.rule.identifier.type.ResourceHeldRule;
import org.apache.shardingsphere.infra.rule.identifier.type.TableContainedRule;
@@ -72,7 +73,9 @@ public final class StandaloneModeContextManager implements ModeContextManager, C
@Override
public void createSchema(final String databaseName, final String schemaName) {
ShardingSphereSchema schema = new ShardingSphereSchema();
- contextManager.getMetaDataContexts().getMetaData().getDatabase(databaseName).putSchema(schemaName, schema);
+ ShardingSphereDatabase database = contextManager.getMetaDataContexts().getMetaData().getDatabase(databaseName);
+ database.putSchema(schemaName, schema);
+ refreshMetaDataHeldRule(database);
contextManager.getMetaDataContexts().getPersistService().getDatabaseMetaDataService().persist(databaseName, schemaName, schema);
}
@@ -81,6 +84,7 @@ public final class StandaloneModeContextManager implements ModeContextManager, C
ShardingSphereDatabase database = contextManager.getMetaDataContexts().getMetaData().getDatabase(alterSchemaPOJO.getDatabaseName());
putSchemaMetaData(database, alterSchemaPOJO.getSchemaName(), alterSchemaPOJO.getRenameSchemaName(), alterSchemaPOJO.getLogicDataSourceName());
removeSchemaMetaData(database, alterSchemaPOJO.getSchemaName());
+ refreshMetaDataHeldRule(database);
DatabaseMetaDataBasedPersistService databaseMetaDataService = contextManager.getMetaDataContexts().getPersistService().getDatabaseMetaDataService();
databaseMetaDataService.persist(alterSchemaPOJO.getDatabaseName(), alterSchemaPOJO.getRenameSchemaName(), database.getSchema(alterSchemaPOJO.getRenameSchemaName()));
databaseMetaDataService.getViewMetaDataPersistService().persist(alterSchemaPOJO.getDatabaseName(), alterSchemaPOJO.getRenameSchemaName(),
@@ -175,6 +179,7 @@ public final class StandaloneModeContextManager implements ModeContextManager, C
tobeRemovedSchemas.add(each.toLowerCase());
}
removeDataNode(database.getRuleMetaData().findRules(MutableDataNodeRule.class), tobeRemovedSchemas, tobeRemovedTables);
+ refreshMetaDataHeldRule(database);
}
@Override
@@ -186,6 +191,7 @@ public final class StandaloneModeContextManager implements ModeContextManager, C
Map<String, ShardingSphereView> views = alterSchemaMetaDataPOJO.getAlteredViews().stream().collect(Collectors.toMap(ShardingSphereView::getName, view -> view));
addDataNode(database, alterSchemaMetaDataPOJO.getLogicDataSourceName(), schemaName, tables, views);
removeDataNode(database, schemaName, alterSchemaMetaDataPOJO.getDroppedTables(), alterSchemaMetaDataPOJO.getDroppedViews());
+ refreshMetaDataHeldRule(database);
DatabaseMetaDataBasedPersistService databaseMetaDataService = contextManager.getMetaDataContexts().getPersistService().getDatabaseMetaDataService();
databaseMetaDataService.getTableMetaDataPersistService().persist(databaseName, schemaName, tables);
databaseMetaDataService.getViewMetaDataPersistService().persist(databaseName, schemaName, views);
@@ -193,6 +199,10 @@ public final class StandaloneModeContextManager implements ModeContextManager, C
alterSchemaMetaDataPOJO.getDroppedViews().forEach(each -> databaseMetaDataService.getViewMetaDataPersistService().delete(databaseName, schemaName, each));
}
+ private void refreshMetaDataHeldRule(final ShardingSphereDatabase database) {
+ contextManager.getMetaDataContexts().getMetaData().getGlobalRuleMetaData().findRules(MetaDataHeldRule.class).forEach(each -> each.alterDatabase(database));
+ }
+
@Override
public void registerStorageUnits(final String databaseName, final Map<String, DataSourceProperties> toBeRegisterStorageUnitProps) throws SQLException {
SwitchingResource switchingResource =