<h2 dir="auto">Bug Report</h2>
<p dir="auto"><strong>For English only</strong>, other languages will not accept.</p>
<p dir="auto">Before report a bug, make sure you have:</p>
<ul dir="auto">
<li>Searched open and closed <a href="https://github.com/apache/shardingsphere/issues">GitHub issues</a>.</li>
<li>Read documentation: <a href="https://shardingsphere.apache.org/document/current/en/overview" rel="nofollow">ShardingSphere Doc</a>.</li>
</ul>
<p dir="auto">Please pay attention on issues you submitted, because we maybe need more details.<br>
If no response anymore and we cannot reproduce it on current information, we will <strong>close it</strong>.</p>
<p dir="auto">Please answer these questions before submitting your issue. Thanks!</p>
<h3 dir="auto">Which version of ShardingSphere did you use?</h3>
<p dir="auto">shardingsphere-jdbc-core 5.2.0</p>
<h3 dir="auto">Which project did you use? ShardingSphere-JDBC or ShardingSphere-Proxy?</h3>
<p dir="auto">ShardingSphere-JDBC</p>
<h3 dir="auto">Expected behavior</h3>
<p dir="auto">I perform DB operations by Hibernate batch insert. i wish the sql insert executed unexceptly.</p>
<h3 dir="auto">Actual behavior</h3>
<p dir="auto">I perform DB operations by Hibernate batch insert.</p>
<p dir="auto">while execute batch insert, the sql statement is like <code class="notranslate">insert into xx (f1,f2,f3) values (?,?,?)</code>, the output exception is like the following:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="        at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:129)                                                                                                                                                                                                                                         
        at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97)                                                                                                                                                                                                                                          
        at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:89)                                                                                                                                                                                                                                          
        at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:63)               "><pre lang="Caused" class="notranslate"><code class="notranslate">        at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:129)                                                                                                                                                                                                                                         
        at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97)                                                                                                                                                                                                                                          
        at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:89)                                                                                                                                                                                                                                          
        at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:63)               
</code></pre></div>
<h3 dir="auto">Reason analyze (If you can)</h3>
<p dir="auto">I guess the root reason is the <code class="notranslate">ShardingInsertValuesToken</code> class did not implemented toString() method.<br>
I reload the class and implement toString() method, the problem resolved.</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="    @Override
    public String toString() {
        return getInsertValues().stream().map(Objects::toString).collect(Collectors.joining(&quot;,&quot;));
    }"><pre class="notranslate"><code class="notranslate">    @Override
    public String toString() {
        return getInsertValues().stream().map(Objects::toString).collect(Collectors.joining(","));
    }
</code></pre></div>
<p dir="auto">I debug the<code class="notranslate">PrepareStatementImpl</code> instance within mysql-connector lib, the actual sql is<br>
`insert invo xx (f1,f2,f3) values org.apache.shardingsphere.sharding.rewrite.token.pojo.ShardingInsertValuesToken@XXX'</p>
<p dir="auto">The problem occours at sql rewrite process, and i found that when no db sharding is configured, the   by depperly debugging.</p>
<p dir="auto">the invocation path something like below:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="SQLRouteEngine -&gt; PartialSQLRouteExecutor#route
"><pre class="notranslate"><code class="notranslate">SQLRouteEngine -&gt; PartialSQLRouteExecutor#route

</code></pre></div>
<h3 dir="auto">Steps to reproduce the behavior, such as: SQL to execute, sharding rule configuration, when exception occur etc.</h3>
<p dir="auto">MultiDataBaseShardingSphereDataSource.java</p>
<div class="highlight highlight-source-java notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="package app.support;

import org.apache.shardingsphere.driver.jdbc.adapter.AbstractDataSourceAdapter;
import org.apache.shardingsphere.driver.jdbc.context.JDBCContext;
import org.apache.shardingsphere.driver.state.DriverStateContext;
import org.apache.shardingsphere.infra.config.database.DatabaseConfiguration;
import org.apache.shardingsphere.infra.config.database.impl.DataSourceProvidedDatabaseConfiguration;
import org.apache.shardingsphere.infra.config.mode.ModeConfiguration;
import org.apache.shardingsphere.infra.config.rule.RuleConfiguration;
import org.apache.shardingsphere.infra.config.rule.scope.GlobalRuleConfiguration;
import org.apache.shardingsphere.infra.instance.metadata.InstanceMetaData;
import org.apache.shardingsphere.infra.instance.metadata.InstanceMetaDataBuilderFactory;
import org.apache.shardingsphere.mode.manager.ContextManager;
import org.apache.shardingsphere.mode.manager.ContextManagerBuilderFactory;
import org.apache.shardingsphere.mode.manager.ContextManagerBuilderParameter;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * ShardingSphere data source. support multi database
 */
public class MultiDatabaseShardingSphereDataSource extends AbstractDataSourceAdapter implements AutoCloseable {

    private final String databaseName;

    private final ContextManager contextManager;

    private final JDBCContext jdbcContext;

    public MultiDatabaseShardingSphereDataSource(final String databaseName, final ModeConfiguration modeConfig, final Map&lt;String, DataSource&gt; dataSourceMap,
                                    final Collection&lt;RuleConfiguration&gt; ruleConfigs, final Properties props) throws SQLException {
        String[] databaseNames = databaseName.split(&quot;,&quot;);
        this.databaseName = databaseNames[0];
        contextManager = createContextManager(databaseNames, modeConfig, dataSourceMap, ruleConfigs, null == props ? new Properties() : props);
        jdbcContext = new JDBCContext(contextManager.getDataSourceMap(databaseNames[0]));
    }

    private ContextManager createContextManager(final String[] databaseNames, final ModeConfiguration modeConfig, final Map&lt;String, DataSource&gt; dataSourceMap,
                                                final Collection&lt;RuleConfiguration&gt; ruleConfigs, final Properties props) throws SQLException {
        InstanceMetaData instanceMetaData = InstanceMetaDataBuilderFactory.create(&quot;JDBC&quot;, -1);
        Collection&lt;RuleConfiguration&gt; globalRuleConfigs = ruleConfigs.stream().filter(each -&gt; each instanceof GlobalRuleConfiguration).collect(Collectors.toList());
        Collection&lt;RuleConfiguration&gt; databaseRuleConfigs = new LinkedList&lt;&gt;(ruleConfigs);
        databaseRuleConfigs.removeAll(globalRuleConfigs);
        Map&lt;String, DatabaseConfiguration&gt; databaseConfigs = Arrays.stream(databaseNames)
                .collect(Collectors.toMap(Function.identity(),
                        e -&gt; new DataSourceProvidedDatabaseConfiguration(dataSourceMap, databaseRuleConfigs)));
        ContextManagerBuilderParameter parameter = new ContextManagerBuilderParameter(modeConfig, databaseConfigs,
                globalRuleConfigs, props, Collections.emptyList(), instanceMetaData);
        return ContextManagerBuilderFactory.getInstance(modeConfig).build(parameter);
    }

    @Override
    public Connection getConnection() throws SQLException {
        return DriverStateContext.getConnection(databaseName, contextManager, jdbcContext);
    }

    @Override
    public Connection getConnection(final String username, final String password) throws SQLException {
        return getConnection();
    }

    /**
     * Close data sources.
     *
     * @param dataSourceNames data source names to be closed
     * @throws Exception exception
     */
    public void close(final Collection&lt;String&gt; dataSourceNames) throws Exception {
        Map&lt;String, DataSource&gt; dataSourceMap = contextManager.getDataSourceMap(databaseName);
        for (String each : dataSourceNames) {
            close(dataSourceMap.get(each));
        }
        contextManager.close();
    }

    private void close(final DataSource dataSource) throws Exception {
        if (dataSource instanceof AutoCloseable) {
            ((AutoCloseable) dataSource).close();
        }
    }

    @Override
    public void close() throws Exception {
        close(contextManager.getDataSourceMap(databaseName).keySet());
    }

    @Override
    public int getLoginTimeout() throws SQLException {
        Map&lt;String, DataSource&gt; dataSourceMap = contextManager.getDataSourceMap(databaseName);
        return dataSourceMap.isEmpty() ? 0 : dataSourceMap.values().iterator().next().getLoginTimeout();
    }

    @Override
    public void setLoginTimeout(final int seconds) throws SQLException {
        for (DataSource each : contextManager.getDataSourceMap(databaseName).values()) {
            each.setLoginTimeout(seconds);
        }
    }
}"><pre class="notranslate"><span class="pl-k">package</span> <span class="pl-s1">app</span>.<span class="pl-s1">support</span>;

<span class="pl-k">import</span> <span class="pl-s1">org</span>.<span class="pl-s1">apache</span>.<span class="pl-s1">shardingsphere</span>.<span class="pl-s1">driver</span>.<span class="pl-s1">jdbc</span>.<span class="pl-s1">adapter</span>.<span class="pl-s1">AbstractDataSourceAdapter</span>;
<span class="pl-k">import</span> <span class="pl-s1">org</span>.<span class="pl-s1">apache</span>.<span class="pl-s1">shardingsphere</span>.<span class="pl-s1">driver</span>.<span class="pl-s1">jdbc</span>.<span class="pl-s1">context</span>.<span class="pl-s1">JDBCContext</span>;
<span class="pl-k">import</span> <span class="pl-s1">org</span>.<span class="pl-s1">apache</span>.<span class="pl-s1">shardingsphere</span>.<span class="pl-s1">driver</span>.<span class="pl-s1">state</span>.<span class="pl-s1">DriverStateContext</span>;
<span class="pl-k">import</span> <span class="pl-s1">org</span>.<span class="pl-s1">apache</span>.<span class="pl-s1">shardingsphere</span>.<span class="pl-s1">infra</span>.<span class="pl-s1">config</span>.<span class="pl-s1">database</span>.<span class="pl-s1">DatabaseConfiguration</span>;
<span class="pl-k">import</span> <span class="pl-s1">org</span>.<span class="pl-s1">apache</span>.<span class="pl-s1">shardingsphere</span>.<span class="pl-s1">infra</span>.<span class="pl-s1">config</span>.<span class="pl-s1">database</span>.<span class="pl-s1">impl</span>.<span class="pl-s1">DataSourceProvidedDatabaseConfiguration</span>;
<span class="pl-k">import</span> <span class="pl-s1">org</span>.<span class="pl-s1">apache</span>.<span class="pl-s1">shardingsphere</span>.<span class="pl-s1">infra</span>.<span class="pl-s1">config</span>.<span class="pl-s1">mode</span>.<span class="pl-s1">ModeConfiguration</span>;
<span class="pl-k">import</span> <span class="pl-s1">org</span>.<span class="pl-s1">apache</span>.<span class="pl-s1">shardingsphere</span>.<span class="pl-s1">infra</span>.<span class="pl-s1">config</span>.<span class="pl-s1">rule</span>.<span class="pl-s1">RuleConfiguration</span>;
<span class="pl-k">import</span> <span class="pl-s1">org</span>.<span class="pl-s1">apache</span>.<span class="pl-s1">shardingsphere</span>.<span class="pl-s1">infra</span>.<span class="pl-s1">config</span>.<span class="pl-s1">rule</span>.<span class="pl-s1">scope</span>.<span class="pl-s1">GlobalRuleConfiguration</span>;
<span class="pl-k">import</span> <span class="pl-s1">org</span>.<span class="pl-s1">apache</span>.<span class="pl-s1">shardingsphere</span>.<span class="pl-s1">infra</span>.<span class="pl-s1">instance</span>.<span class="pl-s1">metadata</span>.<span class="pl-s1">InstanceMetaData</span>;
<span class="pl-k">import</span> <span class="pl-s1">org</span>.<span class="pl-s1">apache</span>.<span class="pl-s1">shardingsphere</span>.<span class="pl-s1">infra</span>.<span class="pl-s1">instance</span>.<span class="pl-s1">metadata</span>.<span class="pl-s1">InstanceMetaDataBuilderFactory</span>;
<span class="pl-k">import</span> <span class="pl-s1">org</span>.<span class="pl-s1">apache</span>.<span class="pl-s1">shardingsphere</span>.<span class="pl-s1">mode</span>.<span class="pl-s1">manager</span>.<span class="pl-s1">ContextManager</span>;
<span class="pl-k">import</span> <span class="pl-s1">org</span>.<span class="pl-s1">apache</span>.<span class="pl-s1">shardingsphere</span>.<span class="pl-s1">mode</span>.<span class="pl-s1">manager</span>.<span class="pl-s1">ContextManagerBuilderFactory</span>;
<span class="pl-k">import</span> <span class="pl-s1">org</span>.<span class="pl-s1">apache</span>.<span class="pl-s1">shardingsphere</span>.<span class="pl-s1">mode</span>.<span class="pl-s1">manager</span>.<span class="pl-s1">ContextManagerBuilderParameter</span>;

<span class="pl-k">import</span> <span class="pl-s1">javax</span>.<span class="pl-s1">sql</span>.<span class="pl-s1">DataSource</span>;
<span class="pl-k">import</span> <span class="pl-s1">java</span>.<span class="pl-s1">sql</span>.<span class="pl-s1">Connection</span>;
<span class="pl-k">import</span> <span class="pl-s1">java</span>.<span class="pl-s1">sql</span>.<span class="pl-s1">SQLException</span>;
<span class="pl-k">import</span> <span class="pl-s1">java</span>.<span class="pl-s1">util</span>.*;
<span class="pl-k">import</span> <span class="pl-s1">java</span>.<span class="pl-s1">util</span>.<span class="pl-s1">function</span>.<span class="pl-s1">Function</span>;
<span class="pl-k">import</span> <span class="pl-s1">java</span>.<span class="pl-s1">util</span>.<span class="pl-s1">stream</span>.<span class="pl-s1">Collectors</span>;

<span class="pl-c">/**</span>
<span class="pl-c"> * ShardingSphere data source. support multi database</span>
<span class="pl-c"> */</span>
<span class="pl-k">public</span> <span class="pl-k">class</span> <span class="pl-smi">MultiDatabaseShardingSphereDataSource</span> <span class="pl-k">extends</span> <span class="pl-smi">AbstractDataSourceAdapter</span> <span class="pl-k">implements</span> <span class="pl-smi">AutoCloseable</span> {

    <span class="pl-k">private</span> <span class="pl-k">final</span> <span class="pl-smi">String</span> <span class="pl-s1">databaseName</span>;

    <span class="pl-k">private</span> <span class="pl-k">final</span> <span class="pl-smi">ContextManager</span> <span class="pl-s1">contextManager</span>;

    <span class="pl-k">private</span> <span class="pl-k">final</span> <span class="pl-smi">JDBCContext</span> <span class="pl-s1">jdbcContext</span>;

    <span class="pl-k">public</span> <span class="pl-smi">MultiDatabaseShardingSphereDataSource</span>(<span class="pl-k">final</span> <span class="pl-smi">String</span> <span class="pl-s1">databaseName</span>, <span class="pl-k">final</span> <span class="pl-smi">ModeConfiguration</span> <span class="pl-s1">modeConfig</span>, <span class="pl-k">final</span> <span class="pl-smi">Map</span>&lt;<span class="pl-smi">String</span>, <span class="pl-smi">DataSource</span>&gt; <span class="pl-s1">dataSourceMap</span>,
                                    <span class="pl-k">final</span> <span class="pl-smi">Collection</span>&lt;<span class="pl-smi">RuleConfiguration</span>&gt; <span class="pl-s1">ruleConfigs</span>, <span class="pl-k">final</span> <span class="pl-smi">Properties</span> <span class="pl-s1">props</span>) <span class="pl-k">throws</span> <span class="pl-smi">SQLException</span> {
        <span class="pl-smi">String</span>[] <span class="pl-s1">databaseNames</span> = <span class="pl-s1">databaseName</span>.<span class="pl-en">split</span>(<span class="pl-s">","</span>);
        <span class="pl-smi">this</span>.<span class="pl-s1">databaseName</span> = <span class="pl-s1">databaseNames</span>[<span class="pl-c1">0</span>];
        <span class="pl-s1">contextManager</span> = <span class="pl-en">createContextManager</span>(<span class="pl-s1">databaseNames</span>, <span class="pl-s1">modeConfig</span>, <span class="pl-s1">dataSourceMap</span>, <span class="pl-s1">ruleConfigs</span>, <span class="pl-c1">null</span> == <span class="pl-s1">props</span> ? <span class="pl-k">new</span> <span class="pl-smi">Properties</span>() : <span class="pl-s1">props</span>);
        <span class="pl-s1">jdbcContext</span> = <span class="pl-k">new</span> <span class="pl-smi">JDBCContext</span>(<span class="pl-s1">contextManager</span>.<span class="pl-en">getDataSourceMap</span>(<span class="pl-s1">databaseNames</span>[<span class="pl-c1">0</span>]));
    }

    <span class="pl-k">private</span> <span class="pl-smi">ContextManager</span> <span class="pl-en">createContextManager</span>(<span class="pl-k">final</span> <span class="pl-smi">String</span>[] <span class="pl-s1">databaseNames</span>, <span class="pl-k">final</span> <span class="pl-smi">ModeConfiguration</span> <span class="pl-s1">modeConfig</span>, <span class="pl-k">final</span> <span class="pl-smi">Map</span>&lt;<span class="pl-smi">String</span>, <span class="pl-smi">DataSource</span>&gt; <span class="pl-s1">dataSourceMap</span>,
                                                <span class="pl-k">final</span> <span class="pl-smi">Collection</span>&lt;<span class="pl-smi">RuleConfiguration</span>&gt; <span class="pl-s1">ruleConfigs</span>, <span class="pl-k">final</span> <span class="pl-smi">Properties</span> <span class="pl-s1">props</span>) <span class="pl-k">throws</span> <span class="pl-smi">SQLException</span> {
        <span class="pl-smi">InstanceMetaData</span> <span class="pl-s1">instanceMetaData</span> = <span class="pl-smi">InstanceMetaDataBuilderFactory</span>.<span class="pl-en">create</span>(<span class="pl-s">"JDBC"</span>, -<span class="pl-c1">1</span>);
        <span class="pl-smi">Collection</span>&lt;<span class="pl-smi">RuleConfiguration</span>&gt; <span class="pl-s1">globalRuleConfigs</span> = <span class="pl-s1">ruleConfigs</span>.<span class="pl-en">stream</span>().<span class="pl-en">filter</span>(<span class="pl-s1">each</span> -&gt; <span class="pl-s1">each</span> <span class="pl-k">instanceof</span> <span class="pl-smi">GlobalRuleConfiguration</span>).<span class="pl-en">collect</span>(<span class="pl-smi">Collectors</span>.<span class="pl-en">toList</span>());
        <span class="pl-smi">Collection</span>&lt;<span class="pl-smi">RuleConfiguration</span>&gt; <span class="pl-s1">databaseRuleConfigs</span> = <span class="pl-k">new</span> <span class="pl-smi">LinkedList</span>&lt;&gt;(<span class="pl-s1">ruleConfigs</span>);
        <span class="pl-s1">databaseRuleConfigs</span>.<span class="pl-en">removeAll</span>(<span class="pl-s1">globalRuleConfigs</span>);
        <span class="pl-smi">Map</span>&lt;<span class="pl-smi">String</span>, <span class="pl-smi">DatabaseConfiguration</span>&gt; <span class="pl-s1">databaseConfigs</span> = <span class="pl-smi">Arrays</span>.<span class="pl-en">stream</span>(<span class="pl-s1">databaseNames</span>)
                .<span class="pl-en">collect</span>(<span class="pl-smi">Collectors</span>.<span class="pl-en">toMap</span>(<span class="pl-smi">Function</span>.<span class="pl-en">identity</span>(),
                        <span class="pl-s1">e</span> -&gt; <span class="pl-k">new</span> <span class="pl-smi">DataSourceProvidedDatabaseConfiguration</span>(<span class="pl-s1">dataSourceMap</span>, <span class="pl-s1">databaseRuleConfigs</span>)));
        <span class="pl-smi">ContextManagerBuilderParameter</span> <span class="pl-s1">parameter</span> = <span class="pl-k">new</span> <span class="pl-smi">ContextManagerBuilderParameter</span>(<span class="pl-s1">modeConfig</span>, <span class="pl-s1">databaseConfigs</span>,
                <span class="pl-s1">globalRuleConfigs</span>, <span class="pl-s1">props</span>, <span class="pl-smi">Collections</span>.<span class="pl-en">emptyList</span>(), <span class="pl-s1">instanceMetaData</span>);
        <span class="pl-k">return</span> <span class="pl-smi">ContextManagerBuilderFactory</span>.<span class="pl-en">getInstance</span>(<span class="pl-s1">modeConfig</span>).<span class="pl-en">build</span>(<span class="pl-s1">parameter</span>);
    }

    <span class="pl-c1">@</span><span class="pl-c1">Override</span>
    <span class="pl-k">public</span> <span class="pl-smi">Connection</span> <span class="pl-en">getConnection</span>() <span class="pl-k">throws</span> <span class="pl-smi">SQLException</span> {
        <span class="pl-k">return</span> <span class="pl-smi">DriverStateContext</span>.<span class="pl-en">getConnection</span>(<span class="pl-s1">databaseName</span>, <span class="pl-s1">contextManager</span>, <span class="pl-s1">jdbcContext</span>);
    }

    <span class="pl-c1">@</span><span class="pl-c1">Override</span>
    <span class="pl-k">public</span> <span class="pl-smi">Connection</span> <span class="pl-en">getConnection</span>(<span class="pl-k">final</span> <span class="pl-smi">String</span> <span class="pl-s1">username</span>, <span class="pl-k">final</span> <span class="pl-smi">String</span> <span class="pl-s1">password</span>) <span class="pl-k">throws</span> <span class="pl-smi">SQLException</span> {
        <span class="pl-k">return</span> <span class="pl-en">getConnection</span>();
    }

    <span class="pl-c">/**</span>
<span class="pl-c">     * Close data sources.</span>
<span class="pl-c">     *</span>
<span class="pl-c">     * @param dataSourceNames data source names to be closed</span>
<span class="pl-c">     * @throws Exception exception</span>
<span class="pl-c">     */</span>
    <span class="pl-k">public</span> <span class="pl-smi">void</span> <span class="pl-en">close</span>(<span class="pl-k">final</span> <span class="pl-smi">Collection</span>&lt;<span class="pl-smi">String</span>&gt; <span class="pl-s1">dataSourceNames</span>) <span class="pl-k">throws</span> <span class="pl-smi">Exception</span> {
        <span class="pl-smi">Map</span>&lt;<span class="pl-smi">String</span>, <span class="pl-smi">DataSource</span>&gt; <span class="pl-s1">dataSourceMap</span> = <span class="pl-s1">contextManager</span>.<span class="pl-en">getDataSourceMap</span>(<span class="pl-s1">databaseName</span>);
        <span class="pl-k">for</span> (<span class="pl-smi">String</span> <span class="pl-s1">each</span> : <span class="pl-s1">dataSourceNames</span>) {
            <span class="pl-en">close</span>(<span class="pl-s1">dataSourceMap</span>.<span class="pl-en">get</span>(<span class="pl-s1">each</span>));
        }
        <span class="pl-s1">contextManager</span>.<span class="pl-en">close</span>();
    }

    <span class="pl-k">private</span> <span class="pl-smi">void</span> <span class="pl-en">close</span>(<span class="pl-k">final</span> <span class="pl-smi">DataSource</span> <span class="pl-s1">dataSource</span>) <span class="pl-k">throws</span> <span class="pl-smi">Exception</span> {
        <span class="pl-k">if</span> (<span class="pl-s1">dataSource</span> <span class="pl-k">instanceof</span> <span class="pl-smi">AutoCloseable</span>) {
            ((<span class="pl-smi">AutoCloseable</span>) <span class="pl-s1">dataSource</span>).<span class="pl-en">close</span>();
        }
    }

    <span class="pl-c1">@</span><span class="pl-c1">Override</span>
    <span class="pl-k">public</span> <span class="pl-smi">void</span> <span class="pl-en">close</span>() <span class="pl-k">throws</span> <span class="pl-smi">Exception</span> {
        <span class="pl-en">close</span>(<span class="pl-s1">contextManager</span>.<span class="pl-en">getDataSourceMap</span>(<span class="pl-s1">databaseName</span>).<span class="pl-en">keySet</span>());
    }

    <span class="pl-c1">@</span><span class="pl-c1">Override</span>
    <span class="pl-k">public</span> <span class="pl-smi">int</span> <span class="pl-en">getLoginTimeout</span>() <span class="pl-k">throws</span> <span class="pl-smi">SQLException</span> {
        <span class="pl-smi">Map</span>&lt;<span class="pl-smi">String</span>, <span class="pl-smi">DataSource</span>&gt; <span class="pl-s1">dataSourceMap</span> = <span class="pl-s1">contextManager</span>.<span class="pl-en">getDataSourceMap</span>(<span class="pl-s1">databaseName</span>);
        <span class="pl-k">return</span> <span class="pl-s1">dataSourceMap</span>.<span class="pl-en">isEmpty</span>() ? <span class="pl-c1">0</span> : <span class="pl-s1">dataSourceMap</span>.<span class="pl-en">values</span>().<span class="pl-en">iterator</span>().<span class="pl-en">next</span>().<span class="pl-en">getLoginTimeout</span>();
    }

    <span class="pl-c1">@</span><span class="pl-c1">Override</span>
    <span class="pl-k">public</span> <span class="pl-smi">void</span> <span class="pl-en">setLoginTimeout</span>(<span class="pl-k">final</span> <span class="pl-smi">int</span> <span class="pl-s1">seconds</span>) <span class="pl-k">throws</span> <span class="pl-smi">SQLException</span> {
        <span class="pl-k">for</span> (<span class="pl-smi">DataSource</span> <span class="pl-s1">each</span> : <span class="pl-s1">contextManager</span>.<span class="pl-en">getDataSourceMap</span>(<span class="pl-s1">databaseName</span>).<span class="pl-en">values</span>()) {
            <span class="pl-s1">each</span>.<span class="pl-en">setLoginTimeout</span>(<span class="pl-s1">seconds</span>);
        }
    }
}</pre></div>
<p dir="auto">DataSource:</p>
<div class="highlight highlight-source-java notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="@Bean
    DataSource dataSource(Environment environment) {
        BindResult&lt;Map&lt;String, DataSourceProperties&gt;&gt; bindResult = Binder.get(environment)
                .bind(&quot;abacus.datasource&quot;, Bindable.mapOf(String.class, DataSourceProperties.class));
        if (!bindResult.isBound()) {
            throw new IllegalArgumentException(&quot;abacus.datasource must be specified&quot;);
        }

        Map&lt;String, DataSource&gt; dataSourceMap = bindResult.get().entrySet().stream()
                .collect(Collectors.toMap(Map.Entry::getKey, e -&gt; e.getValue().initializeDataSourceBuilder().build()));

        ModeConfiguration modeConfig = new ModeConfiguration(&quot;Standalone&quot;, null, false);

        // table rule:
        ParameterizedType type = TypeUtils.parameterize(Map.class, String.class, TypeUtils.parameterize(List.class, String.class));
        ResolvableType tableRuleConfigType = ResolvableType.forType(type);
        BindResult&lt;Map&lt;String, List&lt;String&gt;&gt;&gt; tableRulesResult = Binder.get(environment).bind(&quot;abacus.table-rules&quot;,
                Bindable.of(tableRuleConfigType));

        List&lt;ShardingTableRuleConfiguration&gt; tableRules = tableRulesResult.get().entrySet().stream()
                .flatMap(entry -&gt; {
                    String db = entry.getKey();
                    return entry.getValue().stream().map(table -&gt; new ShardingTableRuleConfiguration(table,
                            db + &quot;.&quot; + table.replaceFirst(&quot;^([^.]+[.])*&quot;, &quot;&quot;)));
                })
                .collect(Collectors.toList());

        BindResult&lt;List&lt;String&gt;&gt; bindingTables = Binder.get(environment).bind(&quot;abacus.binding-tables&quot;, Bindable.listOf(String.class));

        try {
            ShardingRuleConfiguration rule = new ShardingRuleConfiguration();
            rule.setTables(tableRules);
            rule.setBindingTableGroups(bindingTables.get());
            Properties props = new Properties();
            props.put(&quot;sql-show&quot;, true);
//            return ShardingSphereDataSourceFactory.createDataSource(&quot;abacus&quot;, modeConfig, dataSourceMap,
//                    Collections.singletonList(rule), props);
            return new MultiDatabaseShardingSphereDataSource(&quot;abacus,acornhc_account&quot;, modeConfig, dataSourceMap,
                    Collections.singletonList(rule), props);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }"><pre class="notranslate"><span class="pl-c1">@</span><span class="pl-c1">Bean</span>
    <span class="pl-smi">DataSource</span> <span class="pl-s1">dataSource</span>(<span class="pl-smi">Environment</span> <span class="pl-s1">environment</span>) {
        <span class="pl-smi">BindResult</span>&lt;<span class="pl-smi">Map</span>&lt;<span class="pl-smi">String</span>, <span class="pl-smi">DataSourceProperties</span>&gt;&gt; <span class="pl-s1">bindResult</span> = <span class="pl-smi">Binder</span>.<span class="pl-en">get</span>(<span class="pl-s1">environment</span>)
                .<span class="pl-en">bind</span>(<span class="pl-s">"abacus.datasource"</span>, <span class="pl-smi">Bindable</span>.<span class="pl-en">mapOf</span>(<span class="pl-smi">String</span>.<span class="pl-k">class</span>, <span class="pl-smi">DataSourceProperties</span>.<span class="pl-k">class</span>));
        <span class="pl-k">if</span> (!<span class="pl-s1">bindResult</span>.<span class="pl-en">isBound</span>()) {
            <span class="pl-k">throw</span> <span class="pl-k">new</span> <span class="pl-smi">IllegalArgumentException</span>(<span class="pl-s">"abacus.datasource must be specified"</span>);
        }

        <span class="pl-smi">Map</span>&lt;<span class="pl-smi">String</span>, <span class="pl-smi">DataSource</span>&gt; <span class="pl-s1">dataSourceMap</span> = <span class="pl-s1">bindResult</span>.<span class="pl-en">get</span>().<span class="pl-en">entrySet</span>().<span class="pl-en">stream</span>()
                .<span class="pl-en">collect</span>(<span class="pl-smi">Collectors</span>.<span class="pl-en">toMap</span>(<span class="pl-smi">Map</span>.<span class="pl-s1">Entry</span>::<span class="pl-s1">getKey</span>, <span class="pl-s1">e</span> -&gt; <span class="pl-s1">e</span>.<span class="pl-en">getValue</span>().<span class="pl-en">initializeDataSourceBuilder</span>().<span class="pl-en">build</span>()));

        <span class="pl-smi">ModeConfiguration</span> <span class="pl-s1">modeConfig</span> = <span class="pl-k">new</span> <span class="pl-smi">ModeConfiguration</span>(<span class="pl-s">"Standalone"</span>, <span class="pl-c1">null</span>, <span class="pl-c1">false</span>);

        <span class="pl-c">// table rule:</span>
        <span class="pl-smi">ParameterizedType</span> <span class="pl-s1">type</span> = <span class="pl-smi">TypeUtils</span>.<span class="pl-en">parameterize</span>(<span class="pl-smi">Map</span>.<span class="pl-k">class</span>, <span class="pl-smi">String</span>.<span class="pl-k">class</span>, <span class="pl-smi">TypeUtils</span>.<span class="pl-en">parameterize</span>(<span class="pl-smi">List</span>.<span class="pl-k">class</span>, <span class="pl-smi">String</span>.<span class="pl-k">class</span>));
        <span class="pl-smi">ResolvableType</span> <span class="pl-s1">tableRuleConfigType</span> = <span class="pl-smi">ResolvableType</span>.<span class="pl-en">forType</span>(<span class="pl-s1">type</span>);
        <span class="pl-smi">BindResult</span>&lt;<span class="pl-smi">Map</span>&lt;<span class="pl-smi">String</span>, <span class="pl-smi">List</span>&lt;<span class="pl-smi">String</span>&gt;&gt;&gt; <span class="pl-s1">tableRulesResult</span> = <span class="pl-smi">Binder</span>.<span class="pl-en">get</span>(<span class="pl-s1">environment</span>).<span class="pl-en">bind</span>(<span class="pl-s">"abacus.table-rules"</span>,
                <span class="pl-smi">Bindable</span>.<span class="pl-en">of</span>(<span class="pl-s1">tableRuleConfigType</span>));

        <span class="pl-smi">List</span>&lt;<span class="pl-smi">ShardingTableRuleConfiguration</span>&gt; <span class="pl-s1">tableRules</span> = <span class="pl-s1">tableRulesResult</span>.<span class="pl-en">get</span>().<span class="pl-en">entrySet</span>().<span class="pl-en">stream</span>()
                .<span class="pl-en">flatMap</span>(<span class="pl-s1">entry</span> -&gt; {
                    <span class="pl-smi">String</span> <span class="pl-s1">db</span> = <span class="pl-s1">entry</span>.<span class="pl-en">getKey</span>();
                    <span class="pl-k">return</span> <span class="pl-s1">entry</span>.<span class="pl-en">getValue</span>().<span class="pl-en">stream</span>().<span class="pl-en">map</span>(<span class="pl-s1">table</span> -&gt; <span class="pl-k">new</span> <span class="pl-smi">ShardingTableRuleConfiguration</span>(<span class="pl-s1">table</span>,
                            <span class="pl-s1">db</span> + <span class="pl-s">"."</span> + <span class="pl-s1">table</span>.<span class="pl-en">replaceFirst</span>(<span class="pl-s">"^([^.]+[.])*"</span>, <span class="pl-s">""</span>)));
                })
                .<span class="pl-en">collect</span>(<span class="pl-smi">Collectors</span>.<span class="pl-en">toList</span>());

        <span class="pl-smi">BindResult</span>&lt;<span class="pl-smi">List</span>&lt;<span class="pl-smi">String</span>&gt;&gt; <span class="pl-s1">bindingTables</span> = <span class="pl-smi">Binder</span>.<span class="pl-en">get</span>(<span class="pl-s1">environment</span>).<span class="pl-en">bind</span>(<span class="pl-s">"abacus.binding-tables"</span>, <span class="pl-smi">Bindable</span>.<span class="pl-en">listOf</span>(<span class="pl-smi">String</span>.<span class="pl-k">class</span>));

        <span class="pl-k">try</span> {
            <span class="pl-smi">ShardingRuleConfiguration</span> <span class="pl-s1">rule</span> = <span class="pl-k">new</span> <span class="pl-smi">ShardingRuleConfiguration</span>();
            <span class="pl-s1">rule</span>.<span class="pl-en">setTables</span>(<span class="pl-s1">tableRules</span>);
            <span class="pl-s1">rule</span>.<span class="pl-en">setBindingTableGroups</span>(<span class="pl-s1">bindingTables</span>.<span class="pl-en">get</span>());
            <span class="pl-smi">Properties</span> <span class="pl-s1">props</span> = <span class="pl-k">new</span> <span class="pl-smi">Properties</span>();
            <span class="pl-s1">props</span>.<span class="pl-en">put</span>(<span class="pl-s">"sql-show"</span>, <span class="pl-c1">true</span>);
<span class="pl-c">//            return ShardingSphereDataSourceFactory.createDataSource("abacus", modeConfig, dataSourceMap,</span>
<span class="pl-c">//                    Collections.singletonList(rule), props);</span>
            <span class="pl-k">return</span> <span class="pl-k">new</span> <span class="pl-smi">MultiDatabaseShardingSphereDataSource</span>(<span class="pl-s">"abacus,acornhc_account"</span>, <span class="pl-s1">modeConfig</span>, <span class="pl-s1">dataSourceMap</span>,
                    <span class="pl-smi">Collections</span>.<span class="pl-en">singletonList</span>(<span class="pl-s1">rule</span>), <span class="pl-s1">props</span>);
        } <span class="pl-k">catch</span> (<span class="pl-smi">SQLException</span> <span class="pl-s1">e</span>) {
            <span class="pl-k">throw</span> <span class="pl-k">new</span> <span class="pl-smi">RuntimeException</span>(<span class="pl-s1">e</span>);
        }
    }</pre></div>
<p dir="auto">application.yml:</p>
<div class="highlight highlight-source-yaml notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="abacus:
  datasource:
    default:
      url: jdbc:mysql://ip1:port/abacus
      username: xx
      password: aa
    my-cat-account:
      url: jdbc:mysql://ip2:port/
      username: xx
      password: xx
  table-rules:
    default:
      - abacus.tag
      - abacus.tag_binding
      - abacus.tag_category
    my-cat-account:
      - member

  binding-tables:
    - abacus.tag,abacus.tag_binding
    - abacus.tag_category,abacus.tag
"><pre class="notranslate"><span class="pl-ent">abacus</span>:
  <span class="pl-ent">datasource</span>:
    <span class="pl-ent">default</span>:
      <span class="pl-ent">url</span>: <span class="pl-s">jdbc:mysql://ip1:port/abacus</span>
      <span class="pl-ent">username</span>: <span class="pl-s">xx</span>
      <span class="pl-ent">password</span>: <span class="pl-s">aa</span>
    <span class="pl-ent">my-cat-account</span>:
      <span class="pl-ent">url</span>: <span class="pl-s">jdbc:mysql://ip2:port/</span>
      <span class="pl-ent">username</span>: <span class="pl-s">xx</span>
      <span class="pl-ent">password</span>: <span class="pl-s">xx</span>
  <span class="pl-ent">table-rules</span>:
    <span class="pl-ent">default</span>:
      - <span class="pl-s">abacus.tag</span>
      - <span class="pl-s">abacus.tag_binding</span>
      - <span class="pl-s">abacus.tag_category</span>
    <span class="pl-ent">my-cat-account</span>:
      - <span class="pl-s">member</span>

  <span class="pl-ent">binding-tables</span>:
    - <span class="pl-s">abacus.tag,abacus.tag_binding</span>
    - <span class="pl-s">abacus.tag_category,abacus.tag</span>
</pre></div>
<h3 dir="auto">Example codes for reproduce this issue (such as a github link).</h3>
<p dir="auto">For details, please refer to <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="1074104343" data-permission-text="Title is private" data-url="https://github.com/apache/shardingsphere/issues/13994" data-hovercard-type="issue" data-hovercard-url="/apache/shardingsphere/issues/13994/hovercard" href="https://github.com/apache/shardingsphere/issues/13994">#13994</a></p>
<p dir="auto">The ANTLR definition syntax is as follows:</p>
<div class="highlight highlight-source-sql notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="SHOW SHARDING KEY GENERATORS (FROM schemaName)?"><pre class="notranslate">SHOW SHARDING KEY GENERATORS (<span class="pl-k">FROM</span> schemaName)?</pre></div>
<p dir="auto">Examples are as follows:</p>
<div class="highlight highlight-source-sql notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="&gt; SHOW SHARDING KEY GENERATORS;
+-------------------------+--------+-------------------+
| name                    | type   | props             |
+-------------------------+----------------------------+
| uuid_key_generator      | uuid   | &quot;worker-id&quot;=123   |
+-------------------------+--------+-------------------+"><pre class="notranslate"><span class="pl-k">&gt;</span> SHOW SHARDING KEY GENERATORS;
<span class="pl-k">+</span><span class="pl-c"><span class="pl-c">--</span>-----------------------+--------+-------------------+</span>
| name                    | type   | props             |
<span class="pl-k">+</span><span class="pl-c"><span class="pl-c">--</span>-----------------------+----------------------------+</span>
| uuid_key_generator      | uuid   | <span class="pl-s"><span class="pl-pds">"</span>worker-id<span class="pl-pds">"</span></span><span class="pl-k">=</span><span class="pl-c1">123</span>   |
<span class="pl-k">+</span><span class="pl-c"><span class="pl-c">--</span>-----------------------+--------+-------------------+</span></pre></div>