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());
}
}
diff --git a/infra/common/pom.xml b/infra/common/pom.xml
index 6861b2573e3ae..c7e3a0fcdcf52 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..d9314a1bcf75d
--- /dev/null
+++ b/infra/database/type/firebird/src/main/java/org/apache/shardingsphere/infra/database/firebird/metadata/database/FirebirdDatabaseMetaData.java
@@ -0,0 +1,50 @@
+/*
+ * 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;
+
+import java.util.Locale;
+
+/**
+ * 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 formatTableNamePattern(final String tableNamePattern) {
+ return tableNamePattern.toUpperCase();
+ }
+
+ @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 a00e7b29671e1..5e1c763a6a9b4 100644
--- a/infra/database/type/pom.xml
+++ b/infra/database/type/pom.xml
@@ -36,5 +36,6 @@
sqlserver
h2
sql92
+ firebird
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/pom.xml b/jdbc/core/pom.xml
index ea25b383c6919..e23f6979e4406 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/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 1fefc7e0380e7..ec1b208f46953 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
@@ -90,6 +90,8 @@
import org.apache.shardingsphere.traffic.rule.TrafficRule;
import org.apache.shardingsphere.transaction.util.AutoCommitUtils;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.ParameterMetaData;
import java.sql.PreparedStatement;
@@ -265,7 +267,7 @@ private ShardingSphereResultSet doExecuteQuery(final Collection queryResults = executeQuery0(each);
MergedResult mergedResult = mergeQuery(queryResults, each.getSqlStatementContext());
- List resultSets = getResultSets();
+ List resultSets = getResultSets(queryResults);
if (null == columnLabelAndIndexMap) {
columnLabelAndIndexMap = ShardingSphereResultSetUtils.createColumnLabelAndIndexMap(sqlStatementContext, selectContainsEnhancedTable, resultSets.get(0).getMetaData());
}
@@ -580,6 +582,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) {
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 extends SQLLexer> getLexerClass() {
+ return FirebirdLexer.class;
+ }
+
+ @Override
+ public Class extends SQLParser> 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 extends DMLStatementVisitor> getDMLVisitorClass() {
+ return FirebirdDMLStatementVisitor.class;
+ }
+
+ @Override
+ public Class extends DDLStatementVisitor> getDDLVisitorClass() {
+ return FirebirdDDLStatementVisitor.class;
+ }
+
+ @Override
+ public Class extends TCLStatementVisitor> getTCLVisitorClass() {
+ return FirebirdTCLStatementVisitor.class;
+ }
+
+ @Override
+ public Class extends DCLStatementVisitor> getDCLVisitorClass() {
+ return FirebirdDCLStatementVisitor.class;
+ }
+
+ @Override
+ public Class extends DALStatementVisitor> getDALVisitorClass() {
+ return FirebirdDALStatementVisitor.class;
+ }
+
+ @Override
+ public Class extends RLStatementVisitor> 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 4411880d5167e..e6d75140e66b0 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 {
+}