Repository: apache/shardingsphere
Issue: Get error index info when use hibernate.hbm2ddl.auto=update

## Version
* Spring Boot 2.1.5.RELEASE
* ShardingSphere 4.0.0-RC1
* MySQL 5.7
## Question
I have set the option "spring.jpa.properties.hibernate.hbm2ddl.auto=update" 

config application.yml: 
```
datasource:
  names: ds0, ds1, ds2

# ****

sharding:
  default-data-source-name: ds0
# ...
  tables:
     cpn_code:
        actual-data-nodes: ds$->{1..2}.cpn_code$->{0..9}

# ...
```

* Apllication start always send sql  **CREATE INDEX idx_cpnId ON cpn_code...**
 
Because  Index Name in MySql is 'idx_cpnId_cpn_code0, idx_cpnId_cpn_code2...' , hibernate entity
```
@Entity
@Table(name = "cpn_code", indexes = {
        @Index(name = "idx_cpnId", columnList = "cpnId")
})
public class CouponCode {
```


* Sometimes application start fail because got Exception **Cannot find actual data node for data source name: 'ds0' and logic table name: 'cpn_code'**

```
//org.hibernate.tool.schema.internal.GroupedSchemaMigratorImpl#performTablesMigration
//org.hibernate.tool.schema.internal.AbstractSchemaMigrator#applyIndexes
//org.hibernate.tool.schema.internal.AbstractSchemaMigrator#findMatchingIndex
//org.hibernate.tool.schema.extract.internal.TableInformationImpl#getIndex
//org.hibernate.tool.schema.extract.internal.TableInformationImpl#indexes
//org.hibernate.tool.schema.extract.internal.InformationExtractorJdbcDatabaseMetaDataImpl#getIndexes
//org.apache.shardingsphere.shardingjdbc.jdbc.core.datasource.metadata.ResultSetReturnedDatabaseMetaData#getIndexInfo

// when currentDataSourceName is 'ds0' , method getDataNode will throw Exception
return null == table || null == shardingRule ? table : (shardingRule.findTableRule(table).isPresent() ? shardingRule.getDataNode(currentDataSourceName, table).getTableName() : table);
// so I config actual-data-nodes: ds$->{0..2}  to avoid error
```



Changed files:
sharding-jdbc/sharding-jdbc-core/src/main/java/org/apache/shardingsphere/shardingjdbc/jdbc/core/datasource/metadata/ResultSetReturnedDatabaseMetaData.java
sharding-jdbc/sharding-jdbc-core/src/test/java/org/apache/shardingsphere/shardingjdbc/jdbc/core/resultset/DatabaseMetaDataResultSetTest.java
sharding-jdbc/sharding-jdbc-core/src/test/java/org/apache/shardingsphere/shardingjdbc/jdbc/core/datasource/metadata/CachedDatabaseMetaDataTest.java
sharding-jdbc/sharding-jdbc-core/src/main/java/org/apache/shardingsphere/shardingjdbc/jdbc/core/resultset/DatabaseMetaDataResultSet.java

diff --git a/sharding-jdbc/sharding-jdbc-core/src/main/java/org/apache/shardingsphere/shardingjdbc/jdbc/core/datasource/metadata/ResultSetReturnedDatabaseMetaData.java b/sharding-jdbc/sharding-jdbc-core/src/main/java/org/apache/shardingsphere/shardingjdbc/jdbc/core/datasource/metadata/ResultSetReturnedDatabaseMetaData.java
index e029f4baa9e..3db568a57c2 100644
--- a/sharding-jdbc/sharding-jdbc-core/src/main/java/org/apache/shardingsphere/shardingjdbc/jdbc/core/datasource/metadata/ResultSetReturnedDatabaseMetaData.java
+++ b/sharding-jdbc/sharding-jdbc-core/src/main/java/org/apache/shardingsphere/shardingjdbc/jdbc/core/datasource/metadata/ResultSetReturnedDatabaseMetaData.java
@@ -17,6 +17,7 @@
 
 package org.apache.shardingsphere.shardingjdbc.jdbc.core.datasource.metadata;
 
+import org.apache.shardingsphere.core.rule.DataNode;
 import org.apache.shardingsphere.core.rule.ShardingRule;
 import org.apache.shardingsphere.shardingjdbc.jdbc.adapter.WrapperAdapter;
 import org.apache.shardingsphere.shardingjdbc.jdbc.core.resultset.DatabaseMetaDataResultSet;
@@ -257,7 +258,7 @@ public abstract class ResultSetReturnedDatabaseMetaData extends WrapperAdapter i
     }
     
     private String getCurrentDataSourceName() {
-        currentDataSourceName = shardingRule.getShardingDataSourceNames().getRandomDataSourceName();
+        currentDataSourceName = null == currentDataSourceName ? shardingRule.getShardingDataSourceNames().getRandomDataSourceName() : currentDataSourceName;
         return shardingRule.getShardingDataSourceNames().getRawMasterDataSourceName(currentDataSourceName);
     }
     
@@ -266,6 +267,15 @@ public abstract class ResultSetReturnedDatabaseMetaData extends WrapperAdapter i
     }
     
     private String getActualTable(final String table) {
-        return null == table || null == shardingRule ? table : (shardingRule.findTableRule(table).isPresent() ? shardingRule.getDataNode(currentDataSourceName, table).getTableName() : table);
+        if (null == table || null == shardingRule) {
+            return table;
+        }
+        String result = table;
+        if (shardingRule.findTableRule(table).isPresent()) {
+            DataNode dataNode = shardingRule.getDataNode(table);
+            currentDataSourceName = dataNode.getDataSourceName();
+            result = dataNode.getTableName();
+        }
+        return result;
     }
 }
diff --git a/sharding-jdbc/sharding-jdbc-core/src/main/java/org/apache/shardingsphere/shardingjdbc/jdbc/core/resultset/DatabaseMetaDataResultSet.java b/sharding-jdbc/sharding-jdbc-core/src/main/java/org/apache/shardingsphere/shardingjdbc/jdbc/core/resultset/DatabaseMetaDataResultSet.java
index aa4ff31c13c..b71bf21f0a1 100644
--- a/sharding-jdbc/sharding-jdbc-core/src/main/java/org/apache/shardingsphere/shardingjdbc/jdbc/core/resultset/DatabaseMetaDataResultSet.java
+++ b/sharding-jdbc/sharding-jdbc-core/src/main/java/org/apache/shardingsphere/shardingjdbc/jdbc/core/resultset/DatabaseMetaDataResultSet.java
@@ -45,6 +45,8 @@ public final class DatabaseMetaDataResultSet extends AbstractUnsupportedDatabase
     
     private static final String TABLE_NAME = "TABLE_NAME";
     
+    private static final String INDEX_NAME = "INDEX_NAME";
+    
     private final int type;
     
     private final int concurrency;
@@ -82,8 +84,9 @@ public final class DatabaseMetaDataResultSet extends AbstractUnsupportedDatabase
         ArrayList<DatabaseMetaDataObject> result = Lists.newArrayList();
         Set<DatabaseMetaDataObject> removeDuplicationSet = new HashSet<>();
         int tableNameColumnIndex = columnLabelIndexMap.containsKey(TABLE_NAME) ? columnLabelIndexMap.get(TABLE_NAME) : -1;
+        int indexNameColumnIndex = columnLabelIndexMap.containsKey(INDEX_NAME) ? columnLabelIndexMap.get(INDEX_NAME) : -1;
         while (resultSet.next()) {
-            DatabaseMetaDataObject databaseMetaDataObject = generateDatabaseMetaDataObject(tableNameColumnIndex, resultSet);
+            DatabaseMetaDataObject databaseMetaDataObject = generateDatabaseMetaDataObject(tableNameColumnIndex, indexNameColumnIndex, resultSet);
             if (!removeDuplicationSet.contains(databaseMetaDataObject)) {
                 result.add(databaseMetaDataObject);
                 removeDuplicationSet.add(databaseMetaDataObject);
@@ -92,13 +95,17 @@ public final class DatabaseMetaDataResultSet extends AbstractUnsupportedDatabase
         return result.iterator();
     }
     
-    private DatabaseMetaDataObject generateDatabaseMetaDataObject(final int tableNameColumnIndex, final ResultSet resultSet) throws SQLException {
+    private DatabaseMetaDataObject generateDatabaseMetaDataObject(final int tableNameColumnIndex, final int indexNameColumnIndex, final ResultSet resultSet) throws SQLException {
         DatabaseMetaDataObject result = new DatabaseMetaDataObject(resultSetMetaData.getColumnCount());
         for (int i = 1; i <= columnLabelIndexMap.size(); i++) {
             if (tableNameColumnIndex == i) {
                 String tableName = resultSet.getString(i);
                 Collection<String> logicTableNames = shardingRule.getLogicTableNames(tableName);
                 result.addObject(logicTableNames.isEmpty() ? tableName : logicTableNames.iterator().next());
+            } else if (indexNameColumnIndex == i) {
+                String tableName = resultSet.getString(tableNameColumnIndex);
+                String indexName = resultSet.getString(i);
+                result.addObject(indexName.endsWith(tableName) ? indexName.substring(0, indexName.indexOf(tableName) - 1) : indexName);
             } else {
                 result.addObject(resultSet.getObject(i));
             }
diff --git a/sharding-jdbc/sharding-jdbc-core/src/test/java/org/apache/shardingsphere/shardingjdbc/jdbc/core/datasource/metadata/CachedDatabaseMetaDataTest.java b/sharding-jdbc/sharding-jdbc-core/src/test/java/org/apache/shardingsphere/shardingjdbc/jdbc/core/datasource/metadata/CachedDatabaseMetaDataTest.java
index 47a26a5bcb2..875519df792 100644
--- a/sharding-jdbc/sharding-jdbc-core/src/test/java/org/apache/shardingsphere/shardingjdbc/jdbc/core/datasource/metadata/CachedDatabaseMetaDataTest.java
+++ b/sharding-jdbc/sharding-jdbc-core/src/test/java/org/apache/shardingsphere/shardingjdbc/jdbc/core/datasource/metadata/CachedDatabaseMetaDataTest.java
@@ -17,8 +17,10 @@
 
 package org.apache.shardingsphere.shardingjdbc.jdbc.core.datasource.metadata;
 
+import org.apache.shardingsphere.core.rule.DataNode;
 import org.apache.shardingsphere.core.rule.ShardingDataSourceNames;
 import org.apache.shardingsphere.core.rule.ShardingRule;
+import org.apache.shardingsphere.core.rule.TableRule;
 import org.apache.shardingsphere.shardingjdbc.jdbc.core.resultset.DatabaseMetaDataResultSet;
 import org.junit.Before;
 import org.junit.Test;
@@ -43,9 +45,15 @@ import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
+import com.google.common.base.Optional;
+
 @RunWith(MockitoJUnitRunner.class)
 public final class CachedDatabaseMetaDataTest {
     
+    private final String DATASOURCE_NAME = "ds";
+    
+    private final String TABLE_NAME = "table";
+    
     @Mock
     private DataSource dataSource;
     
@@ -64,7 +72,7 @@ public final class CachedDatabaseMetaDataTest {
     
     @Before
     public void setUp() throws SQLException {
-        dataSourceMap.put("ds", dataSource);
+        dataSourceMap.put(DATASOURCE_NAME, dataSource);
         when(dataSource.getConnection()).thenReturn(connection);
         when(connection.getMetaData()).thenReturn(databaseMetaData);
         when(resultSet.getMetaData()).thenReturn(mock(ResultSetMetaData.class));
@@ -74,9 +82,11 @@ public final class CachedDatabaseMetaDataTest {
     private ShardingRule mockShardingRule() {
         ShardingRule result = mock(ShardingRule.class);
         ShardingDataSourceNames shardingDataSourceNames = mock(ShardingDataSourceNames.class);
-        when(shardingDataSourceNames.getRandomDataSourceName()).thenReturn("ds");
-        when(shardingDataSourceNames.getRawMasterDataSourceName("ds")).thenReturn("ds");
+        when(shardingDataSourceNames.getRandomDataSourceName()).thenReturn(DATASOURCE_NAME);
+        when(shardingDataSourceNames.getRawMasterDataSourceName(DATASOURCE_NAME)).thenReturn(DATASOURCE_NAME);
         when(result.getShardingDataSourceNames()).thenReturn(shardingDataSourceNames);
+        when(result.findTableRule(TABLE_NAME)).thenReturn(Optional.of(new TableRule(DATASOURCE_NAME, TABLE_NAME)));
+        when(result.getDataNode(TABLE_NAME)).thenReturn(new DataNode(DATASOURCE_NAME, TABLE_NAME));
         return result;
     }
     
@@ -938,8 +948,8 @@ public final class CachedDatabaseMetaDataTest {
     
     @Test
     public void assertGetIndexInfo() throws SQLException {
-        when(databaseMetaData.getIndexInfo("test", null, null, true, true)).thenReturn(resultSet);
-        assertThat(cachedDatabaseMetaData.getIndexInfo("test", null, null, true, true), instanceOf(DatabaseMetaDataResultSet.class));
+        when(databaseMetaData.getIndexInfo("test", null, TABLE_NAME, true, true)).thenReturn(resultSet);
+        assertThat(cachedDatabaseMetaData.getIndexInfo("test", null, TABLE_NAME, true, true), instanceOf(DatabaseMetaDataResultSet.class));
     }
     
     @Test
diff --git a/sharding-jdbc/sharding-jdbc-core/src/test/java/org/apache/shardingsphere/shardingjdbc/jdbc/core/resultset/DatabaseMetaDataResultSetTest.java b/sharding-jdbc/sharding-jdbc-core/src/test/java/org/apache/shardingsphere/shardingjdbc/jdbc/core/resultset/DatabaseMetaDataResultSetTest.java
index d0440a854c3..00030b4a8d0 100644
--- a/sharding-jdbc/sharding-jdbc-core/src/test/java/org/apache/shardingsphere/shardingjdbc/jdbc/core/resultset/DatabaseMetaDataResultSetTest.java
+++ b/sharding-jdbc/sharding-jdbc-core/src/test/java/org/apache/shardingsphere/shardingjdbc/jdbc/core/resultset/DatabaseMetaDataResultSetTest.java
@@ -65,6 +65,12 @@ public class DatabaseMetaDataResultSetTest {
     
     private static final Date DATE = new Date(System.currentTimeMillis());
     
+    private static final String INDEX_NAME_COLUMN_LABEL = "INDEX_NAME";
+    
+    private static final String ACTUAL_INDEX_NAME = "idx_index_test_table_0";
+    
+    private static final String LOGIC_INDEX_NAME = "idx_index";
+    
     @Mock
     private ResultSetMetaData resultSetMetaData;
     
@@ -78,12 +84,13 @@ public class DatabaseMetaDataResultSetTest {
     
     @SneakyThrows
     private void mockResultSetMetaData() {
-        when(resultSetMetaData.getColumnCount()).thenReturn(5);
+        when(resultSetMetaData.getColumnCount()).thenReturn(6);
         when(resultSetMetaData.getColumnLabel(1)).thenReturn(TABLE_NAME_COLUMN_LABEL);
         when(resultSetMetaData.getColumnLabel(2)).thenReturn(NON_TABLE_NAME_COLUMN_LABEL);
         when(resultSetMetaData.getColumnLabel(3)).thenReturn(NUMBER_COLUMN_LABEL);
         when(resultSetMetaData.getColumnLabel(4)).thenReturn(BYTES_COLUMN_LABEL);
         when(resultSetMetaData.getColumnLabel(5)).thenReturn(DATE_COLUMN_LABEL);
+        when(resultSetMetaData.getColumnLabel(6)).thenReturn(INDEX_NAME_COLUMN_LABEL);
     }
     
     @SneakyThrows
@@ -95,6 +102,7 @@ public class DatabaseMetaDataResultSetTest {
         when(result.getObject(3)).thenReturn(NUMBER);
         when(result.getObject(4)).thenReturn(BYTES);
         when(result.getObject(5)).thenReturn(DATE);
+        when(result.getString(6)).thenReturn(ACTUAL_INDEX_NAME);
         when(result.getType()).thenReturn(ResultSet.TYPE_FORWARD_ONLY);
         when(result.getConcurrency()).thenReturn(ResultSet.CONCUR_READ_ONLY);
         when(result.next()).thenReturn(true, true, false);
@@ -131,6 +139,7 @@ public class DatabaseMetaDataResultSetTest {
         assertThat(databaseMetaDataResultSet.getString(1), is(LOGIC_TABLE_NAME));
         assertThat(databaseMetaDataResultSet.getString(2), is("true"));
         assertThat(databaseMetaDataResultSet.getString(3), is("100"));
+        assertThat(databaseMetaDataResultSet.getString(6), is(LOGIC_INDEX_NAME));
     }
     
     @Test
@@ -139,6 +148,7 @@ public class DatabaseMetaDataResultSetTest {
         assertThat(databaseMetaDataResultSet.getString(TABLE_NAME_COLUMN_LABEL), is(LOGIC_TABLE_NAME));
         assertThat(databaseMetaDataResultSet.getString(NON_TABLE_NAME_COLUMN_LABEL), is("true"));
         assertThat(databaseMetaDataResultSet.getString(NUMBER_COLUMN_LABEL), is("100"));
+        assertThat(databaseMetaDataResultSet.getString(INDEX_NAME_COLUMN_LABEL), is(LOGIC_INDEX_NAME));
     }
     
     @Test
@@ -314,7 +324,7 @@ public class DatabaseMetaDataResultSetTest {
     @Test(expected = SQLException.class)
     public void assertGetObjectOutOfIndexRange() throws SQLException {
         databaseMetaDataResultSet.next();
-        databaseMetaDataResultSet.getObject(6);
+        databaseMetaDataResultSet.getObject(7);
     }
     
     @Test(expected = SQLException.class)