From a3fb75f9dee79d15a55da1ea02ddbe8ec1b376e6 Mon Sep 17 00:00:00 2001 From: TedCraft Date: Fri, 29 Sep 2023 18:11:26 +0300 Subject: [PATCH 1/4] fix getResultSets for Firebird Driver --- .../type/memory/JDBCMemoryQueryResult.java | 5 +++++ .../ShardingSpherePreparedStatement.java | 20 ++++++++++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/infra/executor/src/main/java/org/apache/shardingsphere/infra/executor/sql/execute/result/query/impl/driver/jdbc/type/memory/JDBCMemoryQueryResult.java b/infra/executor/src/main/java/org/apache/shardingsphere/infra/executor/sql/execute/result/query/impl/driver/jdbc/type/memory/JDBCMemoryQueryResult.java index 0f704e9381b7c..929cc5df436a6 100644 --- a/infra/executor/src/main/java/org/apache/shardingsphere/infra/executor/sql/execute/result/query/impl/driver/jdbc/type/memory/JDBCMemoryQueryResult.java +++ b/infra/executor/src/main/java/org/apache/shardingsphere/infra/executor/sql/execute/result/query/impl/driver/jdbc/type/memory/JDBCMemoryQueryResult.java @@ -17,6 +17,7 @@ package org.apache.shardingsphere.infra.executor.sql.execute.result.query.impl.driver.jdbc.type.memory; +import lombok.Getter; import org.apache.shardingsphere.infra.database.core.type.DatabaseType; import org.apache.shardingsphere.infra.executor.sql.execute.result.query.impl.driver.jdbc.metadata.JDBCQueryResultMetaData; import org.apache.shardingsphere.infra.executor.sql.execute.result.query.type.memory.AbstractMemoryQueryResult; @@ -29,7 +30,11 @@ */ public final class JDBCMemoryQueryResult extends AbstractMemoryQueryResult { + @Getter + private final ResultSet resultSet; + public JDBCMemoryQueryResult(final ResultSet resultSet, final DatabaseType databaseType) throws SQLException { super(new JDBCQueryResultMetaData(resultSet.getMetaData()), new QueryResultDataRowLoader(databaseType).load(resultSet.getMetaData().getColumnCount(), resultSet)); + this.resultSet = resultSet; } } diff --git a/jdbc/core/src/main/java/org/apache/shardingsphere/driver/jdbc/core/statement/ShardingSpherePreparedStatement.java b/jdbc/core/src/main/java/org/apache/shardingsphere/driver/jdbc/core/statement/ShardingSpherePreparedStatement.java index 8e691823da260..2d70c5f12a2c2 100644 --- a/jdbc/core/src/main/java/org/apache/shardingsphere/driver/jdbc/core/statement/ShardingSpherePreparedStatement.java +++ b/jdbc/core/src/main/java/org/apache/shardingsphere/driver/jdbc/core/statement/ShardingSpherePreparedStatement.java @@ -88,6 +88,8 @@ import org.apache.shardingsphere.traffic.exception.metadata.EmptyTrafficExecutionUnitException; import org.apache.shardingsphere.traffic.rule.TrafficRule; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.sql.Connection; import java.sql.ParameterMetaData; import java.sql.PreparedStatement; @@ -246,7 +248,7 @@ public ResultSet executeQuery() throws SQLException { executionContext = createExecutionContext(queryContext); List queryResults = executeQuery0(); MergedResult mergedResult = mergeQuery(queryResults); - List resultSets = getResultSets(); + List resultSets = getResultSets(queryResults); if (null == columnLabelAndIndexMap) { columnLabelAndIndexMap = ShardingSphereResultSetUtils.createColumnLabelAndIndexMap(sqlStatementContext, selectContainsEnhancedTable, resultSets.get(0).getMetaData()); } @@ -537,6 +539,22 @@ private List getResultSets() throws SQLException { return result; } + private List getResultSets(List qr) throws SQLException { + List result = new ArrayList<>(qr.size()); + for (QueryResult each : qr) { + try { + Method getResultSet = each.getClass().getDeclaredMethod("getResultSet"); + ResultSet rs = (ResultSet) getResultSet.invoke(each); + if (null != rs) { + result.add(rs); + } + } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException ex) { + return getResultSets(); + } + } + return result; + } + private List getQueryResults(final List resultSets) throws SQLException { List result = new ArrayList<>(resultSets.size()); for (ResultSet each : resultSets) { From 67474cadd776d678281c5b30349ac749da070747 Mon Sep 17 00:00:00 2001 From: TedCraft Date: Thu, 5 Oct 2023 15:19:08 +0300 Subject: [PATCH 2/4] add classes for firebird --- infra/common/pom.xml | 5 + infra/database/type/firebird/pom.xml | 43 ++ .../FirebirdConnectionPropertiesParser.java | 49 ++ .../database/FirebirdDatabaseMetaData.java | 43 ++ .../firebird/type/FirebirdDatabaseType.java | 45 ++ ....core.connector.ConnectionPropertiesParser | 18 + ....metadata.database.DialectDatabaseMetaData | 18 + ...here.infra.database.core.type.DatabaseType | 18 + infra/database/type/pom.xml | 1 + jdbc/core/pom.xml | 5 + parser/sql/dialect/firebird/pom.xml | 40 + .../main/antlr4/imports/firebird/Alphabet.g4 | 48 ++ .../main/antlr4/imports/firebird/BaseRule.g4 | 321 ++++++++ .../main/antlr4/imports/firebird/Comments.g4 | 22 + .../antlr4/imports/firebird/DCLStatement.g4 | 62 ++ .../antlr4/imports/firebird/DDLStatement.g4 | 154 ++++ .../antlr4/imports/firebird/DMLStatement.g4 | 163 +++++ .../imports/firebird/FirebirdKeyword.g4 | 692 ++++++++++++++++++ .../main/antlr4/imports/firebird/Keyword.g4 | 545 ++++++++++++++ .../main/antlr4/imports/firebird/Literals.g4 | 49 ++ .../main/antlr4/imports/firebird/Symbol.g4 | 58 ++ .../antlr4/imports/firebird/TCLStatement.g4 | 36 + .../sql/parser/autogen/FirebirdStatement.g4 | 40 + .../parser/firebird/parser/FirebirdLexer.java | 32 + .../firebird/parser/FirebirdParser.java | 40 + .../firebird/parser/FirebirdParserFacade.java | 43 ++ .../statement/FirebirdStatementVisitor.java | 574 +++++++++++++++ .../FirebirdStatementVisitorFacade.java | 72 ++ .../type/FirebirdDALStatementVisitor.java | 27 + .../type/FirebirdDCLStatementVisitor.java | 51 ++ .../type/FirebirdDDLStatementVisitor.java | 218 ++++++ .../type/FirebirdDMLStatementVisitor.java | 482 ++++++++++++ .../type/FirebirdTCLStatementVisitor.java | 49 ++ ...here.sql.parser.spi.SQLDialectParserFacade | 18 + ...e.sql.parser.spi.SQLStatementVisitorFacade | 18 + parser/sql/dialect/pom.xml | 1 + .../statement/firebird/FirebirdStatement.java | 26 + .../firebird/dcl/FirebirdGrantStatement.java | 27 + .../firebird/dcl/FirebirdRevokeStatement.java | 27 + .../ddl/FirebirdAlterTableStatement.java | 27 + .../ddl/FirebirdCreateTableStatement.java | 27 + .../ddl/FirebirdDropTableStatement.java | 27 + .../firebird/dml/FirebirdDeleteStatement.java | 27 + .../firebird/dml/FirebirdInsertStatement.java | 27 + .../firebird/dml/FirebirdSelectStatement.java | 43 ++ .../firebird/dml/FirebirdUpdateStatement.java | 27 + .../firebird/tcl/FirebirdCommitStatement.java | 27 + .../tcl/FirebirdRollbackStatement.java | 27 + .../tcl/FirebirdSetTransactionStatement.java | 27 + 49 files changed, 4466 insertions(+) create mode 100644 infra/database/type/firebird/pom.xml create mode 100644 infra/database/type/firebird/src/main/java/org/apache/shardingsphere/infra/database/firebird/connector/FirebirdConnectionPropertiesParser.java create mode 100644 infra/database/type/firebird/src/main/java/org/apache/shardingsphere/infra/database/firebird/metadata/database/FirebirdDatabaseMetaData.java create mode 100644 infra/database/type/firebird/src/main/java/org/apache/shardingsphere/infra/database/firebird/type/FirebirdDatabaseType.java create mode 100644 infra/database/type/firebird/src/main/resources/META-INF/services/org.apache.shardingsphere.infra.database.core.connector.ConnectionPropertiesParser create mode 100644 infra/database/type/firebird/src/main/resources/META-INF/services/org.apache.shardingsphere.infra.database.core.metadata.database.DialectDatabaseMetaData create mode 100644 infra/database/type/firebird/src/main/resources/META-INF/services/org.apache.shardingsphere.infra.database.core.type.DatabaseType create mode 100644 parser/sql/dialect/firebird/pom.xml create mode 100644 parser/sql/dialect/firebird/src/main/antlr4/imports/firebird/Alphabet.g4 create mode 100644 parser/sql/dialect/firebird/src/main/antlr4/imports/firebird/BaseRule.g4 create mode 100644 parser/sql/dialect/firebird/src/main/antlr4/imports/firebird/Comments.g4 create mode 100644 parser/sql/dialect/firebird/src/main/antlr4/imports/firebird/DCLStatement.g4 create mode 100644 parser/sql/dialect/firebird/src/main/antlr4/imports/firebird/DDLStatement.g4 create mode 100644 parser/sql/dialect/firebird/src/main/antlr4/imports/firebird/DMLStatement.g4 create mode 100644 parser/sql/dialect/firebird/src/main/antlr4/imports/firebird/FirebirdKeyword.g4 create mode 100644 parser/sql/dialect/firebird/src/main/antlr4/imports/firebird/Keyword.g4 create mode 100644 parser/sql/dialect/firebird/src/main/antlr4/imports/firebird/Literals.g4 create mode 100644 parser/sql/dialect/firebird/src/main/antlr4/imports/firebird/Symbol.g4 create mode 100644 parser/sql/dialect/firebird/src/main/antlr4/imports/firebird/TCLStatement.g4 create mode 100644 parser/sql/dialect/firebird/src/main/antlr4/org/apache/shardingsphere/sql/parser/autogen/FirebirdStatement.g4 create mode 100644 parser/sql/dialect/firebird/src/main/java/org/apache/shardingsphere/sql/parser/firebird/parser/FirebirdLexer.java create mode 100644 parser/sql/dialect/firebird/src/main/java/org/apache/shardingsphere/sql/parser/firebird/parser/FirebirdParser.java create mode 100644 parser/sql/dialect/firebird/src/main/java/org/apache/shardingsphere/sql/parser/firebird/parser/FirebirdParserFacade.java create mode 100644 parser/sql/dialect/firebird/src/main/java/org/apache/shardingsphere/sql/parser/firebird/visitor/statement/FirebirdStatementVisitor.java create mode 100644 parser/sql/dialect/firebird/src/main/java/org/apache/shardingsphere/sql/parser/firebird/visitor/statement/FirebirdStatementVisitorFacade.java create mode 100644 parser/sql/dialect/firebird/src/main/java/org/apache/shardingsphere/sql/parser/firebird/visitor/statement/type/FirebirdDALStatementVisitor.java create mode 100644 parser/sql/dialect/firebird/src/main/java/org/apache/shardingsphere/sql/parser/firebird/visitor/statement/type/FirebirdDCLStatementVisitor.java create mode 100644 parser/sql/dialect/firebird/src/main/java/org/apache/shardingsphere/sql/parser/firebird/visitor/statement/type/FirebirdDDLStatementVisitor.java create mode 100644 parser/sql/dialect/firebird/src/main/java/org/apache/shardingsphere/sql/parser/firebird/visitor/statement/type/FirebirdDMLStatementVisitor.java create mode 100644 parser/sql/dialect/firebird/src/main/java/org/apache/shardingsphere/sql/parser/firebird/visitor/statement/type/FirebirdTCLStatementVisitor.java create mode 100644 parser/sql/dialect/firebird/src/main/resources/META-INF/services/org.apache.shardingsphere.sql.parser.spi.SQLDialectParserFacade create mode 100644 parser/sql/dialect/firebird/src/main/resources/META-INF/services/org.apache.shardingsphere.sql.parser.spi.SQLStatementVisitorFacade create mode 100644 parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/firebird/FirebirdStatement.java create mode 100644 parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/firebird/dcl/FirebirdGrantStatement.java create mode 100644 parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/firebird/dcl/FirebirdRevokeStatement.java create mode 100644 parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/firebird/ddl/FirebirdAlterTableStatement.java create mode 100644 parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/firebird/ddl/FirebirdCreateTableStatement.java create mode 100644 parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/firebird/ddl/FirebirdDropTableStatement.java create mode 100644 parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/firebird/dml/FirebirdDeleteStatement.java create mode 100644 parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/firebird/dml/FirebirdInsertStatement.java create mode 100644 parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/firebird/dml/FirebirdSelectStatement.java create mode 100644 parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/firebird/dml/FirebirdUpdateStatement.java create mode 100644 parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/firebird/tcl/FirebirdCommitStatement.java create mode 100644 parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/firebird/tcl/FirebirdRollbackStatement.java create mode 100644 parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/firebird/tcl/FirebirdSetTransactionStatement.java diff --git a/infra/common/pom.xml b/infra/common/pom.xml index 95e8d9bc3811c..c02ffa6797aba 100644 --- a/infra/common/pom.xml +++ b/infra/common/pom.xml @@ -78,6 +78,11 @@ shardingsphere-infra-database-sql92 ${project.version} + + org.apache.shardingsphere + shardingsphere-infra-database-firebird + ${project.version} + org.apache.shardingsphere shardingsphere-infra-data-source-pool-hikari diff --git a/infra/database/type/firebird/pom.xml b/infra/database/type/firebird/pom.xml new file mode 100644 index 0000000000000..25485c836ad06 --- /dev/null +++ b/infra/database/type/firebird/pom.xml @@ -0,0 +1,43 @@ + + + + + 4.0.0 + + org.apache.shardingsphere + shardingsphere-infra-database-type + 5.4.1-SNAPSHOT + + shardingsphere-infra-database-firebird + ${project.artifactId} + + + + org.apache.shardingsphere + shardingsphere-infra-database-core + ${project.version} + + + + org.apache.shardingsphere + shardingsphere-test-util + ${project.version} + test + + + diff --git a/infra/database/type/firebird/src/main/java/org/apache/shardingsphere/infra/database/firebird/connector/FirebirdConnectionPropertiesParser.java b/infra/database/type/firebird/src/main/java/org/apache/shardingsphere/infra/database/firebird/connector/FirebirdConnectionPropertiesParser.java new file mode 100644 index 0000000000000..1ef311fe6d4a3 --- /dev/null +++ b/infra/database/type/firebird/src/main/java/org/apache/shardingsphere/infra/database/firebird/connector/FirebirdConnectionPropertiesParser.java @@ -0,0 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.shardingsphere.infra.database.firebird.connector; + +import org.apache.shardingsphere.infra.database.core.connector.ConnectionProperties; +import org.apache.shardingsphere.infra.database.core.connector.ConnectionPropertiesParser; +import org.apache.shardingsphere.infra.database.core.connector.StandardConnectionProperties; +import org.apache.shardingsphere.infra.database.core.connector.url.UnrecognizedDatabaseURLException; +import org.apache.shardingsphere.infra.exception.core.ShardingSpherePreconditions; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Connection properties parser of Firebird. + */ +public final class FirebirdConnectionPropertiesParser implements ConnectionPropertiesParser { + + private static final int DEFAULT_PORT = -1; + + private static final Pattern URL_PATTERN = Pattern.compile("jdbc:.*", Pattern.CASE_INSENSITIVE); + + @Override + public ConnectionProperties parse(final String url, final String username, final String catalog) { + Matcher matcher = URL_PATTERN.matcher(url); + ShardingSpherePreconditions.checkState(matcher.find(), () -> new UnrecognizedDatabaseURLException(url, URL_PATTERN.pattern())); + return new StandardConnectionProperties("", DEFAULT_PORT, "", null); + } + + @Override + public String getDatabaseType() { + return "Firebird"; + } +} diff --git a/infra/database/type/firebird/src/main/java/org/apache/shardingsphere/infra/database/firebird/metadata/database/FirebirdDatabaseMetaData.java b/infra/database/type/firebird/src/main/java/org/apache/shardingsphere/infra/database/firebird/metadata/database/FirebirdDatabaseMetaData.java new file mode 100644 index 0000000000000..467aab38775ba --- /dev/null +++ b/infra/database/type/firebird/src/main/java/org/apache/shardingsphere/infra/database/firebird/metadata/database/FirebirdDatabaseMetaData.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.shardingsphere.infra.database.firebird.metadata.database; + +import org.apache.shardingsphere.infra.database.core.metadata.database.DialectDatabaseMetaData; +import org.apache.shardingsphere.infra.database.core.metadata.database.enums.NullsOrderType; +import org.apache.shardingsphere.infra.database.core.metadata.database.enums.QuoteCharacter; + +/** + * Database meta data of Firebird. + */ +public final class FirebirdDatabaseMetaData implements DialectDatabaseMetaData { + + @Override + public QuoteCharacter getQuoteCharacter() { + return QuoteCharacter.QUOTE; + } + + @Override + public NullsOrderType getDefaultNullsOrderType() { + return NullsOrderType.FIRST; + } + + @Override + public String getDatabaseType() { + return "Firebird"; + } +} diff --git a/infra/database/type/firebird/src/main/java/org/apache/shardingsphere/infra/database/firebird/type/FirebirdDatabaseType.java b/infra/database/type/firebird/src/main/java/org/apache/shardingsphere/infra/database/firebird/type/FirebirdDatabaseType.java new file mode 100644 index 0000000000000..97b2b490c940f --- /dev/null +++ b/infra/database/type/firebird/src/main/java/org/apache/shardingsphere/infra/database/firebird/type/FirebirdDatabaseType.java @@ -0,0 +1,45 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.shardingsphere.infra.database.firebird.type; + +import org.apache.shardingsphere.infra.database.core.type.DatabaseType; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; + +/** + * Database type of Firebird. + */ +public final class FirebirdDatabaseType implements DatabaseType { + + @Override + public Collection getJdbcUrlPrefixes() { + return Arrays.asList("jdbc:firebirdsql:"); + } + + @Override + public String getType() { + return "Firebird"; + } + + @Override + public boolean isDefault() { + return false; + } +} diff --git a/infra/database/type/firebird/src/main/resources/META-INF/services/org.apache.shardingsphere.infra.database.core.connector.ConnectionPropertiesParser b/infra/database/type/firebird/src/main/resources/META-INF/services/org.apache.shardingsphere.infra.database.core.connector.ConnectionPropertiesParser new file mode 100644 index 0000000000000..6d440a2f748b2 --- /dev/null +++ b/infra/database/type/firebird/src/main/resources/META-INF/services/org.apache.shardingsphere.infra.database.core.connector.ConnectionPropertiesParser @@ -0,0 +1,18 @@ +# +# 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. +# + +org.apache.shardingsphere.infra.database.firebird.connector.FirebirdConnectionPropertiesParser diff --git a/infra/database/type/firebird/src/main/resources/META-INF/services/org.apache.shardingsphere.infra.database.core.metadata.database.DialectDatabaseMetaData b/infra/database/type/firebird/src/main/resources/META-INF/services/org.apache.shardingsphere.infra.database.core.metadata.database.DialectDatabaseMetaData new file mode 100644 index 0000000000000..f9db1b93a022d --- /dev/null +++ b/infra/database/type/firebird/src/main/resources/META-INF/services/org.apache.shardingsphere.infra.database.core.metadata.database.DialectDatabaseMetaData @@ -0,0 +1,18 @@ +# +# 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. +# + +org.apache.shardingsphere.infra.database.firebird.metadata.database.FirebirdDatabaseMetaData diff --git a/infra/database/type/firebird/src/main/resources/META-INF/services/org.apache.shardingsphere.infra.database.core.type.DatabaseType b/infra/database/type/firebird/src/main/resources/META-INF/services/org.apache.shardingsphere.infra.database.core.type.DatabaseType new file mode 100644 index 0000000000000..79c142d883e1b --- /dev/null +++ b/infra/database/type/firebird/src/main/resources/META-INF/services/org.apache.shardingsphere.infra.database.core.type.DatabaseType @@ -0,0 +1,18 @@ +# +# 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. +# + +org.apache.shardingsphere.infra.database.firebird.type.FirebirdDatabaseType diff --git a/infra/database/type/pom.xml b/infra/database/type/pom.xml index 6306cbc04cd21..954cf0d78cd70 100644 --- a/infra/database/type/pom.xml +++ b/infra/database/type/pom.xml @@ -36,5 +36,6 @@ sqlserver h2 sql92 + firebird diff --git a/jdbc/core/pom.xml b/jdbc/core/pom.xml index bae493cf8ccf2..9999b84a150d3 100644 --- a/jdbc/core/pom.xml +++ b/jdbc/core/pom.xml @@ -72,6 +72,11 @@ shardingsphere-parser-sql-opengauss ${project.version} + + org.apache.shardingsphere + shardingsphere-parser-sql-firebird + ${project.version} + org.apache.shardingsphere diff --git a/parser/sql/dialect/firebird/pom.xml b/parser/sql/dialect/firebird/pom.xml new file mode 100644 index 0000000000000..253c24344d887 --- /dev/null +++ b/parser/sql/dialect/firebird/pom.xml @@ -0,0 +1,40 @@ + + + + + 4.0.0 + + org.apache.shardingsphere + shardingsphere-parser-sql-dialect + 5.4.1-SNAPSHOT + + shardingsphere-parser-sql-firebird + ${project.artifactId} + + + firebird + + + + + org.apache.shardingsphere + shardingsphere-infra-database-firebird + ${project.version} + + + diff --git a/parser/sql/dialect/firebird/src/main/antlr4/imports/firebird/Alphabet.g4 b/parser/sql/dialect/firebird/src/main/antlr4/imports/firebird/Alphabet.g4 new file mode 100644 index 0000000000000..f7603cc7e6384 --- /dev/null +++ b/parser/sql/dialect/firebird/src/main/antlr4/imports/firebird/Alphabet.g4 @@ -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. + */ + +lexer grammar Alphabet; + +FOR_GENERATOR: 'DO NOT MATCH ANY THING, JUST FOR GENERATOR'; + +fragment A: [Aa]; +fragment B: [Bb]; +fragment C: [Cc]; +fragment D: [Dd]; +fragment E: [Ee]; +fragment F: [Ff]; +fragment G: [Gg]; +fragment H: [Hh]; +fragment I: [Ii]; +fragment J: [Jj]; +fragment K: [Kk]; +fragment L: [Ll]; +fragment M: [Mm]; +fragment N: [Nn]; +fragment O: [Oo]; +fragment P: [Pp]; +fragment Q: [Qq]; +fragment R: [Rr]; +fragment S: [Ss]; +fragment T: [Tt]; +fragment U: [Uu]; +fragment V: [Vv]; +fragment W: [Ww]; +fragment X: [Xx]; +fragment Y: [Yy]; +fragment Z: [Zz]; +fragment UL_: '_'; diff --git a/parser/sql/dialect/firebird/src/main/antlr4/imports/firebird/BaseRule.g4 b/parser/sql/dialect/firebird/src/main/antlr4/imports/firebird/BaseRule.g4 new file mode 100644 index 0000000000000..80e3340bd48b8 --- /dev/null +++ b/parser/sql/dialect/firebird/src/main/antlr4/imports/firebird/BaseRule.g4 @@ -0,0 +1,321 @@ +/* + * 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. + */ + +grammar BaseRule; + +import Symbol, Keyword, FirebirdKeyword, Literals; + +parameterMarker + : QUESTION_ + ; + +literals + : stringLiterals + | numberLiterals + | dateTimeLiterals + | hexadecimalLiterals + | bitValueLiterals + | booleanLiterals + | nullValueLiterals + ; + +stringLiterals + : characterSetName? STRING_ collateClause? + ; + +numberLiterals + : (PLUS_ | MINUS_)? NUMBER_ + ; + +dateTimeLiterals + : (DATE | TIME | TIMESTAMP) STRING_ + | LBE_ identifier STRING_ RBE_ + ; + +hexadecimalLiterals + : characterSetName? HEX_DIGIT_ collateClause? + ; + +bitValueLiterals + : characterSetName? BIT_NUM_ collateClause? + ; + +booleanLiterals + : TRUE | FALSE + ; + +nullValueLiterals + : NULL + ; + +identifier + : IDENTIFIER_ | unreservedWord + ; + +unreservedWord + : ADA + | C92 | CATALOG_NAME | CHARACTER_SET_CATALOG | CHARACTER_SET_NAME | CHARACTER_SET_SCHEMA + | CLASS_ORIGIN | COBOL | COLLATION_CATALOG | COLLATION_NAME | COLLATION_SCHEMA + | COLUMN_NAME | COMMAND_FUNCTION | COMMITTED | CONDITION_NUMBER | CONNECTION_NAME + | CONSTRAINT_CATALOG | CONSTRAINT_NAME | CONSTRAINT_SCHEMA | CURSOR_NAME + | DATA | DATETIME_INTERVAL_CODE | DATETIME_INTERVAL_PRECISION | DYNAMIC_FUNCTION + | FORTRAN + | LENGTH + | MESSAGE_LENGTH | MESSAGE_OCTET_LENGTH | MESSAGE_TEXT | MORE92 | MUMPS + | NAME | NULLABLE | NUMBER + | PASCAL | PLI + | REPEATABLE | RETURNED_LENGTH | RETURNED_OCTET_LENGTH | RETURNED_SQLSTATE | ROW_COUNT + | SCALE | SCHEMA_NAME | SERIALIZABLE | SERVER_NAME | SUBCLASS_ORIGIN + | TABLE_NAME | TYPE + | UNCOMMITTED | UNNAMED + ; + +variable + : (AT_? AT_)? (GLOBAL | LOCAL)? DOT_? identifier + ; + +schemaName + : identifier + ; + +tableName + : (owner DOT_)? name + ; + +columnName + : (owner DOT_)? name + ; + +viewName + : identifier + | (owner DOT_)? identifier + ; + +owner + : identifier + ; + +name + : identifier + ; + +constraintName + : identifier + ; + +columnNames + : LP_? columnName (COMMA_ columnName)* RP_? + ; + +tableNames + : LP_? tableName (COMMA_ tableName)* RP_? + ; + +characterSetName + : IDENTIFIER_ + ; + +expr + : expr andOperator expr + | expr orOperator expr + | notOperator expr + | LP_ expr RP_ + | booleanPrimary + ; + +andOperator + : AND | AND_ + ; + +orOperator + : OR + ; + +notOperator + : NOT | NOT_ + ; + +booleanPrimary + : booleanPrimary IS NOT? (TRUE | FALSE | UNKNOWN | NULL) + | booleanPrimary SAFE_EQ_ predicate + | booleanPrimary comparisonOperator predicate + | booleanPrimary comparisonOperator (ALL | ANY) subquery + | predicate + ; + +comparisonOperator + : EQ_ | GTE_ | GT_ | LTE_ | LT_ | NEQ_ + ; + +predicate + : bitExpr NOT? IN subquery + | bitExpr NOT? IN LP_ expr (COMMA_ expr)* RP_ + | bitExpr NOT? BETWEEN bitExpr AND predicate + | bitExpr NOT? LIKE simpleExpr (ESCAPE simpleExpr)? + | bitExpr + ; + +bitExpr + : bitExpr VERTICAL_BAR_ bitExpr + | bitExpr AMPERSAND_ bitExpr + | bitExpr SIGNED_LEFT_SHIFT_ bitExpr + | bitExpr SIGNED_RIGHT_SHIFT_ bitExpr + | bitExpr PLUS_ bitExpr + | bitExpr MINUS_ bitExpr + | bitExpr ASTERISK_ bitExpr + | bitExpr SLASH_ bitExpr + | bitExpr MOD_ bitExpr + | bitExpr CARET_ bitExpr + | bitExpr PLUS_ intervalExpression + | bitExpr MINUS_ intervalExpression + | simpleExpr + ; + +simpleExpr + : functionCall + | parameterMarker + | literals + | columnName + | simpleExpr COLLATE (STRING_ | identifier) + | variable + | (PLUS_ | MINUS_ | TILDE_ | NOT_) simpleExpr + | LP_ expr (COMMA_ expr)* RP_ + | EXISTS? subquery + | LBE_ identifier expr RBE_ + | matchExpression + | caseExpression + | intervalExpression + ; + +functionCall + : aggregationFunction | specialFunction | regularFunction + ; + +aggregationFunction + : aggregationFunctionName LP_ distinct? (expr (COMMA_ expr)* | ASTERISK_)? RP_ + ; + +aggregationFunctionName + : MAX | MIN | SUM | COUNT | AVG + ; + +distinct + : DISTINCT + ; + +specialFunction + : castFunction | convertFunction | positionFunction | substringFunction | extractFunction | trimFunction + ; + +castFunction + : CAST LP_ (expr | NULL) AS dataType RP_ + ; + +convertFunction + : CONVERT LP_ expr USING identifier RP_ + ; + +positionFunction + : POSITION LP_ expr IN expr RP_ + ; + +substringFunction + : SUBSTRING LP_ expr FROM NUMBER_ (FOR NUMBER_)? RP_ + ; + +extractFunction + : EXTRACT LP_ identifier FROM expr RP_ + ; + +trimFunction + : TRIM LP_ (LEADING | BOTH | TRAILING) STRING_ FROM STRING_ RP_ + ; + +regularFunction + : regularFunctionName LP_ (expr (COMMA_ expr)* | ASTERISK_)? RP_ + ; + +regularFunctionName + : identifier | IF | CURRENT_TIMESTAMP | LOCALTIME | LOCALTIMESTAMP | INTERVAL + ; + +matchExpression + : literals MATCH UNIQUE? (PARTIAL | FULL) subquery + ; + +caseExpression + : CASE simpleExpr? caseWhen+ caseElse? END + ; + +caseWhen + : WHEN expr THEN expr + ; + +caseElse + : ELSE expr + ; + +intervalExpression + : INTERVAL expr intervalUnit + ; + +intervalUnit + : MICROSECOND | SECOND | MINUTE | HOUR | DAY | WEEK | MONTH | QUARTER | YEAR + ; + +subquery + : 'Default does not match anything' + ; + +orderByClause + : ORDER BY orderByItem (COMMA_ orderByItem)* + ; + +orderByItem + : (columnName | numberLiterals) (ASC | DESC)? + ; + +dataType + : dataTypeName dataTypeLength? characterSet? collateClause? | dataTypeName LP_ STRING_ (COMMA_ STRING_)* RP_ characterSet? collateClause? + ; + +dataTypeName + : CHARACTER | CHARACTER VARYING | NATIONAL CHARACTER | NATIONAL CHARACTER VARYING | CHAR | VARCHAR | NCHAR + | NATIONAL CHAR | NATIONAL CHAR VARYING | BIT | BIT VARYING | NUMERIC | DECIMAL | DEC | INTEGER | SMALLINT + | FLOAT | REAL | DOUBLE PRECISION | DATE | TIME | TIMESTAMP | INTERVAL | TIME WITH TIME ZONE | TIMESTAMP WITH TIME ZONE + | identifier + ; + +dataTypeLength + : LP_ NUMBER_ (COMMA_ NUMBER_)? RP_ + ; + +characterSet + : (CHARACTER | CHAR) SET EQ_? ignoredIdentifier + ; + +collateClause + : COLLATE EQ_? (STRING_ | ignoredIdentifier) + ; + +ignoredIdentifier + : identifier (DOT_ identifier)? + ; + +dropBehaviour + : (CASCADE | RESTRICT)? + ; diff --git a/parser/sql/dialect/firebird/src/main/antlr4/imports/firebird/Comments.g4 b/parser/sql/dialect/firebird/src/main/antlr4/imports/firebird/Comments.g4 new file mode 100644 index 0000000000000..976def52a8dd7 --- /dev/null +++ b/parser/sql/dialect/firebird/src/main/antlr4/imports/firebird/Comments.g4 @@ -0,0 +1,22 @@ +/* + * 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. + */ + +lexer grammar Comments; + +import Symbol; + +INLINE_COMMENT: (('-- ' | '#') ~[\r\n]* ('\r'? '\n' | EOF) | '--' ('\r'? '\n' | EOF)) -> channel(HIDDEN); diff --git a/parser/sql/dialect/firebird/src/main/antlr4/imports/firebird/DCLStatement.g4 b/parser/sql/dialect/firebird/src/main/antlr4/imports/firebird/DCLStatement.g4 new file mode 100644 index 0000000000000..bfe6b552ac183 --- /dev/null +++ b/parser/sql/dialect/firebird/src/main/antlr4/imports/firebird/DCLStatement.g4 @@ -0,0 +1,62 @@ +/* + * 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. + */ + +grammar DCLStatement; + +import BaseRule; + +grant + : GRANT privilegeClause TO grantee (COMMA_ grantee)* (WITH GRANT OPTION)? + ; + +revoke + : REVOKE (GRANT OPTION FOR)? privilegeClause FROM grantee (COMMA_ grantee)* dropBehaviour + ; + +privilegeClause + : privileges ON onObjectClause + ; + +privileges + : privilegeType columnNames + ; + +privilegeType + : ALL PRIVILEGES + | SELECT + | DELETE + | INSERT + | UPDATE + | REFERENCES + | USAGE + ; + +grantee + : PUBLIC | identifier + ; + +onObjectClause + : objectType? privilegeLevel + ; + +objectType + : TABLE + ; + +privilegeLevel + : tableName + ; diff --git a/parser/sql/dialect/firebird/src/main/antlr4/imports/firebird/DDLStatement.g4 b/parser/sql/dialect/firebird/src/main/antlr4/imports/firebird/DDLStatement.g4 new file mode 100644 index 0000000000000..71a5555610d39 --- /dev/null +++ b/parser/sql/dialect/firebird/src/main/antlr4/imports/firebird/DDLStatement.g4 @@ -0,0 +1,154 @@ +/* + * 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. + */ + +grammar DDLStatement; + +import DMLStatement; + +createTable + : CREATE createTableSpecification? TABLE tableName (createDefinitionClause | createLikeClause) + ; + +alterTable + : ALTER TABLE tableName alterDefinitionClause + ; + +dropTable + : DROP TABLE tableNames dropBehaviour + ; + +createDatabase + : CREATE SCHEMA schemaName createDatabaseSpecification_* + ; + +dropDatabase + : DROP SCHEMA schemaName dropBehaviour + ; + +createView + : CREATE VIEW viewName (LP_ identifier (COMMA_ identifier)* RP_)? + AS select + (WITH (CASCADED | LOCAL)? CHECK OPTION)? + ; + +dropView + : DROP VIEW viewName dropBehaviour + ; + +createTableSpecification + : (GLOBAL | LOCAL) TEMPORARY + ; + +createDefinitionClause + : LP_ createDefinition (COMMA_ createDefinition)* RP_ + ; + +createDatabaseSpecification_ + : DEFAULT CHARACTER SET EQ_? characterSetName + ; + +createDefinition + : columnDefinition | constraintDefinition | checkConstraintDefinition + ; + +columnDefinition + : columnName dataType dataTypeOption* + ; + +dataTypeOption + : primaryKey + | UNIQUE KEY? + | NOT? NULL + | collateClause + | checkConstraintDefinition + | referenceDefinition + | DEFAULT (literals | expr) + | STRING_ + ; + +checkConstraintDefinition + : (CONSTRAINT ignoredIdentifier?)? CHECK expr + ; + +referenceDefinition + : REFERENCES tableName keyParts (MATCH FULL | MATCH PARTIAL | MATCH UNIQUE)? (ON (UPDATE | DELETE) referenceOption)* + ; + +referenceOption + : RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT + ; + +keyParts + : LP_ keyPart (COMMA_ keyPart)* RP_ + ; + +keyPart + : (columnName (LP_ NUMBER_ RP_)? | expr) (ASC | DESC)? + ; + +constraintDefinition + : (CONSTRAINT constraintName?)? (primaryKeyOption | uniqueOption | foreignKeyOption) + ; + +primaryKeyOption + : primaryKey columnNames + ; + +primaryKey + : PRIMARY KEY + ; + +uniqueOption + : UNIQUE keyParts + ; + +foreignKeyOption + : FOREIGN KEY columnNames referenceDefinition + ; + +createLikeClause + : LP_? LIKE tableName RP_? + ; + + +alterDefinitionClause + : addColumnSpecification + | modifyColumnSpecification + | dropColumnSpecification + | addConstraintSpecification + | dropConstraintSpecification + ; + +addColumnSpecification + : ADD COLUMN? columnDefinition + ; + +modifyColumnSpecification + : ALTER COLUMN? columnDefinition + ; + +dropColumnSpecification + : DROP COLUMN? columnName + ; + +addConstraintSpecification + : ADD constraintDefinition + ; + +dropConstraintSpecification + : DROP constraintDefinition + ; diff --git a/parser/sql/dialect/firebird/src/main/antlr4/imports/firebird/DMLStatement.g4 b/parser/sql/dialect/firebird/src/main/antlr4/imports/firebird/DMLStatement.g4 new file mode 100644 index 0000000000000..97707d9110a43 --- /dev/null +++ b/parser/sql/dialect/firebird/src/main/antlr4/imports/firebird/DMLStatement.g4 @@ -0,0 +1,163 @@ +/* + * 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. + */ + +grammar DMLStatement; + +import BaseRule; + +insert + : INSERT INTO? tableName (insertValuesClause | insertSelectClause) + ; + +insertValuesClause + : columnNames? (VALUES | VALUE) assignmentValues (COMMA_ assignmentValues)* + ; + +insertSelectClause + : columnNames? select + ; + +update + : UPDATE tableReferences setAssignmentsClause whereClause? + ; + +assignment + : columnName EQ_ VALUES? LP_? assignmentValue RP_? + ; + +setAssignmentsClause + : SET assignment (COMMA_ assignment)* + ; + +assignmentValues + : LP_ assignmentValue (COMMA_ assignmentValue)* RP_ + | LP_ RP_ + ; + +assignmentValue + : expr | DEFAULT | blobValue + ; + +blobValue + : STRING_ + ; + +delete + : DELETE singleTableClause whereClause? + ; + +singleTableClause + : FROM tableName (AS? alias)? + ; + +select + : combineClause + ; + +combineClause + : selectClause (UNION (ALL)? selectClause)* + ; + +selectClause + : SELECT selectSpecification* projections fromClause? whereClause? groupByClause? havingClause? orderByClause? limitClause? + ; + +selectSpecification + : duplicateSpecification + ; + +duplicateSpecification + : ALL | DISTINCT + ; + +projections + : (unqualifiedShorthand | projection) (COMMA_ projection)* + ; + +projection + : (columnName | expr) (AS? alias)? | qualifiedShorthand + ; + +alias + : identifier | STRING_ + ; + +unqualifiedShorthand + : ASTERISK_ + ; + +qualifiedShorthand + : identifier DOT_ASTERISK_ + ; + +fromClause + : FROM tableReferences + ; + +tableReferences + : escapedTableReference (COMMA_ escapedTableReference)* + ; + +escapedTableReference + : tableReference | LBE_ tableReference RBE_ + ; + +tableReference + : tableFactor joinedTable* + ; + +tableFactor + : tableName (AS? alias)? | subquery AS? alias columnNames? | LP_ tableReferences RP_ + ; + +joinedTable + : ((INNER | CROSS)? JOIN) tableFactor joinSpecification? + | (LEFT | RIGHT) OUTER? JOIN tableFactor joinSpecification + | NATURAL (INNER | (LEFT | RIGHT) (OUTER))? JOIN tableFactor + ; + +joinSpecification + : ON expr | USING columnNames + ; + +whereClause + : WHERE expr + ; + +groupByClause + : GROUP BY orderByItem (COMMA_ orderByItem)* + ; + +havingClause + : HAVING expr + ; + +limitClause + : LIMIT ((limitOffset COMMA_)? limitRowCount | limitRowCount OFFSET limitOffset) + ; + +limitRowCount + : numberLiterals | parameterMarker + ; + +limitOffset + : numberLiterals | parameterMarker + ; + +subquery + : LP_ combineClause RP_ + ; diff --git a/parser/sql/dialect/firebird/src/main/antlr4/imports/firebird/FirebirdKeyword.g4 b/parser/sql/dialect/firebird/src/main/antlr4/imports/firebird/FirebirdKeyword.g4 new file mode 100644 index 0000000000000..5e044e9a0a7cd --- /dev/null +++ b/parser/sql/dialect/firebird/src/main/antlr4/imports/firebird/FirebirdKeyword.g4 @@ -0,0 +1,692 @@ +/* + * 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. + */ + +lexer grammar FirebirdKeyword; + +import Alphabet, Keyword; + +WS + : [ \t\r\n] + ->skip + ; + +ADA + : A D A + ; + +C92 + : C + ; + +CATALOG_NAME + : C A T A L O G UL_ N A M E + ; + +CHARACTER_SET_CATALOG + : C H A R A C T E R UL_ S E T UL_ C A T A L O G + ; + +CHARACTER_SET_NAME + : C H A R A C T E R UL_ S E T UL_ N A M E + ; + +CHARACTER_SET_SCHEMA + : C H A R A C T E R UL_ S E T UL_ S C H E M A + ; + +CLASS_ORIGIN + : C L A S S UL_ O R I G I N + ; + +COBOL + : C O B O L + ; + +COLLATION_CATALOG + : C O L L A T I O N UL_ C A T A L O G + ; + +COLLATION_NAME + : C O L L A T I O N UL_ N A M E + ; + +COLLATION_SCHEMA + : C O L L A T I O N UL_ S C H E M A + ; + +COLUMN_NAME + : C O L U M N UL_ N A M E + ; + +COMMAND_FUNCTION + : C O M M A N D UL_ F U N C T I O N + ; + +COMMITTED + : C O M M I T T E D + ; + +CONDITION_NUMBER + : C O N D I T I O N UL_ N U M B E R + ; + +CONNECTION_NAME + : C O N N E C T I O N UL_ N A M E + ; + +CONSTRAINT_CATALOG + : C O N S T R A I N T UL_ C A T A L O G + ; + +CONSTRAINT_NAME + : C O N S T R A I N T UL_ N A M E + ; + +CONSTRAINT_SCHEMA + : C O N S T R A I N T UL_ S C H E M A + ; + +CURSOR_NAME + : C U R S O R UL_ N A M E + ; + +DATA + : D A T A + ; + +DATETIME_INTERVAL_CODE + : D A T E T I M E UL_ I N T E R V A L UL_ C O D E + ; + +DATETIME_INTERVAL_PRECISION + : D A T E T I M E UL_ I N T E R V A L UL_ P R E C I S I O N + ; + +DYNAMIC_FUNCTION + : D Y N A M I C UL_ F U N C T I O N + ; + +FORTRAN + : F O R T R A N + ; + +LENGTH + : L E N G T H + ; + +MESSAGE_LENGTH + : M E S S A G E UL_ L E N G T H + ; + +MESSAGE_OCTET_LENGTH + : M E S S A G E UL_ O C T E T UL_ L E N G T H + ; + +MESSAGE_TEXT + : M E S S A G E UL_ T E X T + ; + +MORE92 + : M O R E + ; + +MUMPS + : M U M P S + ; + +NULLABLE + : N U L L A B L E + ; + +NUMBER + : N U M B E R + ; + +PASCAL + : P A S C A L + ; + +PLI + : P L I + ; + +REPEATABLE + : R E P E A T A B L E + ; + +RETURNED_LENGTH + : R E T U R N E D UL_ L E N G T H + ; + +RETURNED_OCTET_LENGTH + : R E T U R N E D UL_ O C T E T UL_ L E N G T H + ; + +RETURNED_SQLSTATE + : R E T U R N E D UL_ S Q L S T A T E + ; + +ROW_COUNT + : R O W UL_ C O U N T + ; + +SCALE + : S C A L E + ; + +SCHEMA_NAME + : S C H E M A UL_ N A M E + ; + +SERIALIZABLE + : S E R I A L I Z A B L E + ; + +SERVER_NAME + : S E R V E R UL_ N A M E + ; + +SUBCLASS_ORIGIN + : S U B C L A S S UL_ O R I G I N + ; + +TABLE_NAME + : T A B L E UL_ N A M E + ; + +UNCOMMITTED + : U N C O M M I T T E D + ; + +UNNAMED + : U N N A M E D + ; + +ABSOLUTE + : A B S O L U T E + ; + +ACTION + : A C T I O N + ; + +ALLOCATE + : A L L O C A T E + ; + +ARE + : A R E + ; + +ASSERTION + : A S S E R T I O N + ; + +AT + : A T + ; + +AUTHORIZATION + : A U T H O R I Z A T I O N + ; + +BIT + : B I T + ; + +BIT_LENGTH + : B I T UL_ L E N G T H + ; + +BOTH + : B O T H + ; + +CASCADE + : C A S C A D E + ; + +CATALOG + : C A T A L O G + ; + +CHAR_LENGTH + : C H A R UL_ L E N G T H + ; + +CHARACTER_LENGTH + : C H A R A C T E R UL_ L E N G T H + ; + +CHECK + : C H E C K + ; + +COALESCE + : C O A L E S C E + ; + +COLLATE + : C O L L A T E + ; + +CONNECT + : C O N N E C T + ; + +CONNECTION + : C O N N E C T I O N + ; + +CONSTRAINTS + : C O N S T R A I N T S + ; + +CONTINUE + : C O N T I N U E + ; + +CONVERT + : C O N V E R T + ; + +CORRESPONDING + : C O R R E S P O N D I N G + ; + +CURRENT_DATE + : C U R R E N T UL_ D A T E + ; + +CURRENT_TIME + : C U R R E N T UL_ T I M E + ; + +CURRENT_TIMESTAMP + : C U R R E N T UL_ T I M E S T A M P + ; + +CURSOR + : C U R S O R + ; + +DEALLOCATE + : D E A L L O C A T E + ; + +DEC + : D E C + ; + +DECLARE + : D E C L A R E + ; + +DEFERRABLE + : D E F E R R A B L E + ; + +DEFERRED + : D E F E R R E D + ; + +DESCRIBE + : D E S C R I B E + ; + +DESCRIPTOR + : D E S C R I P T O R + ; + +DIAGNOSTICS + : D I A G N O S T I C S + ; + +DISCONNECT + : D I S C O N N E C T + ; + +DOMAIN + : D O M A I N + ; + +END + : E N D + ; + +END_EXEC + : E N D '-' E X E C + ; + +ESCAPE + : E S C A P E + ; + +EXCEPT + : E X C E P T + ; + +EXCEPTION + : E X C E P T I O N + ; + +EXEC + : E X E C + ; + +EXECUTE + : E X E C U T E + ; + +EXTERNAL + : E X T E R N A L + ; + +EXTRACT + : E X T R A C T + ; + +FETCH + : F E T C H + ; + +FIRST + : F I R S T + ; + +FOUND + : F O U N D + ; + +GET + : G E T + ; + +GLOBAL + : G L O B A L + ; + +GO + : G O + ; + +GOTO + : G O T O + ; + +IDENTITY + : I D E N T I T Y + ; + +IMMEDIATE + : I M M E D I A T E + ; + +INDICATOR + : I N D I C A T O R + ; + +INITIALLY + : I N I T I A L L Y + ; + +INPUT + : I N P U T + ; + +INSENSITIVE + : I N S E N S I T I V E + ; + +INTERSECT + : I N T E R S E C T + ; + +ISOLATION + : I S O L A T I O N + ; + +LANGUAGE + : L A N G U A G E + ; + +LAST + : L A S T + ; + +LEADING + : L E A D I N G + ; + +LEVEL + : L E V E L + ; + +LOWER + : L O W E R + ; + +MATCH + : M A T C H + ; + +MODULE + : M O D U L E + ; + +NATIONAL + : N A T I O N A L + ; + +NCHAR + : N C H A R + ; + +NO + : N O + ; + +NULLIF + : N U L L I F + ; + +NUMERIC + : N U M E R I C + ; + +OCTET_LENGTH + : O C T E T UL_ L E N G T H + ; + +OF + : O F + ; + +ONLY + : O N L Y + ; + +OPTION + : O P T I O N + ; + +OUTPUT + : O U T P U T + ; + +OVERLAPS + : O V E R L A P S + ; + +PAD + : P A D + ; + +PARTIAL + : P A R T I A L + ; + +PREPARE + : P R E P A R E + ; + +PRIOR + : P R I O R + ; + +PRIVILEGES + : P R I V I L E G E S + ; + +PUBLIC + : P U B L I C + ; + +READ + : R E A D + ; + +REFERENCES + : R E F E R E N C E S + ; + +RELATIVE + : R E L A T I V E + ; + +RESTRICT + : R E S T R I C T + ; + +ROWS + : R O W S + ; + +SCROLL + : S C R O L L + ; + +SECTION + : S E C T I O N + ; + +SESSION + : S E S S I O N + ; + +SESSION_USER + : S E S S I O N UL_ U S E R + ; + +SIZE + : S I Z E + ; + +SMALLINT + : S M A L L I N T + ; + +SOME + : S O M E + ; + +SPACE + : S P A C E + ; + +SQLCODE + : S Q L C O D E + ; + +SQLERROR + : S Q L E R R O R + ; + +SQLSTATE + : S Q L S T A T E + ; + +SYSTEM_USER + : S Y S T E M UL_ U S E R + ; + +TEMPORARY + : T E M P O R A R Y + ; + +TIMEZONE_HOUR + : T I M E Z O N E UL_ H O U R + ; + +TIMEZONE_MINUTE + : T I M E Z O N E UL_ M I N U T E + ; + +TRAILING + : T R A I L I N G + ; + +TRANSACTION + : T R A N S A C T I O N + ; + +TRANSLATE + : T R A N S L A T E + ; + +TRANSLATION + : T R A N S L A T I O N + ; + +UNKNOWN + : U N K N O W N + ; + +UPPER + : U P P E R + ; + +USAGE + : U S A G E + ; + +USER + : U S E R + ; + +VALUE + : V A L U E + ; + +VARYING + : V A R Y I N G + ; + +WHENEVER + : W H E N E V E R + ; + +WORK + : W O R K + ; + +WRITE + : W R I T E + ; + +ZONE + : Z O N E + ; diff --git a/parser/sql/dialect/firebird/src/main/antlr4/imports/firebird/Keyword.g4 b/parser/sql/dialect/firebird/src/main/antlr4/imports/firebird/Keyword.g4 new file mode 100644 index 0000000000000..9cd7b9035cf1d --- /dev/null +++ b/parser/sql/dialect/firebird/src/main/antlr4/imports/firebird/Keyword.g4 @@ -0,0 +1,545 @@ +/* + * 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. + */ + +lexer grammar Keyword; + +import Alphabet; + +WS + : [ \t\r\n] + ->skip + ; + +SELECT + : S E L E C T + ; + +INSERT + : I N S E R T + ; + +UPDATE + : U P D A T E + ; + +DELETE + : D E L E T E + ; + +CREATE + : C R E A T E + ; + +ALTER + : A L T E R + ; + +DROP + : D R O P + ; + +TRUNCATE + : T R U N C A T E + ; + +SCHEMA + : S C H E M A + ; + +GRANT + : G R A N T + ; + +REVOKE + : R E V O K E + ; + +ADD + : A D D + ; + +SET + : S E T + ; + +TABLE + : T A B L E + ; + +COLUMN + : C O L U M N + ; + +INDEX + : I N D E X + ; + +CONSTRAINT + : C O N S T R A I N T + ; + +PRIMARY + : P R I M A R Y + ; + +UNIQUE + : U N I Q U E + ; + +FOREIGN + : F O R E I G N + ; + +KEY + : K E Y + ; + +POSITION + : P O S I T I O N + ; + +PRECISION + : P R E C I S I O N + ; + +FUNCTION + : F U N C T I O N + ; + +TRIGGER + : T R I G G E R + ; + +PROCEDURE + : P R O C E D U R E + ; + +VIEW + : V I E W + ; + +INTO + : I N T O + ; + +VALUES + : V A L U E S + ; + +WITH + : W I T H + ; + +UNION + : U N I O N + ; + +DISTINCT + : D I S T I N C T + ; + +CASE + : C A S E + ; + +WHEN + : W H E N + ; + +CAST + : C A S T + ; + +TRIM + : T R I M + ; + +SUBSTRING + : S U B S T R I N G + ; + +FROM + : F R O M + ; + +NATURAL + : N A T U R A L + ; + +JOIN + : J O I N + ; + +FULL + : F U L L + ; + +INNER + : I N N E R + ; + +OUTER + : O U T E R + ; + +LEFT + : L E F T + ; + +RIGHT + : R I G H T + ; + +CROSS + : C R O S S + ; + +USING + : U S I N G + ; + +WHERE + : W H E R E + ; + +AS + : A S + ; + +ON + : O N + ; + +IF + : I F + ; + +ELSE + : E L S E + ; + +THEN + : T H E N + ; + +FOR + : F O R + ; + +TO + : T O + ; + +AND + : A N D + ; + +OR + : O R + ; + +IS + : I S + ; + +NOT + : N O T + ; + +NULL + : N U L L + ; + +TRUE + : T R U E + ; + +FALSE + : F A L S E + ; + +EXISTS + : E X I S T S + ; + +BETWEEN + : B E T W E E N + ; + +IN + : I N + ; + +ALL + : A L L + ; + +ANY + : A N Y + ; + +LIKE + : L I K E + ; + +ORDER + : O R D E R + ; + +GROUP + : G R O U P + ; + +BY + : B Y + ; + +ASC + : A S C + ; + +DESC + : D E S C + ; + +HAVING + : H A V I N G + ; + +LIMIT + : L I M I T + ; + +OFFSET + : O F F S E T + ; + +BEGIN + : B E G I N + ; + +COMMIT + : C O M M I T + ; + +ROLLBACK + : R O L L B A C K + ; + +SAVEPOINT + : S A V E P O I N T + ; + +BOOLEAN + : B O O L E A N + ; + +DOUBLE + : D O U B L E + ; + +CHAR + : C H A R + ; + +CHARACTER + : C H A R A C T E R + ; + +ARRAY + : A R R A Y + ; + +INTERVAL + : I N T E R V A L + ; + +DATE + : D A T E + ; + +TIME + : T I M E + ; + +TIMESTAMP + : T I M E S T A M P + ; + +LOCALTIME + : L O C A L T I M E + ; + +LOCALTIMESTAMP + : L O C A L T I M E S T A M P + ; + +YEAR + : Y E A R + ; + +QUARTER + : Q U A R T E R + ; + +MONTH + : M O N T H + ; + +WEEK + : W E E K + ; + +DAY + : D A Y + ; + +HOUR + : H O U R + ; + +MINUTE + : M I N U T E + ; + +SECOND + : S E C O N D + ; + +MICROSECOND + : M I C R O S E C O N D + ; + +MAX + : M A X + ; + +MIN + : M I N + ; + +SUM + : S U M + ; + +COUNT + : C O U N T + ; + +AVG + : A V G + ; + +DEFAULT + : D E F A U L T + ; + +CURRENT + : C U R R E N T + ; + +ENABLE + : E N A B L E + ; + +DISABLE + : D I S A B L E + ; + +CALL + : C A L L + ; + +INSTANCE + : I N S T A N C E + ; + +PRESERVE + : P R E S E R V E + ; + +DO + : D O + ; + +DEFINER + : D E F I N E R + ; + +CURRENT_USER + : C U R R E N T UL_ U S E R + ; + +SQL + : S Q L + ; + + +CASCADED + : C A S C A D E D + ; + +LOCAL + : L O C A L + ; + +CLOSE + : C L O S E + ; + +OPEN + : O P E N + ; + +NEXT + : N E X T + ; + +NAME + : N A M E + ; + +COLLATION + : C O L L A T I O N + ; + +NAMES + : N A M E S + ; + +INTEGER + : I N T E G E R + ; + +REAL + : R E A L + ; + +DECIMAL + : D E C I M A L + ; + +TYPE + : T Y P E + ; + +VARCHAR + : V A R C H A R + ; + +FLOAT + : F L O A T + ; diff --git a/parser/sql/dialect/firebird/src/main/antlr4/imports/firebird/Literals.g4 b/parser/sql/dialect/firebird/src/main/antlr4/imports/firebird/Literals.g4 new file mode 100644 index 0000000000000..bba66d71a27a7 --- /dev/null +++ b/parser/sql/dialect/firebird/src/main/antlr4/imports/firebird/Literals.g4 @@ -0,0 +1,49 @@ +/* + * 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. + */ + +lexer grammar Literals; + +import Alphabet, Symbol; + +IDENTIFIER_ + : [A-Za-z_$0-9\u0080-\uFFFF]*?[A-Za-z_$\u0080-\uFFFF]+?[A-Za-z_$0-9\u0080-\uFFFF]* + | DQ_ ~'"'+ DQ_ + ; + +STRING_ + : (SQ_ ('\\'. | '\'\'' | ~('\'' | '\\'))* SQ_) + ; + +NUMBER_ + : INT_? DOT_? INT_ (E (PLUS_ | MINUS_)? INT_)? + ; + +HEX_DIGIT_ + : '0x' HEX_+ | 'X' SQ_ HEX_+ SQ_ + ; + +BIT_NUM_ + : '0b' ('0' | '1')+ | B SQ_ ('0' | '1')+ SQ_ + ; + +fragment INT_ + : [0-9]+ + ; + +fragment HEX_ + : [0-9a-fA-F] + ; diff --git a/parser/sql/dialect/firebird/src/main/antlr4/imports/firebird/Symbol.g4 b/parser/sql/dialect/firebird/src/main/antlr4/imports/firebird/Symbol.g4 new file mode 100644 index 0000000000000..a8d1f6955e6ce --- /dev/null +++ b/parser/sql/dialect/firebird/src/main/antlr4/imports/firebird/Symbol.g4 @@ -0,0 +1,58 @@ +/* + * 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. + */ + +lexer grammar Symbol; + +AND_: '&&'; +CONCAT_: '||'; +NOT_: '!'; +TILDE_: '~'; +VERTICAL_BAR_: '|'; +AMPERSAND_: '&'; +SIGNED_LEFT_SHIFT_: '<<'; +SIGNED_RIGHT_SHIFT_: '>>'; +CARET_: '^'; +MOD_: '%'; +COLON_: ':'; +PLUS_: '+'; +MINUS_: '-'; +ASTERISK_: '*'; +SLASH_: '/'; +BACKSLASH_: '\\'; +DOT_: '.'; +DOT_ASTERISK_: '.*'; +SAFE_EQ_: '<=>'; +DEQ_: '=='; +EQ_: '='; +NEQ_: '<>' | '!='; +GT_: '>'; +GTE_: '>='; +LT_: '<'; +LTE_: '<='; +POUND_: '#'; +LP_: '('; +RP_: ')'; +LBE_: '{'; +RBE_: '}'; +LBT_: '['; +RBT_: ']'; +COMMA_: ','; +DQ_: '"'; +SQ_ : '\''; +QUESTION_: '?'; +AT_: '@'; +SEMI_: ';'; diff --git a/parser/sql/dialect/firebird/src/main/antlr4/imports/firebird/TCLStatement.g4 b/parser/sql/dialect/firebird/src/main/antlr4/imports/firebird/TCLStatement.g4 new file mode 100644 index 0000000000000..49540d6d589f5 --- /dev/null +++ b/parser/sql/dialect/firebird/src/main/antlr4/imports/firebird/TCLStatement.g4 @@ -0,0 +1,36 @@ +/* + * 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. + */ + +grammar TCLStatement; + +import BaseRule; + +setTransaction + : SET TRANSACTION ISOLATION LEVEL levelOfIsolation + ; + +commit + : COMMIT + ; + +rollback + : ROLLBACK + ; + +levelOfIsolation + : READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ| SERIALIZABLE + ; \ No newline at end of file diff --git a/parser/sql/dialect/firebird/src/main/antlr4/org/apache/shardingsphere/sql/parser/autogen/FirebirdStatement.g4 b/parser/sql/dialect/firebird/src/main/antlr4/org/apache/shardingsphere/sql/parser/autogen/FirebirdStatement.g4 new file mode 100644 index 0000000000000..b0d0bd13d5ce4 --- /dev/null +++ b/parser/sql/dialect/firebird/src/main/antlr4/org/apache/shardingsphere/sql/parser/autogen/FirebirdStatement.g4 @@ -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. + */ + +grammar FirebirdStatement; + +import Comments, DDLStatement, TCLStatement, DCLStatement; + +execute + : (select + | insert + | update + | delete + | createDatabase + | dropDatabase + | createTable + | alterTable + | dropTable + | createView + | dropView + | setTransaction + | commit + | rollback + | grant + | revoke + ) SEMI_? + ; diff --git a/parser/sql/dialect/firebird/src/main/java/org/apache/shardingsphere/sql/parser/firebird/parser/FirebirdLexer.java b/parser/sql/dialect/firebird/src/main/java/org/apache/shardingsphere/sql/parser/firebird/parser/FirebirdLexer.java new file mode 100644 index 0000000000000..64119db30eebd --- /dev/null +++ b/parser/sql/dialect/firebird/src/main/java/org/apache/shardingsphere/sql/parser/firebird/parser/FirebirdLexer.java @@ -0,0 +1,32 @@ +/* + * 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.firebird.parser; + +import org.antlr.v4.runtime.CharStream; +import org.apache.shardingsphere.sql.parser.api.parser.SQLLexer; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementLexer; + +/** + * SQL lexer for Firebird. + */ +public final class FirebirdLexer extends FirebirdStatementLexer implements SQLLexer { + + public FirebirdLexer(final CharStream input) { + super(input); + } +} diff --git a/parser/sql/dialect/firebird/src/main/java/org/apache/shardingsphere/sql/parser/firebird/parser/FirebirdParser.java b/parser/sql/dialect/firebird/src/main/java/org/apache/shardingsphere/sql/parser/firebird/parser/FirebirdParser.java new file mode 100644 index 0000000000000..3ce69198b3ad4 --- /dev/null +++ b/parser/sql/dialect/firebird/src/main/java/org/apache/shardingsphere/sql/parser/firebird/parser/FirebirdParser.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.firebird.parser; + +import org.antlr.v4.runtime.CommonTokenStream; +import org.antlr.v4.runtime.TokenStream; +import org.apache.shardingsphere.sql.parser.api.parser.SQLParser; +import org.apache.shardingsphere.sql.parser.api.ASTNode; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser; +import org.apache.shardingsphere.sql.parser.core.ParseASTNode; + +/** + * SQL parser for Firebird. + */ +public final class FirebirdParser extends FirebirdStatementParser implements SQLParser { + + public FirebirdParser(final TokenStream input) { + super(input); + } + + @Override + public ASTNode parse() { + return new ParseASTNode(execute(), (CommonTokenStream) getTokenStream()); + } +} diff --git a/parser/sql/dialect/firebird/src/main/java/org/apache/shardingsphere/sql/parser/firebird/parser/FirebirdParserFacade.java b/parser/sql/dialect/firebird/src/main/java/org/apache/shardingsphere/sql/parser/firebird/parser/FirebirdParserFacade.java new file mode 100644 index 0000000000000..7295308b0788d --- /dev/null +++ b/parser/sql/dialect/firebird/src/main/java/org/apache/shardingsphere/sql/parser/firebird/parser/FirebirdParserFacade.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.shardingsphere.sql.parser.firebird.parser; + +import org.apache.shardingsphere.sql.parser.api.parser.SQLLexer; +import org.apache.shardingsphere.sql.parser.api.parser.SQLParser; +import org.apache.shardingsphere.sql.parser.spi.SQLDialectParserFacade; + +/** + * SQL parser facade for Firebird. + */ +public final class FirebirdParserFacade implements SQLDialectParserFacade { + + @Override + public Class getLexerClass() { + return FirebirdLexer.class; + } + + @Override + public Class getParserClass() { + return FirebirdParser.class; + } + + @Override + public String getDatabaseType() { + return "Firebird"; + } +} diff --git a/parser/sql/dialect/firebird/src/main/java/org/apache/shardingsphere/sql/parser/firebird/visitor/statement/FirebirdStatementVisitor.java b/parser/sql/dialect/firebird/src/main/java/org/apache/shardingsphere/sql/parser/firebird/visitor/statement/FirebirdStatementVisitor.java new file mode 100644 index 0000000000000..93ca39287d3fe --- /dev/null +++ b/parser/sql/dialect/firebird/src/main/java/org/apache/shardingsphere/sql/parser/firebird/visitor/statement/FirebirdStatementVisitor.java @@ -0,0 +1,574 @@ +/* + * 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.firebird.visitor.statement; + +import lombok.AccessLevel; +import lombok.Getter; +import org.antlr.v4.runtime.ParserRuleContext; +import org.antlr.v4.runtime.Token; +import org.antlr.v4.runtime.misc.Interval; +import org.antlr.v4.runtime.tree.TerminalNode; +import org.apache.shardingsphere.sql.parser.api.ASTNode; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementBaseVisitor; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.AggregationFunctionContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.BitExprContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.BitValueLiteralsContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.BooleanLiteralsContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.BooleanPrimaryContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.CastFunctionContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.ColumnNameContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.ColumnNamesContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.DataTypeContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.DataTypeLengthContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.DataTypeNameContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.ExprContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.FunctionCallContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.HexadecimalLiteralsContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.IdentifierContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.IntervalExpressionContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.LiteralsContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.NullValueLiteralsContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.NumberLiteralsContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.OrderByClauseContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.OrderByItemContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.OwnerContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.ParameterMarkerContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.PredicateContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.RegularFunctionContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.SchemaNameContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.SimpleExprContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.SpecialFunctionContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.StringLiteralsContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.TableNameContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.TableNamesContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.UnreservedWordContext; +import org.apache.shardingsphere.sql.parser.sql.common.enums.AggregationType; +import org.apache.shardingsphere.sql.parser.sql.common.enums.OrderDirection; +import org.apache.shardingsphere.sql.parser.sql.common.enums.ParameterMarkerType; +import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.ColumnSegment; +import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.BetweenExpression; +import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.BinaryOperationExpression; +import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.ExpressionSegment; +import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.FunctionSegment; +import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.InExpression; +import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.ListExpression; +import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.NotExpression; +import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.complex.CommonExpressionSegment; +import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.simple.LiteralExpressionSegment; +import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.simple.ParameterMarkerExpressionSegment; +import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.subquery.SubqueryExpressionSegment; +import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.subquery.SubquerySegment; +import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.AggregationDistinctProjectionSegment; +import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.AggregationProjectionSegment; +import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.ExpressionProjectionSegment; +import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.order.OrderBySegment; +import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.order.item.ColumnOrderByItemSegment; +import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.order.item.IndexOrderByItemSegment; +import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.order.item.OrderByItemSegment; +import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.DataTypeLengthSegment; +import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.DataTypeSegment; +import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.OwnerSegment; +import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.ParameterMarkerSegment; +import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.SimpleTableSegment; +import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.TableNameSegment; +import org.apache.shardingsphere.sql.parser.sql.common.util.SQLUtils; +import org.apache.shardingsphere.sql.parser.sql.common.value.collection.CollectionValue; +import org.apache.shardingsphere.sql.parser.sql.common.value.identifier.IdentifierValue; +import org.apache.shardingsphere.sql.parser.sql.common.value.keyword.KeywordValue; +import org.apache.shardingsphere.sql.parser.sql.common.value.literal.impl.BooleanLiteralValue; +import org.apache.shardingsphere.sql.parser.sql.common.value.literal.impl.NullLiteralValue; +import org.apache.shardingsphere.sql.parser.sql.common.value.literal.impl.NumberLiteralValue; +import org.apache.shardingsphere.sql.parser.sql.common.value.literal.impl.OtherLiteralValue; +import org.apache.shardingsphere.sql.parser.sql.common.value.literal.impl.StringLiteralValue; +import org.apache.shardingsphere.sql.parser.sql.common.value.parametermarker.ParameterMarkerValue; +import org.apache.shardingsphere.sql.parser.sql.dialect.statement.firebird.dml.FirebirdSelectStatement; + +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; +import java.util.stream.Collectors; + +/** + * Statement visitor for Firebird. + */ +@Getter(AccessLevel.PROTECTED) +public abstract class FirebirdStatementVisitor extends FirebirdStatementBaseVisitor { + + private final Collection parameterMarkerSegments = new LinkedList<>(); + + @Override + public final ASTNode visitParameterMarker(final ParameterMarkerContext ctx) { + return new ParameterMarkerValue(parameterMarkerSegments.size(), ParameterMarkerType.QUESTION); + } + + @Override + public final ASTNode visitLiterals(final LiteralsContext ctx) { + if (null != ctx.stringLiterals()) { + return visit(ctx.stringLiterals()); + } + if (null != ctx.numberLiterals()) { + return visit(ctx.numberLiterals()); + } + if (null != ctx.hexadecimalLiterals()) { + return visit(ctx.hexadecimalLiterals()); + } + if (null != ctx.bitValueLiterals()) { + return visit(ctx.bitValueLiterals()); + } + if (null != ctx.booleanLiterals()) { + return visit(ctx.booleanLiterals()); + } + if (null != ctx.nullValueLiterals()) { + return visit(ctx.nullValueLiterals()); + } + throw new IllegalStateException("Literals must have string, number, dateTime, hex, bit, boolean or null."); + } + + @Override + public final ASTNode visitStringLiterals(final StringLiteralsContext ctx) { + return new StringLiteralValue(ctx.getText()); + } + + @Override + public final ASTNode visitNumberLiterals(final NumberLiteralsContext ctx) { + return new NumberLiteralValue(ctx.getText()); + } + + @Override + public final ASTNode visitHexadecimalLiterals(final HexadecimalLiteralsContext ctx) { + // TODO deal with hexadecimalLiterals + return new OtherLiteralValue(ctx.getText()); + } + + @Override + public final ASTNode visitBitValueLiterals(final BitValueLiteralsContext ctx) { + // TODO deal with bitValueLiterals + return new OtherLiteralValue(ctx.getText()); + } + + @Override + public final ASTNode visitBooleanLiterals(final BooleanLiteralsContext ctx) { + return new BooleanLiteralValue(ctx.getText()); + } + + @Override + public final ASTNode visitNullValueLiterals(final NullValueLiteralsContext ctx) { + return new NullLiteralValue(ctx.getText()); + } + + @Override + public final ASTNode visitIdentifier(final IdentifierContext ctx) { + UnreservedWordContext unreservedWord = ctx.unreservedWord(); + return null == unreservedWord ? new IdentifierValue(ctx.getText()) : visit(unreservedWord); + } + + @Override + public final ASTNode visitUnreservedWord(final UnreservedWordContext ctx) { + return new IdentifierValue(ctx.getText()); + } + + @Override + public final ASTNode visitSchemaName(final SchemaNameContext ctx) { + return visit(ctx.identifier()); + } + + @Override + public final ASTNode visitTableName(final TableNameContext ctx) { + SimpleTableSegment result = new SimpleTableSegment(new TableNameSegment(ctx.name().getStart().getStartIndex(), ctx.name().getStop().getStopIndex(), (IdentifierValue) visit(ctx.name()))); + OwnerContext owner = ctx.owner(); + if (null != owner) { + result.setOwner(new OwnerSegment(owner.getStart().getStartIndex(), owner.getStop().getStopIndex(), (IdentifierValue) visit(owner.identifier()))); + } + return result; + } + + @Override + public final ASTNode visitColumnName(final ColumnNameContext ctx) { + ColumnSegment result = new ColumnSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), (IdentifierValue) visit(ctx.name())); + OwnerContext owner = ctx.owner(); + if (null != owner) { + result.setOwner(new OwnerSegment(owner.getStart().getStartIndex(), owner.getStop().getStopIndex(), (IdentifierValue) visit(owner.identifier()))); + } + return result; + } + + @Override + public final ASTNode visitTableNames(final TableNamesContext ctx) { + CollectionValue result = new CollectionValue<>(); + for (TableNameContext each : ctx.tableName()) { + result.getValue().add((SimpleTableSegment) visit(each)); + } + return result; + } + + @Override + public final ASTNode visitColumnNames(final ColumnNamesContext ctx) { + CollectionValue result = new CollectionValue<>(); + for (ColumnNameContext each : ctx.columnName()) { + result.getValue().add((ColumnSegment) visit(each)); + } + return result; + } + + @Override + public final ASTNode visitExpr(final ExprContext ctx) { + if (null != ctx.booleanPrimary()) { + return visit(ctx.booleanPrimary()); + } + if (null != ctx.LP_()) { + return visit(ctx.expr(0)); + } + if (null != ctx.andOperator()) { + return createBinaryOperationExpression(ctx, ctx.andOperator().getText()); + } + if (null != ctx.orOperator()) { + return createBinaryOperationExpression(ctx, ctx.orOperator().getText()); + } + return new NotExpression(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), (ExpressionSegment) visit(ctx.expr(0)), false); + } + + private ASTNode createBinaryOperationExpression(final ExprContext ctx, final String operator) { + ExpressionSegment left = (ExpressionSegment) visit(ctx.expr(0)); + ExpressionSegment right = (ExpressionSegment) visit(ctx.expr(1)); + String text = ctx.start.getInputStream().getText(new Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex())); + return new BinaryOperationExpression(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), left, right, operator, text); + } + + @Override + public final ASTNode visitBooleanPrimary(final BooleanPrimaryContext ctx) { + if (null != ctx.IS()) { + String rightText = ""; + if (null != ctx.NOT()) { + rightText = rightText.concat(ctx.start.getInputStream().getText(new Interval(ctx.NOT().getSymbol().getStartIndex(), + ctx.NOT().getSymbol().getStopIndex()))).concat(" "); + } + Token operatorToken = null; + if (null != ctx.NULL()) { + operatorToken = ctx.NULL().getSymbol(); + } + if (null != ctx.TRUE()) { + operatorToken = ctx.TRUE().getSymbol(); + } + if (null != ctx.FALSE()) { + operatorToken = ctx.FALSE().getSymbol(); + } + int startIndex = null == operatorToken ? ctx.IS().getSymbol().getStopIndex() + 2 : operatorToken.getStartIndex(); + rightText = rightText.concat(ctx.start.getInputStream().getText(new Interval(startIndex, ctx.stop.getStopIndex()))); + ExpressionSegment right = new LiteralExpressionSegment(ctx.IS().getSymbol().getStopIndex() + 2, ctx.stop.getStopIndex(), rightText); + String text = ctx.start.getInputStream().getText(new Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex())); + ExpressionSegment left = (ExpressionSegment) visit(ctx.booleanPrimary()); + String operator = "IS"; + return new BinaryOperationExpression(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), left, right, operator, text); + } + if (null != ctx.comparisonOperator() || null != ctx.SAFE_EQ_()) { + return createCompareSegment(ctx); + } + return visit(ctx.predicate()); + } + + private ASTNode createCompareSegment(final BooleanPrimaryContext ctx) { + ExpressionSegment left = (ExpressionSegment) visit(ctx.booleanPrimary()); + ExpressionSegment right; + if (null != ctx.predicate()) { + right = (ExpressionSegment) visit(ctx.predicate()); + } else { + right = (ExpressionSegment) visit(ctx.subquery()); + } + String operator = null == ctx.SAFE_EQ_() ? ctx.comparisonOperator().getText() : ctx.SAFE_EQ_().getText(); + String text = ctx.start.getInputStream().getText(new Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex())); + return new BinaryOperationExpression(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), left, right, operator, text); + } + + @Override + public final ASTNode visitPredicate(final PredicateContext ctx) { + if (null != ctx.IN()) { + return createInSegment(ctx); + } + if (null != ctx.BETWEEN()) { + return createBetweenSegment(ctx); + } + if (null != ctx.LIKE()) { + return createBinaryOperationExpressionFromLike(ctx); + } + return visit(ctx.bitExpr(0)); + } + + private BinaryOperationExpression createBinaryOperationExpressionFromLike(final PredicateContext ctx) { + ExpressionSegment left = (ExpressionSegment) visit(ctx.bitExpr(0)); + ListExpression right = new ListExpression(ctx.simpleExpr(0).start.getStartIndex(), ctx.simpleExpr().get(ctx.simpleExpr().size() - 1).stop.getStopIndex()); + for (SimpleExprContext each : ctx.simpleExpr()) { + right.getItems().add((ExpressionSegment) visit(each)); + } + String operator = null == ctx.NOT() ? "LIKE" : "NOT LIKE"; + String text = ctx.start.getInputStream().getText(new Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex())); + return new BinaryOperationExpression(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), left, right, operator, text); + } + + private InExpression createInSegment(final PredicateContext ctx) { + ExpressionSegment left = (ExpressionSegment) visit(ctx.bitExpr(0)); + ExpressionSegment right; + if (null != ctx.subquery()) { + right = new SubqueryExpressionSegment(new SubquerySegment(ctx.subquery().start.getStartIndex(), ctx.subquery().stop.getStopIndex(), (FirebirdSelectStatement) visit(ctx.subquery()))); + } else { + ListExpression listExpression = new ListExpression(ctx.LP_().getSymbol().getStartIndex(), ctx.RP_().getSymbol().getStopIndex()); + for (ExprContext each : ctx.expr()) { + listExpression.getItems().add((ExpressionSegment) visit(each)); + } + right = listExpression; + } + boolean not = null != ctx.NOT(); + return new InExpression(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), left, right, not); + } + + private BetweenExpression createBetweenSegment(final PredicateContext ctx) { + ExpressionSegment left = (ExpressionSegment) visit(ctx.bitExpr(0)); + ExpressionSegment between = (ExpressionSegment) visit(ctx.bitExpr(1)); + ExpressionSegment and = (ExpressionSegment) visit(ctx.predicate()); + boolean not = null != ctx.NOT(); + return new BetweenExpression(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), left, between, and, not); + } + + @Override + public final ASTNode visitBitExpr(final BitExprContext ctx) { + if (null != ctx.simpleExpr()) { + return createExpressionSegment(visit(ctx.simpleExpr()), ctx); + } + ExpressionSegment left = (ExpressionSegment) visit(ctx.getChild(0)); + ExpressionSegment right = (ExpressionSegment) visit(ctx.getChild(2)); + String operator = ctx.getChild(1).getText(); + String text = ctx.start.getInputStream().getText(new Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex())); + return new BinaryOperationExpression(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), left, right, operator, text); + } + + private ASTNode createExpressionSegment(final ASTNode astNode, final ParserRuleContext context) { + if (astNode instanceof StringLiteralValue) { + return new LiteralExpressionSegment(context.start.getStartIndex(), context.stop.getStopIndex(), ((StringLiteralValue) astNode).getValue()); + } + if (astNode instanceof NumberLiteralValue) { + return new LiteralExpressionSegment(context.start.getStartIndex(), context.stop.getStopIndex(), ((NumberLiteralValue) astNode).getValue()); + } + if (astNode instanceof BooleanLiteralValue) { + return new LiteralExpressionSegment(context.start.getStartIndex(), context.stop.getStopIndex(), ((BooleanLiteralValue) astNode).getValue()); + } + if (astNode instanceof ParameterMarkerValue) { + ParameterMarkerValue parameterMarker = (ParameterMarkerValue) astNode; + ParameterMarkerExpressionSegment segment = new ParameterMarkerExpressionSegment(context.start.getStartIndex(), context.stop.getStopIndex(), + parameterMarker.getValue(), parameterMarker.getType()); + parameterMarkerSegments.add(segment); + return segment; + } + if (astNode instanceof SubquerySegment) { + return new SubqueryExpressionSegment((SubquerySegment) astNode); + } + if (astNode instanceof OtherLiteralValue) { + return new CommonExpressionSegment(context.getStart().getStartIndex(), context.getStop().getStopIndex(), ((OtherLiteralValue) astNode).getValue()); + } + return astNode; + } + + @Override + public final ASTNode visitSimpleExpr(final SimpleExprContext ctx) { + int startIndex = ctx.getStart().getStartIndex(); + int stopIndex = ctx.getStop().getStopIndex(); + if (null != ctx.subquery()) { + return new SubquerySegment(startIndex, stopIndex, (FirebirdSelectStatement) visit(ctx.subquery())); + } + if (null != ctx.parameterMarker()) { + ParameterMarkerValue parameterMarker = (ParameterMarkerValue) visit(ctx.parameterMarker()); + ParameterMarkerExpressionSegment segment = new ParameterMarkerExpressionSegment(startIndex, stopIndex, parameterMarker.getValue(), parameterMarker.getType()); + parameterMarkerSegments.add(segment); + return segment; + } + if (null != ctx.literals()) { + return SQLUtils.createLiteralExpression(visit(ctx.literals()), startIndex, stopIndex, ctx.literals().start.getInputStream().getText(new Interval(startIndex, stopIndex))); + } + if (null != ctx.functionCall()) { + return visit(ctx.functionCall()); + } + if (null != ctx.columnName()) { + return visit(ctx.columnName()); + } + return new CommonExpressionSegment(startIndex, stopIndex, ctx.getText()); + } + + @Override + public final ASTNode visitIntervalExpression(final IntervalExpressionContext ctx) { + calculateParameterCount(Collections.singleton(ctx.expr())); + return new ExpressionProjectionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), getOriginalText(ctx)); + } + + @Override + public final ASTNode visitFunctionCall(final FunctionCallContext ctx) { + if (null != ctx.aggregationFunction()) { + return visit(ctx.aggregationFunction()); + } + if (null != ctx.specialFunction()) { + return visit(ctx.specialFunction()); + } + if (null != ctx.regularFunction()) { + return visit(ctx.regularFunction()); + } + throw new IllegalStateException("FunctionCallContext must have aggregationFunction, regularFunction or specialFunction."); + } + + @Override + public final ASTNode visitAggregationFunction(final AggregationFunctionContext ctx) { + String aggregationType = ctx.aggregationFunctionName().getText(); + return AggregationType.isAggregationType(aggregationType) + ? createAggregationSegment(ctx, aggregationType) + : new ExpressionProjectionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), getOriginalText(ctx)); + } + + private ASTNode createAggregationSegment(final AggregationFunctionContext ctx, final String aggregationType) { + AggregationType type = AggregationType.valueOf(aggregationType.toUpperCase()); + if (null != ctx.distinct()) { + AggregationDistinctProjectionSegment result = + new AggregationDistinctProjectionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), type, getOriginalText(ctx), getDistinctExpression(ctx)); + result.getParameters().addAll(getExpressions(ctx)); + return result; + } + AggregationProjectionSegment result = new AggregationProjectionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), type, getOriginalText(ctx)); + result.getParameters().addAll(getExpressions(ctx)); + return result; + } + + private Collection getExpressions(final AggregationFunctionContext ctx) { + if (null == ctx.expr()) { + return Collections.emptyList(); + } + Collection result = new LinkedList<>(); + for (ExprContext each : ctx.expr()) { + result.add((ExpressionSegment) visit(each)); + } + return result; + } + + private String getDistinctExpression(final AggregationFunctionContext ctx) { + StringBuilder result = new StringBuilder(); + for (int i = 3; i < ctx.getChildCount() - 1; i++) { + result.append(ctx.getChild(i).getText()); + } + return result.toString(); + } + + @Override + public final ASTNode visitSpecialFunction(final SpecialFunctionContext ctx) { + if (null != ctx.castFunction()) { + return visit(ctx.castFunction()); + } + return new FunctionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), ctx.getChild(0).getChild(0).getText(), getOriginalText(ctx)); + } + + @Override + public final ASTNode visitCastFunction(final CastFunctionContext ctx) { + calculateParameterCount(Collections.singleton(ctx.expr())); + FunctionSegment result = new FunctionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), ctx.CAST().getText(), getOriginalText(ctx)); + ASTNode exprSegment = visit(ctx.expr()); + if (exprSegment instanceof ColumnSegment) { + result.getParameters().add((ColumnSegment) exprSegment); + } else if (exprSegment instanceof LiteralExpressionSegment) { + result.getParameters().add((LiteralExpressionSegment) exprSegment); + } + result.getParameters().add((DataTypeSegment) visit(ctx.dataType())); + return result; + } + + @Override + public final ASTNode visitRegularFunction(final RegularFunctionContext ctx) { + FunctionSegment result = new FunctionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), ctx.regularFunctionName().getText(), getOriginalText(ctx)); + Collection expressionSegments = ctx.expr().stream().map(each -> (ExpressionSegment) visit(each)).collect(Collectors.toList()); + result.getParameters().addAll(expressionSegments); + return result; + } + + @Override + public final ASTNode visitDataTypeName(final DataTypeNameContext ctx) { + Collection dataTypeNames = new LinkedList<>(); + for (int i = 0; i < ctx.getChildCount(); i++) { + dataTypeNames.add(ctx.getChild(i).getText()); + } + return new KeywordValue(String.join(" ", dataTypeNames)); + } + + // TODO :FIXME, sql case id: insert_with_str_to_date + private void calculateParameterCount(final Collection exprContexts) { + for (ExprContext each : exprContexts) { + visit(each); + } + } + + @Override + public final ASTNode visitOrderByClause(final OrderByClauseContext ctx) { + Collection items = new LinkedList<>(); + for (OrderByItemContext each : ctx.orderByItem()) { + items.add((OrderByItemSegment) visit(each)); + } + return new OrderBySegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), items); + } + + @Override + public final ASTNode visitOrderByItem(final OrderByItemContext ctx) { + OrderDirection orderDirection = null == ctx.DESC() ? OrderDirection.ASC : OrderDirection.DESC; + if (null != ctx.columnName()) { + ColumnSegment column = (ColumnSegment) visit(ctx.columnName()); + return new ColumnOrderByItemSegment(column, orderDirection, null); + } + return new IndexOrderByItemSegment(ctx.numberLiterals().getStart().getStartIndex(), ctx.numberLiterals().getStop().getStopIndex(), + SQLUtils.getExactlyNumber(ctx.numberLiterals().getText(), 10).intValue(), orderDirection, null); + } + + @Override + public final ASTNode visitDataType(final DataTypeContext ctx) { + DataTypeSegment result = new DataTypeSegment(); + result.setDataTypeName(((KeywordValue) visit(ctx.dataTypeName())).getValue()); + result.setStartIndex(ctx.start.getStartIndex()); + result.setStopIndex(ctx.stop.getStopIndex()); + if (null != ctx.dataTypeLength()) { + DataTypeLengthSegment dataTypeLengthSegment = (DataTypeLengthSegment) visit(ctx.dataTypeLength()); + result.setDataLength(dataTypeLengthSegment); + } + return result; + } + + @Override + public final ASTNode visitDataTypeLength(final DataTypeLengthContext ctx) { + DataTypeLengthSegment result = new DataTypeLengthSegment(); + result.setStartIndex(ctx.start.getStartIndex()); + result.setStopIndex(ctx.stop.getStartIndex()); + List numbers = ctx.NUMBER_(); + if (numbers.size() == 1) { + result.setPrecision(Integer.parseInt(numbers.get(0).getText())); + } + if (numbers.size() == 2) { + result.setPrecision(Integer.parseInt(numbers.get(0).getText())); + result.setScale(Integer.parseInt(numbers.get(1).getText())); + } + return result; + } + + /** + * Get original text. + * + * @param ctx context + * @return original text + */ + protected String getOriginalText(final ParserRuleContext ctx) { + return ctx.start.getInputStream().getText(new Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex())); + } +} diff --git a/parser/sql/dialect/firebird/src/main/java/org/apache/shardingsphere/sql/parser/firebird/visitor/statement/FirebirdStatementVisitorFacade.java b/parser/sql/dialect/firebird/src/main/java/org/apache/shardingsphere/sql/parser/firebird/visitor/statement/FirebirdStatementVisitorFacade.java new file mode 100644 index 0000000000000..ce991d853c977 --- /dev/null +++ b/parser/sql/dialect/firebird/src/main/java/org/apache/shardingsphere/sql/parser/firebird/visitor/statement/FirebirdStatementVisitorFacade.java @@ -0,0 +1,72 @@ +/* + * 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.firebird.visitor.statement; + +import org.apache.shardingsphere.sql.parser.spi.SQLStatementVisitorFacade; +import org.apache.shardingsphere.sql.parser.api.visitor.statement.type.DALStatementVisitor; +import org.apache.shardingsphere.sql.parser.api.visitor.statement.type.DCLStatementVisitor; +import org.apache.shardingsphere.sql.parser.api.visitor.statement.type.DDLStatementVisitor; +import org.apache.shardingsphere.sql.parser.api.visitor.statement.type.DMLStatementVisitor; +import org.apache.shardingsphere.sql.parser.api.visitor.statement.type.RLStatementVisitor; +import org.apache.shardingsphere.sql.parser.api.visitor.statement.type.TCLStatementVisitor; +import org.apache.shardingsphere.sql.parser.firebird.visitor.statement.type.FirebirdDALStatementVisitor; +import org.apache.shardingsphere.sql.parser.firebird.visitor.statement.type.FirebirdDCLStatementVisitor; +import org.apache.shardingsphere.sql.parser.firebird.visitor.statement.type.FirebirdDDLStatementVisitor; +import org.apache.shardingsphere.sql.parser.firebird.visitor.statement.type.FirebirdDMLStatementVisitor; +import org.apache.shardingsphere.sql.parser.firebird.visitor.statement.type.FirebirdTCLStatementVisitor; + +/** + * Statement visitor facade for Firebird. + */ +public final class FirebirdStatementVisitorFacade implements SQLStatementVisitorFacade { + + @Override + public Class getDMLVisitorClass() { + return FirebirdDMLStatementVisitor.class; + } + + @Override + public Class getDDLVisitorClass() { + return FirebirdDDLStatementVisitor.class; + } + + @Override + public Class getTCLVisitorClass() { + return FirebirdTCLStatementVisitor.class; + } + + @Override + public Class getDCLVisitorClass() { + return FirebirdDCLStatementVisitor.class; + } + + @Override + public Class getDALVisitorClass() { + return FirebirdDALStatementVisitor.class; + } + + @Override + public Class getRLVisitorClass() { + return null; + } + + @Override + public String getDatabaseType() { + return "Firebird"; + } +} diff --git a/parser/sql/dialect/firebird/src/main/java/org/apache/shardingsphere/sql/parser/firebird/visitor/statement/type/FirebirdDALStatementVisitor.java b/parser/sql/dialect/firebird/src/main/java/org/apache/shardingsphere/sql/parser/firebird/visitor/statement/type/FirebirdDALStatementVisitor.java new file mode 100644 index 0000000000000..3dc7d7a55da6b --- /dev/null +++ b/parser/sql/dialect/firebird/src/main/java/org/apache/shardingsphere/sql/parser/firebird/visitor/statement/type/FirebirdDALStatementVisitor.java @@ -0,0 +1,27 @@ +/* + * 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.firebird.visitor.statement.type; + +import org.apache.shardingsphere.sql.parser.api.visitor.statement.type.DALStatementVisitor; +import org.apache.shardingsphere.sql.parser.firebird.visitor.statement.FirebirdStatementVisitor; + +/** + * DAL statement visitor for Firebird. + */ +public final class FirebirdDALStatementVisitor extends FirebirdStatementVisitor implements DALStatementVisitor { +} diff --git a/parser/sql/dialect/firebird/src/main/java/org/apache/shardingsphere/sql/parser/firebird/visitor/statement/type/FirebirdDCLStatementVisitor.java b/parser/sql/dialect/firebird/src/main/java/org/apache/shardingsphere/sql/parser/firebird/visitor/statement/type/FirebirdDCLStatementVisitor.java new file mode 100644 index 0000000000000..9fd087c4f2d90 --- /dev/null +++ b/parser/sql/dialect/firebird/src/main/java/org/apache/shardingsphere/sql/parser/firebird/visitor/statement/type/FirebirdDCLStatementVisitor.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.firebird.visitor.statement.type; + +import org.apache.shardingsphere.sql.parser.api.ASTNode; +import org.apache.shardingsphere.sql.parser.api.visitor.statement.type.DCLStatementVisitor; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.GrantContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.RevokeContext; +import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.SimpleTableSegment; +import org.apache.shardingsphere.sql.parser.sql.dialect.statement.firebird.dcl.FirebirdGrantStatement; +import org.apache.shardingsphere.sql.parser.sql.dialect.statement.firebird.dcl.FirebirdRevokeStatement; +import org.apache.shardingsphere.sql.parser.firebird.visitor.statement.FirebirdStatementVisitor; + +/** + * DCL statement visitor for Firebird. + */ +public final class FirebirdDCLStatementVisitor extends FirebirdStatementVisitor implements DCLStatementVisitor { + + @Override + public ASTNode visitGrant(final GrantContext ctx) { + FirebirdGrantStatement result = new FirebirdGrantStatement(); + if (null != ctx.privilegeClause()) { + result.getTables().add((SimpleTableSegment) visit(ctx.privilegeClause().onObjectClause().privilegeLevel().tableName())); + } + return result; + } + + @Override + public ASTNode visitRevoke(final RevokeContext ctx) { + FirebirdRevokeStatement result = new FirebirdRevokeStatement(); + if (null != ctx.privilegeClause()) { + result.getTables().add((SimpleTableSegment) visit(ctx.privilegeClause().onObjectClause().privilegeLevel().tableName())); + } + return result; + } +} diff --git a/parser/sql/dialect/firebird/src/main/java/org/apache/shardingsphere/sql/parser/firebird/visitor/statement/type/FirebirdDDLStatementVisitor.java b/parser/sql/dialect/firebird/src/main/java/org/apache/shardingsphere/sql/parser/firebird/visitor/statement/type/FirebirdDDLStatementVisitor.java new file mode 100644 index 0000000000000..88c86e081de50 --- /dev/null +++ b/parser/sql/dialect/firebird/src/main/java/org/apache/shardingsphere/sql/parser/firebird/visitor/statement/type/FirebirdDDLStatementVisitor.java @@ -0,0 +1,218 @@ +/* + * 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.firebird.visitor.statement.type; + +import org.apache.shardingsphere.sql.parser.api.ASTNode; +import org.apache.shardingsphere.sql.parser.api.visitor.statement.type.DDLStatementVisitor; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.AddColumnSpecificationContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.AddConstraintSpecificationContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.AlterDefinitionClauseContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.AlterTableContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.CheckConstraintDefinitionContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.ColumnDefinitionContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.ConstraintDefinitionContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.ConstraintNameContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.CreateDefinitionClauseContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.CreateDefinitionContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.CreateTableContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.DataTypeOptionContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.DropColumnSpecificationContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.DropConstraintSpecificationContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.DropTableContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.ModifyColumnSpecificationContext; +import org.apache.shardingsphere.sql.parser.sql.common.segment.ddl.AlterDefinitionSegment; +import org.apache.shardingsphere.sql.parser.sql.common.segment.ddl.CreateDefinitionSegment; +import org.apache.shardingsphere.sql.parser.sql.common.segment.ddl.column.ColumnDefinitionSegment; +import org.apache.shardingsphere.sql.parser.sql.common.segment.ddl.column.alter.AddColumnDefinitionSegment; +import org.apache.shardingsphere.sql.parser.sql.common.segment.ddl.column.alter.DropColumnDefinitionSegment; +import org.apache.shardingsphere.sql.parser.sql.common.segment.ddl.column.alter.ModifyColumnDefinitionSegment; +import org.apache.shardingsphere.sql.parser.sql.common.segment.ddl.constraint.ConstraintDefinitionSegment; +import org.apache.shardingsphere.sql.parser.sql.common.segment.ddl.constraint.ConstraintSegment; +import org.apache.shardingsphere.sql.parser.sql.common.segment.ddl.constraint.alter.AddConstraintDefinitionSegment; +import org.apache.shardingsphere.sql.parser.sql.common.segment.ddl.constraint.alter.DropConstraintDefinitionSegment; +import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.ColumnSegment; +import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.DataTypeSegment; +import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.SimpleTableSegment; +import org.apache.shardingsphere.sql.parser.sql.common.value.collection.CollectionValue; +import org.apache.shardingsphere.sql.parser.sql.common.value.identifier.IdentifierValue; +import org.apache.shardingsphere.sql.parser.sql.dialect.statement.firebird.ddl.FirebirdAlterTableStatement; +import org.apache.shardingsphere.sql.parser.sql.dialect.statement.firebird.ddl.FirebirdCreateTableStatement; +import org.apache.shardingsphere.sql.parser.sql.dialect.statement.firebird.ddl.FirebirdDropTableStatement; +import org.apache.shardingsphere.sql.parser.firebird.visitor.statement.FirebirdStatementVisitor; + +import java.util.Collections; + +/** + * DDL statement visitor for Firebird. + */ +public final class FirebirdDDLStatementVisitor extends FirebirdStatementVisitor implements DDLStatementVisitor { + + @SuppressWarnings("unchecked") + @Override + public ASTNode visitCreateTable(final CreateTableContext ctx) { + FirebirdCreateTableStatement result = new FirebirdCreateTableStatement(); + result.setTable((SimpleTableSegment) visit(ctx.tableName())); + if (null != ctx.createDefinitionClause()) { + CollectionValue createDefinitions = (CollectionValue) visit(ctx.createDefinitionClause()); + for (CreateDefinitionSegment each : createDefinitions.getValue()) { + if (each instanceof ColumnDefinitionSegment) { + result.getColumnDefinitions().add((ColumnDefinitionSegment) each); + } else if (each instanceof ConstraintDefinitionSegment) { + result.getConstraintDefinitions().add((ConstraintDefinitionSegment) each); + } + } + } + return result; + } + + @Override + public ASTNode visitCreateDefinitionClause(final CreateDefinitionClauseContext ctx) { + CollectionValue result = new CollectionValue<>(); + for (CreateDefinitionContext each : ctx.createDefinition()) { + if (null != each.columnDefinition()) { + result.getValue().add((ColumnDefinitionSegment) visit(each.columnDefinition())); + } + if (null != each.constraintDefinition()) { + result.getValue().add((ConstraintDefinitionSegment) visit(each.constraintDefinition())); + } + if (null != each.checkConstraintDefinition()) { + result.getValue().add((ConstraintDefinitionSegment) visit(each.checkConstraintDefinition())); + } + } + return result; + } + + @Override + public ASTNode visitColumnDefinition(final ColumnDefinitionContext ctx) { + ColumnSegment column = (ColumnSegment) visit(ctx.columnName()); + DataTypeSegment dataType = (DataTypeSegment) visit(ctx.dataType()); + boolean isPrimaryKey = ctx.dataTypeOption().stream().anyMatch(each -> null != each.primaryKey()); + // TODO parse not null + ColumnDefinitionSegment result = new ColumnDefinitionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), column, dataType, isPrimaryKey, false); + for (DataTypeOptionContext each : ctx.dataTypeOption()) { + if (null != each.referenceDefinition()) { + result.getReferencedTables().add((SimpleTableSegment) visit(each.referenceDefinition().tableName())); + } + } + return result; + } + + @Override + public ASTNode visitCheckConstraintDefinition(final CheckConstraintDefinitionContext ctx) { + return new ConstraintDefinitionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex()); + } + + @Override + public ASTNode visitAddConstraintSpecification(final AddConstraintSpecificationContext ctx) { + return new AddConstraintDefinitionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), (ConstraintDefinitionSegment) visit(ctx.constraintDefinition())); + } + + @Override + public ASTNode visitDropConstraintSpecification(final DropConstraintSpecificationContext ctx) { + return new DropConstraintDefinitionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), (ConstraintSegment) visit(ctx.constraintDefinition().constraintName())); + } + + @SuppressWarnings("unchecked") + @Override + public ASTNode visitConstraintDefinition(final ConstraintDefinitionContext ctx) { + ConstraintDefinitionSegment result = new ConstraintDefinitionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex()); + if (null != ctx.constraintName()) { + result.setConstraintName((ConstraintSegment) visit(ctx.constraintName())); + } + if (null != ctx.primaryKeyOption()) { + result.getPrimaryKeyColumns().addAll(((CollectionValue) visit(ctx.primaryKeyOption().columnNames())).getValue()); + } + if (null != ctx.foreignKeyOption()) { + result.setReferencedTable((SimpleTableSegment) visit(ctx.foreignKeyOption().referenceDefinition().tableName())); + } + return result; + } + + @Override + public ASTNode visitConstraintName(final ConstraintNameContext ctx) { + return new ConstraintSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), (IdentifierValue) visit(ctx.identifier())); + } + + @SuppressWarnings("unchecked") + @Override + public ASTNode visitAlterTable(final AlterTableContext ctx) { + FirebirdAlterTableStatement result = new FirebirdAlterTableStatement(); + result.setTable((SimpleTableSegment) visit(ctx.tableName())); + if (null != ctx.alterDefinitionClause()) { + for (AlterDefinitionSegment each : ((CollectionValue) visit(ctx.alterDefinitionClause())).getValue()) { + if (each instanceof AddColumnDefinitionSegment) { + result.getAddColumnDefinitions().add((AddColumnDefinitionSegment) each); + } else if (each instanceof ModifyColumnDefinitionSegment) { + result.getModifyColumnDefinitions().add((ModifyColumnDefinitionSegment) each); + } else if (each instanceof DropColumnDefinitionSegment) { + result.getDropColumnDefinitions().add((DropColumnDefinitionSegment) each); + } else if (each instanceof AddConstraintDefinitionSegment) { + result.getAddConstraintDefinitions().add((AddConstraintDefinitionSegment) each); + } else if (each instanceof DropConstraintDefinitionSegment) { + result.getDropConstraintDefinitions().add((DropConstraintDefinitionSegment) each); + } + } + } + return result; + } + + @SuppressWarnings("unchecked") + @Override + public ASTNode visitAlterDefinitionClause(final AlterDefinitionClauseContext ctx) { + CollectionValue result = new CollectionValue<>(); + if (null != ctx.addColumnSpecification()) { + result.getValue().addAll(((CollectionValue) visit(ctx.addColumnSpecification())).getValue()); + } + if (null != ctx.modifyColumnSpecification()) { + result.getValue().add((ModifyColumnDefinitionSegment) visit(ctx.modifyColumnSpecification())); + } + if (null != ctx.dropColumnSpecification()) { + result.getValue().add((DropColumnDefinitionSegment) visit(ctx.dropColumnSpecification())); + } + return result; + } + + @Override + public ASTNode visitAddColumnSpecification(final AddColumnSpecificationContext ctx) { + CollectionValue result = new CollectionValue<>(); + AddColumnDefinitionSegment addColumnDefinition = new AddColumnDefinitionSegment( + ctx.columnDefinition().getStart().getStartIndex(), ctx.columnDefinition().getStop().getStopIndex(), + Collections.singletonList((ColumnDefinitionSegment) visit(ctx.columnDefinition()))); + result.getValue().add(addColumnDefinition); + return result; + } + + @Override + public ASTNode visitModifyColumnSpecification(final ModifyColumnSpecificationContext ctx) { + // TODO visit pk and table ref + return new ModifyColumnDefinitionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), (ColumnDefinitionSegment) visit(ctx.columnDefinition())); + } + + @Override + public ASTNode visitDropColumnSpecification(final DropColumnSpecificationContext ctx) { + return new DropColumnDefinitionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), Collections.singleton((ColumnSegment) visit(ctx.columnName()))); + } + + @SuppressWarnings("unchecked") + @Override + public ASTNode visitDropTable(final DropTableContext ctx) { + FirebirdDropTableStatement result = new FirebirdDropTableStatement(); + result.getTables().addAll(((CollectionValue) visit(ctx.tableNames())).getValue()); + return result; + } +} diff --git a/parser/sql/dialect/firebird/src/main/java/org/apache/shardingsphere/sql/parser/firebird/visitor/statement/type/FirebirdDMLStatementVisitor.java b/parser/sql/dialect/firebird/src/main/java/org/apache/shardingsphere/sql/parser/firebird/visitor/statement/type/FirebirdDMLStatementVisitor.java new file mode 100644 index 0000000000000..40274ed627a0e --- /dev/null +++ b/parser/sql/dialect/firebird/src/main/java/org/apache/shardingsphere/sql/parser/firebird/visitor/statement/type/FirebirdDMLStatementVisitor.java @@ -0,0 +1,482 @@ +/* + * 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.firebird.visitor.statement.type; + +import org.antlr.v4.runtime.misc.Interval; +import org.apache.shardingsphere.sql.parser.api.ASTNode; +import org.apache.shardingsphere.sql.parser.api.visitor.statement.type.DMLStatementVisitor; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.AliasContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.AssignmentContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.AssignmentValueContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.AssignmentValuesContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.ColumnNamesContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.CombineClauseContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.DeleteContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.DuplicateSpecificationContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.EscapedTableReferenceContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.ExprContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.FromClauseContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.GroupByClauseContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.HavingClauseContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.InsertContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.InsertValuesClauseContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.JoinSpecificationContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.JoinedTableContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.OrderByItemContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.ProjectionContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.ProjectionsContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.QualifiedShorthandContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.SelectClauseContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.SelectContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.SelectSpecificationContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.SetAssignmentsClauseContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.SingleTableClauseContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.SubqueryContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.TableFactorContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.TableReferenceContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.TableReferencesContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.UpdateContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.WhereClauseContext; +import org.apache.shardingsphere.sql.parser.sql.common.enums.JoinType; +import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.assignment.AssignmentSegment; +import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.assignment.ColumnAssignmentSegment; +import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.assignment.InsertValuesSegment; +import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.assignment.SetAssignmentSegment; +import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.ColumnSegment; +import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.InsertColumnsSegment; +import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.BinaryOperationExpression; +import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.ExpressionSegment; +import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.FunctionSegment; +import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.complex.CommonExpressionSegment; +import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.simple.LiteralExpressionSegment; +import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.simple.ParameterMarkerExpressionSegment; +import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.subquery.SubqueryExpressionSegment; +import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.subquery.SubquerySegment; +import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.AggregationProjectionSegment; +import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.ColumnProjectionSegment; +import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.ExpressionProjectionSegment; +import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.ProjectionSegment; +import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.ProjectionsSegment; +import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.ShorthandProjectionSegment; +import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.SubqueryProjectionSegment; +import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.order.GroupBySegment; +import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.order.OrderBySegment; +import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.order.item.OrderByItemSegment; +import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.predicate.HavingSegment; +import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.predicate.WhereSegment; +import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.AliasSegment; +import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.OwnerSegment; +import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.JoinTableSegment; +import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.SimpleTableSegment; +import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.SubqueryTableSegment; +import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.TableSegment; +import org.apache.shardingsphere.sql.parser.sql.common.value.collection.CollectionValue; +import org.apache.shardingsphere.sql.parser.sql.common.value.identifier.IdentifierValue; +import org.apache.shardingsphere.sql.parser.sql.common.value.literal.impl.BooleanLiteralValue; +import org.apache.shardingsphere.sql.parser.sql.dialect.statement.firebird.dml.FirebirdDeleteStatement; +import org.apache.shardingsphere.sql.parser.sql.dialect.statement.firebird.dml.FirebirdInsertStatement; +import org.apache.shardingsphere.sql.parser.sql.dialect.statement.firebird.dml.FirebirdSelectStatement; +import org.apache.shardingsphere.sql.parser.sql.dialect.statement.firebird.dml.FirebirdUpdateStatement; +import org.apache.shardingsphere.sql.parser.firebird.visitor.statement.FirebirdStatementVisitor; + +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; +import java.util.stream.Collectors; + +/** + * DML statement visitor for Firebird. + */ +public final class FirebirdDMLStatementVisitor extends FirebirdStatementVisitor implements DMLStatementVisitor { + + @Override + public ASTNode visitInsert(final InsertContext ctx) { + FirebirdInsertStatement result = (FirebirdInsertStatement) visit(ctx.insertValuesClause()); + result.setTable((SimpleTableSegment) visit(ctx.tableName())); + result.addParameterMarkerSegments(getParameterMarkerSegments()); + return result; + } + + @SuppressWarnings("unchecked") + @Override + public ASTNode visitInsertValuesClause(final InsertValuesClauseContext ctx) { + FirebirdInsertStatement result = new FirebirdInsertStatement(); + if (null != ctx.columnNames()) { + ColumnNamesContext columnNames = ctx.columnNames(); + CollectionValue columnSegments = (CollectionValue) visit(columnNames); + result.setInsertColumns(new InsertColumnsSegment(columnNames.start.getStartIndex(), columnNames.stop.getStopIndex(), columnSegments.getValue())); + } else { + result.setInsertColumns(new InsertColumnsSegment(ctx.start.getStartIndex() - 1, ctx.start.getStartIndex() - 1, Collections.emptyList())); + } + result.getValues().addAll(createInsertValuesSegments(ctx.assignmentValues())); + return result; + } + + private Collection createInsertValuesSegments(final Collection assignmentValuesContexts) { + Collection result = new LinkedList<>(); + for (AssignmentValuesContext each : assignmentValuesContexts) { + result.add((InsertValuesSegment) visit(each)); + } + return result; + } + + @Override + public ASTNode visitUpdate(final UpdateContext ctx) { + FirebirdUpdateStatement result = new FirebirdUpdateStatement(); + result.setTable((TableSegment) visit(ctx.tableReferences())); + result.setSetAssignment((SetAssignmentSegment) visit(ctx.setAssignmentsClause())); + if (null != ctx.whereClause()) { + result.setWhere((WhereSegment) visit(ctx.whereClause())); + } + result.addParameterMarkerSegments(getParameterMarkerSegments()); + return result; + } + + @Override + public ASTNode visitSetAssignmentsClause(final SetAssignmentsClauseContext ctx) { + Collection assignments = new LinkedList<>(); + for (AssignmentContext each : ctx.assignment()) { + assignments.add((AssignmentSegment) visit(each)); + } + return new SetAssignmentSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), assignments); + } + + @Override + public ASTNode visitAssignmentValues(final AssignmentValuesContext ctx) { + List segments = new LinkedList<>(); + for (AssignmentValueContext each : ctx.assignmentValue()) { + segments.add((ExpressionSegment) visit(each)); + } + return new InsertValuesSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), segments); + } + + @Override + public ASTNode visitAssignment(final AssignmentContext ctx) { + ColumnSegment column = (ColumnSegment) visitColumnName(ctx.columnName()); + List columnSegments = new LinkedList<>(); + columnSegments.add(column); + ExpressionSegment value = (ExpressionSegment) visit(ctx.assignmentValue()); + AssignmentSegment result = new ColumnAssignmentSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), columnSegments, value); + result.getColumns().add(column); + return result; + } + + @Override + public ASTNode visitAssignmentValue(final AssignmentValueContext ctx) { + ExprContext expr = ctx.expr(); + if (null != expr) { + return visit(expr); + } + return new CommonExpressionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), ctx.getText()); + } + + @Override + public ASTNode visitDelete(final DeleteContext ctx) { + FirebirdDeleteStatement result = new FirebirdDeleteStatement(); + result.setTable((TableSegment) visit(ctx.singleTableClause())); + if (null != ctx.whereClause()) { + result.setWhere((WhereSegment) visit(ctx.whereClause())); + } + result.addParameterMarkerSegments(getParameterMarkerSegments()); + return result; + } + + @Override + public ASTNode visitSingleTableClause(final SingleTableClauseContext ctx) { + SimpleTableSegment result = (SimpleTableSegment) visit(ctx.tableName()); + if (null != ctx.alias()) { + result.setAlias((AliasSegment) visit(ctx.alias())); + } + return result; + } + + @Override + public ASTNode visitSelect(final SelectContext ctx) { + // TODO :Unsupported for withClause. + FirebirdSelectStatement result = (FirebirdSelectStatement) visit(ctx.combineClause()); + result.addParameterMarkerSegments(getParameterMarkerSegments()); + return result; + } + + @Override + public ASTNode visitCombineClause(final CombineClauseContext ctx) { + // TODO :Unsupported for union SQL. + return visit(ctx.selectClause(0)); + } + + @Override + public ASTNode visitSelectClause(final SelectClauseContext ctx) { + FirebirdSelectStatement result = new FirebirdSelectStatement(); + result.setProjections((ProjectionsSegment) visit(ctx.projections())); + if (!ctx.selectSpecification().isEmpty()) { + result.getProjections().setDistinctRow(isDistinct(ctx.selectSpecification().get(0))); + } + if (null != ctx.fromClause()) { + TableSegment tableSegment = (TableSegment) visit(ctx.fromClause()); + result.setFrom(tableSegment); + } + if (null != ctx.whereClause()) { + result.setWhere((WhereSegment) visit(ctx.whereClause())); + } + if (null != ctx.groupByClause()) { + result.setGroupBy((GroupBySegment) visit(ctx.groupByClause())); + } + if (null != ctx.orderByClause()) { + result.setOrderBy((OrderBySegment) visit(ctx.orderByClause())); + } + if (null != ctx.havingClause()) { + result.setHaving((HavingSegment) visit(ctx.havingClause())); + } + return result; + } + + @Override + public ASTNode visitHavingClause(final HavingClauseContext ctx) { + ExpressionSegment expr = (ExpressionSegment) visit(ctx.expr()); + return new HavingSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), expr); + } + + private boolean isDistinct(final SelectSpecificationContext ctx) { + return ((BooleanLiteralValue) visit(ctx.duplicateSpecification())).getValue(); + } + + @Override + public ASTNode visitDuplicateSpecification(final DuplicateSpecificationContext ctx) { + return new BooleanLiteralValue(null != ctx.DISTINCT()); + } + + @Override + public ASTNode visitProjections(final ProjectionsContext ctx) { + Collection projections = new LinkedList<>(); + if (null != ctx.unqualifiedShorthand()) { + projections.add(new ShorthandProjectionSegment(ctx.unqualifiedShorthand().getStart().getStartIndex(), ctx.unqualifiedShorthand().getStop().getStopIndex())); + } + for (ProjectionContext each : ctx.projection()) { + projections.add((ProjectionSegment) visit(each)); + } + ProjectionsSegment result = new ProjectionsSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex()); + result.getProjections().addAll(projections); + return result; + } + + @Override + public ASTNode visitProjection(final ProjectionContext ctx) { + // FIXME :The stop index of project is the stop index of projection, instead of alias. + if (null != ctx.qualifiedShorthand()) { + QualifiedShorthandContext shorthand = ctx.qualifiedShorthand(); + ShorthandProjectionSegment result = new ShorthandProjectionSegment(shorthand.getStart().getStartIndex(), shorthand.getStop().getStopIndex()); + IdentifierValue identifier = new IdentifierValue(shorthand.identifier().getText()); + result.setOwner(new OwnerSegment(shorthand.identifier().getStart().getStartIndex(), shorthand.identifier().getStop().getStopIndex(), identifier)); + return result; + } + AliasSegment alias = null == ctx.alias() ? null : (AliasSegment) visit(ctx.alias()); + if (null != ctx.columnName()) { + ColumnSegment column = (ColumnSegment) visit(ctx.columnName()); + ColumnProjectionSegment result = new ColumnProjectionSegment(column); + result.setAlias(alias); + return result; + } + return createProjection(ctx, alias); + } + + @Override + public ASTNode visitAlias(final AliasContext ctx) { + return null == ctx.identifier() + ? new AliasSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), new IdentifierValue(ctx.STRING_().getText())) + : new AliasSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), (IdentifierValue) visit(ctx.identifier())); + } + + private ASTNode createProjection(final ProjectionContext ctx, final AliasSegment alias) { + ASTNode projection = visit(ctx.expr()); + if (projection instanceof AggregationProjectionSegment) { + ((AggregationProjectionSegment) projection).setAlias(alias); + return projection; + } + if (projection instanceof ExpressionProjectionSegment) { + ((ExpressionProjectionSegment) projection).setAlias(alias); + return projection; + } + if (projection instanceof FunctionSegment) { + FunctionSegment segment = (FunctionSegment) projection; + ExpressionProjectionSegment result = new ExpressionProjectionSegment(segment.getStartIndex(), segment.getStopIndex(), segment.getText(), segment); + result.setAlias(alias); + return result; + } + if (projection instanceof CommonExpressionSegment) { + CommonExpressionSegment segment = (CommonExpressionSegment) projection; + ExpressionProjectionSegment result = new ExpressionProjectionSegment(segment.getStartIndex(), segment.getStopIndex(), segment.getText(), segment); + result.setAlias(alias); + return result; + } + // FIXME :For DISTINCT() + if (projection instanceof ColumnSegment) { + ExpressionProjectionSegment result = new ExpressionProjectionSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), getOriginalText(ctx), (ColumnSegment) projection); + result.setAlias(alias); + return result; + } + if (projection instanceof SubqueryExpressionSegment) { + SubqueryExpressionSegment subqueryExpressionSegment = (SubqueryExpressionSegment) projection; + String text = ctx.start.getInputStream().getText(new Interval(subqueryExpressionSegment.getStartIndex(), subqueryExpressionSegment.getStopIndex())); + SubqueryProjectionSegment result = new SubqueryProjectionSegment(((SubqueryExpressionSegment) projection).getSubquery(), text); + result.setAlias(alias); + return result; + } + if (projection instanceof BinaryOperationExpression) { + BinaryOperationExpression binaryExpression = (BinaryOperationExpression) projection; + int startIndex = binaryExpression.getStartIndex(); + int stopIndex = null == alias ? binaryExpression.getStopIndex() : alias.getStopIndex(); + ExpressionProjectionSegment result = new ExpressionProjectionSegment(startIndex, stopIndex, binaryExpression.getText(), binaryExpression); + result.setAlias(alias); + return result; + } + if (projection instanceof ParameterMarkerExpressionSegment) { + ParameterMarkerExpressionSegment result = (ParameterMarkerExpressionSegment) projection; + result.setAlias(alias); + return projection; + } + LiteralExpressionSegment column = (LiteralExpressionSegment) projection; + ExpressionProjectionSegment result = null == alias ? new ExpressionProjectionSegment(column.getStartIndex(), column.getStopIndex(), String.valueOf(column.getLiterals()), column) + : new ExpressionProjectionSegment(column.getStartIndex(), ctx.alias().stop.getStopIndex(), String.valueOf(column.getLiterals()), column); + result.setAlias(alias); + return result; + } + + @Override + public ASTNode visitFromClause(final FromClauseContext ctx) { + return visit(ctx.tableReferences()); + } + + @Override + public ASTNode visitTableReferences(final TableReferencesContext ctx) { + TableSegment result = (TableSegment) visit(ctx.escapedTableReference(0)); + if (ctx.escapedTableReference().size() > 1) { + for (int i = 1; i < ctx.escapedTableReference().size(); i++) { + result = generateJoinTableSourceFromEscapedTableReference(ctx.escapedTableReference(i), result); + } + } + return result; + } + + private JoinTableSegment generateJoinTableSourceFromEscapedTableReference(final EscapedTableReferenceContext ctx, final TableSegment tableSegment) { + JoinTableSegment result = new JoinTableSegment(); + result.setStartIndex(tableSegment.getStartIndex()); + result.setStopIndex(ctx.stop.getStopIndex()); + result.setLeft(tableSegment); + result.setRight((TableSegment) visit(ctx)); + result.setJoinType(JoinType.COMMA.name()); + return result; + } + + @Override + public ASTNode visitEscapedTableReference(final EscapedTableReferenceContext ctx) { + return visit(ctx.tableReference()); + } + + @Override + public ASTNode visitTableReference(final TableReferenceContext ctx) { + TableSegment result; + TableSegment left; + left = (TableSegment) visit(ctx.tableFactor()); + if (!ctx.joinedTable().isEmpty()) { + for (JoinedTableContext each : ctx.joinedTable()) { + left = visitJoinedTable(each, left); + } + } + result = left; + return result; + } + + @Override + public ASTNode visitTableFactor(final TableFactorContext ctx) { + if (null != ctx.subquery()) { + FirebirdSelectStatement subquery = (FirebirdSelectStatement) visit(ctx.subquery()); + SubquerySegment subquerySegment = new SubquerySegment(ctx.subquery().start.getStartIndex(), ctx.subquery().stop.getStopIndex(), subquery); + SubqueryTableSegment result = new SubqueryTableSegment(subquerySegment); + if (null != ctx.alias()) { + result.setAlias((AliasSegment) visit(ctx.alias())); + } + return result; + } + if (null != ctx.tableName()) { + SimpleTableSegment result = (SimpleTableSegment) visit(ctx.tableName()); + if (null != ctx.alias()) { + result.setAlias((AliasSegment) visit(ctx.alias())); + } + return result; + } + return visit(ctx.tableReferences()); + } + + private JoinTableSegment visitJoinedTable(final JoinedTableContext ctx, final TableSegment tableSegment) { + JoinTableSegment result = new JoinTableSegment(); + result.setLeft(tableSegment); + result.setStartIndex(tableSegment.getStartIndex()); + result.setStopIndex(ctx.stop.getStopIndex()); + TableSegment right = (TableSegment) visit(ctx.tableFactor()); + result.setRight(right); + result.setJoinType(getJoinType(ctx)); + if (null != ctx.joinSpecification()) { + visitJoinSpecification(ctx.joinSpecification(), result); + } + return result; + } + + private String getJoinType(final JoinedTableContext ctx) { + if (null != ctx.LEFT()) { + return JoinType.LEFT.name(); + } else if (null != ctx.RIGHT()) { + return JoinType.RIGHT.name(); + } else if (null != ctx.INNER()) { + return JoinType.INNER.name(); + } else if (null != ctx.CROSS()) { + return JoinType.CROSS.name(); + } + return JoinType.INNER.name(); + } + + private void visitJoinSpecification(final JoinSpecificationContext ctx, final JoinTableSegment joinTableSource) { + if (null != ctx.expr()) { + ExpressionSegment condition = (ExpressionSegment) visit(ctx.expr()); + joinTableSource.setCondition(condition); + } + if (null != ctx.USING()) { + joinTableSource.setUsing(ctx.columnNames().columnName().stream().map(each -> (ColumnSegment) visit(each)).collect(Collectors.toList())); + } + } + + @Override + public ASTNode visitWhereClause(final WhereClauseContext ctx) { + ExpressionSegment segment = (ExpressionSegment) visit(ctx.expr()); + return new WhereSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), segment); + } + + @Override + public ASTNode visitGroupByClause(final GroupByClauseContext ctx) { + Collection items = new LinkedList<>(); + for (OrderByItemContext each : ctx.orderByItem()) { + items.add((OrderByItemSegment) visit(each)); + } + return new GroupBySegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), items); + } + + @Override + public ASTNode visitSubquery(final SubqueryContext ctx) { + return visit(ctx.combineClause()); + } +} diff --git a/parser/sql/dialect/firebird/src/main/java/org/apache/shardingsphere/sql/parser/firebird/visitor/statement/type/FirebirdTCLStatementVisitor.java b/parser/sql/dialect/firebird/src/main/java/org/apache/shardingsphere/sql/parser/firebird/visitor/statement/type/FirebirdTCLStatementVisitor.java new file mode 100644 index 0000000000000..9ea2928e186ce --- /dev/null +++ b/parser/sql/dialect/firebird/src/main/java/org/apache/shardingsphere/sql/parser/firebird/visitor/statement/type/FirebirdTCLStatementVisitor.java @@ -0,0 +1,49 @@ +/* + * 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.firebird.visitor.statement.type; + +import org.apache.shardingsphere.sql.parser.api.ASTNode; +import org.apache.shardingsphere.sql.parser.api.visitor.statement.type.TCLStatementVisitor; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.CommitContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.RollbackContext; +import org.apache.shardingsphere.sql.parser.autogen.FirebirdStatementParser.SetTransactionContext; +import org.apache.shardingsphere.sql.parser.sql.dialect.statement.firebird.tcl.FirebirdCommitStatement; +import org.apache.shardingsphere.sql.parser.sql.dialect.statement.firebird.tcl.FirebirdRollbackStatement; +import org.apache.shardingsphere.sql.parser.sql.dialect.statement.firebird.tcl.FirebirdSetTransactionStatement; +import org.apache.shardingsphere.sql.parser.firebird.visitor.statement.FirebirdStatementVisitor; + +/** + * TCL statement visitor for Firebird. + */ +public final class FirebirdTCLStatementVisitor extends FirebirdStatementVisitor implements TCLStatementVisitor { + + @Override + public ASTNode visitSetTransaction(final SetTransactionContext ctx) { + return new FirebirdSetTransactionStatement(); + } + + @Override + public ASTNode visitCommit(final CommitContext ctx) { + return new FirebirdCommitStatement(); + } + + @Override + public ASTNode visitRollback(final RollbackContext ctx) { + return new FirebirdRollbackStatement(); + } +} diff --git a/parser/sql/dialect/firebird/src/main/resources/META-INF/services/org.apache.shardingsphere.sql.parser.spi.SQLDialectParserFacade b/parser/sql/dialect/firebird/src/main/resources/META-INF/services/org.apache.shardingsphere.sql.parser.spi.SQLDialectParserFacade new file mode 100644 index 0000000000000..54f86719a61bd --- /dev/null +++ b/parser/sql/dialect/firebird/src/main/resources/META-INF/services/org.apache.shardingsphere.sql.parser.spi.SQLDialectParserFacade @@ -0,0 +1,18 @@ +# +# 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. +# + +org.apache.shardingsphere.sql.parser.firebird.parser.FirebirdParserFacade diff --git a/parser/sql/dialect/firebird/src/main/resources/META-INF/services/org.apache.shardingsphere.sql.parser.spi.SQLStatementVisitorFacade b/parser/sql/dialect/firebird/src/main/resources/META-INF/services/org.apache.shardingsphere.sql.parser.spi.SQLStatementVisitorFacade new file mode 100644 index 0000000000000..0b5cf05d3c537 --- /dev/null +++ b/parser/sql/dialect/firebird/src/main/resources/META-INF/services/org.apache.shardingsphere.sql.parser.spi.SQLStatementVisitorFacade @@ -0,0 +1,18 @@ +# +# 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. +# + +org.apache.shardingsphere.sql.parser.firebird.visitor.statement.FirebirdStatementVisitorFacade diff --git a/parser/sql/dialect/pom.xml b/parser/sql/dialect/pom.xml index 0a7b2276a5bb5..6a5eddaa4c838 100644 --- a/parser/sql/dialect/pom.xml +++ b/parser/sql/dialect/pom.xml @@ -33,6 +33,7 @@ oracle sqlserver opengauss + firebird diff --git a/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/firebird/FirebirdStatement.java b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/firebird/FirebirdStatement.java new file mode 100644 index 0000000000000..fec180a7ffc10 --- /dev/null +++ b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/firebird/FirebirdStatement.java @@ -0,0 +1,26 @@ +/* + * 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.sql.dialect.statement.firebird; + +import org.apache.shardingsphere.sql.parser.sql.common.statement.SQLStatement; + +/** + * SQL92 statement. + */ +public interface FirebirdStatement extends SQLStatement { +} diff --git a/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/firebird/dcl/FirebirdGrantStatement.java b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/firebird/dcl/FirebirdGrantStatement.java new file mode 100644 index 0000000000000..de3a2daa9f1e1 --- /dev/null +++ b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/firebird/dcl/FirebirdGrantStatement.java @@ -0,0 +1,27 @@ +/* + * 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.sql.dialect.statement.firebird.dcl; + +import org.apache.shardingsphere.sql.parser.sql.common.statement.dcl.GrantStatement; +import org.apache.shardingsphere.sql.parser.sql.dialect.statement.firebird.FirebirdStatement; + +/** + * SQL92 grant statement. + */ +public final class FirebirdGrantStatement extends GrantStatement implements FirebirdStatement { +} diff --git a/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/firebird/dcl/FirebirdRevokeStatement.java b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/firebird/dcl/FirebirdRevokeStatement.java new file mode 100644 index 0000000000000..086502af64409 --- /dev/null +++ b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/firebird/dcl/FirebirdRevokeStatement.java @@ -0,0 +1,27 @@ +/* + * 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.sql.dialect.statement.firebird.dcl; + +import org.apache.shardingsphere.sql.parser.sql.common.statement.dcl.RevokeStatement; +import org.apache.shardingsphere.sql.parser.sql.dialect.statement.firebird.FirebirdStatement; + +/** + * SQL92 revoke statement. + */ +public final class FirebirdRevokeStatement extends RevokeStatement implements FirebirdStatement { +} diff --git a/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/firebird/ddl/FirebirdAlterTableStatement.java b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/firebird/ddl/FirebirdAlterTableStatement.java new file mode 100644 index 0000000000000..a6cd8dd738c5f --- /dev/null +++ b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/firebird/ddl/FirebirdAlterTableStatement.java @@ -0,0 +1,27 @@ +/* + * 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.sql.dialect.statement.firebird.ddl; + +import org.apache.shardingsphere.sql.parser.sql.common.statement.ddl.AlterTableStatement; +import org.apache.shardingsphere.sql.parser.sql.dialect.statement.firebird.FirebirdStatement; + +/** + * SQL92 alter table statement. + */ +public final class FirebirdAlterTableStatement extends AlterTableStatement implements FirebirdStatement { +} diff --git a/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/firebird/ddl/FirebirdCreateTableStatement.java b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/firebird/ddl/FirebirdCreateTableStatement.java new file mode 100644 index 0000000000000..5e51b768ab891 --- /dev/null +++ b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/firebird/ddl/FirebirdCreateTableStatement.java @@ -0,0 +1,27 @@ +/* + * 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.sql.dialect.statement.firebird.ddl; + +import org.apache.shardingsphere.sql.parser.sql.common.statement.ddl.CreateTableStatement; +import org.apache.shardingsphere.sql.parser.sql.dialect.statement.firebird.FirebirdStatement; + +/** + * SQL92 create table statement. + */ +public final class FirebirdCreateTableStatement extends CreateTableStatement implements FirebirdStatement { +} \ No newline at end of file diff --git a/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/firebird/ddl/FirebirdDropTableStatement.java b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/firebird/ddl/FirebirdDropTableStatement.java new file mode 100644 index 0000000000000..c0403b42923b3 --- /dev/null +++ b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/firebird/ddl/FirebirdDropTableStatement.java @@ -0,0 +1,27 @@ +/* + * 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.sql.dialect.statement.firebird.ddl; + +import org.apache.shardingsphere.sql.parser.sql.common.statement.ddl.DropTableStatement; +import org.apache.shardingsphere.sql.parser.sql.dialect.statement.firebird.FirebirdStatement; + +/** + * SQL92 drop table statement. + */ +public final class FirebirdDropTableStatement extends DropTableStatement implements FirebirdStatement { +} \ No newline at end of file diff --git a/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/firebird/dml/FirebirdDeleteStatement.java b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/firebird/dml/FirebirdDeleteStatement.java new file mode 100644 index 0000000000000..48f0099db86a8 --- /dev/null +++ b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/firebird/dml/FirebirdDeleteStatement.java @@ -0,0 +1,27 @@ +/* + * 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.sql.dialect.statement.firebird.dml; + +import org.apache.shardingsphere.sql.parser.sql.common.statement.dml.DeleteStatement; +import org.apache.shardingsphere.sql.parser.sql.dialect.statement.firebird.FirebirdStatement; + +/** + * SQL92 delete statement. + */ +public final class FirebirdDeleteStatement extends DeleteStatement implements FirebirdStatement { +} diff --git a/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/firebird/dml/FirebirdInsertStatement.java b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/firebird/dml/FirebirdInsertStatement.java new file mode 100644 index 0000000000000..b235d04ecb238 --- /dev/null +++ b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/firebird/dml/FirebirdInsertStatement.java @@ -0,0 +1,27 @@ +/* + * 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.sql.dialect.statement.firebird.dml; + +import org.apache.shardingsphere.sql.parser.sql.common.statement.dml.InsertStatement; +import org.apache.shardingsphere.sql.parser.sql.dialect.statement.firebird.FirebirdStatement; + +/** + * SQL92 insert statement. + */ +public final class FirebirdInsertStatement extends InsertStatement implements FirebirdStatement { +} diff --git a/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/firebird/dml/FirebirdSelectStatement.java b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/firebird/dml/FirebirdSelectStatement.java new file mode 100644 index 0000000000000..87468a2b90f7a --- /dev/null +++ b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/firebird/dml/FirebirdSelectStatement.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.shardingsphere.sql.parser.sql.dialect.statement.firebird.dml; + +import lombok.Setter; +import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.pagination.limit.LimitSegment; +import org.apache.shardingsphere.sql.parser.sql.common.statement.dml.SelectStatement; +import org.apache.shardingsphere.sql.parser.sql.dialect.statement.firebird.FirebirdStatement; + +import java.util.Optional; + +/** + * SQL92 select statement. + */ +@Setter +public final class FirebirdSelectStatement extends SelectStatement implements FirebirdStatement { + + private LimitSegment limit; + + /** + * Get order by segment. + * + * @return order by segment + */ + public Optional getLimit() { + return Optional.ofNullable(limit); + } +} diff --git a/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/firebird/dml/FirebirdUpdateStatement.java b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/firebird/dml/FirebirdUpdateStatement.java new file mode 100644 index 0000000000000..bfb88c35d7aa4 --- /dev/null +++ b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/firebird/dml/FirebirdUpdateStatement.java @@ -0,0 +1,27 @@ +/* + * 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.sql.dialect.statement.firebird.dml; + +import org.apache.shardingsphere.sql.parser.sql.common.statement.dml.UpdateStatement; +import org.apache.shardingsphere.sql.parser.sql.dialect.statement.firebird.FirebirdStatement; + +/** + * SQL92 update statement. + */ +public final class FirebirdUpdateStatement extends UpdateStatement implements FirebirdStatement { +} diff --git a/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/firebird/tcl/FirebirdCommitStatement.java b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/firebird/tcl/FirebirdCommitStatement.java new file mode 100644 index 0000000000000..033e4ded68fcd --- /dev/null +++ b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/firebird/tcl/FirebirdCommitStatement.java @@ -0,0 +1,27 @@ +/* + * 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.sql.dialect.statement.firebird.tcl; + +import org.apache.shardingsphere.sql.parser.sql.common.statement.tcl.CommitStatement; +import org.apache.shardingsphere.sql.parser.sql.dialect.statement.firebird.FirebirdStatement; + +/** + * SQL92 commit statement. + */ +public final class FirebirdCommitStatement extends CommitStatement implements FirebirdStatement { +} diff --git a/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/firebird/tcl/FirebirdRollbackStatement.java b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/firebird/tcl/FirebirdRollbackStatement.java new file mode 100644 index 0000000000000..47b9f6ed6e4d5 --- /dev/null +++ b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/firebird/tcl/FirebirdRollbackStatement.java @@ -0,0 +1,27 @@ +/* + * 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.sql.dialect.statement.firebird.tcl; + +import org.apache.shardingsphere.sql.parser.sql.common.statement.tcl.RollbackStatement; +import org.apache.shardingsphere.sql.parser.sql.dialect.statement.firebird.FirebirdStatement; + +/** + * SQL92 rollback statement. + */ +public final class FirebirdRollbackStatement extends RollbackStatement implements FirebirdStatement { +} diff --git a/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/firebird/tcl/FirebirdSetTransactionStatement.java b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/firebird/tcl/FirebirdSetTransactionStatement.java new file mode 100644 index 0000000000000..28bd41a51a0f9 --- /dev/null +++ b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/firebird/tcl/FirebirdSetTransactionStatement.java @@ -0,0 +1,27 @@ +/* + * 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.sql.dialect.statement.firebird.tcl; + +import org.apache.shardingsphere.sql.parser.sql.common.statement.tcl.SetTransactionStatement; +import org.apache.shardingsphere.sql.parser.sql.dialect.statement.firebird.FirebirdStatement; + +/** + * SQL92 set transaction statement. + */ +public final class FirebirdSetTransactionStatement extends SetTransactionStatement implements FirebirdStatement { +} From 8b92ef02f8ed029b777cd54a60827135876d0c61 Mon Sep 17 00:00:00 2001 From: TedCraft Date: Wed, 1 Nov 2023 20:12:52 +0300 Subject: [PATCH 3/4] add firebird class to statement context --- .../binder/context/statement/CommonSQLStatementContext.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/context/statement/CommonSQLStatementContext.java b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/context/statement/CommonSQLStatementContext.java index 9b4016e6819e2..4ad7d95508600 100644 --- a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/context/statement/CommonSQLStatementContext.java +++ b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/context/statement/CommonSQLStatementContext.java @@ -28,6 +28,7 @@ import org.apache.shardingsphere.sql.parser.sql.dialect.statement.oracle.OracleStatement; import org.apache.shardingsphere.sql.parser.sql.dialect.statement.postgresql.PostgreSQLStatement; import org.apache.shardingsphere.sql.parser.sql.dialect.statement.sql92.SQL92Statement; +import org.apache.shardingsphere.sql.parser.sql.dialect.statement.firebird.FirebirdStatement; import org.apache.shardingsphere.sql.parser.sql.dialect.statement.sqlserver.SQLServerStatement; import java.util.Collections; @@ -69,6 +70,9 @@ private DatabaseType getDatabaseType(final SQLStatement sqlStatement) { if (sqlStatement instanceof SQL92Statement) { return TypedSPILoader.getService(DatabaseType.class, "SQL92"); } + if (sqlStatement instanceof FirebirdStatement) { + return TypedSPILoader.getService(DatabaseType.class, "Firebird"); + } throw new UnsupportedSQLOperationException(sqlStatement.getClass().getName()); } } From 94b09bc01c6240499bfd423cafdfc43c9d578eaa Mon Sep 17 00:00:00 2001 From: TedCraft Date: Fri, 10 Nov 2023 21:44:40 +0300 Subject: [PATCH 4/4] fix for firebird database table metadata didn't load --- .../metadata/database/FirebirdDatabaseMetaData.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/infra/database/type/firebird/src/main/java/org/apache/shardingsphere/infra/database/firebird/metadata/database/FirebirdDatabaseMetaData.java b/infra/database/type/firebird/src/main/java/org/apache/shardingsphere/infra/database/firebird/metadata/database/FirebirdDatabaseMetaData.java index 467aab38775ba..d9314a1bcf75d 100644 --- a/infra/database/type/firebird/src/main/java/org/apache/shardingsphere/infra/database/firebird/metadata/database/FirebirdDatabaseMetaData.java +++ b/infra/database/type/firebird/src/main/java/org/apache/shardingsphere/infra/database/firebird/metadata/database/FirebirdDatabaseMetaData.java @@ -21,6 +21,8 @@ import org.apache.shardingsphere.infra.database.core.metadata.database.enums.NullsOrderType; import org.apache.shardingsphere.infra.database.core.metadata.database.enums.QuoteCharacter; +import java.util.Locale; + /** * Database meta data of Firebird. */ @@ -36,6 +38,11 @@ public NullsOrderType getDefaultNullsOrderType() { return NullsOrderType.FIRST; } + @Override + public String formatTableNamePattern(final String tableNamePattern) { + return tableNamePattern.toUpperCase(); + } + @Override public String getDatabaseType() { return "Firebird";