You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by su...@apache.org on 2023/04/20 15:52:29 UTC

[shardingsphere] branch master updated: Refactor SQLFormatVisitor (#25252)

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

sunnianjun 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 6860c2e405f Refactor SQLFormatVisitor (#25252)
6860c2e405f is described below

commit 6860c2e405ffef859a2385224e4247e50e05bb59
Author: Liang Zhang <zh...@apache.org>
AuthorDate: Thu Apr 20 23:51:59 2023 +0800

    Refactor SQLFormatVisitor (#25252)
---
 .../content/reference/sharding/parse.cn.md         |   4 +-
 .../content/reference/sharding/parse.en.md         |   4 +-
 sql-parser/dialect/mysql/pom.xml                   |   9 +
 .../format/{impl => }/MySQLFormatSQLVisitor.java   | 184 ++++++++++-----------
 .../format/facade/MySQLFormatSQLVisitorFacade.java |  78 ---------
 .../format/impl/MySQLDALFormatSQLVisitor.java      |  35 ----
 .../format/impl/MySQLDCLFormatSQLVisitor.java      |  35 ----
 .../format/impl/MySQLDDLFormatSQLVisitor.java      |  35 ----
 .../format/impl/MySQLDMLFormatSQLVisitor.java      |  35 ----
 .../format/impl/MySQLRLFormatSQLVisitor.java       |  35 ----
 .../format/impl/MySQLTCLFormatSQLVisitor.java      |  35 ----
 ....parser.api.visitor.operation.SQLFormatVisitor} |   3 +-
 ....shardingsphere.sql.parser.spi.SQLVisitorFacade |   1 -
 .../sql/parser/mysql/MySQLFormatSQLVisitorIT.java  | 143 ++++++++++++++++
 .../sql/parser/mysql/MySQLFormatTest.java          | 158 ------------------
 .../sql/parser/mysql/MySQLParameterizedTest.java   | 134 ---------------
 .../sql/parser/api/SQLFormatEngine.java            |  51 ++++++
 sql-parser/spi/pom.xml                             |   5 +
 .../api/visitor/operation/SQLFormatVisitor.java    |   4 +-
 19 files changed, 297 insertions(+), 691 deletions(-)

diff --git a/docs/document/content/reference/sharding/parse.cn.md b/docs/document/content/reference/sharding/parse.cn.md
index 8edf9651e6a..3c5aadb4534 100644
--- a/docs/document/content/reference/sharding/parse.cn.md
+++ b/docs/document/content/reference/sharding/parse.cn.md
@@ -99,9 +99,7 @@ SQLStatement sqlStatement = sqlVisitorEngine.visit(parseASTNode);
 - SQL 格式化
 
 ```java
-ParseASTNode parseASTNode = parserEngine.parse(sql, useCache);
-SQLVisitorEngine sqlVisitorEngine = new SQLVisitorEngine(sql, "FORMAT", useCache, new Properties());
-String result = sqlVisitorEngine.visit(parseASTNode);
+new SQLFormatEngine(databaseType, cacheOption).format(sql, useCache, props);
 ```
 
 例子:
diff --git a/docs/document/content/reference/sharding/parse.en.md b/docs/document/content/reference/sharding/parse.en.md
index 6fcfabce703..7eb7e81c81f 100644
--- a/docs/document/content/reference/sharding/parse.en.md
+++ b/docs/document/content/reference/sharding/parse.en.md
@@ -96,9 +96,7 @@ SQLStatement sqlStatement = sqlVisitorEngine.visit(parseASTNode);
 - SQL Formatting
 
 ```java
-ParseASTNode parseASTNode = parserEngine.parse(sql, useCache);
-SQLVisitorEngine sqlVisitorEngine = new SQLVisitorEngine(sql, "FORMAT", useCache, new Properties());
-String result = sqlVisitorEngine.visit(parseASTNode);
+new SQLFormatEngine(databaseType, cacheOption).format(sql, useCache, props);
 ```
 
 Example:
diff --git a/sql-parser/dialect/mysql/pom.xml b/sql-parser/dialect/mysql/pom.xml
index 634b0ddde3a..e6e19e90caa 100644
--- a/sql-parser/dialect/mysql/pom.xml
+++ b/sql-parser/dialect/mysql/pom.xml
@@ -30,4 +30,13 @@
     <properties>
         <dialect.parser>mysql</dialect.parser>
     </properties>
+    
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.shardingsphere</groupId>
+            <artifactId>shardingsphere-test-util</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
 </project>
diff --git a/sql-parser/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/format/impl/MySQLFormatSQLVisitor.java b/sql-parser/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/format/MySQLFormatSQLVisitor.java
similarity index 88%
rename from sql-parser/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/format/impl/MySQLFormatSQLVisitor.java
rename to sql-parser/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/format/MySQLFormatSQLVisitor.java
index cd7b92f80af..e34c250c519 100644
--- a/sql-parser/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/format/impl/MySQLFormatSQLVisitor.java
+++ b/sql-parser/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/format/MySQLFormatSQLVisitor.java
@@ -15,14 +15,12 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.sql.parser.mysql.visitor.format.impl;
+package org.apache.shardingsphere.sql.parser.mysql.visitor.format;
 
-import lombok.Getter;
-import lombok.NoArgsConstructor;
-import lombok.Setter;
 import org.antlr.v4.runtime.tree.ParseTree;
 import org.antlr.v4.runtime.tree.RuleNode;
 import org.antlr.v4.runtime.tree.TerminalNode;
+import org.apache.shardingsphere.sql.parser.api.visitor.operation.SQLFormatVisitor;
 import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementBaseVisitor;
 import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.AliasContext;
 import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.AlterCommandListContext;
@@ -75,36 +73,26 @@ import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.WithCla
 import java.util.Properties;
 
 /**
- * MySQL Format SQL visitor for MySQL.
+ * Format SQL visitor for MySQL.
  */
-@NoArgsConstructor
-@Getter
-@Setter
-public abstract class MySQLFormatSQLVisitor extends MySQLStatementBaseVisitor<String> {
+public final class MySQLFormatSQLVisitor extends MySQLStatementBaseVisitor<String> implements SQLFormatVisitor {
     
-    private StringBuilder result = new StringBuilder();
+    private final StringBuilder formattedSQL = new StringBuilder();
     
     private boolean upperCase = true;
     
     private boolean parameterized = true;
     
-    private int indentCount;
-    
-    private int lines;
-    
     private int projectionsCountOfLine = 3;
     
-    public MySQLFormatSQLVisitor(final Properties props) {
+    private int indentCount;
+    
+    @Override
+    public void init(final Properties props) {
         if (null != props) {
-            if (props.containsKey("upperCase")) {
-                setUpperCase(Boolean.parseBoolean(props.getProperty("upperCase")));
-            }
-            if (props.containsKey("parameterized")) {
-                setParameterized(Boolean.parseBoolean(props.getProperty("parameterized")));
-            }
-            if (props.containsKey("projectionsCountOfLine")) {
-                setProjectionsCountOfLine(Integer.parseInt(props.getProperty("projectionsCountOfLine")));
-            }
+            upperCase = Boolean.parseBoolean(props.getProperty("upperCase", Boolean.TRUE.toString()));
+            parameterized = Boolean.parseBoolean(props.getProperty("parameterized", Boolean.TRUE.toString()));
+            projectionsCountOfLine = Integer.parseInt(props.getProperty("projectionsCountOfLine", "3"));
         }
     }
     
@@ -115,12 +103,12 @@ public abstract class MySQLFormatSQLVisitor extends MySQLStatementBaseVisitor<St
         } else {
             visit(ctx.queryExpression());
             if (null != ctx.lockClauseList()) {
-                result.append(" ");
+                formattedSQL.append(" ");
                 visit(ctx.lockClauseList());
             }
         }
         formatPrint(";");
-        return result.toString();
+        return formattedSQL.toString();
     }
     
     @Override
@@ -138,7 +126,7 @@ public abstract class MySQLFormatSQLVisitor extends MySQLStatementBaseVisitor<St
             formatPrint(" ");
             visit(ctx.limitClause());
         }
-        return result.toString();
+        return formattedSQL.toString();
     }
     
     @Override
@@ -150,7 +138,7 @@ public abstract class MySQLFormatSQLVisitor extends MySQLStatementBaseVisitor<St
         if (null == ctx.queryExpressionParens()) {
             visit(ctx.queryExpression());
             if (null != ctx.lockClauseList()) {
-                result.append(" ");
+                formattedSQL.append(" ");
                 visit(ctx.lockClauseList());
             }
         } else {
@@ -159,7 +147,7 @@ public abstract class MySQLFormatSQLVisitor extends MySQLStatementBaseVisitor<St
         indentCount--;
         formatPrintln();
         formatPrint(")");
-        return result.toString();
+        return formattedSQL.toString();
     }
     
     @Override
@@ -173,18 +161,18 @@ public abstract class MySQLFormatSQLVisitor extends MySQLStatementBaseVisitor<St
             visit(ctx.queryExpressionParens());
             visit(ctx.combineClause());
         }
-        return result.toString();
+        return formattedSQL.toString();
     }
     
     @Override
     public String visitCombineClause(final CombineClauseContext ctx) {
-        result.append("\nUNION\n");
+        formattedSQL.append("\nUNION\n");
         if (null != ctx.combineOption()) {
             visit(ctx.combineOption());
-            result.append(" ");
+            formattedSQL.append(" ");
         }
         visit(null == ctx.queryPrimary() ? ctx.queryExpressionParens() : ctx.queryPrimary());
-        return result.toString();
+        return formattedSQL.toString();
     }
     
     @Override
@@ -216,14 +204,14 @@ public abstract class MySQLFormatSQLVisitor extends MySQLStatementBaseVisitor<St
             formatPrintln();
             visit(ctx.windowClause());
         }
-        return result.toString();
+        return formattedSQL.toString();
     }
     
     @Override
     public String visitTableStatement(final TableStatementContext ctx) {
         formatPrint("TABLE ");
         visit(ctx.tableName());
-        return result.toString();
+        return formattedSQL.toString();
     }
     
     @Override
@@ -253,7 +241,7 @@ public abstract class MySQLFormatSQLVisitor extends MySQLStatementBaseVisitor<St
             formatPrintln();
             visit(ctx.onDuplicateKeyClause());
         }
-        return result.toString();
+        return formattedSQL.toString();
     }
     
     @Override
@@ -268,7 +256,7 @@ public abstract class MySQLFormatSQLVisitor extends MySQLStatementBaseVisitor<St
             visit(ctx.identifier(i));
         }
         formatPrint(")");
-        return result.toString();
+        return formattedSQL.toString();
     }
     
     @Override
@@ -304,7 +292,7 @@ public abstract class MySQLFormatSQLVisitor extends MySQLStatementBaseVisitor<St
             formatPrintln();
             visit(ctx.valueReference());
         }
-        return result.toString();
+        return formattedSQL.toString();
     }
     
     @Override
@@ -322,7 +310,7 @@ public abstract class MySQLFormatSQLVisitor extends MySQLStatementBaseVisitor<St
         }
         formatPrintln();
         visit(ctx.select());
-        return result.toString();
+        return formattedSQL.toString();
     }
     
     @Override
@@ -342,7 +330,7 @@ public abstract class MySQLFormatSQLVisitor extends MySQLStatementBaseVisitor<St
             visit(ctx.assignment(i));
         }
         indentCount--;
-        return result.toString();
+        return formattedSQL.toString();
     }
     
     @Override
@@ -356,7 +344,7 @@ public abstract class MySQLFormatSQLVisitor extends MySQLStatementBaseVisitor<St
             visit(ctx.alias(i));
         }
         formatPrint(")");
-        return result.toString();
+        return formattedSQL.toString();
     }
     
     @Override
@@ -378,7 +366,7 @@ public abstract class MySQLFormatSQLVisitor extends MySQLStatementBaseVisitor<St
             visit(ctx.assignment(i));
         }
         indentCount--;
-        return result.toString();
+        return formattedSQL.toString();
     }
     
     @Override
@@ -388,14 +376,14 @@ public abstract class MySQLFormatSQLVisitor extends MySQLStatementBaseVisitor<St
             formatPrint(".");
         }
         formatPrint(ctx.name().getText());
-        return result.toString();
+        return formattedSQL.toString();
     }
     
     @Override
     public String visitTableValueConstructor(final TableValueConstructorContext ctx) {
         formatPrint("VALUES ");
         visit(ctx.rowConstructorList());
-        return result.toString();
+        return formattedSQL.toString();
     }
     
     @Override
@@ -416,7 +404,7 @@ public abstract class MySQLFormatSQLVisitor extends MySQLStatementBaseVisitor<St
             visit(ctx.standaloneAlterTableAction());
             indentCount--;
         }
-        return result.toString();
+        return formattedSQL.toString();
     }
     
     @Override
@@ -430,7 +418,7 @@ public abstract class MySQLFormatSQLVisitor extends MySQLStatementBaseVisitor<St
         } else {
             visit(ctx.alterTablePartitionOptions());
         }
-        return result.toString();
+        return formattedSQL.toString();
     }
     
     @Override
@@ -444,7 +432,7 @@ public abstract class MySQLFormatSQLVisitor extends MySQLStatementBaseVisitor<St
         } else if (null != ctx.alterList()) {
             visit(ctx.alterList());
         }
-        return result.toString();
+        return formattedSQL.toString();
     }
     
     @Override
@@ -462,7 +450,7 @@ public abstract class MySQLFormatSQLVisitor extends MySQLStatementBaseVisitor<St
                 child.accept(this);
             }
         }
-        return result.toString();
+        return formattedSQL.toString();
     }
     
     @Override
@@ -474,7 +462,7 @@ public abstract class MySQLFormatSQLVisitor extends MySQLStatementBaseVisitor<St
             }
             visit(ctx.getChild(i));
         }
-        return result.toString();
+        return formattedSQL.toString();
     }
     
     @Override
@@ -484,7 +472,7 @@ public abstract class MySQLFormatSQLVisitor extends MySQLStatementBaseVisitor<St
             formatPrintln(",");
         }
         visit(ctx.standaloneAlterCommands());
-        return result.toString();
+        return formattedSQL.toString();
     }
     
     @Override
@@ -498,7 +486,7 @@ public abstract class MySQLFormatSQLVisitor extends MySQLStatementBaseVisitor<St
             formatPrint(" ");
             visit(ctx.assignmentValues(i));
         }
-        return result.toString();
+        return formattedSQL.toString();
     }
     
     @Override
@@ -512,7 +500,7 @@ public abstract class MySQLFormatSQLVisitor extends MySQLStatementBaseVisitor<St
             visit(ctx.assignmentValue(i));
         }
         formatPrint(")");
-        return result.toString();
+        return formattedSQL.toString();
     }
     
     @Override
@@ -523,7 +511,7 @@ public abstract class MySQLFormatSQLVisitor extends MySQLStatementBaseVisitor<St
         formatPrintln();
         visit(ctx.expr());
         indentCount--;
-        return result.toString();
+        return formattedSQL.toString();
     }
     
     @Override
@@ -538,7 +526,7 @@ public abstract class MySQLFormatSQLVisitor extends MySQLStatementBaseVisitor<St
         } else {
             visitChildren(ctx);
         }
-        return result.toString();
+        return formattedSQL.toString();
     }
     
     private void visitLogicalOperator(final ExprContext ctx, final String operator) {
@@ -554,7 +542,7 @@ public abstract class MySQLFormatSQLVisitor extends MySQLStatementBaseVisitor<St
     @Override
     public String visitAlias(final AliasContext ctx) {
         formatPrint(ctx.getText());
-        return result.toString();
+        return formattedSQL.toString();
     }
     
     @Override
@@ -562,13 +550,13 @@ public abstract class MySQLFormatSQLVisitor extends MySQLStatementBaseVisitor<St
         indentCount++;
         if (null != ctx.unqualifiedShorthand()) {
             visit(ctx.unqualifiedShorthand());
-            result.append(" ");
+            formattedSQL.append(" ");
         }
         int projectionCount = ctx.projection().size();
         int lineItemCount = 0;
         for (int i = 0; i < projectionCount; i++) {
             if (0 != i) {
-                result.append(", ");
+                formattedSQL.append(", ");
                 if (lineItemCount >= projectionsCountOfLine) {
                     lineItemCount = 0;
                     formatPrintln();
@@ -578,7 +566,7 @@ public abstract class MySQLFormatSQLVisitor extends MySQLStatementBaseVisitor<St
             lineItemCount++;
         }
         indentCount--;
-        return result.toString();
+        return formattedSQL.toString();
     }
     
     @Override
@@ -596,7 +584,7 @@ public abstract class MySQLFormatSQLVisitor extends MySQLStatementBaseVisitor<St
         if (null != ctx.qualifiedShorthand()) {
             visit(ctx.qualifiedShorthand());
         }
-        return result.toString();
+        return formattedSQL.toString();
     }
     
     @Override
@@ -608,7 +596,7 @@ public abstract class MySQLFormatSQLVisitor extends MySQLStatementBaseVisitor<St
         formatPrint("\n");
         formatPrint(")");
         indentCount--;
-        return result.toString();
+        return formattedSQL.toString();
     }
     
     @Override
@@ -620,7 +608,7 @@ public abstract class MySQLFormatSQLVisitor extends MySQLStatementBaseVisitor<St
             }
             visit(ctx.tableElement(i));
         }
-        return result.toString();
+        return formattedSQL.toString();
     }
     
     @Override
@@ -628,7 +616,7 @@ public abstract class MySQLFormatSQLVisitor extends MySQLStatementBaseVisitor<St
         formatPrint("(");
         formatPrint(ctx.NUMBER_().getText());
         formatPrint(")");
-        return result.toString();
+        return formattedSQL.toString();
     }
     
     @Override
@@ -646,7 +634,7 @@ public abstract class MySQLFormatSQLVisitor extends MySQLStatementBaseVisitor<St
         formatPrint("(");
         formatPrint(ctx.NUMBER_().getText());
         formatPrint(")");
-        return result.toString();
+        return formattedSQL.toString();
     }
     
     @Override
@@ -659,7 +647,7 @@ public abstract class MySQLFormatSQLVisitor extends MySQLStatementBaseVisitor<St
             }
             child.accept(this);
         }
-        return result.toString();
+        return formattedSQL.toString();
     }
     
     @Override
@@ -675,14 +663,14 @@ public abstract class MySQLFormatSQLVisitor extends MySQLStatementBaseVisitor<St
             }
         }
         formatPrint(")");
-        return result.toString();
+        return formattedSQL.toString();
     }
     
     @Override
     public String visitUserVariable(final UserVariableContext ctx) {
         formatPrint("@");
         visit(ctx.textOrIdentifier());
-        return result.toString();
+        return formattedSQL.toString();
     }
     
     @Override
@@ -697,22 +685,22 @@ public abstract class MySQLFormatSQLVisitor extends MySQLStatementBaseVisitor<St
             formatPrint(".");
             visit(ctx.rvalueSystemVariable().identifier());
         }
-        return result.toString();
+        return formattedSQL.toString();
     }
     
     @Override
     public String visitTerminal(final TerminalNode node) {
         if ("<EOF>".equals(node.getText())) {
-            return result.toString();
+            return formattedSQL.toString();
         }
         formatPrint(upperCase ? node.getText().toUpperCase() : node.getText().toLowerCase());
-        return result.toString();
+        return formattedSQL.toString();
     }
     
     @Override
     public String visitIdentifier(final IdentifierContext ctx) {
         formatPrint(ctx.getText());
-        return result.toString();
+        return formattedSQL.toString();
     }
     
     @Override
@@ -722,21 +710,21 @@ public abstract class MySQLFormatSQLVisitor extends MySQLStatementBaseVisitor<St
         } else {
             super.visitLiterals(ctx);
         }
-        return result.toString();
+        return formattedSQL.toString();
     }
     
     @Override
     public String visitTemporalLiterals(final TemporalLiteralsContext ctx) {
         visit(ctx.getChild(0));
         formatPrint(ctx.SINGLE_QUOTED_TEXT().getText());
-        return result.toString();
+        return formattedSQL.toString();
     }
     
     @Override
     public String visitStringLiterals(final StringLiteralsContext ctx) {
         if (parameterized) {
             formatPrint("?");
-            return result.toString();
+            return formattedSQL.toString();
         }
         if (null == ctx.string_()) {
             visit(ctx.NCHAR_TEXT());
@@ -746,19 +734,19 @@ public abstract class MySQLFormatSQLVisitor extends MySQLStatementBaseVisitor<St
             }
             visit(ctx.string_());
         }
-        return result.toString();
+        return formattedSQL.toString();
     }
     
     @Override
     public String visitString_(final String_Context ctx) {
         formatPrint(ctx.getText());
-        return result.toString();
+        return formattedSQL.toString();
     }
     
     @Override
     public String visitNumberLiterals(final NumberLiteralsContext ctx) {
         formatPrint(parameterized ? "?" : ctx.getText());
-        return result.toString();
+        return formattedSQL.toString();
     }
     
     @Override
@@ -766,31 +754,31 @@ public abstract class MySQLFormatSQLVisitor extends MySQLStatementBaseVisitor<St
         formatPrint("WITH ");
         if (null != ctx.RECURSIVE()) {
             visit(ctx.RECURSIVE());
-            result.append(" ");
+            formattedSQL.append(" ");
         }
         for (int i = 0; i < ctx.cteClause().size(); i++) {
             if (i != 0 && i < ctx.cteClause().size() - 1) {
-                result.append(", ");
+                formattedSQL.append(", ");
             }
             visit(ctx.cteClause(i));
         }
         if (null != ctx.parent) {
-            result.append("\n");
+            formattedSQL.append("\n");
         }
-        return result.toString();
+        return formattedSQL.toString();
     }
     
     @Override
     public String visitCteClause(final CteClauseContext ctx) {
         visit(ctx.identifier());
-        result.append(" ");
+        formattedSQL.append(" ");
         if (null != ctx.columnNames()) {
             visit(ctx.columnNames());
-            result.append(" ");
+            formattedSQL.append(" ");
         }
-        result.append("AS ");
+        formattedSQL.append("AS ");
         visit(ctx.subquery());
-        return result.toString();
+        return formattedSQL.toString();
     }
     
     @Override
@@ -798,12 +786,12 @@ public abstract class MySQLFormatSQLVisitor extends MySQLStatementBaseVisitor<St
         int columnCount = ctx.columnName().size();
         for (int i = 0; i < columnCount; i++) {
             if (i != 0 && i < columnCount - 1) {
-                result.append(", ");
+                formattedSQL.append(", ");
             } else {
                 visit(ctx.columnName(i));
             }
         }
-        return result.toString();
+        return formattedSQL.toString();
     }
     
     @Override
@@ -826,38 +814,32 @@ public abstract class MySQLFormatSQLVisitor extends MySQLStatementBaseVisitor<St
     }
     
     private void formatPrint(final char value) {
-        if (null == result) {
-            return;
-        }
-        result.append(value);
+        formattedSQL.append(value);
     }
     
     private void formatPrint(final String text) {
-        if (null == result) {
-            return;
-        }
-        result.append(text);
+        formattedSQL.append(text);
     }
     
-    protected void formatPrintIndent() {
-        if (null == result) {
-            return;
-        }
+    private void formatPrintIndent() {
         for (int i = 0; i < indentCount; ++i) {
-            result.append('\t');
+            formattedSQL.append('\t');
         }
     }
     
     private void formatPrintln() {
         formatPrint('\n');
-        lines++;
         formatPrintIndent();
     }
     
     private void formatPrintln(final String text) {
         formatPrint(text);
         formatPrint('\n');
-        lines++;
         formatPrintIndent();
     }
+    
+    @Override
+    public String getType() {
+        return "MySQL";
+    }
 }
diff --git a/sql-parser/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/format/facade/MySQLFormatSQLVisitorFacade.java b/sql-parser/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/format/facade/MySQLFormatSQLVisitorFacade.java
deleted file mode 100644
index f89551ded72..00000000000
--- a/sql-parser/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/format/facade/MySQLFormatSQLVisitorFacade.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * 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.sql.parser.mysql.visitor.format.facade;
-
-import org.apache.shardingsphere.sql.parser.spi.SQLVisitorFacade;
-import org.apache.shardingsphere.sql.parser.api.visitor.type.DALSQLVisitor;
-import org.apache.shardingsphere.sql.parser.api.visitor.type.DCLSQLVisitor;
-import org.apache.shardingsphere.sql.parser.api.visitor.type.DDLSQLVisitor;
-import org.apache.shardingsphere.sql.parser.api.visitor.type.DMLSQLVisitor;
-import org.apache.shardingsphere.sql.parser.api.visitor.type.RLSQLVisitor;
-import org.apache.shardingsphere.sql.parser.api.visitor.type.TCLSQLVisitor;
-import org.apache.shardingsphere.sql.parser.mysql.visitor.format.impl.MySQLDALFormatSQLVisitor;
-import org.apache.shardingsphere.sql.parser.mysql.visitor.format.impl.MySQLDCLFormatSQLVisitor;
-import org.apache.shardingsphere.sql.parser.mysql.visitor.format.impl.MySQLDDLFormatSQLVisitor;
-import org.apache.shardingsphere.sql.parser.mysql.visitor.format.impl.MySQLDMLFormatSQLVisitor;
-import org.apache.shardingsphere.sql.parser.mysql.visitor.format.impl.MySQLRLFormatSQLVisitor;
-import org.apache.shardingsphere.sql.parser.mysql.visitor.format.impl.MySQLTCLFormatSQLVisitor;
-
-/**
- * Format SQL Visitor facade for MySQL.
- */
-public final class MySQLFormatSQLVisitorFacade implements SQLVisitorFacade {
-    
-    @Override
-    public Class<? extends DMLSQLVisitor> getDMLVisitorClass() {
-        return MySQLDMLFormatSQLVisitor.class;
-    }
-    
-    @Override
-    public Class<? extends DDLSQLVisitor> getDDLVisitorClass() {
-        return MySQLDDLFormatSQLVisitor.class;
-    }
-    
-    @Override
-    public Class<? extends TCLSQLVisitor> getTCLVisitorClass() {
-        return MySQLTCLFormatSQLVisitor.class;
-    }
-    
-    @Override
-    public Class<? extends DCLSQLVisitor> getDCLVisitorClass() {
-        return MySQLDCLFormatSQLVisitor.class;
-    }
-    
-    @Override
-    public Class<? extends DALSQLVisitor> getDALVisitorClass() {
-        return MySQLDALFormatSQLVisitor.class;
-    }
-    
-    @Override
-    public Class<? extends RLSQLVisitor> getRLVisitorClass() {
-        return MySQLRLFormatSQLVisitor.class;
-    }
-    
-    @Override
-    public String getDatabaseType() {
-        return "MySQL";
-    }
-    
-    @Override
-    public String getVisitorType() {
-        return "FORMAT";
-    }
-}
diff --git a/sql-parser/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/format/impl/MySQLDALFormatSQLVisitor.java b/sql-parser/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/format/impl/MySQLDALFormatSQLVisitor.java
deleted file mode 100644
index 92db0b0f2b6..00000000000
--- a/sql-parser/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/format/impl/MySQLDALFormatSQLVisitor.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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.sql.parser.mysql.visitor.format.impl;
-
-import lombok.NoArgsConstructor;
-import org.apache.shardingsphere.sql.parser.api.visitor.operation.SQLFormatVisitor;
-import org.apache.shardingsphere.sql.parser.api.visitor.type.DALSQLVisitor;
-
-import java.util.Properties;
-
-/**
- * DAL Format SQL visitor for MySQL.
- */
-@NoArgsConstructor
-public final class MySQLDALFormatSQLVisitor extends MySQLFormatSQLVisitor implements DALSQLVisitor, SQLFormatVisitor {
-    
-    public MySQLDALFormatSQLVisitor(final Properties props) {
-        super(props);
-    }
-}
diff --git a/sql-parser/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/format/impl/MySQLDCLFormatSQLVisitor.java b/sql-parser/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/format/impl/MySQLDCLFormatSQLVisitor.java
deleted file mode 100644
index ab936ebba55..00000000000
--- a/sql-parser/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/format/impl/MySQLDCLFormatSQLVisitor.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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.sql.parser.mysql.visitor.format.impl;
-
-import lombok.NoArgsConstructor;
-import org.apache.shardingsphere.sql.parser.api.visitor.operation.SQLFormatVisitor;
-import org.apache.shardingsphere.sql.parser.api.visitor.type.DCLSQLVisitor;
-
-import java.util.Properties;
-
-/**
- * DCL Format SQL visitor for MySQL.
- */
-@NoArgsConstructor
-public final class MySQLDCLFormatSQLVisitor extends MySQLFormatSQLVisitor implements DCLSQLVisitor, SQLFormatVisitor {
-    
-    public MySQLDCLFormatSQLVisitor(final Properties props) {
-        super(props);
-    }
-}
diff --git a/sql-parser/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/format/impl/MySQLDDLFormatSQLVisitor.java b/sql-parser/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/format/impl/MySQLDDLFormatSQLVisitor.java
deleted file mode 100644
index 8f40ac9778b..00000000000
--- a/sql-parser/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/format/impl/MySQLDDLFormatSQLVisitor.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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.sql.parser.mysql.visitor.format.impl;
-
-import lombok.NoArgsConstructor;
-import org.apache.shardingsphere.sql.parser.api.visitor.operation.SQLFormatVisitor;
-import org.apache.shardingsphere.sql.parser.api.visitor.type.DDLSQLVisitor;
-
-import java.util.Properties;
-
-/**
- * DDL Format SQL visitor for MySQL.
- */
-@NoArgsConstructor
-public final class MySQLDDLFormatSQLVisitor extends MySQLFormatSQLVisitor implements DDLSQLVisitor, SQLFormatVisitor {
-    
-    public MySQLDDLFormatSQLVisitor(final Properties props) {
-        super(props);
-    }
-}
diff --git a/sql-parser/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/format/impl/MySQLDMLFormatSQLVisitor.java b/sql-parser/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/format/impl/MySQLDMLFormatSQLVisitor.java
deleted file mode 100644
index d14192dfb53..00000000000
--- a/sql-parser/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/format/impl/MySQLDMLFormatSQLVisitor.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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.sql.parser.mysql.visitor.format.impl;
-
-import lombok.NoArgsConstructor;
-import org.apache.shardingsphere.sql.parser.api.visitor.operation.SQLFormatVisitor;
-import org.apache.shardingsphere.sql.parser.api.visitor.type.DMLSQLVisitor;
-
-import java.util.Properties;
-
-/**
- * DML Format SQL visitor for MySQL.
- */
-@NoArgsConstructor
-public final class MySQLDMLFormatSQLVisitor extends MySQLFormatSQLVisitor implements DMLSQLVisitor, SQLFormatVisitor {
-    
-    public MySQLDMLFormatSQLVisitor(final Properties props) {
-        super(props);
-    }
-}
diff --git a/sql-parser/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/format/impl/MySQLRLFormatSQLVisitor.java b/sql-parser/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/format/impl/MySQLRLFormatSQLVisitor.java
deleted file mode 100644
index 921fb53674a..00000000000
--- a/sql-parser/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/format/impl/MySQLRLFormatSQLVisitor.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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.sql.parser.mysql.visitor.format.impl;
-
-import lombok.NoArgsConstructor;
-import org.apache.shardingsphere.sql.parser.api.visitor.operation.SQLFormatVisitor;
-import org.apache.shardingsphere.sql.parser.api.visitor.type.RLSQLVisitor;
-
-import java.util.Properties;
-
-/**
- * RL Format SQL visitor for MySQL.
- */
-@NoArgsConstructor
-public final class MySQLRLFormatSQLVisitor extends MySQLFormatSQLVisitor implements RLSQLVisitor, SQLFormatVisitor {
-    
-    public MySQLRLFormatSQLVisitor(final Properties props) {
-        super(props);
-    }
-}
diff --git a/sql-parser/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/format/impl/MySQLTCLFormatSQLVisitor.java b/sql-parser/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/format/impl/MySQLTCLFormatSQLVisitor.java
deleted file mode 100644
index cee5cfc5031..00000000000
--- a/sql-parser/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/format/impl/MySQLTCLFormatSQLVisitor.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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.sql.parser.mysql.visitor.format.impl;
-
-import lombok.NoArgsConstructor;
-import org.apache.shardingsphere.sql.parser.api.visitor.operation.SQLFormatVisitor;
-import org.apache.shardingsphere.sql.parser.api.visitor.type.TCLSQLVisitor;
-
-import java.util.Properties;
-
-/**
- * TCL Format SQL visitor for MySQL.
- */
-@NoArgsConstructor
-public final class MySQLTCLFormatSQLVisitor extends MySQLFormatSQLVisitor implements TCLSQLVisitor, SQLFormatVisitor {
-    
-    public MySQLTCLFormatSQLVisitor(final Properties props) {
-        super(props);
-    }
-}
diff --git a/sql-parser/dialect/mysql/src/main/resources/META-INF/services/org.apache.shardingsphere.sql.parser.spi.SQLVisitorFacade b/sql-parser/dialect/mysql/src/main/resources/META-INF/services/org.apache.shardingsphere.sql.parser.api.visitor.operation.SQLFormatVisitor
similarity index 80%
copy from sql-parser/dialect/mysql/src/main/resources/META-INF/services/org.apache.shardingsphere.sql.parser.spi.SQLVisitorFacade
copy to sql-parser/dialect/mysql/src/main/resources/META-INF/services/org.apache.shardingsphere.sql.parser.api.visitor.operation.SQLFormatVisitor
index 6b31cc1e55b..40361266c0e 100644
--- a/sql-parser/dialect/mysql/src/main/resources/META-INF/services/org.apache.shardingsphere.sql.parser.spi.SQLVisitorFacade
+++ b/sql-parser/dialect/mysql/src/main/resources/META-INF/services/org.apache.shardingsphere.sql.parser.api.visitor.operation.SQLFormatVisitor
@@ -15,5 +15,4 @@
 # limitations under the License.
 #
 
-org.apache.shardingsphere.sql.parser.mysql.visitor.statement.facade.MySQLStatementSQLVisitorFacade
-org.apache.shardingsphere.sql.parser.mysql.visitor.format.facade.MySQLFormatSQLVisitorFacade
+org.apache.shardingsphere.sql.parser.mysql.visitor.format.MySQLFormatSQLVisitor
diff --git a/sql-parser/dialect/mysql/src/main/resources/META-INF/services/org.apache.shardingsphere.sql.parser.spi.SQLVisitorFacade b/sql-parser/dialect/mysql/src/main/resources/META-INF/services/org.apache.shardingsphere.sql.parser.spi.SQLVisitorFacade
index 6b31cc1e55b..2325af965bf 100644
--- a/sql-parser/dialect/mysql/src/main/resources/META-INF/services/org.apache.shardingsphere.sql.parser.spi.SQLVisitorFacade
+++ b/sql-parser/dialect/mysql/src/main/resources/META-INF/services/org.apache.shardingsphere.sql.parser.spi.SQLVisitorFacade
@@ -16,4 +16,3 @@
 #
 
 org.apache.shardingsphere.sql.parser.mysql.visitor.statement.facade.MySQLStatementSQLVisitorFacade
-org.apache.shardingsphere.sql.parser.mysql.visitor.format.facade.MySQLFormatSQLVisitorFacade
diff --git a/sql-parser/dialect/mysql/src/test/java/org/apache/shardingsphere/sql/parser/mysql/MySQLFormatSQLVisitorIT.java b/sql-parser/dialect/mysql/src/test/java/org/apache/shardingsphere/sql/parser/mysql/MySQLFormatSQLVisitorIT.java
new file mode 100644
index 00000000000..372964c7841
--- /dev/null
+++ b/sql-parser/dialect/mysql/src/test/java/org/apache/shardingsphere/sql/parser/mysql/MySQLFormatSQLVisitorIT.java
@@ -0,0 +1,143 @@
+/*
+ * 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.sql.parser.mysql;
+
+import org.apache.shardingsphere.sql.parser.api.CacheOption;
+import org.apache.shardingsphere.sql.parser.api.SQLFormatEngine;
+import org.apache.shardingsphere.test.util.PropertiesBuilder;
+import org.apache.shardingsphere.test.util.PropertiesBuilder.Property;
+import org.junit.jupiter.api.extension.ExtensionContext;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.ArgumentsProvider;
+import org.junit.jupiter.params.provider.ArgumentsSource;
+
+import java.util.stream.Stream;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+class MySQLFormatSQLVisitorIT {
+    
+    @ParameterizedTest(name = "{0}")
+    @ArgumentsSource(TestCaseArgumentsProvider.class)
+    void assertSQLFormat(final String caseId, final String inputSQL, final String expectFormattedSQL, final String expectFormattedParameterizedSQL) {
+        SQLFormatEngine sqlFormatEngine = new SQLFormatEngine("MySQL", new CacheOption(1, 1L));
+        assertThat(sqlFormatEngine.format(inputSQL, false, PropertiesBuilder.build(new Property("parameterized", Boolean.FALSE.toString()))), is(expectFormattedSQL));
+        assertThat(sqlFormatEngine.format(inputSQL, false, PropertiesBuilder.build(new Property("parameterized", Boolean.TRUE.toString()))), is(expectFormattedParameterizedSQL));
+    }
+    
+    private static class TestCaseArgumentsProvider implements ArgumentsProvider {
+        
+        @Override
+        public Stream<? extends Arguments> provideArguments(final ExtensionContext extensionContext) {
+            return Stream.of(Arguments.of("select_with_union",
+                    "select a+1 as b, name n from table1 join table2 where id=1 and name='lu';",
+                    "SELECT a + 1 AS b, name n\nFROM table1 JOIN table2\nWHERE \n\tid = 1\n\tand name = 'lu';",
+                    "SELECT a + ? AS b, name n\nFROM table1 JOIN table2\nWHERE \n\tid = ?\n\tand name = ?;"),
+                    Arguments.of("select_item_nums",
+                            "select id, name, age, sex, ss, yy from table1 where id=1",
+                            "SELECT id , name , age , \n\tsex , ss , yy \nFROM table1\nWHERE \n\tid = 1;",
+                            "SELECT id , name , age , \n\tsex , ss , yy \nFROM table1\nWHERE \n\tid = ?;"),
+                    Arguments.of("select_with_subquery",
+                            "select id, name, age, count(*) as n, (select id, name, age, sex from table2 where id=2) as sid, yyyy from table1 where id=1",
+                            "SELECT id , name , age , \n\tCOUNT(*) AS n, \n\t(\n\t\tSELECT id , name , age , \n\t\t\tsex \n\t\t"
+                                    + "FROM table2\n\t\tWHERE \n\t\t\tid = 2\n\t) AS sid, yyyy \nFROM table1\nWHERE \n\tid = 1;",
+                            "SELECT id , name , age , \n\tCOUNT(*) AS n, \n\t(\n\t\tSELECT id , name , age , \n\t\t\tsex \n\t\t"
+                                    + "FROM table2\n\t\tWHERE \n\t\t\tid = ?\n\t) AS sid, yyyy \nFROM table1\nWHERE \n\tid = ?;"),
+                    Arguments.of("select_where_num",
+                            "select id, name, age, sex, ss, yy from table1 where id=1 and name=1 and a=1 and b=2 and c=4 and d=3",
+                            "SELECT id , name , age , \n\tsex , ss , yy \nFROM table1\nWHERE \n\tid = 1\n\tand name = 1\n\tand a = 1\n\tand b = 2\n\tand c = 4\n\tand d = 3;",
+                            "SELECT id , name , age , \n\tsex , ss , yy \nFROM table1\nWHERE \n\tid = ?\n\tand name = ?\n\tand a = ?\n\tand b = ?\n\tand c = ?\n\tand d = ?;"),
+                    Arguments.of("alter_table",
+                            "ALTER TABLE t_order ADD column4 DATE, ADD column5 DATETIME, engine ss max_rows 10,min_rows 2, ADD column6 TIMESTAMP, ADD column7 TIME;",
+                            "ALTER TABLE t_order\n\tADD column4 DATE,\n\tADD column5 DATETIME,\n\tENGINE ss\n\tMAX_ROWS 10,\n\tMIN_ROWS 2,\n\tADD column6 TIMESTAMP,\n\tADD column7 TIME",
+                            "ALTER TABLE t_order\n\tADD column4 DATE,\n\tADD column5 DATETIME,\n\tENGINE ss\n\tMAX_ROWS 10,\n\tMIN_ROWS 2,\n\tADD column6 TIMESTAMP,\n\tADD column7 TIME"),
+                    Arguments.of("create_table",
+                            "CREATE TABLE IF NOT EXISTS `runoob_tbl`(\n"
+                                    + "`runoob_id` INT UNSIGNED AUTO_INCREMENT,\n"
+                                    + "`runoob_title` VARCHAR(100) NOT NULL,\n"
+                                    + "`runoob_author` VARCHAR(40) NOT NULL,\n"
+                                    + "`runoob_test` NATIONAL CHAR(40),\n"
+                                    + "`submission_date` DATE,\n"
+                                    + "PRIMARY KEY (`runoob_id`)\n"
+                                    + ")ENGINE=InnoDB DEFAULT CHARSET=utf8;",
+                            "CREATE TABLE IF NOT EXISTS `runoob_tbl` (\n"
+                                    + "\t`runoob_id` INT UNSIGNED AUTO_INCREMENT,\n"
+                                    + "\t`runoob_title` VARCHAR(100) NOT NULL,\n"
+                                    + "\t`runoob_author` VARCHAR(40) NOT NULL,\n"
+                                    + "\t`runoob_test` NATIONAL CHAR(40),\n"
+                                    + "\t`submission_date` DATE,\n"
+                                    + "\tPRIMARY KEY (`runoob_id`)\n"
+                                    + ") ENGINE = InnoDB DEFAULT CHARSET = utf8",
+                            "CREATE TABLE IF NOT EXISTS `runoob_tbl` (\n"
+                                    + "\t`runoob_id` INT UNSIGNED AUTO_INCREMENT,\n"
+                                    + "\t`runoob_title` VARCHAR(100) NOT NULL,\n"
+                                    + "\t`runoob_author` VARCHAR(40) NOT NULL,\n"
+                                    + "\t`runoob_test` NATIONAL CHAR(40),\n"
+                                    + "\t`submission_date` DATE,\n"
+                                    + "\tPRIMARY KEY (`runoob_id`)\n"
+                                    + ") ENGINE = InnoDB DEFAULT CHARSET = utf8"),
+                    Arguments.of("insert_with_muti_value",
+                            "INSERT INTO t_order_item(order_id, user_id, status, creation_date) values (1, 1, 'insert', '2017-08-08'), "
+                                    + "(2, 2, 'insert', '2017-08-08') ON DUPLICATE KEY UPDATE status = 'init'",
+                            "INSERT  INTO t_order_item (order_id , user_id , status , creation_date)\nVALUES\n\t(1, 1, 'insert', '2017-08-08'),\n"
+                                    + "\t(2, 2, 'insert', '2017-08-08')\nON DUPLICATE KEY UPDATE status = 'init'",
+                            "INSERT  INTO t_order_item (order_id , user_id , status , creation_date)\nVALUES\n\t(?, ?, ?, ?),\n"
+                                    + "\t(?, ?, ?, ?)\nON DUPLICATE KEY UPDATE status = ?"),
+                    Arguments.of("insert_with_muti_set",
+                            "INSERT INTO t_order SET order_id = 1, user_id = 1, status = convert(to_base64(aes_encrypt(1, 'key')) USING utf8) ON DUPLICATE KEY UPDATE status = VALUES(status)",
+                            "INSERT  INTO t_order SET order_id = 1,\n\tuser_id = 1,\n\tstatus = CONVERT(to_base64(aes_encrypt(1 , 'key')) USING utf8)\n"
+                                    + "ON DUPLICATE KEY UPDATE status = VALUES(status)",
+                            "INSERT  INTO t_order SET order_id = ?,\n\tuser_id = ?,\n\tstatus = CONVERT(to_base64(aes_encrypt(? , ?)) USING utf8)\n"
+                                    + "ON DUPLICATE KEY UPDATE status = VALUES(status)"),
+                    Arguments.of("insert_with_select",
+                            "INSERT INTO t_order (order_id, user_id, status) SELECT order_id, user_id, status FROM t_order WHERE order_id = 1",
+                            "INSERT  INTO t_order (order_id , user_id , status) \nSELECT order_id , user_id , status \nFROM t_order\nWHERE \n\torder_id = 1;",
+                            "INSERT  INTO t_order (order_id , user_id , status) \nSELECT order_id , user_id , status \nFROM t_order\nWHERE \n\torder_id = ?;"),
+                    Arguments.of("only_comment", "/* c_zz_xdba_test_4 login */", "", ""),
+                    Arguments.of("select_with_Variable",
+                            "SELECT @@SESSION.auto_increment_increment AS auto_increment_increment, @@character_set_client AS character_set_client, "
+                                    + "@@character_set_connection AS character_set_connection, @@character_set_results AS character_set_results, @@character_set_server AS character_set_server, "
+                                    + "@@collation_server AS collation_server, @@collation_connection AS collation_connection, "
+                                    + "@@init_connect AS init_connect, @@interactive_timeout AS interactive_timeout, "
+                                    + "@@license AS license, @@lower_case_table_names AS lower_case_table_names, "
+                                    + "@@max_allowed_packet AS max_allowed_packet, @@net_buffer_length AS net_buffer_length, "
+                                    + "@@net_write_timeout AS net_write_timeout, @@query_cache_size AS query_cache_size, @@query_cache_type AS query_cache_type, @@sql_mode AS sql_mode, "
+                                    + "@@system_time_zone AS system_time_zone, @@time_zone AS time_zone, @@tx_isolation AS transaction_isolation, @@wait_timeout AS wait_timeout",
+                            "SELECT "
+                                    + "@@SESSION.auto_increment_increment AS auto_increment_increment, @@character_set_client AS character_set_client, "
+                                    + "@@character_set_connection AS character_set_connection, \n"
+                                    + "\t@@character_set_results AS character_set_results, @@character_set_server AS character_set_server, @@collation_server AS collation_server, \n"
+                                    + "\t@@collation_connection AS collation_connection, @@init_connect AS init_connect, @@interactive_timeout AS interactive_timeout, \n"
+                                    + "\t@@license AS license, @@lower_case_table_names AS lower_case_table_names, @@max_allowed_packet AS max_allowed_packet, \n"
+                                    + "\t@@net_buffer_length AS net_buffer_length, @@net_write_timeout AS net_write_timeout, @@query_cache_size AS query_cache_size, \n"
+                                    + "\t@@query_cache_type AS query_cache_type, @@sql_mode AS sql_mode, @@system_time_zone AS system_time_zone, \n"
+                                    + "\t@@time_zone AS time_zone, @@tx_isolation AS transaction_isolation, @@wait_timeout AS wait_timeout;",
+                            "SELECT "
+                                    + "@@SESSION.auto_increment_increment AS auto_increment_increment, @@character_set_client AS character_set_client, "
+                                    + "@@character_set_connection AS character_set_connection, \n"
+                                    + "\t@@character_set_results AS character_set_results, @@character_set_server AS character_set_server, @@collation_server AS collation_server, \n"
+                                    + "\t@@collation_connection AS collation_connection, @@init_connect AS init_connect, @@interactive_timeout AS interactive_timeout, \n"
+                                    + "\t@@license AS license, @@lower_case_table_names AS lower_case_table_names, @@max_allowed_packet AS max_allowed_packet, \n"
+                                    + "\t@@net_buffer_length AS net_buffer_length, @@net_write_timeout AS net_write_timeout, @@query_cache_size AS query_cache_size, \n"
+                                    + "\t@@query_cache_type AS query_cache_type, @@sql_mode AS sql_mode, @@system_time_zone AS system_time_zone, \n"
+                                    + "\t@@time_zone AS time_zone, @@tx_isolation AS transaction_isolation, @@wait_timeout AS wait_timeout;"));
+        }
+    }
+}
diff --git a/sql-parser/dialect/mysql/src/test/java/org/apache/shardingsphere/sql/parser/mysql/MySQLFormatTest.java b/sql-parser/dialect/mysql/src/test/java/org/apache/shardingsphere/sql/parser/mysql/MySQLFormatTest.java
deleted file mode 100644
index ec9067ce4fa..00000000000
--- a/sql-parser/dialect/mysql/src/test/java/org/apache/shardingsphere/sql/parser/mysql/MySQLFormatTest.java
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * 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.sql.parser.mysql;
-
-import org.antlr.v4.runtime.CodePointBuffer;
-import org.antlr.v4.runtime.CodePointCharStream;
-import org.antlr.v4.runtime.CommonTokenStream;
-import org.antlr.v4.runtime.tree.ParseTree;
-import org.apache.shardingsphere.sql.parser.core.ParseASTNode;
-import org.apache.shardingsphere.sql.parser.mysql.parser.MySQLLexer;
-import org.apache.shardingsphere.sql.parser.mysql.parser.MySQLParser;
-import org.apache.shardingsphere.sql.parser.mysql.visitor.format.impl.MySQLDMLFormatSQLVisitor;
-import org.apache.shardingsphere.sql.parser.mysql.visitor.format.impl.MySQLFormatSQLVisitor;
-import org.junit.jupiter.api.extension.ExtensionContext;
-import org.junit.jupiter.params.ParameterizedTest;
-import org.junit.jupiter.params.provider.Arguments;
-import org.junit.jupiter.params.provider.ArgumentsProvider;
-import org.junit.jupiter.params.provider.ArgumentsSource;
-
-import java.nio.CharBuffer;
-import java.util.stream.Stream;
-
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.MatcherAssert.assertThat;
-
-class MySQLFormatTest {
-    
-    @ParameterizedTest(name = "{0}")
-    @ArgumentsSource(TestCaseArgumentsProvider.class)
-    void assertSQLFormat(final String caseId, final String inputSQL, final String expectFormattedSQL) {
-        CodePointBuffer buffer = CodePointBuffer.withChars(CharBuffer.wrap(inputSQL.toCharArray()));
-        MySQLLexer lexer = new MySQLLexer(CodePointCharStream.fromBuffer(buffer));
-        MySQLParser parser = new MySQLParser(new CommonTokenStream(lexer));
-        ParseTree tree = ((ParseASTNode) parser.parse()).getRootNode();
-        MySQLFormatSQLVisitor visitor = new MySQLDMLFormatSQLVisitor();
-        visitor.setParameterized(false);
-        assertThat(visitor.visit(tree), is(expectFormattedSQL));
-    }
-    
-    private static class TestCaseArgumentsProvider implements ArgumentsProvider {
-        
-        @Override
-        public Stream<? extends Arguments> provideArguments(final ExtensionContext extensionContext) {
-            return Stream.of(Arguments.of("select_with_union", "select a+1 as b, name n from table1 join table2 where id=1 and name='lu';", "SELECT a + 1 AS b, name n\n"
-                    + "FROM table1 JOIN table2\n"
-                    + "WHERE \n"
-                    + "\tid = 1\n"
-                    + "\tand name = 'lu';"),
-                    Arguments.of("select_item_nums", "select id, name, age, sex, ss, yy from table1 where id=1", "SELECT id , name , age , \n"
-                            + "\tsex , ss , yy \n"
-                            + "FROM table1\n"
-                            + "WHERE \n"
-                            + "\tid = 1;"),
-                    Arguments.of("select_with_subquery", "select id, name, age, count(*) as n, (select id, name, age, sex from table2 where id=2) as sid, yyyy from table1 where id=1", "SELECT id ,"
-                            + " name , age , \n"
-                            + "\tCOUNT(*) AS n, \n"
-                            + "\t(\n"
-                            + "\t\tSELECT id , name , age , \n"
-                            + "\t\t\tsex \n"
-                            + "\t\tFROM table2\n"
-                            + "\t\tWHERE \n"
-                            + "\t\t\tid = 2\n"
-                            + "\t) AS sid, yyyy \n"
-                            + "FROM table1\n"
-                            + "WHERE \n"
-                            + "\tid = 1;"),
-                    Arguments.of("select_where_num", "select id, name, age, sex, ss, yy from table1 where id=1 and name=1 and a=1 and b=2 and c=4 and d=3", "SELECT id , name , age , \n"
-                            + "\tsex , ss , yy \n"
-                            + "FROM table1\n"
-                            + "WHERE \n"
-                            + "\tid = 1\n"
-                            + "\tand name = 1\n"
-                            + "\tand a = 1\n"
-                            + "\tand b = 2\n"
-                            + "\tand c = 4\n"
-                            + "\tand d = 3;"),
-                    Arguments.of("alter_table", "ALTER TABLE t_order ADD column4 DATE, ADD column5 DATETIME, engine ss max_rows 10,min_rows 2, ADD column6 TIMESTAMP, ADD column7 TIME;", ""
-                            + "ALTER TABLE t_order\n"
-                            + "\tADD column4 DATE,\n"
-                            + "\tADD column5 DATETIME,\n"
-                            + "\tENGINE ss\n"
-                            + "\tMAX_ROWS 10,\n"
-                            + "\tMIN_ROWS 2,\n"
-                            + "\tADD column6 TIMESTAMP,\n"
-                            + "\tADD column7 TIME"),
-                    Arguments.of("create_table", "CREATE TABLE IF NOT EXISTS `runoob_tbl`(\n"
-                            + "`runoob_id` INT UNSIGNED AUTO_INCREMENT,\n"
-                            + "`runoob_title` VARCHAR(100) NOT NULL,\n"
-                            + "`runoob_author` VARCHAR(40) NOT NULL,\n"
-                            + "`runoob_test` NATIONAL CHAR(40),\n"
-                            + "`submission_date` DATE,\n"
-                            + "PRIMARY KEY (`runoob_id`)\n"
-                            + ")ENGINE=InnoDB DEFAULT CHARSET=utf8;",
-                            "CREATE TABLE IF NOT EXISTS `runoob_tbl` (\n"
-                                    + "\t`runoob_id` INT UNSIGNED AUTO_INCREMENT,\n"
-                                    + "\t`runoob_title` VARCHAR(100) NOT NULL,\n"
-                                    + "\t`runoob_author` VARCHAR(40) NOT NULL,\n"
-                                    + "\t`runoob_test` NATIONAL CHAR(40),\n"
-                                    + "\t`submission_date` DATE,\n"
-                                    + "\tPRIMARY KEY (`runoob_id`)\n"
-                                    + ") ENGINE = InnoDB DEFAULT CHARSET = utf8"),
-                    Arguments.of("insert_with_muti_value", "INSERT INTO t_order_item(order_id, user_id, status, creation_date) values (1, 1, 'insert', '2017-08-08'), "
-                            + "(2, 2, 'insert', '2017-08-08') "
-                            + "ON DUPLICATE KEY UPDATE status = 'init'",
-                            "INSERT  INTO t_order_item (order_id , user_id , status , creation_date)\n"
-                                    + "VALUES\n"
-                                    + "\t(1, 1, 'insert', '2017-08-08'),\n"
-                                    + "\t(2, 2, 'insert', '2017-08-08')\n"
-                                    + "ON DUPLICATE KEY UPDATE status = 'init'"),
-                    Arguments.of("insert_with_muti_set", "INSERT INTO t_order SET order_id = 1, user_id = 1, status = convert(to_base64(aes_encrypt(1, 'key')) USING utf8) "
-                            + "ON DUPLICATE KEY UPDATE status = VALUES(status)",
-                            "INSERT  INTO t_order "
-                                    + "SET order_id = 1,\n"
-                                    + "\tuser_id = 1,\n"
-                                    + "\tstatus = CONVERT(to_base64(aes_encrypt(1 , 'key')) USING utf8)\n"
-                                    + "ON DUPLICATE KEY UPDATE status = VALUES(status)"),
-                    Arguments.of("insert_with_select", "INSERT INTO t_order (order_id, user_id, status) SELECT order_id, user_id, status FROM t_order WHERE order_id = 1", "INSERT  INTO t_order "
-                            + "(order_id , user_id , status) \n"
-                            + "SELECT order_id , user_id , status \n"
-                            + "FROM t_order\n"
-                            + "WHERE \n"
-                            + "\torder_id = 1;"),
-                    Arguments.of("only_comment", "/* c_zz_xdba_test_4 login */", ""),
-                    Arguments.of("select_with_Variable", "SELECT @@SESSION.auto_increment_increment AS auto_increment_increment, @@character_set_client AS character_set_client, "
-                            + "@@character_set_connection AS character_set_connection, @@character_set_results AS character_set_results, @@character_set_server AS character_set_server, "
-                            + "@@collation_server AS collation_server, @@collation_connection AS collation_connection, "
-                            + "@@init_connect AS init_connect, @@interactive_timeout AS interactive_timeout, "
-                            + "@@license AS license, @@lower_case_table_names AS lower_case_table_names, "
-                            + "@@max_allowed_packet AS max_allowed_packet, @@net_buffer_length AS net_buffer_length, "
-                            + "@@net_write_timeout AS net_write_timeout, @@query_cache_size AS query_cache_size, @@query_cache_type AS query_cache_type, @@sql_mode AS sql_mode, "
-                            + "@@system_time_zone AS system_time_zone, @@time_zone AS time_zone, @@tx_isolation AS transaction_isolation, @@wait_timeout AS wait_timeout",
-                            "SELECT "
-                                    + "@@SESSION.auto_increment_increment AS auto_increment_increment, @@character_set_client AS character_set_client, "
-                                    + "@@character_set_connection AS character_set_connection, \n"
-                                    + "\t@@character_set_results AS character_set_results, @@character_set_server AS character_set_server, @@collation_server AS collation_server, \n"
-                                    + "\t@@collation_connection AS collation_connection, @@init_connect AS init_connect, @@interactive_timeout AS interactive_timeout, \n"
-                                    + "\t@@license AS license, @@lower_case_table_names AS lower_case_table_names, @@max_allowed_packet AS max_allowed_packet, \n"
-                                    + "\t@@net_buffer_length AS net_buffer_length, @@net_write_timeout AS net_write_timeout, @@query_cache_size AS query_cache_size, \n"
-                                    + "\t@@query_cache_type AS query_cache_type, @@sql_mode AS sql_mode, @@system_time_zone AS system_time_zone, \n"
-                                    + "\t@@time_zone AS time_zone, @@tx_isolation AS transaction_isolation, @@wait_timeout AS wait_timeout;"));
-        }
-    }
-}
diff --git a/sql-parser/dialect/mysql/src/test/java/org/apache/shardingsphere/sql/parser/mysql/MySQLParameterizedTest.java b/sql-parser/dialect/mysql/src/test/java/org/apache/shardingsphere/sql/parser/mysql/MySQLParameterizedTest.java
deleted file mode 100644
index a45bc40823a..00000000000
--- a/sql-parser/dialect/mysql/src/test/java/org/apache/shardingsphere/sql/parser/mysql/MySQLParameterizedTest.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * 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.sql.parser.mysql;
-
-import org.antlr.v4.runtime.CodePointBuffer;
-import org.antlr.v4.runtime.CodePointCharStream;
-import org.antlr.v4.runtime.CommonTokenStream;
-import org.antlr.v4.runtime.tree.ParseTree;
-import org.apache.shardingsphere.sql.parser.core.ParseASTNode;
-import org.apache.shardingsphere.sql.parser.mysql.parser.MySQLLexer;
-import org.apache.shardingsphere.sql.parser.mysql.parser.MySQLParser;
-import org.apache.shardingsphere.sql.parser.mysql.visitor.format.impl.MySQLDMLFormatSQLVisitor;
-import org.apache.shardingsphere.sql.parser.mysql.visitor.format.impl.MySQLFormatSQLVisitor;
-import org.junit.jupiter.api.extension.ExtensionContext;
-import org.junit.jupiter.params.ParameterizedTest;
-import org.junit.jupiter.params.provider.Arguments;
-import org.junit.jupiter.params.provider.ArgumentsProvider;
-import org.junit.jupiter.params.provider.ArgumentsSource;
-
-import java.nio.CharBuffer;
-import java.util.stream.Stream;
-
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.MatcherAssert.assertThat;
-
-class MySQLParameterizedTest {
-    
-    @ParameterizedTest(name = "{0}")
-    @ArgumentsSource(TestCaseArgumentsProvider.class)
-    void assertSQLFormat(final String caseId, final String inputSQL, final String expectFormattedSQL) {
-        CodePointBuffer buffer = CodePointBuffer.withChars(CharBuffer.wrap(inputSQL.toCharArray()));
-        MySQLLexer lexer = new MySQLLexer(CodePointCharStream.fromBuffer(buffer));
-        MySQLParser parser = new MySQLParser(new CommonTokenStream(lexer));
-        ParseTree tree = ((ParseASTNode) parser.parse()).getRootNode();
-        MySQLFormatSQLVisitor visitor = new MySQLDMLFormatSQLVisitor();
-        assertThat(visitor.visit(tree), is(expectFormattedSQL));
-    }
-    
-    private static class TestCaseArgumentsProvider implements ArgumentsProvider {
-        
-        @Override
-        public Stream<? extends Arguments> provideArguments(final ExtensionContext extensionContext) {
-            return Stream.of(
-                    Arguments.of("select_with_union", "select a+1 as b, name n from table1 join table2 where id=1 and name='lu';", "SELECT a + ? AS b, name n\n"
-                            + "FROM table1 JOIN table2\n"
-                            + "WHERE \n"
-                            + "\tid = ?\n"
-                            + "\tand name = ?;"),
-                    Arguments.of("select_item_nums", "select id, name, age, sex, ss, yy from table1 where id=1", "SELECT id , name , age , \n"
-                            + "\tsex , ss , yy \n"
-                            + "FROM table1\n"
-                            + "WHERE \n"
-                            + "\tid = ?;"),
-                    Arguments.of("select_with_subquery", "select id, name, age, count(*) as n, (select id, name, age, sex from table2 where id=2) as sid, yyyy from table1 where id=1", "SELECT id ,"
-                            + " name , age , \n"
-                            + "\tCOUNT(*) AS n, \n"
-                            + "\t(\n"
-                            + "\t\tSELECT id , name , age , \n"
-                            + "\t\t\tsex \n"
-                            + "\t\tFROM table2\n"
-                            + "\t\tWHERE \n"
-                            + "\t\t\tid = ?\n"
-                            + "\t) AS sid, yyyy \n"
-                            + "FROM table1\n"
-                            + "WHERE \n"
-                            + "\tid = ?;"),
-                    Arguments.of("select_where_num", "select id, name, age, sex, ss, yy from table1 where id=1 and name=1 and a=1 and b=2 and c=4 and d=3", "SELECT id , name , age , \n"
-                            + "\tsex , ss , yy \n"
-                            + "FROM table1\n"
-                            + "WHERE \n"
-                            + "\tid = ?\n"
-                            + "\tand name = ?\n"
-                            + "\tand a = ?\n"
-                            + "\tand b = ?\n"
-                            + "\tand c = ?\n"
-                            + "\tand d = ?;"),
-                    Arguments.of("alter_table", "ALTER TABLE t_order ADD column4 DATE, ADD column5 DATETIME, engine ss max_rows 10,min_rows 2, ADD column6 TIMESTAMP, ADD column7 TIME;", ""
-                            + "ALTER TABLE t_order\n"
-                            + "\tADD column4 DATE,\n"
-                            + "\tADD column5 DATETIME,\n"
-                            + "\tENGINE ss\n"
-                            + "\tMAX_ROWS 10,\n"
-                            + "\tMIN_ROWS 2,\n"
-                            + "\tADD column6 TIMESTAMP,\n"
-                            + "\tADD column7 TIME"),
-                    Arguments.of("create_table", "CREATE TABLE IF NOT EXISTS `runoob_tbl`(\n"
-                            + "`runoob_id` INT UNSIGNED AUTO_INCREMENT,\n"
-                            + "`runoob_title` VARCHAR(100) NOT NULL,\n"
-                            + "`runoob_author` VARCHAR(40) NOT NULL,\n"
-                            + "`runoob_test` NATIONAL CHAR(40),\n"
-                            + "`submission_date` DATE,\n"
-                            + "PRIMARY KEY (`runoob_id`)\n"
-                            + ")ENGINE=InnoDB DEFAULT CHARSET=utf8;",
-                            "CREATE TABLE IF NOT EXISTS `runoob_tbl` (\n"
-                                    + "\t`runoob_id` INT UNSIGNED AUTO_INCREMENT,\n"
-                                    + "\t`runoob_title` VARCHAR(100) NOT NULL,\n"
-                                    + "\t`runoob_author` VARCHAR(40) NOT NULL,\n"
-                                    + "\t`runoob_test` NATIONAL CHAR(40),\n"
-                                    + "\t`submission_date` DATE,\n"
-                                    + "\tPRIMARY KEY (`runoob_id`)\n"
-                                    + ") ENGINE = InnoDB DEFAULT CHARSET = utf8"),
-                    Arguments.of("select_with_column",
-                            "select id, name, age, count(table1.id) as n, (select id, name, age, sex from table2 where id=2) as sid, yyyy from table1 where id=1",
-                            "SELECT id ,"
-                                    + " name , age , \n"
-                                    + "\tCOUNT(table1.id) AS n, \n"
-                                    + "\t(\n"
-                                    + "\t\tSELECT id , name , age , \n"
-                                    + "\t\t\tsex \n"
-                                    + "\t\tFROM table2\n"
-                                    + "\t\tWHERE \n"
-                                    + "\t\t\tid = ?\n"
-                                    + "\t) AS sid, yyyy \n"
-                                    + "FROM table1\n"
-                                    + "WHERE \n"
-                                    + "\tid = ?;"));
-        }
-    }
-}
diff --git a/sql-parser/engine/src/main/java/org/apache/shardingsphere/sql/parser/api/SQLFormatEngine.java b/sql-parser/engine/src/main/java/org/apache/shardingsphere/sql/parser/api/SQLFormatEngine.java
new file mode 100644
index 00000000000..79854b981ee
--- /dev/null
+++ b/sql-parser/engine/src/main/java/org/apache/shardingsphere/sql/parser/api/SQLFormatEngine.java
@@ -0,0 +1,51 @@
+/*
+ * 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.sql.parser.api;
+
+import lombok.RequiredArgsConstructor;
+import org.antlr.v4.runtime.tree.ParseTree;
+import org.antlr.v4.runtime.tree.ParseTreeVisitor;
+import org.apache.shardingsphere.infra.util.spi.type.typed.TypedSPILoader;
+import org.apache.shardingsphere.sql.parser.api.visitor.operation.SQLFormatVisitor;
+
+import java.util.Properties;
+
+/**
+ * SQL format engine.
+ */
+@RequiredArgsConstructor
+public final class SQLFormatEngine {
+    
+    private final String databaseType;
+    
+    private final CacheOption cacheOption;
+    
+    /**
+     * Format SQL.
+     * 
+     * @param sql SQL to be formatted
+     * @param useCache whether use cache
+     * @param props properties
+     * @return formatted SQL
+     */
+    @SuppressWarnings("unchecked")
+    public String format(final String sql, final boolean useCache, final Properties props) {
+        ParseTree parseTree = new SQLParserEngine(databaseType, cacheOption).parse(sql, useCache).getRootNode();
+        return ((ParseTreeVisitor<String>) TypedSPILoader.getService(SQLFormatVisitor.class, databaseType, props)).visit(parseTree);
+    }
+}
diff --git a/sql-parser/spi/pom.xml b/sql-parser/spi/pom.xml
index 72c2e580976..1d43425f948 100644
--- a/sql-parser/spi/pom.xml
+++ b/sql-parser/spi/pom.xml
@@ -33,5 +33,10 @@
             <artifactId>shardingsphere-infra-util</artifactId>
             <version>${project.version}</version>
         </dependency>
+        
+        <dependency>
+            <groupId>org.antlr</groupId>
+            <artifactId>antlr4-runtime</artifactId>
+        </dependency>
     </dependencies>
 </project>
diff --git a/sql-parser/spi/src/main/java/org/apache/shardingsphere/sql/parser/api/visitor/operation/SQLFormatVisitor.java b/sql-parser/spi/src/main/java/org/apache/shardingsphere/sql/parser/api/visitor/operation/SQLFormatVisitor.java
index ce52239dbf2..dfbd979a84e 100644
--- a/sql-parser/spi/src/main/java/org/apache/shardingsphere/sql/parser/api/visitor/operation/SQLFormatVisitor.java
+++ b/sql-parser/spi/src/main/java/org/apache/shardingsphere/sql/parser/api/visitor/operation/SQLFormatVisitor.java
@@ -17,8 +17,10 @@
 
 package org.apache.shardingsphere.sql.parser.api.visitor.operation;
 
+import org.apache.shardingsphere.infra.util.spi.type.typed.TypedSPI;
+
 /**
  * SQL format visitor.
  */
-public interface SQLFormatVisitor extends SQLOperationVisitor {
+public interface SQLFormatVisitor extends SQLOperationVisitor, TypedSPI {
 }