From 808d3c7ae14123837ea22391727da8919aa76ecd Mon Sep 17 00:00:00 2001 From: Lukas Eder Date: Wed, 5 Feb 2020 13:48:17 +0100 Subject: [PATCH] [jOOQ/jOOQ#9791] Meta.getTables() returns the same table for each catalog in SQL Server --- .../src/main/java/org/jooq/impl/MetaImpl.java | 97 +++++++++++-------- 1 file changed, 57 insertions(+), 40 deletions(-) diff --git a/jOOQ/src/main/java/org/jooq/impl/MetaImpl.java b/jOOQ/src/main/java/org/jooq/impl/MetaImpl.java index 18f181a6db..0b75626b0c 100644 --- a/jOOQ/src/main/java/org/jooq/impl/MetaImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/MetaImpl.java @@ -160,7 +160,7 @@ final class MetaImpl extends AbstractMeta { super(configuration); this.databaseMetaData = databaseMetaData; - this.inverseSchemaCatalog = INVERSE_SCHEMA_CATALOG.contains(configuration.family()); + this.inverseSchemaCatalog = INVERSE_SCHEMA_CATALOG.contains(family()); } private interface MetaFunction { @@ -291,6 +291,12 @@ final class MetaImpl extends AbstractMeta { @Override public Result run(DatabaseMetaData meta) throws SQLException { return dsl().fetch( + + + + + + meta.getSchemas(), // [#2681] Work around a flaw in the MySQL JDBC driver @@ -346,7 +352,7 @@ final class MetaImpl extends AbstractMeta { public Result run(DatabaseMetaData meta) throws SQLException { String[] types = null; - switch (configuration.family()) { + switch (family()) { // [#3977] PostgreSQL returns other object types, too @@ -384,13 +390,15 @@ final class MetaImpl extends AbstractMeta { - if (!inverseSchemaCatalog) - rs = meta.getTables(null, getName(), "%", types); + // [#2760] MySQL JDBC confuses "catalog" and "schema" - else + else if (inverseSchemaCatalog) rs = meta.getTables(getName(), null, "%", types); + else + rs = meta.getTables(null, getName(), "%", types); + return dsl().fetch( rs, @@ -409,11 +417,7 @@ final class MetaImpl extends AbstractMeta { String schema = table.get(1, String.class); String name = table.get(2, String.class); - // [#2760] MySQL JDBC confuses "catalog" and "schema" - result.add(new MetaTable(name, this, getColumns( - inverseSchemaCatalog ? catalog : schema, - name - ))); + result.add(new MetaTable(name, this, getColumns(catalog, schema, name))); // TODO: Find a more efficient way to do this // Result pkColumns = executor.fetch(meta().getPrimaryKeys(catalog, schema, name)) @@ -426,50 +430,52 @@ final class MetaImpl extends AbstractMeta { } @SuppressWarnings("unchecked") - private final Result getColumns(String schema, String table) { + private final Result getColumns(String catalog, String schema, String table) { // SQLite JDBC's DatabaseMetaData.getColumns() can only return a single // table's columns - if (columnCache == null && configuration.family() != SQLITE) { - Result columns = getColumns0(schema, "%"); + if (columnCache == null && family() != SQLITE) { + Result columns = getColumns0(catalog, schema, "%"); Field tableCat = (Field) columns.field(0); // TABLE_CAT Field tableSchem = (Field) columns.field(1); // TABLE_SCHEM Field tableName = (Field) columns.field(2); // TABLE_NAME - Map> groups = - columns.intoGroups(new Field[] { - inverseSchemaCatalog ? tableCat : tableSchem, - tableName - }); - + Map> groups = columns.intoGroups(new Field[] { tableCat, tableSchem, tableName }); columnCache = new LinkedHashMap<>(); for (Entry> entry : groups.entrySet()) { Record key = entry.getKey(); Result value = entry.getValue(); - columnCache.put(name(key.get(inverseSchemaCatalog ? tableCat : tableSchem), key.get(tableName)), value); + columnCache.put(name(key.get(tableCat), key.get(tableSchem), key.get(tableName)), value); } } if (columnCache != null) - return columnCache.get(name(schema, table)); + return columnCache.get(name(catalog, schema, table)); else - return getColumns0(schema, table); + return getColumns0(catalog, schema, table); } - private final Result getColumns0(final String schema, final String table) { + private final Result getColumns0(final String catalog, final String schema, final String table) { return meta(new MetaFunction() { @Override public Result run(DatabaseMetaData meta) throws SQLException { ResultSet rs; - if (!inverseSchemaCatalog) + // [#2760] MySQL JDBC confuses "catalog" and "schema" + if (inverseSchemaCatalog) + rs = meta.getColumns(catalog, null, table, "%"); + + + + + + + + else rs = meta.getColumns(null, schema, table, "%"); - // [#2760] MySQL JDBC confuses "catalog" and "schema" - else - rs = meta.getColumns(schema, null, table, "%"); // Work around a bug in the SQL Server JDBC driver by // coercing data types to the expected types @@ -571,13 +577,19 @@ final class MetaImpl extends AbstractMeta { public Result run(DatabaseMetaData meta) throws SQLException { ResultSet rs; - if (!inverseSchemaCatalog) - rs = meta.getIndexInfo(null, schema, getName(), false, true); - // [#2760] MySQL JDBC confuses "catalog" and "schema" - else + if (inverseSchemaCatalog) rs = meta.getIndexInfo(schema, null, getName(), false, true); + + + + + + + else + rs = meta.getIndexInfo(null, schema, getName(), false, true); + return dsl().fetch( rs, String.class, // TABLE_CAT @@ -610,7 +622,6 @@ final class MetaImpl extends AbstractMeta { @Override public final UniqueKey getPrimaryKey() { - SQLDialect family = configuration.family(); @@ -623,13 +634,19 @@ final class MetaImpl extends AbstractMeta { public Result run(DatabaseMetaData meta) throws SQLException { ResultSet rs; - if (!inverseSchemaCatalog) - rs = meta.getPrimaryKeys(null, schema, getName()); - // [#2760] MySQL JDBC confuses "catalog" and "schema" - else + if (inverseSchemaCatalog) rs = meta.getPrimaryKeys(schema, null, getName()); + + + + + + + else + rs = meta.getPrimaryKeys(null, schema, getName()); + return dsl().fetch( rs, String.class, // TABLE_CAT @@ -765,7 +782,7 @@ final class MetaImpl extends AbstractMeta { f[i] = (TableField) field(name); // [#5097] Work around a bug in the Xerial JDBC driver for SQLite - if (f[i] == null && configuration.family() == SQLITE) + if (f[i] == null && family() == SQLITE) // [#2656] Use native support for case-insensitive column // lookup, once this is implemented @@ -844,7 +861,7 @@ final class MetaImpl extends AbstractMeta { // TODO: Exception handling should be moved inside SQLDataType DataType type = null; try { - type = DefaultDataType.getDataType(configuration.family(), typeName, precision, scale); + type = DefaultDataType.getDataType(family(), typeName, precision, scale); // JDBC doesn't distinguish between precision and length type = type.precision(precision, scale); @@ -859,11 +876,11 @@ final class MetaImpl extends AbstractMeta { try { // [#7194] Some databases report all default values as expressions, not as values - if (EXPRESSION_COLUMN_DEFAULT.contains(configuration.family())) + if (EXPRESSION_COLUMN_DEFAULT.contains(family())) type = type.defaultValue(DSL.field(defaultValue, type)); // [#5574] MySQL mixes constant value expressions with other column expressions here - else if (CURRENT_TIMESTAMP_COLUMN_DEFAULT.contains(configuration.family()) && "CURRENT_TIMESTAMP".equalsIgnoreCase(defaultValue)) + else if (CURRENT_TIMESTAMP_COLUMN_DEFAULT.contains(family()) && "CURRENT_TIMESTAMP".equalsIgnoreCase(defaultValue)) type = type.defaultValue(DSL.field(defaultValue, type)); else type = type.defaultValue(DSL.inline(defaultValue, type));