From ed247c684ee8a9ad0bfc09ea722ae37d06d50f68 Mon Sep 17 00:00:00 2001 From: Lukas Eder Date: Tue, 18 Nov 2014 14:15:17 +0100 Subject: [PATCH] [#2925] Add support for Firebird stored procedures --- .../jooq/util/firebird/FirebirdDatabase.java | 93 +++++++++++- .../firebird/FirebirdRoutineDefinition.java | 118 +++++++++++++++ .../firebird/FirebirdTableDefinition.java | 67 ++------- .../firebird/FirebirdTableValuedFunction.java | 142 ++++++++++++++++++ .../java/org/jooq/impl/AbstractRoutine.java | 8 +- .../main/java/org/jooq/impl/TableImpl.java | 12 +- 6 files changed, 379 insertions(+), 61 deletions(-) create mode 100644 jOOQ-meta/src/main/java/org/jooq/util/firebird/FirebirdRoutineDefinition.java create mode 100644 jOOQ-meta/src/main/java/org/jooq/util/firebird/FirebirdTableValuedFunction.java diff --git a/jOOQ-meta/src/main/java/org/jooq/util/firebird/FirebirdDatabase.java b/jOOQ-meta/src/main/java/org/jooq/util/firebird/FirebirdDatabase.java index 1e64d35893..bb2857d538 100644 --- a/jOOQ-meta/src/main/java/org/jooq/util/firebird/FirebirdDatabase.java +++ b/jOOQ-meta/src/main/java/org/jooq/util/firebird/FirebirdDatabase.java @@ -40,8 +40,12 @@ */ package org.jooq.util.firebird; +import static org.jooq.impl.DSL.decode; +import static org.jooq.impl.DSL.inline; +import static org.jooq.impl.DSL.select; import static org.jooq.util.firebird.rdb.Tables.RDB$GENERATORS; import static org.jooq.util.firebird.rdb.Tables.RDB$INDEX_SEGMENTS; +import static org.jooq.util.firebird.rdb.Tables.RDB$PROCEDURES; import static org.jooq.util.firebird.rdb.Tables.RDB$REF_CONSTRAINTS; import static org.jooq.util.firebird.rdb.Tables.RDB$RELATIONS; import static org.jooq.util.firebird.rdb.Tables.RDB$RELATION_CONSTRAINTS; @@ -51,7 +55,9 @@ import java.util.ArrayList; import java.util.List; import org.jooq.DSLContext; +import org.jooq.Field; import org.jooq.Record; +import org.jooq.Record2; import org.jooq.Record3; import org.jooq.Result; import org.jooq.SQLDialect; @@ -70,6 +76,7 @@ import org.jooq.util.SchemaDefinition; import org.jooq.util.SequenceDefinition; import org.jooq.util.TableDefinition; import org.jooq.util.UDTDefinition; +import org.jooq.util.firebird.rdb.tables.Rdb$fields; import org.jooq.util.firebird.rdb.tables.Rdb$indexSegments; import org.jooq.util.firebird.rdb.tables.Rdb$refConstraints; import org.jooq.util.firebird.rdb.tables.Rdb$relationConstraints; @@ -219,14 +226,28 @@ public class FirebirdDatabase extends AbstractDatabase { protected List getTables0() throws SQLException { List result = new ArrayList(); - for (String tableName : create() - .select(RDB$RELATIONS.RDB$RELATION_NAME.trim()) + for (Record2 record : create() + .select( + RDB$RELATIONS.RDB$RELATION_NAME.trim(), + inline(false).as("table_valued_function")) .from(RDB$RELATIONS) - .orderBy(1) - .fetch(0, String.class)) { + .unionAll( + select( + RDB$PROCEDURES.RDB$PROCEDURE_NAME.trim(), + inline(true).as("table_valued_function")) + .from(RDB$PROCEDURES) - TableDefinition tableDef = new FirebirdTableDefinition(getSchemata().get(0), tableName, ""); - result.add(tableDef); + // "selectable" procedures + .where(RDB$PROCEDURES.RDB$PROCEDURE_TYPE.eq((short) 1)) + ) + .orderBy(1)) { + + if (record.value2()) { + result.add(new FirebirdTableValuedFunction(getSchemata().get(0), record.value1(), "")); + } + else { + result.add(new FirebirdTableDefinition(getSchemata().get(0), record.value1(), "")); + } } return result; @@ -235,6 +256,19 @@ public class FirebirdDatabase extends AbstractDatabase { @Override protected List getRoutines0() throws SQLException { List result = new ArrayList(); + + for (String procedureName : create() + .select(RDB$PROCEDURES.RDB$PROCEDURE_NAME.trim()) + .from(RDB$PROCEDURES) + + // "executable" procedures + .where(RDB$PROCEDURES.RDB$PROCEDURE_TYPE.eq((short) 2)) + .orderBy(1) + .fetch(0, String.class)) { + + result.add(new FirebirdRoutineDefinition(getSchemata().get(0), procedureName)); + } + return result; } @@ -266,4 +300,51 @@ public class FirebirdDatabase extends AbstractDatabase { protected DSLContext create0() { return DSL.using(getConnection(), SQLDialect.FIREBIRD); } + + static Field FIELD_TYPE(Rdb$fields f) { + return decode().value(f.RDB$FIELD_TYPE) + .when((short) 7, decode() + .when(f.RDB$FIELD_SUB_TYPE.eq((short) 1), "NUMERIC") + .when(f.RDB$FIELD_SUB_TYPE.eq((short) 0) + .and(f.RDB$FIELD_SCALE.lt((short) 0)), "NUMERIC") + .when(f.RDB$FIELD_SUB_TYPE.eq((short) 2), "DECIMAL") + .otherwise("SMALLINT")) + .when((short) 8, decode() + .when(f.RDB$FIELD_SUB_TYPE.eq((short) 1), "NUMERIC") + .when(f.RDB$FIELD_SUB_TYPE.eq((short) 0) + .and(f.RDB$FIELD_SCALE.lt((short) 0)), "NUMERIC") + .when(f.RDB$FIELD_SUB_TYPE.eq((short) 2), "DECIMAL") + .otherwise("INTEGER")) + .when((short) 9, "QUAD") + .when((short) 10, "FLOAT") + .when((short) 11, "D_FLOAT") + .when((short) 12, "DATE") + .when((short) 13, "TIME") + .when((short) 14, "CHAR") + .when((short) 16, decode() + .when(f.RDB$FIELD_SUB_TYPE.eq((short) 1), "NUMERIC") + .when(f.RDB$FIELD_SUB_TYPE.eq((short) 0) + .and(f.RDB$FIELD_SCALE.lt((short) 0)), "NUMERIC") + .when(f.RDB$FIELD_SUB_TYPE.eq((short) 2), "DECIMAL") + .otherwise("BIGINT")) + .when((short) 27, "DOUBLE") + .when((short) 35, "TIMESTAMP") + .when((short) 37, "VARCHAR") + .when((short) 40, "CSTRING") + .when((short) 261, decode().value(f.RDB$FIELD_SUB_TYPE) + .when((short) 0, "BLOB") + .when((short) 1, "BLOB SUB_TYPE TEXT") + .otherwise("BLOB")) + .otherwise("UNKNOWN"); + } + + static Field FIELD_SCALE(Rdb$fields f) { + return f.RDB$FIELD_SCALE.neg(); + } + + static Field CHARACTER_LENGTH(Rdb$fields f) { + return decode().value(f.RDB$FIELD_TYPE) + .when((short) 261, (short) 0) + .otherwise(f.RDB$CHARACTER_LENGTH); + } } diff --git a/jOOQ-meta/src/main/java/org/jooq/util/firebird/FirebirdRoutineDefinition.java b/jOOQ-meta/src/main/java/org/jooq/util/firebird/FirebirdRoutineDefinition.java new file mode 100644 index 0000000000..367b5b8a14 --- /dev/null +++ b/jOOQ-meta/src/main/java/org/jooq/util/firebird/FirebirdRoutineDefinition.java @@ -0,0 +1,118 @@ +/** + * Copyright (c) 2009-2014, Data Geekery GmbH (http://www.datageekery.com) + * All rights reserved. + * + * This work is dual-licensed + * - under the Apache Software License 2.0 (the "ASL") + * - under the jOOQ License and Maintenance Agreement (the "jOOQ License") + * ============================================================================= + * You may choose which license applies to you: + * + * - If you're using this work with Open Source databases, you may choose + * either ASL or jOOQ License. + * - If you're using this work with at least one commercial database, you must + * choose jOOQ License + * + * For more information, please visit http://www.jooq.org/licenses + * + * Apache Software License 2.0: + * ----------------------------------------------------------------------------- + * Licensed 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. + * + * jOOQ License and Maintenance Agreement: + * ----------------------------------------------------------------------------- + * Data Geekery grants the Customer the non-exclusive, timely limited and + * non-transferable license to install and use the Software under the terms of + * the jOOQ License and Maintenance Agreement. + * + * This library is distributed with a LIMITED WARRANTY. See the jOOQ License + * and Maintenance Agreement for more details: http://www.jooq.org/licensing + */ +package org.jooq.util.firebird; + +import static org.jooq.util.firebird.FirebirdDatabase.CHARACTER_LENGTH; +import static org.jooq.util.firebird.FirebirdDatabase.FIELD_SCALE; +import static org.jooq.util.firebird.FirebirdDatabase.FIELD_TYPE; +import static org.jooq.util.firebird.rdb.Tables.RDB$FIELDS; +import static org.jooq.util.firebird.rdb.Tables.RDB$PROCEDURE_PARAMETERS; + +import java.sql.SQLException; + +import org.jooq.Record; +import org.jooq.impl.DSL; +import org.jooq.util.AbstractRoutineDefinition; +import org.jooq.util.DataTypeDefinition; +import org.jooq.util.DefaultDataTypeDefinition; +import org.jooq.util.DefaultParameterDefinition; +import org.jooq.util.InOutDefinition; +import org.jooq.util.ParameterDefinition; +import org.jooq.util.SchemaDefinition; +import org.jooq.util.firebird.rdb.tables.Rdb$fields; +import org.jooq.util.firebird.rdb.tables.Rdb$procedureParameters; + +/** + * @author Lukas Eder + */ +public class FirebirdRoutineDefinition extends AbstractRoutineDefinition { + + public FirebirdRoutineDefinition(SchemaDefinition schema, String name) { + super(schema, null, name, null, null, false); + } + + @Override + protected void init0() throws SQLException { + Rdb$procedureParameters p = RDB$PROCEDURE_PARAMETERS.as("p"); + Rdb$fields f = RDB$FIELDS.as("f"); + int i = 0; + + for (Record record : create() + .select( + p.RDB$PARAMETER_NUMBER, + p.RDB$PARAMETER_TYPE, + p.RDB$PARAMETER_NAME.trim().as(p.RDB$PARAMETER_NAME), + FIELD_TYPE(f).as("FIELD_TYPE"), + CHARACTER_LENGTH(f).as("CHARACTER_LENGTH"), + f.RDB$FIELD_PRECISION, + FIELD_SCALE(f).as("FIELD_SCALE"), + DSL.bitOr(p.RDB$NULL_FLAG.nvl((short) 0), f.RDB$NULL_FLAG.nvl((short) 0)).as(p.RDB$NULL_FLAG), + p.RDB$DEFAULT_SOURCE) + .from(p) + .leftOuterJoin(f).on(p.RDB$FIELD_SOURCE.eq(f.RDB$FIELD_NAME)) + .where(p.RDB$PROCEDURE_NAME.eq(getName())) + .orderBy( + p.RDB$PARAMETER_TYPE.desc(), + p.RDB$PARAMETER_NUMBER.asc())) { + + DataTypeDefinition type = new DefaultDataTypeDefinition( + getDatabase(), + getSchema(), + record.getValue("FIELD_TYPE", String.class), + record.getValue("CHARACTER_LENGTH", short.class), + record.getValue(f.RDB$FIELD_PRECISION), + record.getValue("FIELD_SCALE", Integer.class), + record.getValue(p.RDB$NULL_FLAG) == 0, + record.getValue(p.RDB$DEFAULT_SOURCE) != null + ); + + ParameterDefinition parameter = new DefaultParameterDefinition( + this, + record.getValue(p.RDB$PARAMETER_NAME), + i++, + type + ); + + addParameter(record.getValue(p.RDB$PARAMETER_TYPE, int.class).equals(0) ? InOutDefinition.IN : InOutDefinition.OUT, parameter); + } + + } +} diff --git a/jOOQ-meta/src/main/java/org/jooq/util/firebird/FirebirdTableDefinition.java b/jOOQ-meta/src/main/java/org/jooq/util/firebird/FirebirdTableDefinition.java index dc50ac622d..f8533c9c57 100644 --- a/jOOQ-meta/src/main/java/org/jooq/util/firebird/FirebirdTableDefinition.java +++ b/jOOQ-meta/src/main/java/org/jooq/util/firebird/FirebirdTableDefinition.java @@ -40,7 +40,9 @@ */ package org.jooq.util.firebird; -import static org.jooq.impl.DSL.decode; +import static org.jooq.util.firebird.FirebirdDatabase.CHARACTER_LENGTH; +import static org.jooq.util.firebird.FirebirdDatabase.FIELD_SCALE; +import static org.jooq.util.firebird.FirebirdDatabase.FIELD_TYPE; import static org.jooq.util.firebird.rdb.Tables.RDB$FIELDS; import static org.jooq.util.firebird.rdb.Tables.RDB$RELATION_FIELDS; @@ -76,57 +78,20 @@ public class FirebirdTableDefinition extends AbstractTableDefinition { // Inspiration for the below query was taken from jaybird's // DatabaseMetaData implementation - for (Record record : create().select( - r.RDB$FIELD_NAME.trim(), - r.RDB$DESCRIPTION, - r.RDB$DEFAULT_VALUE, - DSL.bitOr(r.RDB$NULL_FLAG.nvl((short) 0), f.RDB$NULL_FLAG.nvl((short) 0)).as(r.RDB$NULL_FLAG.getName()), - r.RDB$DEFAULT_SOURCE, - r.RDB$FIELD_POSITION, + for (Record record : create() + .select( + r.RDB$FIELD_NAME.trim(), + r.RDB$DESCRIPTION, + r.RDB$DEFAULT_VALUE, + DSL.bitOr(r.RDB$NULL_FLAG.nvl((short) 0), f.RDB$NULL_FLAG.nvl((short) 0)).as(r.RDB$NULL_FLAG), + r.RDB$DEFAULT_SOURCE, + r.RDB$FIELD_POSITION, - // [#3342] FIELD_LENGTH should be ignored for LOBs - decode().value(f.RDB$FIELD_TYPE) - .when((short) 261, (short) 0) - .otherwise(f.RDB$CHARACTER_LENGTH) - .as("CHARACTER_LENGTH"), - f.RDB$FIELD_PRECISION, - f.RDB$FIELD_SCALE.neg().as("FIELD_SCALE"), - - // FIELD_TYPE - decode().value(f.RDB$FIELD_TYPE) - .when((short) 7, decode() - .when(f.RDB$FIELD_SUB_TYPE.eq((short) 1), "NUMERIC") - .when(f.RDB$FIELD_SUB_TYPE.eq((short) 0) - .and(f.RDB$FIELD_SCALE.lt((short) 0)), "NUMERIC") - .when(f.RDB$FIELD_SUB_TYPE.eq((short) 2), "DECIMAL") - .otherwise("SMALLINT")) - .when((short) 8, decode() - .when(f.RDB$FIELD_SUB_TYPE.eq((short) 1), "NUMERIC") - .when(f.RDB$FIELD_SUB_TYPE.eq((short) 0) - .and(f.RDB$FIELD_SCALE.lt((short) 0)), "NUMERIC") - .when(f.RDB$FIELD_SUB_TYPE.eq((short) 2), "DECIMAL") - .otherwise("INTEGER")) - .when((short) 9, "QUAD") - .when((short) 10, "FLOAT") - .when((short) 11, "D_FLOAT") - .when((short) 12, "DATE") - .when((short) 13, "TIME") - .when((short) 14, "CHAR") - .when((short) 16, decode() - .when(f.RDB$FIELD_SUB_TYPE.eq((short) 1), "NUMERIC") - .when(f.RDB$FIELD_SUB_TYPE.eq((short) 0) - .and(f.RDB$FIELD_SCALE.lt((short) 0)), "NUMERIC") - .when(f.RDB$FIELD_SUB_TYPE.eq((short) 2), "DECIMAL") - .otherwise("BIGINT")) - .when((short) 27, "DOUBLE") - .when((short) 35, "TIMESTAMP") - .when((short) 37, "VARCHAR") - .when((short) 40, "CSTRING") - .when((short) 261, decode().value(f.RDB$FIELD_SUB_TYPE) - .when((short) 0, "BLOB") - .when((short) 1, "BLOB SUB_TYPE TEXT") - .otherwise("BLOB")) - .otherwise("UNKNOWN").as("FIELD_TYPE"), + // [#3342] FIELD_LENGTH should be ignored for LOBs + CHARACTER_LENGTH(f).as("CHARACTER_LENGTH"), + f.RDB$FIELD_PRECISION, + FIELD_SCALE(f).as("FIELD_SCALE"), + FIELD_TYPE(f).as("FIELD_TYPE"), f.RDB$FIELD_SUB_TYPE) .from(r) .leftOuterJoin(f).on(r.RDB$FIELD_SOURCE.eq(f.RDB$FIELD_NAME)) diff --git a/jOOQ-meta/src/main/java/org/jooq/util/firebird/FirebirdTableValuedFunction.java b/jOOQ-meta/src/main/java/org/jooq/util/firebird/FirebirdTableValuedFunction.java new file mode 100644 index 0000000000..01491ba50c --- /dev/null +++ b/jOOQ-meta/src/main/java/org/jooq/util/firebird/FirebirdTableValuedFunction.java @@ -0,0 +1,142 @@ +/** + * Copyright (c) 2009-2014, Data Geekery GmbH (http://www.datageekery.com) + * All rights reserved. + * + * This work is dual-licensed + * - under the Apache Software License 2.0 (the "ASL") + * - under the jOOQ License and Maintenance Agreement (the "jOOQ License") + * ============================================================================= + * You may choose which license applies to you: + * + * - If you're using this work with Open Source databases, you may choose + * either ASL or jOOQ License. + * - If you're using this work with at least one commercial database, you must + * choose jOOQ License + * + * For more information, please visit http://www.jooq.org/licenses + * + * Apache Software License 2.0: + * ----------------------------------------------------------------------------- + * Licensed 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. + * + * jOOQ License and Maintenance Agreement: + * ----------------------------------------------------------------------------- + * Data Geekery grants the Customer the non-exclusive, timely limited and + * non-transferable license to install and use the Software under the terms of + * the jOOQ License and Maintenance Agreement. + * + * This library is distributed with a LIMITED WARRANTY. See the jOOQ License + * and Maintenance Agreement for more details: http://www.jooq.org/licensing + */ +package org.jooq.util.firebird; + +import static org.jooq.util.firebird.FirebirdDatabase.CHARACTER_LENGTH; +import static org.jooq.util.firebird.FirebirdDatabase.FIELD_SCALE; +import static org.jooq.util.firebird.FirebirdDatabase.FIELD_TYPE; +import static org.jooq.util.firebird.rdb.Tables.RDB$FIELDS; +import static org.jooq.util.firebird.rdb.Tables.RDB$PROCEDURE_PARAMETERS; + +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +import org.jooq.Record; +import org.jooq.impl.DSL; +import org.jooq.util.AbstractTableDefinition; +import org.jooq.util.ColumnDefinition; +import org.jooq.util.DefaultColumnDefinition; +import org.jooq.util.DefaultDataTypeDefinition; +import org.jooq.util.ParameterDefinition; +import org.jooq.util.SchemaDefinition; +import org.jooq.util.firebird.rdb.tables.Rdb$fields; +import org.jooq.util.firebird.rdb.tables.Rdb$procedureParameters; + +/** + * @author Lukas Eder + */ +public class FirebirdTableValuedFunction extends AbstractTableDefinition { + + private final FirebirdRoutineDefinition routine; + + public FirebirdTableValuedFunction(SchemaDefinition schema, String name, String comment) { + super(schema, name, comment); + + routine = new FirebirdRoutineDefinition(schema, name); + } + + @Override + protected List getElements0() throws SQLException { + List result = new ArrayList(); + + Rdb$procedureParameters p = RDB$PROCEDURE_PARAMETERS.as("p"); + Rdb$fields f = RDB$FIELDS.as("f"); + + // Inspiration for the below query was taken from jaybird's + // DatabaseMetaData implementation + for (Record record : create() + .select( + p.RDB$PARAMETER_NUMBER, + p.RDB$PARAMETER_NAME.trim(), + p.RDB$DESCRIPTION, + p.RDB$DEFAULT_VALUE, + DSL.bitOr(p.RDB$NULL_FLAG.nvl((short) 0), f.RDB$NULL_FLAG.nvl((short) 0)).as(p.RDB$NULL_FLAG), + p.RDB$DEFAULT_SOURCE, + + // [#3342] FIELD_LENGTH should be ignored for LOBs + CHARACTER_LENGTH(f).as("CHARACTER_LENGTH"), + f.RDB$FIELD_PRECISION, + FIELD_SCALE(f).as("FIELD_SCALE"), + FIELD_TYPE(f).as("FIELD_TYPE"), + f.RDB$FIELD_SUB_TYPE) + .from(p) + .leftOuterJoin(f).on(p.RDB$FIELD_SOURCE.eq(f.RDB$FIELD_NAME)) + .where(p.RDB$PROCEDURE_NAME.eq(getName())) + .and(p.RDB$PARAMETER_TYPE.eq((short) 1)) + .orderBy(p.RDB$PARAMETER_NUMBER)) { + + DefaultDataTypeDefinition type = new DefaultDataTypeDefinition( + getDatabase(), + getSchema(), + record.getValue("FIELD_TYPE", String.class), + record.getValue("CHARACTER_LENGTH", short.class), + record.getValue(f.RDB$FIELD_PRECISION), + record.getValue("FIELD_SCALE", Integer.class), + record.getValue(p.RDB$NULL_FLAG) == 0, + record.getValue(p.RDB$DEFAULT_SOURCE) != null + ); + + ColumnDefinition column = new DefaultColumnDefinition( + getDatabase().getTable(getSchema(), getName()), + record.getValue(p.RDB$PARAMETER_NAME.trim()), + record.getValue(p.RDB$PARAMETER_NUMBER), + type, + false, + null + ); + + result.add(column); + } + + return result; + } + + @Override + public boolean isTableValuedFunction() { + return true; + } + + @Override + protected List getParameters0() { + return routine.getInParameters(); + } +} diff --git a/jOOQ/src/main/java/org/jooq/impl/AbstractRoutine.java b/jOOQ/src/main/java/org/jooq/impl/AbstractRoutine.java index e10470af77..019864608d 100644 --- a/jOOQ/src/main/java/org/jooq/impl/AbstractRoutine.java +++ b/jOOQ/src/main/java/org/jooq/impl/AbstractRoutine.java @@ -43,6 +43,7 @@ package org.jooq.impl; import static java.lang.Boolean.TRUE; import static org.jooq.Clause.FIELD; import static org.jooq.Clause.FIELD_FUNCTION; +import static org.jooq.SQLDialect.FIREBIRD; // ... import static org.jooq.SQLDialect.POSTGRES; // ... @@ -344,7 +345,12 @@ public abstract class AbstractRoutine extends AbstractQueryPart implements Ro xx xxxxxxx xxx xxxxx xx xxxxxxxxx xxxxxx xxxx xxx xxxx xxxxxxxxx xx xxx xxxxxxxxxx xx xxxxxxxx xx xxx xxxxxx xx [/pro] */ - Utils.consumeResultSets(ctx, listener, results, null); + + // [#2925] Jaybird currently doesn't like fetching OUT parameters and consuming ResultSets + // http://tracker.firebirdsql.org/browse/JDBC-350 + if (ctx.family() != FIREBIRD) + Utils.consumeResultSets(ctx, listener, results, null); + fetchOutParameters(ctx); return 0; } diff --git a/jOOQ/src/main/java/org/jooq/impl/TableImpl.java b/jOOQ/src/main/java/org/jooq/impl/TableImpl.java index 5700de71b7..ad8dcb18e9 100644 --- a/jOOQ/src/main/java/org/jooq/impl/TableImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/TableImpl.java @@ -44,6 +44,7 @@ package org.jooq.impl; import static org.jooq.Clause.TABLE; import static org.jooq.Clause.TABLE_ALIAS; import static org.jooq.Clause.TABLE_REFERENCE; +import static org.jooq.SQLDialect.FIREBIRD; import java.util.Arrays; @@ -143,9 +144,14 @@ public class TableImpl extends AbstractTable { ctx.literal(Utils.getMappedTable(ctx.configuration(), this).getName()); if (parameters != null && ctx.declareTables()) { - ctx.sql("(") - .visit(new QueryPartList>(parameters)) - .sql(")"); + + // [#2925] Some dialects don't like empty parameter lists + if (ctx.family() == FIREBIRD && parameters.length == 0) + ctx.visit(new QueryPartList>(parameters)); + else + ctx.sql("(") + .visit(new QueryPartList>(parameters)) + .sql(")"); } } }