You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by pa...@apache.org on 2021/10/09 11:15:16 UTC

[shardingsphere] branch master updated: add parameterized unit test for sql node convert (#12955)

This is an automated email from the ASF dual-hosted git repository.

panjuan 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 ef85b77  add parameterized unit test for sql node convert (#12955)
ef85b77 is described below

commit ef85b7783b6b7470adc57e4eae5e3326c551ae2e
Author: Zhengqiang Duan <du...@apache.org>
AuthorDate: Sat Oct 9 19:14:27 2021 +0800

    add parameterized unit test for sql node convert (#12955)
    
    * add parameterized unit test for sql node convert
    
    * fix checkstyle
---
 .../engine/SQLNodeConvertParameterizedTest.java    | 100 ++++++++++++++
 .../parameterized/jaxb/SQLNodeConvertCase.java     |  43 ++++++
 .../parameterized/jaxb/SQLNodeConvertCases.java    |  40 ++++++
 .../jaxb/SQLNodeConvertCasesRegistry.java          |  47 +++++++
 .../loader/SQLNodeConvertCasesLoader.java          | 146 +++++++++++++++++++++
 .../statement/SelectStatementConverterTest.java    |  60 ---------
 .../test/resources/converter/supported/select.xml  |  26 ++++
 7 files changed, 402 insertions(+), 60 deletions(-)

diff --git a/shardingsphere-infra/shardingsphere-infra-optimize/src/test/java/org/apache/shardingsphere/infra/optimize/converter/parameterized/engine/SQLNodeConvertParameterizedTest.java b/shardingsphere-infra/shardingsphere-infra-optimize/src/test/java/org/apache/shardingsphere/infra/optimize/converter/parameterized/engine/SQLNodeConvertParameterizedTest.java
new file mode 100644
index 0000000..5b30e06
--- /dev/null
+++ b/shardingsphere-infra/shardingsphere-infra-optimize/src/test/java/org/apache/shardingsphere/infra/optimize/converter/parameterized/engine/SQLNodeConvertParameterizedTest.java
@@ -0,0 +1,100 @@
+/*
+ * 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.optimize.converter.parameterized.engine;
+
+import lombok.RequiredArgsConstructor;
+import lombok.SneakyThrows;
+import org.apache.calcite.config.CalciteConnectionConfig;
+import org.apache.calcite.config.CalciteConnectionConfigImpl;
+import org.apache.calcite.config.CalciteConnectionProperty;
+import org.apache.calcite.sql.SqlNode;
+import org.apache.calcite.sql.parser.SqlParseException;
+import org.apache.calcite.sql.parser.SqlParser;
+import org.apache.calcite.sql.parser.SqlParser.Config;
+import org.apache.calcite.sql.parser.impl.SqlParserImpl;
+import org.apache.calcite.util.Litmus;
+import org.apache.shardingsphere.infra.database.type.DatabaseType;
+import org.apache.shardingsphere.infra.database.type.DatabaseTypeRegistry;
+import org.apache.shardingsphere.infra.optimize.context.parser.dialect.OptimizerSQLDialectBuilderFactory;
+import org.apache.shardingsphere.infra.optimize.converter.SQLNodeConvertEngine;
+import org.apache.shardingsphere.infra.optimize.converter.parameterized.jaxb.SQLNodeConvertCasesRegistry;
+import org.apache.shardingsphere.infra.optimize.converter.parameterized.loader.SQLNodeConvertCasesLoader;
+import org.apache.shardingsphere.sql.parser.api.SQLParserEngine;
+import org.apache.shardingsphere.sql.parser.api.SQLVisitorEngine;
+import org.apache.shardingsphere.sql.parser.sql.common.statement.SQLStatement;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Properties;
+
+import static org.junit.Assert.assertTrue;
+
+@RunWith(Parameterized.class)
+@RequiredArgsConstructor
+public final class SQLNodeConvertParameterizedTest {
+    
+    private static final SQLNodeConvertCasesLoader SQL_NODE_CONVERT_CASES_LOADER = SQLNodeConvertCasesRegistry.getInstance().getSqlNodeConvertCasesLoader();
+    
+    private final String caseId;
+    
+    private final String databaseType;
+    
+    @Parameters(name = "{0} -> {1}")
+    public static Collection<Object[]> getTestParameters() {
+        return SQLNodeConvertParameterizedTest.getTestParameters("H2", "MySQL", "PostgreSQL", "Oracle", "SQLServer", "SQL92");
+    }
+    
+    private static Collection<Object[]> getTestParameters(final String... databaseTypes) {
+        return SQL_NODE_CONVERT_CASES_LOADER.getTestParameters(Arrays.asList(databaseTypes));
+    }
+    
+    @Test
+    public void assertSQLNodeConvert() {
+        String databaseType = "H2".equals(this.databaseType) ? "MySQL" : this.databaseType;
+        String sql = SQL_NODE_CONVERT_CASES_LOADER.getCaseValue(caseId);
+        SqlNode expected = parseSqlNode(databaseType, sql);
+        SqlNode actual = SQLNodeConvertEngine.convert(parseSQLStatement(databaseType, sql));
+        assertTrue(expected.equalsDeep(actual, Litmus.THROW));
+    }
+    
+    @SneakyThrows(SqlParseException.class)
+    private SqlNode parseSqlNode(final String databaseType, final String sql) {
+        return SqlParser.create(sql, createConfig(DatabaseTypeRegistry.getActualDatabaseType(databaseType))).parseQuery();
+    }
+    
+    private Config createConfig(final DatabaseType databaseType) {
+        CalciteConnectionConfig connectionConfig = new CalciteConnectionConfigImpl(createSQLDialectProperties(databaseType));
+        return SqlParser.config().withLex(connectionConfig.lex())
+                .withIdentifierMaxLength(SqlParser.DEFAULT_IDENTIFIER_MAX_LENGTH).withConformance(connectionConfig.conformance()).withParserFactory(SqlParserImpl.FACTORY);
+    }
+    
+    private Properties createSQLDialectProperties(final DatabaseType databaseType) {
+        Properties result = new Properties();
+        result.setProperty(CalciteConnectionProperty.TIME_ZONE.camelName(), "UTC");
+        result.putAll(OptimizerSQLDialectBuilderFactory.build(databaseType, result));
+        return result;
+    }
+    
+    private SQLStatement parseSQLStatement(final String databaseType, final String sql) {
+        return new SQLVisitorEngine(databaseType, "STATEMENT", new Properties()).visit(new SQLParserEngine(databaseType, true).parse(sql, false));
+    }
+}
diff --git a/shardingsphere-infra/shardingsphere-infra-optimize/src/test/java/org/apache/shardingsphere/infra/optimize/converter/parameterized/jaxb/SQLNodeConvertCase.java b/shardingsphere-infra/shardingsphere-infra-optimize/src/test/java/org/apache/shardingsphere/infra/optimize/converter/parameterized/jaxb/SQLNodeConvertCase.java
new file mode 100644
index 0000000..05dfbe3
--- /dev/null
+++ b/shardingsphere-infra/shardingsphere-infra-optimize/src/test/java/org/apache/shardingsphere/infra/optimize/converter/parameterized/jaxb/SQLNodeConvertCase.java
@@ -0,0 +1,43 @@
+/*
+ * 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.optimize.converter.parameterized.jaxb;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+
+/**
+ * SQL node convert case for xml tag.
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@Getter
+@Setter
+public final class SQLNodeConvertCase {
+    
+    @XmlAttribute
+    private String id;
+    
+    @XmlAttribute
+    private String value;
+    
+    @XmlAttribute(name = "db-types")
+    private String databaseTypes;
+}
diff --git a/shardingsphere-infra/shardingsphere-infra-optimize/src/test/java/org/apache/shardingsphere/infra/optimize/converter/parameterized/jaxb/SQLNodeConvertCases.java b/shardingsphere-infra/shardingsphere-infra-optimize/src/test/java/org/apache/shardingsphere/infra/optimize/converter/parameterized/jaxb/SQLNodeConvertCases.java
new file mode 100644
index 0000000..e4acca4
--- /dev/null
+++ b/shardingsphere-infra/shardingsphere-infra-optimize/src/test/java/org/apache/shardingsphere/infra/optimize/converter/parameterized/jaxb/SQLNodeConvertCases.java
@@ -0,0 +1,40 @@
+/*
+ * 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.optimize.converter.parameterized.jaxb;
+
+import lombok.Getter;
+
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * SQL node convert cases for xml root tag.
+ */
+@XmlRootElement(name = "sql-cases")
+@Getter
+public final class SQLNodeConvertCases {
+    
+    @XmlAttribute(name = "db-types")
+    private String databaseTypes;
+    
+    @XmlElement(name = "sql-case")
+    private final List<SQLNodeConvertCase> sqlNodeConvertCases = new LinkedList<>();
+}
diff --git a/shardingsphere-infra/shardingsphere-infra-optimize/src/test/java/org/apache/shardingsphere/infra/optimize/converter/parameterized/jaxb/SQLNodeConvertCasesRegistry.java b/shardingsphere-infra/shardingsphere-infra-optimize/src/test/java/org/apache/shardingsphere/infra/optimize/converter/parameterized/jaxb/SQLNodeConvertCasesRegistry.java
new file mode 100644
index 0000000..fb63419
--- /dev/null
+++ b/shardingsphere-infra/shardingsphere-infra-optimize/src/test/java/org/apache/shardingsphere/infra/optimize/converter/parameterized/jaxb/SQLNodeConvertCasesRegistry.java
@@ -0,0 +1,47 @@
+/*
+ * 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.optimize.converter.parameterized.jaxb;
+
+import lombok.Getter;
+import org.apache.shardingsphere.infra.optimize.converter.parameterized.loader.SQLNodeConvertCasesLoader;
+
+/**
+ * SQL node convert cases registry.
+ */
+public final class SQLNodeConvertCasesRegistry {
+    
+    private static final SQLNodeConvertCasesRegistry INSTANCE = new SQLNodeConvertCasesRegistry();
+    
+    private static final String CASE_PATH = "converter/supported/";
+    
+    @Getter
+    private final SQLNodeConvertCasesLoader sqlNodeConvertCasesLoader;
+    
+    private SQLNodeConvertCasesRegistry() {
+        sqlNodeConvertCasesLoader = new SQLNodeConvertCasesLoader(CASE_PATH);
+    }
+    
+    /**
+     * Get singleton instance.
+     * 
+     * @return singleton instance
+     */
+    public static SQLNodeConvertCasesRegistry getInstance() {
+        return INSTANCE;
+    }
+}
diff --git a/shardingsphere-infra/shardingsphere-infra-optimize/src/test/java/org/apache/shardingsphere/infra/optimize/converter/parameterized/loader/SQLNodeConvertCasesLoader.java b/shardingsphere-infra/shardingsphere-infra-optimize/src/test/java/org/apache/shardingsphere/infra/optimize/converter/parameterized/loader/SQLNodeConvertCasesLoader.java
new file mode 100644
index 0000000..7d94714c
--- /dev/null
+++ b/shardingsphere-infra/shardingsphere-infra-optimize/src/test/java/org/apache/shardingsphere/infra/optimize/converter/parameterized/loader/SQLNodeConvertCasesLoader.java
@@ -0,0 +1,146 @@
+/*
+ * 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.optimize.converter.parameterized.loader;
+
+import com.google.common.base.Preconditions;
+import com.google.common.base.Splitter;
+import com.google.common.base.Strings;
+import lombok.SneakyThrows;
+import org.apache.shardingsphere.infra.optimize.converter.parameterized.jaxb.SQLNodeConvertCase;
+import org.apache.shardingsphere.infra.optimize.converter.parameterized.jaxb.SQLNodeConvertCases;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.TreeMap;
+
+/**
+ * SQL node convert cases loader.
+ */
+public final class SQLNodeConvertCasesLoader {
+    
+    private static final String FILE_EXTENSION = ".xml";
+    
+    private final Map<String, SQLNodeConvertCase> cases;
+    
+    public SQLNodeConvertCasesLoader(final String rootDirection) {
+        cases = load(rootDirection);
+    }
+    
+    @SneakyThrows({JAXBException.class, IOException.class})
+    private Map<String, SQLNodeConvertCase> load(final String path) {
+        Map<String, SQLNodeConvertCase> result = new TreeMap<>();
+        for (File each : loadFiles(path)) {
+            buildCaseMap(result, new FileInputStream(each));
+        }
+        return result;
+    }
+    
+    @SneakyThrows({URISyntaxException.class, IOException.class})
+    private static Collection<File> loadFiles(final String path) {
+        URL url = SQLNodeConvertCasesLoader.class.getClassLoader().getResource(path);
+        if (null == url) {
+            return Collections.emptyList();
+        }
+        Collection<File> result = new LinkedList<>();
+        Files.walkFileTree(Paths.get(url.toURI()), new SimpleFileVisitor<Path>() {
+            
+            @Override
+            public FileVisitResult visitFile(final Path file, final BasicFileAttributes attributes) {
+                if (file.toString().endsWith(FILE_EXTENSION)) {
+                    result.add(file.toFile());
+                }
+                return FileVisitResult.CONTINUE;
+            }
+        });
+        return result;
+    }
+
+    private void buildCaseMap(final Map<String, SQLNodeConvertCase> sqlNodeConvertCaseMap, final InputStream inputStream) throws JAXBException {
+        SQLNodeConvertCases sqlNodeConvertCases = (SQLNodeConvertCases) JAXBContext.newInstance(SQLNodeConvertCases.class).createUnmarshaller().unmarshal(inputStream);
+        for (SQLNodeConvertCase each : sqlNodeConvertCases.getSqlNodeConvertCases()) {
+            if (null == each.getDatabaseTypes()) {
+                each.setDatabaseTypes(sqlNodeConvertCases.getDatabaseTypes());
+            }
+            Preconditions.checkState(!sqlNodeConvertCaseMap.containsKey(each.getId()), "Find duplicated SQL node convert case ID: %s", each.getId());
+            sqlNodeConvertCaseMap.put(each.getId(), each);
+        }
+    }
+    
+    /**
+     * Get case value.
+     *
+     * @param caseId case ID
+     * @return case value
+     */
+    public String getCaseValue(final String caseId) {
+        Preconditions.checkState(cases.containsKey(caseId), "Can't find SQL of ID: %s", caseId);
+        return cases.get(caseId).getValue();
+    }
+    
+    /**
+     * Get test parameters for junit parameterized test cases.
+     *
+     * @param databaseTypes database types
+     * @return test parameters for junit parameterized test cases
+     */
+    public Collection<Object[]> getTestParameters(final Collection<String> databaseTypes) {
+        Collection<Object[]> result = new LinkedList<>();
+        for (SQLNodeConvertCase each : cases.values()) {
+            result.addAll(getSQLTestParameters(databaseTypes, each));
+        }
+        return result;
+    }
+    
+    private Collection<Object[]> getSQLTestParameters(final Collection<String> databaseTypes, final SQLNodeConvertCase sqlNodeConvertCase) {
+        Collection<Object[]> result = new LinkedList<>();
+        for (String each : getDatabaseTypes(sqlNodeConvertCase.getDatabaseTypes())) {
+            if (databaseTypes.contains(each)) {
+                Object[] parameters = new Object[2];
+                parameters[0] = sqlNodeConvertCase.getId();
+                parameters[1] = each;
+                result.add(parameters);
+            }
+        }
+        return result;
+    }
+    
+    private static Collection<String> getDatabaseTypes(final String databaseTypes) {
+        return Strings.isNullOrEmpty(databaseTypes) ? getAllDatabaseTypes() : Splitter.on(',').trimResults().splitToList(databaseTypes);
+    }
+    
+    private static Collection<String> getAllDatabaseTypes() {
+        return Arrays.asList("H2", "MySQL", "PostgreSQL", "Oracle", "SQLServer", "SQL92");
+    }
+}
diff --git a/shardingsphere-infra/shardingsphere-infra-optimize/src/test/java/org/apache/shardingsphere/infra/optimize/converter/statement/SelectStatementConverterTest.java b/shardingsphere-infra/shardingsphere-infra-optimize/src/test/java/org/apache/shardingsphere/infra/optimize/converter/statement/SelectStatementConverterTest.java
index 5a97bb9..2f915a6 100644
--- a/shardingsphere-infra/shardingsphere-infra-optimize/src/test/java/org/apache/shardingsphere/infra/optimize/converter/statement/SelectStatementConverterTest.java
+++ b/shardingsphere-infra/shardingsphere-infra-optimize/src/test/java/org/apache/shardingsphere/infra/optimize/converter/statement/SelectStatementConverterTest.java
@@ -26,7 +26,6 @@ import org.apache.calcite.sql.parser.SqlParseException;
 import org.apache.calcite.sql.parser.SqlParser;
 import org.apache.calcite.sql.parser.SqlParser.Config;
 import org.apache.calcite.sql.validate.SqlConformanceEnum;
-import org.apache.calcite.util.Litmus;
 import org.apache.shardingsphere.infra.config.properties.ConfigurationProperties;
 import org.apache.shardingsphere.infra.database.type.DatabaseType;
 import org.apache.shardingsphere.infra.database.type.DatabaseTypeRegistry;
@@ -46,7 +45,6 @@ import static org.hamcrest.CoreMatchers.is;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
 
 public final class SelectStatementConverterTest {
     
@@ -174,64 +172,6 @@ public final class SelectStatementConverterTest {
         // TODO outer join is not supported by parser of ShardingSphere 
     }
     
-    @Test
-    public void assertConvertExistSubquery() {
-        String sql = "SELECT t_order_federate.order_id, t_order_federate.user_id FROM t_order_federate " 
-                + "WHERE EXISTS (SELECT * FROM t_user_info WHERE t_order_federate.user_id = t_user_info.user_id)";
-        SQLStatement sqlStatement = sqlStatementParserEngine.parse(sql, false);
-        SqlNode expected = parse(sql, new MySQLDatabaseType());
-        SqlNode actual = SQLNodeConvertEngine.convert(sqlStatement);
-        assertTrue(expected.equalsDeep(actual, Litmus.THROW));
-    }
-    
-    @Test
-    public void assertConvertNotExistSubquery() {
-        String sql = "SELECT t_order_federate.order_id, t_order_federate.user_id FROM t_order_federate "
-                + "WHERE NOT EXISTS (SELECT * FROM t_user_info WHERE t_order_federate.user_id = t_user_info.user_id)";
-        SQLStatement sqlStatement = sqlStatementParserEngine.parse(sql, false);
-        SqlNode expected = parse(sql, new MySQLDatabaseType());
-        SqlNode actual = SQLNodeConvertEngine.convert(sqlStatement);
-        assertTrue(expected.equalsDeep(actual, Litmus.THROW));
-    }
-    
-    @Test
-    public void assertConvertJoinSubquery() {
-        String sql = "SELECT t_order_federate.order_id, t_order_federate.user_id, u.user_id " 
-                + "FROM t_order_federate, (SELECT * FROM t_user_info) as u WHERE t_order_federate.user_id = u.user_id";
-        SQLStatement sqlStatement = sqlStatementParserEngine.parse(sql, false);
-        SqlNode expected = parse(sql, new MySQLDatabaseType());
-        SqlNode actual = SQLNodeConvertEngine.convert(sqlStatement);
-        assertTrue(expected.equalsDeep(actual, Litmus.THROW));
-    }
-    
-    @Test
-    public void assertConvertProjectionSubquery() {
-        String sql = "SELECT t_order_federate.order_id, t_order_federate.user_id, (SELECT COUNT(*) FROM t_user_info) FROM t_order_federate";
-        SQLStatement sqlStatement = sqlStatementParserEngine.parse(sql, false);
-        SqlNode expected = parse(sql, new MySQLDatabaseType());
-        SqlNode actual = SQLNodeConvertEngine.convert(sqlStatement);
-        assertTrue(expected.equalsDeep(actual, Litmus.THROW));
-    }
-    
-    @Test
-    public void assertConvertInSubquery() {
-        String sql = "SELECT t_order_federate.order_id, t_order_federate.user_id FROM t_order_federate WHERE user_id IN (SELECT * FROM t_user_info)";
-        SQLStatement sqlStatement = sqlStatementParserEngine.parse(sql, false);
-        SqlNode expected = parse(sql, new MySQLDatabaseType());
-        SqlNode actual = SQLNodeConvertEngine.convert(sqlStatement);
-        assertTrue(expected.equalsDeep(actual, Litmus.THROW));
-    }
-    
-    @Test
-    public void assertConvertBetweenAndSubquery() {
-        String sql = "SELECT t_order_federate.order_id, t_order_federate.user_id FROM t_order_federate " 
-                + "WHERE user_id BETWEEN (SELECT user_id FROM t_user_info WHERE information = 'before') AND (SELECT user_id FROM t_user_info WHERE information = 'after')";
-        SQLStatement sqlStatement = sqlStatementParserEngine.parse(sql, false);
-        SqlNode expected = parse(sql, new MySQLDatabaseType());
-        SqlNode actual = SQLNodeConvertEngine.convert(sqlStatement);
-        assertTrue(expected.equalsDeep(actual, Litmus.THROW));
-    }
-    
     @SneakyThrows(SqlParseException.class)
     private SqlNode parse(final String sql, final DatabaseType databaseType) {
         return SqlParser.create(sql, Config.DEFAULT.withConformance(getSQLConformance(databaseType)).withLex(getLex(databaseType))).parseQuery();
diff --git a/shardingsphere-infra/shardingsphere-infra-optimize/src/test/resources/converter/supported/select.xml b/shardingsphere-infra/shardingsphere-infra-optimize/src/test/resources/converter/supported/select.xml
new file mode 100644
index 0000000..f7787ab
--- /dev/null
+++ b/shardingsphere-infra/shardingsphere-infra-optimize/src/test/resources/converter/supported/select.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 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.
+  -->
+
+<sql-cases>
+    <sql-case id="select_with_join_table_subquery" value="SELECT t_order_federate.order_id, t_order_federate.user_id, u.user_id FROM t_order_federate, (SELECT * FROM t_user_info) as u WHERE t_order_federate.user_id = u.user_id" db-types="MySQL"/>
+    <sql-case id="select_with_projection_subquery" value="SELECT t_order_federate.order_id, t_order_federate.user_id, (SELECT COUNT(*) FROM t_user_info) FROM t_order_federate" db-types="MySQL"/>
+    <sql-case id="select_with_in_subquery_condition" value="SELECT t_order_federate.order_id, t_order_federate.user_id FROM t_order_federate WHERE user_id IN (SELECT * FROM t_user_info)" db-types="MySQL"/>
+    <sql-case id="select_with_between_and_subquery_condition" value="SELECT t_order_federate.order_id, t_order_federate.user_id FROM t_order_federate WHERE user_id BETWEEN (SELECT user_id FROM t_user_info WHERE information = 'before') AND (SELECT user_id FROM t_user_info WHERE information = 'after')" db-types="MySQL"/>
+    <sql-case id="select_with_exist_subquery_condition" value="SELECT t_order_federate.order_id, t_order_federate.user_id FROM t_order_federate WHERE EXISTS (SELECT * FROM t_user_info WHERE t_order_federate.user_id = t_user_info.user_id)" db-types="MySQL"/>
+    <sql-case id="select_with_not_exist_subquery_condition" value="SELECT t_order_federate.order_id, t_order_federate.user_id FROM t_order_federate WHERE NOT EXISTS (SELECT * FROM t_user_info WHERE t_order_federate.user_id = t_user_info.user_id)" db-types="MySQL"/>
+</sql-cases>