diff --git a/jOOQ/src/main/java/org/jooq/SchemaMapping.java b/jOOQ/src/main/java/org/jooq/SchemaMapping.java index 786f881944..2bbd750269 100644 --- a/jOOQ/src/main/java/org/jooq/SchemaMapping.java +++ b/jOOQ/src/main/java/org/jooq/SchemaMapping.java @@ -40,6 +40,7 @@ package org.jooq; import static org.jooq.impl.DSL.name; import static org.jooq.impl.DSL.schema; import static org.jooq.tools.StringUtils.isBlank; +import static org.jooq.tools.StringUtils.isEmpty; import java.io.Serializable; import java.util.HashMap; @@ -281,7 +282,8 @@ public class SchemaMapping implements Serializable { String catalogName = result.getName(); // [#4642] Don't initialise catalog mapping if not necessary - if (!mapping().getCatalogs().isEmpty()) { + RenderMapping m = mapping(); + if (!m.getCatalogs().isEmpty() || !isEmpty(m.getDefaultCatalog())) { // Lazy initialise catalog mapping if (!getCatalogs().containsKey(catalogName)) { @@ -290,7 +292,7 @@ public class SchemaMapping implements Serializable { // want to use a Configuration and dependent objects in a "thread-safe" manner synchronized (this) { if (!getCatalogs().containsKey(catalogName)) { - for (MappedCatalog c : mapping().getCatalogs()) { + for (MappedCatalog c : m.getCatalogs()) { // A configured mapping was found, add a renamed catalog if (matches(c, catalogName)) { @@ -306,6 +308,11 @@ public class SchemaMapping implements Serializable { } } + // [#13035] Cache the application of the defaultCatalog + if ("".equals(result.getName()) + || result.getName().equals(m.getDefaultCatalog())) + result = null; + // Add mapped catalog or self if no mapping was found getCatalogs().put(catalogName, result); } @@ -315,11 +322,6 @@ public class SchemaMapping implements Serializable { result = getCatalogs().get(catalogName); } - // The configured default catalog is mapped to "null". This prevents - // it from being rendered to SQL - if ("".equals(result.getName()) || result.getName().equals(mapping().getDefaultCatalog())) - result = null; - return result; } @@ -339,21 +341,26 @@ public class SchemaMapping implements Serializable { else if (schema instanceof RenamedSchema) return schema; Schema result = schema; - if (result == null) - result = schema(name("")); - - Catalog catalog = result.getCatalog(); - if (catalog == null) - catalog = DSL.catalog(name("")); - - // [#2089] DefaultSchema has an empty schema name - // [#7498] But we're mapping those names as well - String catalogName = catalog.getName(); - String schemaName = result.getName(); - String key = StringUtils.isEmpty(catalogName) ? schemaName : catalogName + '.' + schemaName; + RenderMapping m = mapping(); // [#4642] Don't initialise schema mapping if not necessary - if (!mapping().getSchemata().isEmpty() || !mapping().getCatalogs().isEmpty()) { + if (!m.getSchemata().isEmpty() || + !m.getCatalogs().isEmpty() || + !isEmpty(m.getDefaultSchema()) || + !isEmpty(m.getDefaultCatalog())) { + + if (result == null) + result = schema(name("")); + + Catalog catalog = result.getCatalog(); + if (catalog == null) + catalog = DSL.catalog(name("")); + + // [#2089] DefaultSchema has an empty schema name + // [#7498] But we're mapping those names as well + String catalogName = catalog.getName(); + String schemaName = result.getName(); + String key = StringUtils.isEmpty(catalogName) ? schemaName : catalogName + '.' + schemaName; // Lazy initialise schema mapping if (!getSchemata().containsKey(key)) { @@ -364,7 +371,7 @@ public class SchemaMapping implements Serializable { if (!getSchemata().containsKey(key)) { catalogLoop: - for (MappedCatalog c : mapping().getCatalogs()) { + for (MappedCatalog c : m.getCatalogs()) { if (matches(c, catalogName)) { for (MappedSchema s : c.getSchemata()) { if (matches(s, schemaName)) { @@ -386,8 +393,8 @@ public class SchemaMapping implements Serializable { } } - if (!(result instanceof RenamedSchema)) - for (MappedSchema s : mapping().getSchemata()) { + if (!(result instanceof RenamedSchema)) { + for (MappedSchema s : m.getSchemata()) { // A configured mapping was found, add a renamed schema if (matches(s, schemaName)) { @@ -395,13 +402,27 @@ public class SchemaMapping implements Serializable { // Ignore self-mappings and void-mappings if (!isBlank(s.getOutput())) if (s.getInput() != null && !s.getOutput().equals(schemaName)) - result = new RenamedSchema(catalog, result, s.getOutput()); + result = new RenamedSchema(map(catalog), result, s.getOutput()); else if (s.getInputExpression() != null) - result = new RenamedSchema(catalog, result, s.getInputExpression().matcher(schemaName).replaceAll(s.getOutput())); + result = new RenamedSchema(map(catalog), result, s.getInputExpression().matcher(schemaName).replaceAll(s.getOutput())); break; } } + } + + // [#13034] Apply defaultCatalog irrespective of defaultSchema and the above mappings + if (result.getCatalog() != null && map(result.getCatalog()) == null) + result = new RenamedSchema(null, result, result.getName()); + + // [#13035] Cache the application of the defaultSchema + if ("".equals(result.getName())) + result = null; + else if (result.getName().equals(m.getDefaultSchema()) + && (result.getCatalog() == null + || "".equals(result.getCatalog().getName()) + || result.getCatalog().getName().equals(m.getDefaultCatalog()))) + result = null; // Add mapped schema or self if no mapping was found getSchemata().put(key, result); @@ -412,15 +433,6 @@ public class SchemaMapping implements Serializable { result = getSchemata().get(key); } - // The configured default schema is mapped to "null". This prevents - // it from being rendered to SQL - if ("".equals(result.getName()) - || result.getName().equals(mapping().getDefaultSchema()) - && (result.getCatalog() == null - || "".equals(result.getCatalog().getName()) - || result.getCatalog().getName().equals(mapping().getDefaultCatalog()))) - result = null; - return result; } diff --git a/jOOQ/src/main/java/org/jooq/impl/AbstractAggregateFunction.java b/jOOQ/src/main/java/org/jooq/impl/AbstractAggregateFunction.java index f865551fbe..c30f29cbd6 100644 --- a/jOOQ/src/main/java/org/jooq/impl/AbstractAggregateFunction.java +++ b/jOOQ/src/main/java/org/jooq/impl/AbstractAggregateFunction.java @@ -240,7 +240,7 @@ implements - ctx.visit(getQualifiedName()); + AbstractFunction.acceptFunctionName(ctx, true, getQualifiedName()); } final void acceptArguments0(Context ctx) { diff --git a/jOOQ/src/main/java/org/jooq/impl/AbstractRoutine.java b/jOOQ/src/main/java/org/jooq/impl/AbstractRoutine.java index 51c8dca853..5e980dc71e 100644 --- a/jOOQ/src/main/java/org/jooq/impl/AbstractRoutine.java +++ b/jOOQ/src/main/java/org/jooq/impl/AbstractRoutine.java @@ -2166,7 +2166,13 @@ implements fields.add(getInValues().get(parameter)); } - Field result = function(name != null ? name(name) : AbstractRoutine.this.getQualifiedName(ctx), returnType, fields.toArray(EMPTY_FIELD)); + // [#13033] Schema mapping has already been applied, don't re-apply it + Field result = new Function<>( + name != null ? name(name) : AbstractRoutine.this.getQualifiedName(ctx), + returnType, + false, + fields.toArray(EMPTY_FIELD) + ); // [#3592] Decrease SQL -> PL/SQL context switches with Oracle Scalar Subquery Caching if (TRUE.equals(settings(ctx.configuration()).isRenderScalarSubqueriesForStoredFunctions())) diff --git a/jOOQ/src/main/java/org/jooq/impl/Function.java b/jOOQ/src/main/java/org/jooq/impl/Function.java index 8c45f8aa1c..3c77798dbd 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Function.java +++ b/jOOQ/src/main/java/org/jooq/impl/Function.java @@ -39,25 +39,18 @@ package org.jooq.impl; import static org.jooq.impl.DSL.unquotedName; import static org.jooq.impl.Tools.EMPTY_FIELD; -import static org.jooq.impl.Tools.camelCase; -import java.util.function.BiFunction; -import java.util.function.Predicate; - -import org.jooq.Context; import org.jooq.DataType; import org.jooq.Field; -import org.jooq.Function1; import org.jooq.Name; import org.jooq.QueryPart; // ... -// ... import org.jooq.impl.QOM.UnmodifiableList; /** * @author Lukas Eder */ -final class Function extends AbstractField implements QOM.Function { +final class Function extends AbstractFunction { private final QueryPartList> arguments; @@ -66,23 +59,18 @@ final class Function extends AbstractField implements QOM.Function { } Function(Name name, DataType type, Field... arguments) { - super(name, type); + this(name, type, true, arguments); + } + + Function(Name name, DataType type, boolean applySchemaMapping, Field... arguments) { + super(name, type, applySchemaMapping); this.arguments = new QueryPartList<>(arguments); } @Override - public final void accept(Context ctx) { - switch (ctx.family()) { - - - - - - default: - ctx.visit(getQualifiedName()).sql('(').visit(arguments).sql(')'); - break; - } + final QueryPart arguments() { + return arguments; } // ------------------------------------------------------------------------- @@ -104,15 +92,6 @@ final class Function extends AbstractField implements QOM.Function { - - - - - - - - - diff --git a/jOOQ/src/main/java/org/jooq/impl/Function1.java b/jOOQ/src/main/java/org/jooq/impl/Function1.java index 3b69514f84..5eb6a16dcb 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Function1.java +++ b/jOOQ/src/main/java/org/jooq/impl/Function1.java @@ -37,44 +37,28 @@ */ package org.jooq.impl; -import static org.jooq.impl.Tools.camelCase; - -import java.util.function.BiFunction; -import java.util.function.Predicate; - -import org.jooq.Context; import org.jooq.DataType; import org.jooq.Field; import org.jooq.Name; import org.jooq.QueryPart; // ... -// ... import org.jooq.impl.QOM.UnmodifiableList; /** * @author Lukas Eder */ -final class Function1 extends AbstractField implements QOM.Function { +final class Function1 extends AbstractFunction { private final Field argument; Function1(Name name, DataType type, Field argument) { - super(name, type); + super(name, type, true); this.argument = argument; } @Override - public final void accept(Context ctx) { - switch (ctx.family()) { - - - - - - default: - ctx.visit(getQualifiedName()).sql('(').visit(argument).sql(')'); - break; - } + final QueryPart arguments() { + return argument; } // ------------------------------------------------------------------------- @@ -100,12 +84,16 @@ final class Function1 extends AbstractField implements QOM.Function { + // ------------------------------------------------------------------------- + // The Object API + // ------------------------------------------------------------------------- - - - - - - - + @Override + public boolean equals(Object that) { + if (that instanceof Function1) + return getQualifiedName().equals(((Function1) that).getQualifiedName()) + && argument.equals(((Function1) that).argument); + else + return super.equals(that); + } }