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 2022/05/09 02:11:42 UTC

[shardingsphere] branch master updated: Fix metadata load lost when refresh create table statement with PostgreSQL schema (#17459)

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 b960f8a4a03 Fix metadata load lost when refresh create table statement with PostgreSQL schema (#17459)
b960f8a4a03 is described below

commit b960f8a4a03dce28dd59556612a4b7f9f47bbfc9
Author: Zhengqiang Duan <du...@apache.org>
AuthorDate: Mon May 9 10:11:37 2022 +0800

    Fix metadata load lost when refresh create table statement with PostgreSQL schema (#17459)
---
 .../metadata/schema/util/TableMetaDataUtil.java    | 16 +++--
 .../schema/util/TableMetaDataUtilTest.java         | 74 ++++++++++++++++++++--
 .../context/refresher/MetaDataRefreshEngine.java   |  2 +-
 3 files changed, 82 insertions(+), 10 deletions(-)

diff --git a/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/metadata/schema/util/TableMetaDataUtil.java b/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/metadata/schema/util/TableMetaDataUtil.java
index 3def8581b1a..895d5a98aa1 100644
--- a/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/metadata/schema/util/TableMetaDataUtil.java
+++ b/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/metadata/schema/util/TableMetaDataUtil.java
@@ -78,14 +78,20 @@ public class TableMetaDataUtil {
     }
     
     private static void addOneActualTableDataNode(final SchemaBuilderMaterials materials, final Map<String, Collection<String>> dataSourceTableGroups, final DataNodes dataNodes, final String table) {
-        Optional<DataNode> optional = dataNodes.getDataNodes(table).stream().filter(each -> materials.getDataSourceMap().containsKey(each.getDataSourceName().contains(".")
-                ? each.getDataSourceName().split("\\.")[0]
-                : each.getDataSourceName())).findFirst();
-        String dataSourceName = optional.map(DataNode::getDataSourceName).orElseGet(() -> materials.getDataSourceMap().keySet().iterator().next());
-        String tableName = optional.map(DataNode::getTableName).orElse(table);
+        Optional<DataNode> dataNode = dataNodes.getDataNodes(table).stream().filter(each -> isSameDataSourceNameSchemaName(materials, each)).findFirst();
+        String dataSourceName = dataNode.map(DataNode::getDataSourceName).orElseGet(() -> materials.getDataSourceMap().keySet().iterator().next());
+        String tableName = dataNode.map(DataNode::getTableName).orElse(table);
         addDataSourceTableGroups(dataSourceName, tableName, dataSourceTableGroups);
     }
     
+    private static boolean isSameDataSourceNameSchemaName(final SchemaBuilderMaterials materials, final DataNode dataNode) {
+        String dataSourceName = dataNode.getDataSourceName().contains(".") ? dataNode.getDataSourceName().split("\\.")[0] : dataNode.getDataSourceName();
+        if (!materials.getDataSourceMap().containsKey(dataSourceName)) {
+            return false;
+        }
+        return null == dataNode.getSchemaName() || dataNode.getSchemaName().equalsIgnoreCase(materials.getDefaultSchemaName());
+    }
+    
     private static void addAllActualTableDataNode(final SchemaBuilderMaterials materials, final Map<String, Collection<String>> dataSourceTableGroups, final DataNodes dataNodes, final String table) {
         Collection<DataNode> tableDataNodes = dataNodes.getDataNodes(table);
         if (tableDataNodes.isEmpty()) {
diff --git a/shardingsphere-infra/shardingsphere-infra-common/src/test/java/org/apache/shardingsphere/infra/metadata/schema/util/TableMetaDataUtilTest.java b/shardingsphere-infra/shardingsphere-infra-common/src/test/java/org/apache/shardingsphere/infra/metadata/schema/util/TableMetaDataUtilTest.java
index ff23c9ede84..ae82b5e9b8e 100644
--- a/shardingsphere-infra/shardingsphere-infra-common/src/test/java/org/apache/shardingsphere/infra/metadata/schema/util/TableMetaDataUtilTest.java
+++ b/shardingsphere-infra/shardingsphere-infra-common/src/test/java/org/apache/shardingsphere/infra/metadata/schema/util/TableMetaDataUtilTest.java
@@ -19,25 +19,91 @@ package org.apache.shardingsphere.infra.metadata.schema.util;
 
 import org.apache.shardingsphere.infra.config.props.ConfigurationProperties;
 import org.apache.shardingsphere.infra.database.type.DatabaseType;
+import org.apache.shardingsphere.infra.datanode.DataNode;
 import org.apache.shardingsphere.infra.metadata.schema.builder.SchemaBuilderMaterials;
+import org.apache.shardingsphere.infra.metadata.schema.loader.TableMetaDataLoaderMaterial;
 import org.apache.shardingsphere.infra.rule.identifier.type.DataNodeContainedRule;
 import org.apache.shardingsphere.infra.rule.identifier.type.DataSourceContainedRule;
 import org.apache.shardingsphere.test.mock.MockedDataSource;
 import org.junit.Test;
 
+import javax.sql.DataSource;
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
 
 import static org.hamcrest.CoreMatchers.is;
 import static org.junit.Assert.assertThat;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
 
 public final class TableMetaDataUtilTest {
     
     @Test
-    public void assertGetTableMetaDataLoadMaterial() {
-        SchemaBuilderMaterials materials = new SchemaBuilderMaterials(mock(DatabaseType.class), Collections.singletonMap("foo_ds", new MockedDataSource()),
-                Arrays.asList(mock(DataNodeContainedRule.class), mock(DataSourceContainedRule.class)), mock(ConfigurationProperties.class), "sharding_db");
-        assertThat(TableMetaDataUtil.getTableMetaDataLoadMaterial(Collections.singleton("t_user"), materials, false).size(), is(1));
+    public void assertGetTableMetaDataLoadMaterialWhenConfigCheckMetaDataEnable() {
+        DataNodeContainedRule dataNodeContainedRule = mock(DataNodeContainedRule.class);
+        when(dataNodeContainedRule.getDataNodesByTableName("t_order")).thenReturn(mockShardingDataNodes());
+        SchemaBuilderMaterials materials = new SchemaBuilderMaterials(mock(DatabaseType.class), mockDataSourceMap(),
+                Arrays.asList(dataNodeContainedRule, mock(DataSourceContainedRule.class)), mock(ConfigurationProperties.class), "sharding_db");
+        Collection<TableMetaDataLoaderMaterial> actual = TableMetaDataUtil.getTableMetaDataLoadMaterial(Collections.singleton("t_order"), materials, true);
+        assertThat(actual.size(), is(2));
+        Iterator<TableMetaDataLoaderMaterial> iterator = actual.iterator();
+        TableMetaDataLoaderMaterial firstMaterial = iterator.next();
+        assertThat(firstMaterial.getDefaultSchemaName(), is("sharding_db"));
+        assertThat(firstMaterial.getTableNames(), is(Collections.singletonList("t_order_0")));
+        TableMetaDataLoaderMaterial secondMaterial = iterator.next();
+        assertThat(secondMaterial.getDefaultSchemaName(), is("sharding_db"));
+        assertThat(secondMaterial.getTableNames(), is(Collections.singletonList("t_order_1")));
+    }
+    
+    @Test
+    public void assertGetTableMetaDataLoadMaterialWhenNotConfigCheckMetaDataEnable() {
+        DataNodeContainedRule dataNodeContainedRule = mock(DataNodeContainedRule.class);
+        when(dataNodeContainedRule.getDataNodesByTableName("t_order")).thenReturn(mockShardingDataNodes());
+        SchemaBuilderMaterials materials = new SchemaBuilderMaterials(mock(DatabaseType.class), mockDataSourceMap(),
+                Arrays.asList(dataNodeContainedRule, mock(DataSourceContainedRule.class)), mock(ConfigurationProperties.class), "sharding_db");
+        Collection<TableMetaDataLoaderMaterial> actual = TableMetaDataUtil.getTableMetaDataLoadMaterial(Collections.singleton("t_order"), materials, false);
+        assertThat(actual.size(), is(1));
+        Iterator<TableMetaDataLoaderMaterial> iterator = actual.iterator();
+        TableMetaDataLoaderMaterial firstMaterial = iterator.next();
+        assertThat(firstMaterial.getDefaultSchemaName(), is("sharding_db"));
+        assertThat(firstMaterial.getTableNames(), is(Collections.singletonList("t_order_0")));
+    }
+    
+    @Test
+    public void assertGetTableMetaDataLoadMaterialWhenNotConfigCheckMetaDataEnableForSingleTableDataNode() {
+        DataNodeContainedRule dataNodeContainedRule = mock(DataNodeContainedRule.class);
+        when(dataNodeContainedRule.getDataNodesByTableName("t_single")).thenReturn(mockSingleTableDataNodes());
+        SchemaBuilderMaterials materials = new SchemaBuilderMaterials(mock(DatabaseType.class), mockDataSourceMap(),
+                Arrays.asList(dataNodeContainedRule, mock(DataSourceContainedRule.class)), mock(ConfigurationProperties.class), "public");
+        Collection<TableMetaDataLoaderMaterial> actual = TableMetaDataUtil.getTableMetaDataLoadMaterial(Collections.singleton("t_single"), materials, false);
+        assertThat(actual.size(), is(1));
+        Iterator<TableMetaDataLoaderMaterial> iterator = actual.iterator();
+        TableMetaDataLoaderMaterial firstMaterial = iterator.next();
+        assertThat(firstMaterial.getDefaultSchemaName(), is("public"));
+        assertThat(firstMaterial.getTableNames(), is(Collections.singletonList("t_single")));
+    }
+    
+    private Collection<DataNode> mockShardingDataNodes() {
+        return Arrays.asList(new DataNode("ds_0.t_order_0"), new DataNode("ds_1.t_order_1"));
+    }
+    
+    private List<DataNode> mockSingleTableDataNodes() {
+        DataNode firstDataNode = new DataNode("ds_0.t_single");
+        firstDataNode.setSchemaName("public");
+        DataNode secondDataNode = new DataNode("ds_0.t_single");
+        secondDataNode.setSchemaName("test");
+        return Arrays.asList(firstDataNode, secondDataNode);
+    }
+    
+    private Map<String, DataSource> mockDataSourceMap() {
+        Map<String, DataSource> result = new HashMap<>(2, 1);
+        result.put("ds_0", new MockedDataSource());
+        result.put("ds_1", new MockedDataSource());
+        return result;
     }
 }
diff --git a/shardingsphere-infra/shardingsphere-infra-context/src/main/java/org/apache/shardingsphere/infra/context/refresher/MetaDataRefreshEngine.java b/shardingsphere-infra/shardingsphere-infra-context/src/main/java/org/apache/shardingsphere/infra/context/refresher/MetaDataRefreshEngine.java
index 087b923656e..6c39ced60d7 100644
--- a/shardingsphere-infra/shardingsphere-infra-context/src/main/java/org/apache/shardingsphere/infra/context/refresher/MetaDataRefreshEngine.java
+++ b/shardingsphere-infra/shardingsphere-infra-context/src/main/java/org/apache/shardingsphere/infra/context/refresher/MetaDataRefreshEngine.java
@@ -65,7 +65,7 @@ public final class MetaDataRefreshEngine {
         }
         Optional<MetaDataRefresher> schemaRefresher = MetaDataRefresherFactory.newInstance(sqlStatementClass);
         if (schemaRefresher.isPresent()) {
-            String schemaName = sqlStatementContext.getTablesContext().getSchemaName().orElse(sqlStatementContext.getDatabaseType().getDefaultSchema(metaData.getDatabaseName()));
+            String schemaName = sqlStatementContext.getTablesContext().getSchemaName().orElseGet(() -> sqlStatementContext.getDatabaseType().getDefaultSchema(metaData.getDatabaseName()));
             schemaRefresher.get().refresh(metaData, federationMetaData, optimizerPlanners, logicDataSourceNamesSupplier.get(), schemaName, sqlStatementContext.getSqlStatement(), props);
         } else {
             IGNORABLE_SQL_STATEMENT_CLASSES.add(sqlStatementClass);