From ead87d484543d56a7ceb70ad744a3980baa4f59e Mon Sep 17 00:00:00 2001 From: Liang Zhang Date: Wed, 28 Oct 2020 21:31:42 +0800 Subject: [PATCH] Redesign SQL parser and visitor API (#7946) * Refactor SQLParserFactory * Refactor SQLParserFactory * Refactor SQLParserFactory * Refactor SQLParserExecutor * Move SQLParserFacadeRegistry to parser package * Merge SQLStatementVisitorFactory and SQLFormatVisitorFactory * Add generic on SQLVisitorFactory * Refactor StandardSQLStatementParserEngineFactory * Move SQLParserEngine inside core package * Add SQLVisitorEngineFactory * Add generic type for SQLVisitorEngineFactory * Revert invalid changes --- .../engine/executor/RDLSQLParserExecutor.java | 2 +- .../sql/parser/ShardingSphereParser.java | 2 +- .../sql/parser/mysql/parser/MySQLParser.java | 2 +- .../parser/oracle/parser/OracleParser.java | 2 +- .../postgresql/parser/PostgreSQLParser.java | 2 +- .../sql/parser/sql92/parser/SQL92Parser.java | 2 +- .../sqlserver/parser/SQLServerParser.java | 2 +- .../parser}/SQLParserEngine.java | 42 ++++++++++-- .../parser}/SQLParserEngineFactory.java | 20 +++--- .../parser/api/visitor/SQLVisitorEngine.java | 48 ++++++++++++++ .../api/visitor/SQLVisitorEngineFactory.java | 40 +++++++++++ .../core/{ => parser}/ParseASTNode.java | 2 +- .../parser/core/parser/SQLParserExecutor.java | 66 ------------------- .../{ => parser}/SQLParserFacadeRegistry.java | 2 +- .../parser/core/parser/SQLParserFactory.java | 27 +++++--- .../core/visitor/SQLFormatVisitorFactory.java | 65 ------------------ ...torFactory.java => SQLVisitorFactory.java} | 23 ++++--- .../parser/core/visitor/SQLVisitorRule.java | 36 +++++----- .../StandardSQLStatementParserEngine.java | 7 +- ...andardSQLStatementParserEngineFactory.java | 16 ++--- .../SQLParserEngineFactoryTest.java | 3 +- 21 files changed, 204 insertions(+), 207 deletions(-) rename shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/main/java/org/apache/shardingsphere/sql/parser/{engine => api/parser}/SQLParserEngine.java (53%) rename shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/main/java/org/apache/shardingsphere/sql/parser/{engine => api/parser}/SQLParserEngineFactory.java (78%) create mode 100644 shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/main/java/org/apache/shardingsphere/sql/parser/api/visitor/SQLVisitorEngine.java create mode 100644 shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/main/java/org/apache/shardingsphere/sql/parser/api/visitor/SQLVisitorEngineFactory.java rename shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/main/java/org/apache/shardingsphere/sql/parser/core/{ => parser}/ParseASTNode.java (95%) delete mode 100644 shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/main/java/org/apache/shardingsphere/sql/parser/core/parser/SQLParserExecutor.java rename shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/main/java/org/apache/shardingsphere/sql/parser/core/{ => parser}/SQLParserFacadeRegistry.java (97%) delete mode 100644 shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/main/java/org/apache/shardingsphere/sql/parser/core/visitor/SQLFormatVisitorFactory.java rename shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/main/java/org/apache/shardingsphere/sql/parser/core/visitor/{SQLStatementVisitorFactory.java => SQLVisitorFactory.java} (77%) rename shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/test/java/org/apache/shardingsphere/sql/parser/{engine => api}/SQLParserEngineFactoryTest.java (92%) diff --git a/shardingsphere-rdl-parser/shardingsphere-rdl-parser-engine/src/main/java/org/apache/shardingsphere/rdl/parser/engine/executor/RDLSQLParserExecutor.java b/shardingsphere-rdl-parser/shardingsphere-rdl-parser-engine/src/main/java/org/apache/shardingsphere/rdl/parser/engine/executor/RDLSQLParserExecutor.java index 24643b5514..1c449925ff 100644 --- a/shardingsphere-rdl-parser/shardingsphere-rdl-parser-engine/src/main/java/org/apache/shardingsphere/rdl/parser/engine/executor/RDLSQLParserExecutor.java +++ b/shardingsphere-rdl-parser/shardingsphere-rdl-parser-engine/src/main/java/org/apache/shardingsphere/rdl/parser/engine/executor/RDLSQLParserExecutor.java @@ -31,7 +31,7 @@ import org.antlr.v4.runtime.tree.ErrorNode; import org.apache.shardingsphere.rdl.parser.autogen.ShardingSphereStatementLexer; import org.apache.shardingsphere.rdl.parser.sql.parser.ShardingSphereParser; import org.apache.shardingsphere.sql.parser.api.parser.SQLParser; -import org.apache.shardingsphere.sql.parser.core.ParseASTNode; +import org.apache.shardingsphere.sql.parser.core.parser.ParseASTNode; import org.apache.shardingsphere.sql.parser.exception.SQLParsingException; import java.nio.CharBuffer; diff --git a/shardingsphere-rdl-parser/shardingsphere-rdl-parser-sql/src/main/java/org/apache/shardingsphere/rdl/parser/sql/parser/ShardingSphereParser.java b/shardingsphere-rdl-parser/shardingsphere-rdl-parser-sql/src/main/java/org/apache/shardingsphere/rdl/parser/sql/parser/ShardingSphereParser.java index 4b16ca1719..2c3d3b7307 100644 --- a/shardingsphere-rdl-parser/shardingsphere-rdl-parser-sql/src/main/java/org/apache/shardingsphere/rdl/parser/sql/parser/ShardingSphereParser.java +++ b/shardingsphere-rdl-parser/shardingsphere-rdl-parser-sql/src/main/java/org/apache/shardingsphere/rdl/parser/sql/parser/ShardingSphereParser.java @@ -21,7 +21,7 @@ import org.antlr.v4.runtime.TokenStream; import org.apache.shardingsphere.rdl.parser.autogen.ShardingSphereStatementParser; import org.apache.shardingsphere.sql.parser.api.visitor.ASTNode; import org.apache.shardingsphere.sql.parser.api.parser.SQLParser; -import org.apache.shardingsphere.sql.parser.core.ParseASTNode; +import org.apache.shardingsphere.sql.parser.core.parser.ParseASTNode; /** * SQL parser for RDL. diff --git a/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/parser/MySQLParser.java b/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/parser/MySQLParser.java index b3b8f63bfb..523e66e480 100644 --- a/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/parser/MySQLParser.java +++ b/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/parser/MySQLParser.java @@ -21,7 +21,7 @@ import org.antlr.v4.runtime.TokenStream; import org.apache.shardingsphere.sql.parser.api.visitor.ASTNode; import org.apache.shardingsphere.sql.parser.api.parser.SQLParser; import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser; -import org.apache.shardingsphere.sql.parser.core.ParseASTNode; +import org.apache.shardingsphere.sql.parser.core.parser.ParseASTNode; /** * SQL parser for MySQL. diff --git a/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-oracle/src/main/java/org/apache/shardingsphere/sql/parser/oracle/parser/OracleParser.java b/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-oracle/src/main/java/org/apache/shardingsphere/sql/parser/oracle/parser/OracleParser.java index 990f88c6d2..35b5ecb003 100644 --- a/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-oracle/src/main/java/org/apache/shardingsphere/sql/parser/oracle/parser/OracleParser.java +++ b/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-oracle/src/main/java/org/apache/shardingsphere/sql/parser/oracle/parser/OracleParser.java @@ -21,7 +21,7 @@ import org.antlr.v4.runtime.TokenStream; import org.apache.shardingsphere.sql.parser.api.visitor.ASTNode; import org.apache.shardingsphere.sql.parser.api.parser.SQLParser; import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser; -import org.apache.shardingsphere.sql.parser.core.ParseASTNode; +import org.apache.shardingsphere.sql.parser.core.parser.ParseASTNode; /** * SQL parser for Oracle. diff --git a/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-postgresql/src/main/java/org/apache/shardingsphere/sql/parser/postgresql/parser/PostgreSQLParser.java b/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-postgresql/src/main/java/org/apache/shardingsphere/sql/parser/postgresql/parser/PostgreSQLParser.java index 10f9250a7d..f471186f07 100644 --- a/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-postgresql/src/main/java/org/apache/shardingsphere/sql/parser/postgresql/parser/PostgreSQLParser.java +++ b/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-postgresql/src/main/java/org/apache/shardingsphere/sql/parser/postgresql/parser/PostgreSQLParser.java @@ -21,7 +21,7 @@ import org.antlr.v4.runtime.TokenStream; import org.apache.shardingsphere.sql.parser.api.visitor.ASTNode; import org.apache.shardingsphere.sql.parser.api.parser.SQLParser; import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser; -import org.apache.shardingsphere.sql.parser.core.ParseASTNode; +import org.apache.shardingsphere.sql.parser.core.parser.ParseASTNode; /** * SQL parser for PostgreSQL. diff --git a/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-sql92/src/main/java/org/apache/shardingsphere/sql/parser/sql92/parser/SQL92Parser.java b/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-sql92/src/main/java/org/apache/shardingsphere/sql/parser/sql92/parser/SQL92Parser.java index dfa421d1b1..b8d3585c10 100644 --- a/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-sql92/src/main/java/org/apache/shardingsphere/sql/parser/sql92/parser/SQL92Parser.java +++ b/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-sql92/src/main/java/org/apache/shardingsphere/sql/parser/sql92/parser/SQL92Parser.java @@ -21,7 +21,7 @@ import org.antlr.v4.runtime.TokenStream; import org.apache.shardingsphere.sql.parser.api.visitor.ASTNode; import org.apache.shardingsphere.sql.parser.api.parser.SQLParser; import org.apache.shardingsphere.sql.parser.autogen.SQL92StatementParser; -import org.apache.shardingsphere.sql.parser.core.ParseASTNode; +import org.apache.shardingsphere.sql.parser.core.parser.ParseASTNode; /** * SQL parser for SQL92. diff --git a/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-sqlserver/src/main/java/org/apache/shardingsphere/sql/parser/sqlserver/parser/SQLServerParser.java b/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-sqlserver/src/main/java/org/apache/shardingsphere/sql/parser/sqlserver/parser/SQLServerParser.java index 1b7eef1e8d..ed80c18f00 100644 --- a/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-sqlserver/src/main/java/org/apache/shardingsphere/sql/parser/sqlserver/parser/SQLServerParser.java +++ b/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-sqlserver/src/main/java/org/apache/shardingsphere/sql/parser/sqlserver/parser/SQLServerParser.java @@ -21,7 +21,7 @@ import org.antlr.v4.runtime.TokenStream; import org.apache.shardingsphere.sql.parser.api.visitor.ASTNode; import org.apache.shardingsphere.sql.parser.api.parser.SQLParser; import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser; -import org.apache.shardingsphere.sql.parser.core.ParseASTNode; +import org.apache.shardingsphere.sql.parser.core.parser.ParseASTNode; /** * SQL parser for SQLServer. diff --git a/shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/main/java/org/apache/shardingsphere/sql/parser/engine/SQLParserEngine.java b/shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/main/java/org/apache/shardingsphere/sql/parser/api/parser/SQLParserEngine.java similarity index 53% rename from shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/main/java/org/apache/shardingsphere/sql/parser/engine/SQLParserEngine.java rename to shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/main/java/org/apache/shardingsphere/sql/parser/api/parser/SQLParserEngine.java index 567a628daa..9a159fc7f5 100644 --- a/shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/main/java/org/apache/shardingsphere/sql/parser/engine/SQLParserEngine.java +++ b/shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/main/java/org/apache/shardingsphere/sql/parser/api/parser/SQLParserEngine.java @@ -15,12 +15,19 @@ * limitations under the License. */ -package org.apache.shardingsphere.sql.parser.engine; +package org.apache.shardingsphere.sql.parser.api.parser; import lombok.RequiredArgsConstructor; +import org.antlr.v4.runtime.BailErrorStrategy; +import org.antlr.v4.runtime.Parser; +import org.antlr.v4.runtime.atn.PredictionMode; +import org.antlr.v4.runtime.misc.ParseCancellationException; +import org.antlr.v4.runtime.tree.ErrorNode; import org.antlr.v4.runtime.tree.ParseTree; import org.apache.shardingsphere.sql.parser.cache.SQLParsedResultCache; -import org.apache.shardingsphere.sql.parser.core.parser.SQLParserExecutor; +import org.apache.shardingsphere.sql.parser.core.parser.ParseASTNode; +import org.apache.shardingsphere.sql.parser.core.parser.SQLParserFactory; +import org.apache.shardingsphere.sql.parser.exception.SQLParsingException; import java.util.Optional; @@ -30,13 +37,13 @@ import java.util.Optional; @RequiredArgsConstructor public final class SQLParserEngine { - private final String databaseTypeName; + private final String databaseType; private final SQLParsedResultCache cache = new SQLParsedResultCache<>(); /** - * Parse SQL. - * + * Parse. + * * @param sql SQL to be parsed * @param useCache whether use cache * @return parse tree @@ -49,12 +56,33 @@ public final class SQLParserEngine { if (parseTree.isPresent()) { return parseTree.get(); } - ParseTree result = new SQLParserExecutor(databaseTypeName, sql).execute().getRootNode(); + ParseTree result = parse(sql); cache.put(sql, result); return result; } private ParseTree parse(final String sql) { - return new SQLParserExecutor(databaseTypeName, sql).execute().getRootNode(); + ParseASTNode result = twoPhaseParse(sql); + if (result.getRootNode() instanceof ErrorNode) { + throw new SQLParsingException(String.format("Unsupported SQL of `%s`", sql)); + } + return result.getRootNode(); + } + + private ParseASTNode twoPhaseParse(final String sql) { + SQLParser sqlParser = SQLParserFactory.newInstance(databaseType, sql); + try { + setPredictionMode((Parser) sqlParser, PredictionMode.SLL); + return (ParseASTNode) sqlParser.parse(); + } catch (final ParseCancellationException ex) { + ((Parser) sqlParser).reset(); + setPredictionMode((Parser) sqlParser, PredictionMode.LL); + return (ParseASTNode) sqlParser.parse(); + } + } + + private void setPredictionMode(final Parser sqlParser, final PredictionMode mode) { + sqlParser.setErrorHandler(new BailErrorStrategy()); + sqlParser.getInterpreter().setPredictionMode(mode); } } diff --git a/shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/main/java/org/apache/shardingsphere/sql/parser/engine/SQLParserEngineFactory.java b/shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/main/java/org/apache/shardingsphere/sql/parser/api/parser/SQLParserEngineFactory.java similarity index 78% rename from shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/main/java/org/apache/shardingsphere/sql/parser/engine/SQLParserEngineFactory.java rename to shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/main/java/org/apache/shardingsphere/sql/parser/api/parser/SQLParserEngineFactory.java index 1571ba9a24..70e22030eb 100644 --- a/shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/main/java/org/apache/shardingsphere/sql/parser/engine/SQLParserEngineFactory.java +++ b/shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/main/java/org/apache/shardingsphere/sql/parser/api/parser/SQLParserEngineFactory.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.shardingsphere.sql.parser.engine; +package org.apache.shardingsphere.sql.parser.api.parser; import lombok.AccessLevel; import lombok.NoArgsConstructor; @@ -33,20 +33,20 @@ public final class SQLParserEngineFactory { /** * Get SQL parser engine. - *x - * @param databaseTypeName name of database type + * + * @param databaseType database type * @return SQL parser engine */ - public static SQLParserEngine getSQLParserEngine(final String databaseTypeName) { - if (ENGINES.containsKey(databaseTypeName)) { - return ENGINES.get(databaseTypeName); + public static SQLParserEngine getSQLParserEngine(final String databaseType) { + if (ENGINES.containsKey(databaseType)) { + return ENGINES.get(databaseType); } synchronized (ENGINES) { - if (ENGINES.containsKey(databaseTypeName)) { - return ENGINES.get(databaseTypeName); + if (ENGINES.containsKey(databaseType)) { + return ENGINES.get(databaseType); } - SQLParserEngine result = new SQLParserEngine(databaseTypeName); - ENGINES.put(databaseTypeName, result); + SQLParserEngine result = new SQLParserEngine(databaseType); + ENGINES.put(databaseType, result); return result; } } diff --git a/shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/main/java/org/apache/shardingsphere/sql/parser/api/visitor/SQLVisitorEngine.java b/shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/main/java/org/apache/shardingsphere/sql/parser/api/visitor/SQLVisitorEngine.java new file mode 100644 index 0000000000..b488522d4f --- /dev/null +++ b/shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/main/java/org/apache/shardingsphere/sql/parser/api/visitor/SQLVisitorEngine.java @@ -0,0 +1,48 @@ +/* + * 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.visitor; + +import lombok.RequiredArgsConstructor; +import org.antlr.v4.runtime.tree.ParseTree; +import org.antlr.v4.runtime.tree.ParseTreeVisitor; +import org.apache.shardingsphere.sql.parser.core.visitor.SQLVisitorFactory; +import org.apache.shardingsphere.sql.parser.core.visitor.SQLVisitorRule; + +/** + * SQL visitor engnie. + * + * @param type of return value + */ +@RequiredArgsConstructor +public final class SQLVisitorEngine { + + private final String databaseType; + + private final String visitorType; + + /** + * Visit parse tree. + * + * @param parseTree parse tree + * @return visit result + */ + public T visit(final ParseTree parseTree) { + ParseTreeVisitor visitor = SQLVisitorFactory.newInstance(databaseType, visitorType, SQLVisitorRule.valueOf(parseTree.getClass())); + return parseTree.accept(visitor); + } +} diff --git a/shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/main/java/org/apache/shardingsphere/sql/parser/api/visitor/SQLVisitorEngineFactory.java b/shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/main/java/org/apache/shardingsphere/sql/parser/api/visitor/SQLVisitorEngineFactory.java new file mode 100644 index 0000000000..c30f3dfa18 --- /dev/null +++ b/shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/main/java/org/apache/shardingsphere/sql/parser/api/visitor/SQLVisitorEngineFactory.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.sql.parser.api.visitor; + +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + +/** + * SQL visitor engine factory. + */ +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public final class SQLVisitorEngineFactory { + + /** + * Get SQL visitor engine. + * + * @param databaseType database type + * @param visitorType visitor type + * @param type of visitor result + * @return SQL visitor engine + */ + public static SQLVisitorEngine getSQLVisitorEngine(final String databaseType, final String visitorType) { + return new SQLVisitorEngine<>(databaseType, visitorType); + } +} diff --git a/shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/main/java/org/apache/shardingsphere/sql/parser/core/ParseASTNode.java b/shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/main/java/org/apache/shardingsphere/sql/parser/core/parser/ParseASTNode.java similarity index 95% rename from shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/main/java/org/apache/shardingsphere/sql/parser/core/ParseASTNode.java rename to shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/main/java/org/apache/shardingsphere/sql/parser/core/parser/ParseASTNode.java index 6f2772e4d5..9da8f77e89 100644 --- a/shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/main/java/org/apache/shardingsphere/sql/parser/core/ParseASTNode.java +++ b/shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/main/java/org/apache/shardingsphere/sql/parser/core/parser/ParseASTNode.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.shardingsphere.sql.parser.core; +package org.apache.shardingsphere.sql.parser.core.parser; import lombok.RequiredArgsConstructor; import org.antlr.v4.runtime.tree.ParseTree; diff --git a/shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/main/java/org/apache/shardingsphere/sql/parser/core/parser/SQLParserExecutor.java b/shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/main/java/org/apache/shardingsphere/sql/parser/core/parser/SQLParserExecutor.java deleted file mode 100644 index b64d92aefe..0000000000 --- a/shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/main/java/org/apache/shardingsphere/sql/parser/core/parser/SQLParserExecutor.java +++ /dev/null @@ -1,66 +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.core.parser; - -import lombok.RequiredArgsConstructor; -import org.antlr.v4.runtime.BailErrorStrategy; -import org.antlr.v4.runtime.Parser; -import org.antlr.v4.runtime.atn.PredictionMode; -import org.antlr.v4.runtime.misc.ParseCancellationException; -import org.antlr.v4.runtime.tree.ErrorNode; -import org.apache.shardingsphere.sql.parser.api.parser.SQLParser; -import org.apache.shardingsphere.sql.parser.core.ParseASTNode; -import org.apache.shardingsphere.sql.parser.exception.SQLParsingException; - -/** - * SQL parser executor. - */ -@RequiredArgsConstructor -public final class SQLParserExecutor { - - private final String databaseTypeName; - - private final String sql; - - /** - * Execute to parse SQL. - * - * @return AST node - */ - public ParseASTNode execute() { - ParseASTNode result = twoPhaseParse(); - if (result.getRootNode() instanceof ErrorNode) { - throw new SQLParsingException(String.format("Unsupported SQL of `%s`", sql)); - } - return result; - } - - private ParseASTNode twoPhaseParse() { - SQLParser sqlParser = SQLParserFactory.newInstance(databaseTypeName, sql); - try { - ((Parser) sqlParser).setErrorHandler(new BailErrorStrategy()); - ((Parser) sqlParser).getInterpreter().setPredictionMode(PredictionMode.SLL); - return (ParseASTNode) sqlParser.parse(); - } catch (final ParseCancellationException ex) { - ((Parser) sqlParser).reset(); - ((Parser) sqlParser).setErrorHandler(new BailErrorStrategy()); - ((Parser) sqlParser).getInterpreter().setPredictionMode(PredictionMode.LL); - return (ParseASTNode) sqlParser.parse(); - } - } -} diff --git a/shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/main/java/org/apache/shardingsphere/sql/parser/core/SQLParserFacadeRegistry.java b/shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/main/java/org/apache/shardingsphere/sql/parser/core/parser/SQLParserFacadeRegistry.java similarity index 97% rename from shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/main/java/org/apache/shardingsphere/sql/parser/core/SQLParserFacadeRegistry.java rename to shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/main/java/org/apache/shardingsphere/sql/parser/core/parser/SQLParserFacadeRegistry.java index 126c356ae0..ca957f5ae8 100644 --- a/shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/main/java/org/apache/shardingsphere/sql/parser/core/SQLParserFacadeRegistry.java +++ b/shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/main/java/org/apache/shardingsphere/sql/parser/core/parser/SQLParserFacadeRegistry.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.shardingsphere.sql.parser.core; +package org.apache.shardingsphere.sql.parser.core.parser; import org.apache.shardingsphere.sql.parser.spi.SQLParserFacade; diff --git a/shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/main/java/org/apache/shardingsphere/sql/parser/core/parser/SQLParserFactory.java b/shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/main/java/org/apache/shardingsphere/sql/parser/core/parser/SQLParserFactory.java index 6a4b987c70..9b838e2100 100644 --- a/shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/main/java/org/apache/shardingsphere/sql/parser/core/parser/SQLParserFactory.java +++ b/shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/main/java/org/apache/shardingsphere/sql/parser/core/parser/SQLParserFactory.java @@ -26,8 +26,8 @@ import org.antlr.v4.runtime.CodePointCharStream; import org.antlr.v4.runtime.CommonTokenStream; import org.antlr.v4.runtime.Lexer; import org.antlr.v4.runtime.TokenStream; +import org.apache.shardingsphere.sql.parser.api.lexer.SQLLexer; import org.apache.shardingsphere.sql.parser.api.parser.SQLParser; -import org.apache.shardingsphere.sql.parser.core.SQLParserFacadeRegistry; import org.apache.shardingsphere.sql.parser.spi.SQLParserFacade; import java.nio.CharBuffer; @@ -38,22 +38,31 @@ import java.nio.CharBuffer; @NoArgsConstructor(access = AccessLevel.PRIVATE) public final class SQLParserFactory { - /** + /** * New instance of SQL parser. * - * @param databaseTypeName name of database type + * @param databaseType database type * @param sql SQL * @return SQL parser */ - public static SQLParser newInstance(final String databaseTypeName, final String sql) { - return createSQLParser(sql, SQLParserFacadeRegistry.getInstance().getSQLParserFacade(databaseTypeName)); + public static SQLParser newInstance(final String databaseType, final String sql) { + SQLParserFacade sqlParserFacade = SQLParserFacadeRegistry.getInstance().getSQLParserFacade(databaseType); + return createSQLParser(createTokenStream(sql, sqlParserFacade.getLexerClass()), sqlParserFacade.getParserClass()); } @SneakyThrows(ReflectiveOperationException.class) - private static SQLParser createSQLParser(final String sql, final SQLParserFacade config) { + private static SQLParser createSQLParser(final TokenStream tokenStream, final Class parserClass) { + return parserClass.getConstructor(TokenStream.class).newInstance(tokenStream); + } + + @SneakyThrows(ReflectiveOperationException.class) + private static TokenStream createTokenStream(final String sql, final Class lexerClass) { + Lexer lexer = (Lexer) lexerClass.getConstructor(CharStream.class).newInstance(getSQLCharStream(sql)); + return new CommonTokenStream(lexer); + } + + private static CharStream getSQLCharStream(final String sql) { CodePointBuffer buffer = CodePointBuffer.withChars(CharBuffer.wrap(sql.toCharArray())); - CodePointCharStream codePointCharStream = CodePointCharStream.fromBuffer(buffer); - Lexer lexer = (Lexer) config.getLexerClass().getConstructor(CharStream.class).newInstance(codePointCharStream); - return config.getParserClass().getConstructor(TokenStream.class).newInstance(new CommonTokenStream(lexer)); + return CodePointCharStream.fromBuffer(buffer); } } diff --git a/shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/main/java/org/apache/shardingsphere/sql/parser/core/visitor/SQLFormatVisitorFactory.java b/shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/main/java/org/apache/shardingsphere/sql/parser/core/visitor/SQLFormatVisitorFactory.java deleted file mode 100644 index 5abcec8fcc..0000000000 --- a/shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/main/java/org/apache/shardingsphere/sql/parser/core/visitor/SQLFormatVisitorFactory.java +++ /dev/null @@ -1,65 +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.core.visitor; - -import lombok.AccessLevel; -import lombok.NoArgsConstructor; -import lombok.SneakyThrows; -import org.antlr.v4.runtime.tree.ParseTreeVisitor; -import org.apache.shardingsphere.sql.parser.exception.SQLParsingException; -import org.apache.shardingsphere.sql.parser.spi.SQLVisitorFacade; -import org.apache.shardingsphere.sql.parser.sql.common.statement.SQLStatementType; - -/** - * SQL format visitor factory. - */ -@NoArgsConstructor(access = AccessLevel.PRIVATE) -public final class SQLFormatVisitorFactory { - - /** - * New instance of SQL format visitor. - * - * @param databaseTypeName name of database type - * @param sqlVisitorRule visitor rule - * @return parse tree visitor - */ - public static ParseTreeVisitor newInstance(final String databaseTypeName, final SQLVisitorRule sqlVisitorRule) { - SQLVisitorFacade facade = SQLVisitorFacadeRegistry.getInstance().getSQLVisitorFacade(databaseTypeName, "FORMAT"); - return createParseTreeVisitor(facade, sqlVisitorRule.getType()); - } - - @SneakyThrows(ReflectiveOperationException.class) - private static ParseTreeVisitor createParseTreeVisitor(final SQLVisitorFacade visitorFacade, final SQLStatementType type) { - switch (type) { - case DML: - return (ParseTreeVisitor) visitorFacade.getDMLVisitorClass().getConstructor().newInstance(); - case DDL: - return (ParseTreeVisitor) visitorFacade.getDDLVisitorClass().getConstructor().newInstance(); - case TCL: - return (ParseTreeVisitor) visitorFacade.getTCLVisitorClass().getConstructor().newInstance(); - case DCL: - return (ParseTreeVisitor) visitorFacade.getDCLVisitorClass().getConstructor().newInstance(); - case DAL: - return (ParseTreeVisitor) visitorFacade.getDALVisitorClass().getConstructor().newInstance(); - case RL: - return (ParseTreeVisitor) visitorFacade.getRLVisitorClass().getConstructor().newInstance(); - default: - throw new SQLParsingException("Can not support SQL statement type: `%s`", type); - } - } -} diff --git a/shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/main/java/org/apache/shardingsphere/sql/parser/core/visitor/SQLStatementVisitorFactory.java b/shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/main/java/org/apache/shardingsphere/sql/parser/core/visitor/SQLVisitorFactory.java similarity index 77% rename from shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/main/java/org/apache/shardingsphere/sql/parser/core/visitor/SQLStatementVisitorFactory.java rename to shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/main/java/org/apache/shardingsphere/sql/parser/core/visitor/SQLVisitorFactory.java index 5e53c5889d..8e7701f83d 100644 --- a/shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/main/java/org/apache/shardingsphere/sql/parser/core/visitor/SQLStatementVisitorFactory.java +++ b/shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/main/java/org/apache/shardingsphere/sql/parser/core/visitor/SQLVisitorFactory.java @@ -26,25 +26,28 @@ import org.apache.shardingsphere.sql.parser.spi.SQLVisitorFacade; import org.apache.shardingsphere.sql.parser.sql.common.statement.SQLStatementType; /** - * SQL statement visitor factory. + * SQL visitor factory. */ @NoArgsConstructor(access = AccessLevel.PRIVATE) -public final class SQLStatementVisitorFactory { +public final class SQLVisitorFactory { - /** - * New instance of SQL statement visitor. + /** + * New instance of SQL visitor. * - * @param databaseTypeName name of database type - * @param sqlVisitorRule SQL visitor rule + * @param databaseType database type + * @param visitorType SQL visitor type + * @param visitorRule SQL visitor rule + * @param type of visitor result * @return parse tree visitor */ - public static ParseTreeVisitor newInstance(final String databaseTypeName, final SQLVisitorRule sqlVisitorRule) { - SQLVisitorFacade facade = SQLVisitorFacadeRegistry.getInstance().getSQLVisitorFacade(databaseTypeName, "STATEMENT"); - return createParseTreeVisitor(facade, sqlVisitorRule.getType()); + public static ParseTreeVisitor newInstance(final String databaseType, final String visitorType, final SQLVisitorRule visitorRule) { + SQLVisitorFacade facade = SQLVisitorFacadeRegistry.getInstance().getSQLVisitorFacade(databaseType, visitorType); + return createParseTreeVisitor(facade, visitorRule.getType()); } + @SuppressWarnings("unchecked") @SneakyThrows(ReflectiveOperationException.class) - private static ParseTreeVisitor createParseTreeVisitor(final SQLVisitorFacade visitorFacade, final SQLStatementType type) { + private static ParseTreeVisitor createParseTreeVisitor(final SQLVisitorFacade visitorFacade, final SQLStatementType type) { switch (type) { case DML: return (ParseTreeVisitor) visitorFacade.getDMLVisitorClass().getConstructor().newInstance(); diff --git a/shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/main/java/org/apache/shardingsphere/sql/parser/core/visitor/SQLVisitorRule.java b/shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/main/java/org/apache/shardingsphere/sql/parser/core/visitor/SQLVisitorRule.java index 230903b775..d0dcfeb177 100644 --- a/shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/main/java/org/apache/shardingsphere/sql/parser/core/visitor/SQLVisitorRule.java +++ b/shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/main/java/org/apache/shardingsphere/sql/parser/core/visitor/SQLVisitorRule.java @@ -51,47 +51,47 @@ public enum SQLVisitorRule { ALTER_INDEX("AlterIndex", SQLStatementType.DDL), DROP_INDEX("DropIndex", SQLStatementType.DDL), - + CREATE_PROCEDURE("CreateProcedure", SQLStatementType.DDL), - + ALTER_PROCEDURE("AlterProcedure", SQLStatementType.DDL), - + DROP_PROCEDURE("DropProcedure", SQLStatementType.DDL), - + CREATE_FUNCTION("CreateFunction", SQLStatementType.DDL), - + ALTER_FUNCTION("AlterFunction", SQLStatementType.DDL), - + DROP_FUNCTION("DropFunction", SQLStatementType.DDL), - + CREATE_DATABASE("CreateDatabase", SQLStatementType.DDL), ALTER_DATABASE("AlterDatabase", SQLStatementType.DDL), - + DROP_DATABASE("DropDatabase", SQLStatementType.DDL), - + CREATE_EVENT("CreateEvent", SQLStatementType.DDL), - + ALTER_EVENT("AlterEvent", SQLStatementType.DDL), DROP_EVENT("DropEvent", SQLStatementType.DDL), - + ALTER_INSTANCE("AlterInstance", SQLStatementType.DDL), - + CREATE_LOGFILE_GROUP("CreateLogfileGroup", SQLStatementType.DDL), - + ALTER_LOGFILE_GROUP("AlterLogfileGroup", SQLStatementType.DDL), - + DROP_LOGFILE_GROUP("DropLogfileGroup", SQLStatementType.DDL), - + CREATE_SERVER("CreateServer", SQLStatementType.DDL), ALTER_SERVER("AlterServer", SQLStatementType.DDL), - + DROP_SERVER("DropServer", SQLStatementType.DDL), - + CREATE_TRIGGER("CreateTrigger", SQLStatementType.DDL), - + DROP_TRIGGER("DropTrigger", SQLStatementType.DDL), CREATE_VIEW("CreateView", SQLStatementType.DDL), diff --git a/shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/main/java/org/apache/shardingsphere/sql/parser/statement/standard/StandardSQLStatementParserEngine.java b/shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/main/java/org/apache/shardingsphere/sql/parser/statement/standard/StandardSQLStatementParserEngine.java index b3bda7d953..664ad424db 100644 --- a/shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/main/java/org/apache/shardingsphere/sql/parser/statement/standard/StandardSQLStatementParserEngine.java +++ b/shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/main/java/org/apache/shardingsphere/sql/parser/statement/standard/StandardSQLStatementParserEngine.java @@ -21,9 +21,9 @@ import lombok.RequiredArgsConstructor; import org.antlr.v4.runtime.tree.ParseTree; import org.antlr.v4.runtime.tree.ParseTreeVisitor; import org.apache.shardingsphere.sql.parser.cache.SQLParsedResultCache; -import org.apache.shardingsphere.sql.parser.core.visitor.SQLStatementVisitorFactory; +import org.apache.shardingsphere.sql.parser.core.visitor.SQLVisitorFactory; import org.apache.shardingsphere.sql.parser.core.visitor.SQLVisitorRule; -import org.apache.shardingsphere.sql.parser.engine.SQLParserEngineFactory; +import org.apache.shardingsphere.sql.parser.api.parser.SQLParserEngineFactory; import org.apache.shardingsphere.sql.parser.hook.ParsingHookRegistry; import org.apache.shardingsphere.sql.parser.sql.common.statement.SQLStatement; import org.apache.shardingsphere.sql.parser.statement.SQLStatementParserEngine; @@ -76,10 +76,9 @@ public final class StandardSQLStatementParserEngine implements SQLStatementParse return result; } - @SuppressWarnings("unchecked") private SQLStatement parseSQLStatement(final String sql) { ParseTree parseTree = SQLParserEngineFactory.getSQLParserEngine(databaseTypeName).parse(sql, false); - ParseTreeVisitor visitor = SQLStatementVisitorFactory.newInstance(databaseTypeName, SQLVisitorRule.valueOf(parseTree.getClass())); + ParseTreeVisitor visitor = SQLVisitorFactory.newInstance(databaseTypeName, "STATEMENT", SQLVisitorRule.valueOf(parseTree.getClass())); return parseTree.accept(visitor); } } diff --git a/shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/main/java/org/apache/shardingsphere/sql/parser/statement/standard/StandardSQLStatementParserEngineFactory.java b/shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/main/java/org/apache/shardingsphere/sql/parser/statement/standard/StandardSQLStatementParserEngineFactory.java index 617800a973..8c637a37df 100644 --- a/shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/main/java/org/apache/shardingsphere/sql/parser/statement/standard/StandardSQLStatementParserEngineFactory.java +++ b/shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/main/java/org/apache/shardingsphere/sql/parser/statement/standard/StandardSQLStatementParserEngineFactory.java @@ -34,19 +34,19 @@ public final class StandardSQLStatementParserEngineFactory { /** * Get standard SQL statement parser engine. *x - * @param databaseTypeName name of database type + * @param databaseType name of database type * @return standard SQL statement parser engine */ - public static StandardSQLStatementParserEngine getSQLStatementParserEngine(final String databaseTypeName) { - if (ENGINES.containsKey(databaseTypeName)) { - return ENGINES.get(databaseTypeName); + public static StandardSQLStatementParserEngine getSQLStatementParserEngine(final String databaseType) { + if (ENGINES.containsKey(databaseType)) { + return ENGINES.get(databaseType); } synchronized (ENGINES) { - if (ENGINES.containsKey(databaseTypeName)) { - return ENGINES.get(databaseTypeName); + if (ENGINES.containsKey(databaseType)) { + return ENGINES.get(databaseType); } - StandardSQLStatementParserEngine result = new StandardSQLStatementParserEngine(databaseTypeName); - ENGINES.put(databaseTypeName, result); + StandardSQLStatementParserEngine result = new StandardSQLStatementParserEngine(databaseType); + ENGINES.put(databaseType, result); return result; } } diff --git a/shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/test/java/org/apache/shardingsphere/sql/parser/engine/SQLParserEngineFactoryTest.java b/shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/test/java/org/apache/shardingsphere/sql/parser/api/SQLParserEngineFactoryTest.java similarity index 92% rename from shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/test/java/org/apache/shardingsphere/sql/parser/engine/SQLParserEngineFactoryTest.java rename to shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/test/java/org/apache/shardingsphere/sql/parser/api/SQLParserEngineFactoryTest.java index 73dd287847..1887e21216 100644 --- a/shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/test/java/org/apache/shardingsphere/sql/parser/engine/SQLParserEngineFactoryTest.java +++ b/shardingsphere-sql-parser/shardingsphere-sql-parser-engine/src/test/java/org/apache/shardingsphere/sql/parser/api/SQLParserEngineFactoryTest.java @@ -15,8 +15,9 @@ * limitations under the License. */ -package org.apache.shardingsphere.sql.parser.engine; +package org.apache.shardingsphere.sql.parser.api; +import org.apache.shardingsphere.sql.parser.api.parser.SQLParserEngineFactory; import org.junit.After; import org.junit.Before; import org.junit.Test; -- GitLab