diff --git a/jOOQ/src/main/java/org/jooq/DSLContext.java b/jOOQ/src/main/java/org/jooq/DSLContext.java index 521733aa64..e4a7a6673d 100644 --- a/jOOQ/src/main/java/org/jooq/DSLContext.java +++ b/jOOQ/src/main/java/org/jooq/DSLContext.java @@ -44,6 +44,7 @@ package org.jooq; // ... // ... // ... +// ... import static org.jooq.SQLDialect.CUBRID; // ... import static org.jooq.SQLDialect.DERBY; diff --git a/jOOQ/src/main/java/org/jooq/impl/AbstractField.java b/jOOQ/src/main/java/org/jooq/impl/AbstractField.java index 8a70808b2c..ade0588aa0 100644 --- a/jOOQ/src/main/java/org/jooq/impl/AbstractField.java +++ b/jOOQ/src/main/java/org/jooq/impl/AbstractField.java @@ -635,8 +635,8 @@ abstract class AbstractField extends AbstractTypedNamed implements Field> TRUE_VALUES = Tools.inline(Convert.TRUE_VALUES.toArray(EMPTY_STRING)); - static final List> FALSE_VALUES = Tools.inline(Convert.FALSE_VALUES.toArray(EMPTY_STRING)); + static final List> TRUE_VALUES = Tools.mapToList(Convert.TRUE_VALUES, v -> DSL.inline(v)); + static final List> FALSE_VALUES = Tools.mapToList(Convert.FALSE_VALUES, v -> DSL.inline(v)); } @SuppressWarnings({ "unchecked" }) diff --git a/jOOQ/src/main/java/org/jooq/impl/AbstractTable.java b/jOOQ/src/main/java/org/jooq/impl/AbstractTable.java index b5955b07d6..3e9d1937ce 100644 --- a/jOOQ/src/main/java/org/jooq/impl/AbstractTable.java +++ b/jOOQ/src/main/java/org/jooq/impl/AbstractTable.java @@ -996,7 +996,7 @@ abstract class AbstractTable extends AbstractNamed implements @Override public final Table as(Table otherTable, Field... otherFields) { - return as(otherTable.getUnqualifiedName(), Tools.fieldNames(otherFields)); + return as(otherTable.getUnqualifiedName(), Tools.map(otherFields, Field::getUnqualifiedName, Name[]::new)); } @Override diff --git a/jOOQ/src/main/java/org/jooq/impl/Alias.java b/jOOQ/src/main/java/org/jooq/impl/Alias.java index f583244656..c22d43b1c0 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Alias.java +++ b/jOOQ/src/main/java/org/jooq/impl/Alias.java @@ -79,6 +79,7 @@ import static org.jooq.impl.DSL.select; import static org.jooq.impl.Keywords.K_AS; import static org.jooq.impl.QueryPartListView.wrap; import static org.jooq.impl.Tools.fieldNames; +import static org.jooq.impl.Tools.mapToList; import static org.jooq.impl.Tools.visitSubquery; import static org.jooq.impl.Tools.BooleanDataKey.DATA_AS_REQUIRED; import static org.jooq.impl.Tools.BooleanDataKey.DATA_UNALIAS_ALIASED_EXPRESSIONS; @@ -88,6 +89,7 @@ import static org.jooq.impl.Values.NO_SUPPORT_VALUES; import java.util.HashSet; import java.util.List; import java.util.Set; +import java.util.function.Predicate; import org.jooq.Clause; import org.jooq.Context; @@ -120,13 +122,13 @@ final class Alias extends AbstractQueryPart { final Q wrapping; final Name alias; final Name[] fieldAliases; - final boolean wrapInParentheses; + final Predicate> wrapInParentheses; Alias(Q wrapped, Q wrapping, Name alias) { - this(wrapped, wrapping, alias, null, false); + this(wrapped, wrapping, alias, null, c -> false); } - Alias(Q wrapped, Q wrapping, Name alias, Name[] fieldAliases, boolean wrapInParentheses) { + Alias(Q wrapped, Q wrapping, Name alias, Name[] fieldAliases, Predicate> wrapInParentheses) { this.wrapped = wrapped; this.wrapping = wrapping; this.alias = alias; @@ -230,7 +232,7 @@ final class Alias extends AbstractQueryPart { // [#9486] H2 cannot handle duplicate column names in derived tables, despite derived column lists // See: https://github.com/h2database/h2database/issues/2532 if (SUPPORT_DERIVED_COLUMN_NAMES_SPECIAL3.contains(dialect)) { - List names = fieldNames(select); + List names = mapToList(select, Field::getUnqualifiedName); if (names.size() > 0 && names.size() == new HashSet<>(names).size()) { toSQLWrapped(context); @@ -346,9 +348,11 @@ final class Alias extends AbstractQueryPart { } private final void toSQLWrapped(Context ctx) { - ctx.sql(wrapInParentheses ? "(" : "") + boolean wrap = wrapInParentheses.test(ctx); + + ctx.sql(wrap ? "(" : "") .visit(wrapped) - .sql(wrapInParentheses ? ")" : ""); + .sql(wrap ? ")" : ""); } private final void toSQLDerivedColumnList(Context ctx) { diff --git a/jOOQ/src/main/java/org/jooq/impl/AliasedSelect.java b/jOOQ/src/main/java/org/jooq/impl/AliasedSelect.java index 77f53e12ec..0622ee4990 100644 --- a/jOOQ/src/main/java/org/jooq/impl/AliasedSelect.java +++ b/jOOQ/src/main/java/org/jooq/impl/AliasedSelect.java @@ -90,12 +90,12 @@ final class AliasedSelect extends AbstractTable { if (q != null && (!q.getOrderBy().isEmpty() || Tools.hasEmbeddedFields(q.getSelect()))) return query.asTable(alias, aliases); else - return new TableAlias<>(this, alias, true); + return new TableAlias<>(this, alias, c -> true); } @Override public final Table as(Name alias, Name... fieldAliases) { - return new TableAlias<>(this, alias, fieldAliases, true); + return new TableAlias<>(this, alias, fieldAliases, c -> true); } @Override diff --git a/jOOQ/src/main/java/org/jooq/impl/CreateTableImpl.java b/jOOQ/src/main/java/org/jooq/impl/CreateTableImpl.java index e05d33bbfe..7ab416674e 100644 --- a/jOOQ/src/main/java/org/jooq/impl/CreateTableImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/CreateTableImpl.java @@ -76,6 +76,7 @@ import static org.jooq.impl.DSL.asterisk; import static org.jooq.impl.DSL.commentOnTable; import static org.jooq.impl.DSL.createIndex; import static org.jooq.impl.DSL.field; +import static org.jooq.impl.DSL.inline; import static org.jooq.impl.DSL.insertInto; import static org.jooq.impl.DSL.name; import static org.jooq.impl.DSL.select; @@ -99,10 +100,9 @@ import static org.jooq.impl.Keywords.K_WITH_NO_DATA; import static org.jooq.impl.SQLDataType.INTEGER; import static org.jooq.impl.Tools.EMPTY_FIELD; import static org.jooq.impl.Tools.begin; -import static org.jooq.impl.Tools.beginExecuteImmediate; -import static org.jooq.impl.Tools.endExecuteImmediate; -import static org.jooq.impl.Tools.enumLiterals; +import static org.jooq.impl.Tools.enums; import static org.jooq.impl.Tools.executeImmediate; +import static org.jooq.impl.Tools.mapToList; import static org.jooq.impl.Tools.storedEnumType; import static org.jooq.impl.Tools.tryCatch; import static org.jooq.impl.Tools.BooleanDataKey.DATA_SELECT_NO_DATA; @@ -138,7 +138,6 @@ import org.jooq.Select; import org.jooq.Table; import org.jooq.TableOptions.OnCommit; -import org.jetbrains.annotations.NotNull; /** * @author Lukas Eder @@ -549,11 +548,12 @@ final class CreateTableImpl extends AbstractDDLQuery implements if (EMULATE_STORED_ENUM_TYPES_AS_CHECK.contains(ctx.dialect()) || !storedEnumType(enumType)) { Field field = columnFields.get(i); + List> literals = mapToList(enums(enumType.getType()), e -> inline(e.getLiteral())); ctx.sql(',') .formatSeparator() .visit(DSL.constraint(table.getName() + "_" + field.getName() + "_chk") - .check(((Field) field).in(Tools.inline(enumLiterals(enumType.getType()))))); + .check(((Field) field).in(literals))); } } } diff --git a/jOOQ/src/main/java/org/jooq/impl/CreateTypeImpl.java b/jOOQ/src/main/java/org/jooq/impl/CreateTypeImpl.java index 20c5c824de..8c7b06c9b7 100644 --- a/jOOQ/src/main/java/org/jooq/impl/CreateTypeImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/CreateTypeImpl.java @@ -85,7 +85,7 @@ final class CreateTypeImpl extends AbstractDDLQuery implements @Override public final CreateTypeFinalStep asEnum(String... v) { - return asEnum(Tools.inline(v)); + return asEnum(Tools.mapToList(v, s -> DSL.inline(s))); } @SafeVarargs diff --git a/jOOQ/src/main/java/org/jooq/impl/CreateViewImpl.java b/jOOQ/src/main/java/org/jooq/impl/CreateViewImpl.java index 306c96b8ee..b39aba176c 100644 --- a/jOOQ/src/main/java/org/jooq/impl/CreateViewImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/CreateViewImpl.java @@ -68,6 +68,7 @@ import static org.jooq.impl.Keywords.K_REPLACE; import static org.jooq.impl.Keywords.K_VIEW; import static org.jooq.impl.QueryPartListView.wrap; import static org.jooq.impl.Tools.EMPTY_FIELD; +import static org.jooq.impl.Tools.map; import static org.jooq.impl.Tools.tryCatch; import java.util.List; @@ -81,6 +82,7 @@ import org.jooq.CreateViewAsStep; import org.jooq.CreateViewFinalStep; import org.jooq.DSLContext; import org.jooq.Field; +import org.jooq.Name; import org.jooq.QueryPart; import org.jooq.Record; import org.jooq.ResultQuery; @@ -88,7 +90,6 @@ import org.jooq.SQL; import org.jooq.SQLDialect; import org.jooq.Select; import org.jooq.Table; -import org.jooq.conf.ParamType; /** * @author Lukas Eder @@ -265,7 +266,7 @@ final class CreateViewImpl extends AbstractDDLQuery implements // [#4806] CREATE VIEW doesn't accept parameters in most databases .visit( rename && !renameSupported - ? selectFrom(parsed().asTable(name("t"), Tools.fieldNames(f))) + ? selectFrom(parsed().asTable(name("t"), map(f, Field::getUnqualifiedName, Name[]::new))) : select, INLINED ) diff --git a/jOOQ/src/main/java/org/jooq/impl/DSL.java b/jOOQ/src/main/java/org/jooq/impl/DSL.java index 1ea990b7ae..b940c8c271 100644 --- a/jOOQ/src/main/java/org/jooq/impl/DSL.java +++ b/jOOQ/src/main/java/org/jooq/impl/DSL.java @@ -47,6 +47,7 @@ import static org.jooq.Operator.OR; // ... // ... // ... +// ... import static org.jooq.SQLDialect.CUBRID; // ... // ... @@ -351,6 +352,7 @@ import org.jooq.Row8; import org.jooq.Row9; import org.jooq.RowCountQuery; import org.jooq.RowN; +import org.jooq.Rows; import org.jooq.SQL; import org.jooq.SQLDialect; import org.jooq.Schema; @@ -19294,7 +19296,7 @@ public class DSL { @NotNull @Support({ H2, MARIADB, MYSQL, POSTGRES }) public static JSONObjectNullStep jsonObject(Field... entries) { - return new JSONObject<>(SQLDataType.JSON, Tools.jsonEntries(entries)); + return new JSONObject<>(SQLDataType.JSON, Tools.mapToList(entries, f -> jsonEntry(f))); } /** @@ -19321,7 +19323,7 @@ public class DSL { @NotNull @Support({ H2, MARIADB, MYSQL, POSTGRES }) public static JSONObjectNullStep jsonbObject(Field... entries) { - return new JSONObject<>(SQLDataType.JSONB, Tools.jsonEntries(entries)); + return new JSONObject<>(SQLDataType.JSONB, Tools.mapToList(entries, f -> jsonEntry(f))); } /** @@ -27529,6 +27531,72 @@ public class DSL { return new Values(rows).as("v", columns); } + /** + * Create a VALUES() expression of degree 1. + *

+ * The VALUES() constructor is a tool supported by some + * databases to allow for constructing tables from constant values. + *

+ * If a database doesn't support the VALUES() constructor, it + * can be emulated using SELECT .. UNION ALL ... The following + * expressions are equivalent: + *

+ *


+     * -- Using VALUES() constructor
+     * VALUES(val1_1),
+     *       (val2_1),
+     *       (val3_1)
+     * AS "v"("c1"  )
+     *
+     * -- Using UNION ALL
+     * SELECT val1_1 AS "c1") UNION ALL
+     * SELECT val1_1 AS "c1") UNION ALL
+     * SELECT val1_1 AS "c1")
+     * 
+ *

+ * Use {@link Table#as(String, String...)} to rename the resulting table and + * its columns. + */ + @SafeVarargs + @NotNull + @Support + public static Table> values(T... values) { + return values(Tools.map(values, t -> row(t), Row1[]::new)); + } + + /** + * Create a VALUES() expression of degree 1. + *

+ * The VALUES() constructor is a tool supported by some + * databases to allow for constructing tables from constant values. + *

+ * If a database doesn't support the VALUES() constructor, it + * can be emulated using SELECT .. UNION ALL ... The following + * expressions are equivalent: + *

+ *


+     * -- Using VALUES() constructor
+     * VALUES(val1_1),
+     *       (val2_1),
+     *       (val3_1)
+     * AS "v"("c1"  )
+     *
+     * -- Using UNION ALL
+     * SELECT val1_1 AS "c1") UNION ALL
+     * SELECT val1_1 AS "c1") UNION ALL
+     * SELECT val1_1 AS "c1")
+     * 
+ *

+ * Use {@link Table#as(String, String...)} to rename the resulting table and + * its columns. + */ + @SafeVarargs + @NotNull + @Support + public static Table> values(Field... values) { + return values(Tools.map(values, f -> row(f), Row1[]::new)); + } + /** diff --git a/jOOQ/src/main/java/org/jooq/impl/DerivedTable.java b/jOOQ/src/main/java/org/jooq/impl/DerivedTable.java index fe21421faf..511fbed2b6 100644 --- a/jOOQ/src/main/java/org/jooq/impl/DerivedTable.java +++ b/jOOQ/src/main/java/org/jooq/impl/DerivedTable.java @@ -70,12 +70,12 @@ class DerivedTable extends AbstractTable { @Override public final Table as(Name alias) { - return new TableAlias<>(this, alias, true); + return new TableAlias<>(this, alias, c -> true); } @Override public final Table as(Name alias, Name... fieldAliases) { - return new TableAlias<>(this, alias, fieldAliases, true); + return new TableAlias<>(this, alias, fieldAliases, c -> true); } @Override diff --git a/jOOQ/src/main/java/org/jooq/impl/InsertQueryImpl.java b/jOOQ/src/main/java/org/jooq/impl/InsertQueryImpl.java index 59bd8487b2..ccf1a3d85f 100644 --- a/jOOQ/src/main/java/org/jooq/impl/InsertQueryImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/InsertQueryImpl.java @@ -818,7 +818,7 @@ final class InsertQueryImpl extends AbstractStoreQuery impl // [#6375] INSERT .. VALUES and INSERT .. SELECT distinction also in MERGE Table t; if (s != null) { - t = s.asTable("t", fieldNameStrings(insertMaps.fields().toArray(EMPTY_FIELD))); + t = s.asTable("t", Tools.map(insertMaps.fields(), Field::getName, String[]::new)); if (NO_SUPPORT_DERIVED_COLUMN_LIST_IN_MERGE_USING.contains(configuration.dialect())) t = selectFrom(t).asTable("t"); diff --git a/jOOQ/src/main/java/org/jooq/impl/Interpreter.java b/jOOQ/src/main/java/org/jooq/impl/Interpreter.java index 74edbcf891..f3e5d7fee1 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Interpreter.java +++ b/jOOQ/src/main/java/org/jooq/impl/Interpreter.java @@ -52,6 +52,7 @@ import static org.jooq.impl.SQLDataType.BIGINT; import static org.jooq.impl.Tools.EMPTY_FIELD; import static org.jooq.impl.Tools.dataTypes; import static org.jooq.impl.Tools.intersect; +import static org.jooq.impl.Tools.mapToList; import static org.jooq.impl.Tools.normaliseNameCase; import static org.jooq.impl.Tools.reverseIterable; import static org.jooq.tools.StringUtils.defaultIfNull; @@ -59,6 +60,7 @@ import static org.jooq.tools.StringUtils.defaultIfNull; import java.util.AbstractList; import java.util.ArrayDeque; import java.util.ArrayList; +import java.util.Collection; import java.util.Deque; import java.util.HashMap; import java.util.HashSet; @@ -807,7 +809,7 @@ final class Interpreter { List> columnTypes = query.$select() != null ? dataTypes(query.$select()) - : asList(dataTypes(query.$fields())); + : mapToList(query.$fields(), f -> f.getDataType()); newTable(table, schema, asList(query.$fields()), columnTypes, query.$select(), null, TableOptions.view(query.$select())); } @@ -957,7 +959,7 @@ final class Interpreter { throw notExists(table); MutableIndex existing = find(mt.indexes, index); - List mtf = mt.sortFields(Tools.sortFields(query.$on())); + List mtf = mt.sortFields(query.$on()); if (existing != null) { if (!query.$createIndexIfNotExists()) @@ -1711,7 +1713,7 @@ final class Interpreter { return result; } - final List sortFields(List> ofs) { + final List sortFields(Collection> ofs) { List result = new ArrayList<>(); for (OrderField of : ofs) { diff --git a/jOOQ/src/main/java/org/jooq/impl/JoinTable.java b/jOOQ/src/main/java/org/jooq/impl/JoinTable.java index 1e1337202b..876d37a56f 100755 --- a/jOOQ/src/main/java/org/jooq/impl/JoinTable.java +++ b/jOOQ/src/main/java/org/jooq/impl/JoinTable.java @@ -535,12 +535,12 @@ implements @Override public final Table as(Name alias) { - return new TableAlias<>(this, alias, true); + return new TableAlias<>(this, alias, c -> true); } @Override public final Table as(Name alias, Name... fieldAliases) { - return new TableAlias<>(this, alias, fieldAliases, true); + return new TableAlias<>(this, alias, fieldAliases, c -> true); } @Override diff --git a/jOOQ/src/main/java/org/jooq/impl/ParsingConnection.java b/jOOQ/src/main/java/org/jooq/impl/ParsingConnection.java index f8ef1ba9e4..a5978eda41 100644 --- a/jOOQ/src/main/java/org/jooq/impl/ParsingConnection.java +++ b/jOOQ/src/main/java/org/jooq/impl/ParsingConnection.java @@ -41,6 +41,7 @@ import static java.util.Arrays.asList; import static java.util.Collections.emptyList; import static org.jooq.impl.Tools.EMPTY_PARAM; import static org.jooq.impl.Tools.dataTypes; +import static org.jooq.impl.Tools.mapToList; import java.sql.CallableStatement; import java.sql.PreparedStatement; @@ -132,7 +133,7 @@ final class ParsingConnection extends DefaultConnection { return new CacheValue(configuration, sql, bindValues); }, CacheType.CACHE_PARSING_CONNECTION, - () -> Cache.key(sql, asList(dataTypes(nonNull(bindValues)))) + () -> Cache.key(sql, mapToList(nonNull(bindValues), f -> f.getDataType())) ).rendered(bindValues); log.debug("Translating to", result.sql); diff --git a/jOOQ/src/main/java/org/jooq/impl/Pivot.java b/jOOQ/src/main/java/org/jooq/impl/Pivot.java index 67360a6034..a979341103 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Pivot.java +++ b/jOOQ/src/main/java/org/jooq/impl/Pivot.java @@ -349,5 +349,6 @@ package org.jooq.impl; + diff --git a/jOOQ/src/main/java/org/jooq/impl/R2DBC.java b/jOOQ/src/main/java/org/jooq/impl/R2DBC.java index 43701449cf..dfad8dc889 100644 --- a/jOOQ/src/main/java/org/jooq/impl/R2DBC.java +++ b/jOOQ/src/main/java/org/jooq/impl/R2DBC.java @@ -419,7 +419,7 @@ final class R2DBC { && !q2.nativeSupportReturning(configuration.dsl())) - stmt.returnGeneratedValues(fieldNameStrings(q2.returningResolvedAsterisks.toArray(EMPTY_FIELD))); + stmt.returnGeneratedValues(Tools.map(q2.returningResolvedAsterisks, Field::getName, String[]::new)); stmt.execute().subscribe(resultSubscriber.apply(query, downstream)); } diff --git a/jOOQ/src/main/java/org/jooq/impl/SelectQueryImpl.java b/jOOQ/src/main/java/org/jooq/impl/SelectQueryImpl.java index 5166938d5d..2c2e529a19 100644 --- a/jOOQ/src/main/java/org/jooq/impl/SelectQueryImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/SelectQueryImpl.java @@ -39,6 +39,7 @@ package org.jooq.impl; import static java.lang.Boolean.TRUE; import static java.util.Arrays.asList; +import static java.util.Collections.emptyList; import static java.util.function.Function.identity; import static org.jooq.Clause.SELECT; import static org.jooq.Clause.SELECT_CONNECT_BY; @@ -183,6 +184,7 @@ import static org.jooq.impl.Tools.fieldArray; import static org.jooq.impl.Tools.hasAmbiguousNames; import static org.jooq.impl.Tools.isNotEmpty; import static org.jooq.impl.Tools.isWindow; +import static org.jooq.impl.Tools.mapToList; import static org.jooq.impl.Tools.qualify; import static org.jooq.impl.Tools.recordType; import static org.jooq.impl.Tools.search; @@ -1392,7 +1394,7 @@ final class SelectQueryImpl extends AbstractResultQuery imp DSL.select(qualify(table(name("t")), select)) .from(copy.asTable("t")) .where(rn.eq(one())) - .orderBy(unqualified(orderBy.toArray(EMPTY_SORTFIELD))); + .orderBy(mapToList(orderBy, o -> unqualified(o))); if (limit.numberOfRows != null) { SelectLimitPercentStep s2 = s1.limit((Param) limit.numberOfRows); @@ -3211,7 +3213,7 @@ final class SelectQueryImpl extends AbstractResultQuery imp // [#7222] Workaround for https://issues.apache.org/jira/browse/DERBY-6983 if (ctx.family() == DERBY) - ctx.visit(new SelectFieldList<>(Tools.unqualified(fields))); + ctx.visit(new SelectFieldList<>(mapToList(fields, Tools::unqualified))); else ctx.sql('*'); @@ -3711,6 +3713,8 @@ final class SelectQueryImpl extends AbstractResultQuery imp + + return f; } diff --git a/jOOQ/src/main/java/org/jooq/impl/TableAlias.java b/jOOQ/src/main/java/org/jooq/impl/TableAlias.java index 865c173bef..e2f8a676b0 100644 --- a/jOOQ/src/main/java/org/jooq/impl/TableAlias.java +++ b/jOOQ/src/main/java/org/jooq/impl/TableAlias.java @@ -40,6 +40,7 @@ package org.jooq.impl; import java.util.ArrayList; import java.util.List; +import java.util.function.Predicate; import org.jooq.Clause; import org.jooq.Context; @@ -63,18 +64,18 @@ final class TableAlias extends AbstractTable { final FieldsImpl aliasedFields; TableAlias(Table table, Name alias) { - this(table, alias, null, false); + this(table, alias, null, c -> false); } - TableAlias(Table table, Name alias, boolean wrapInParentheses) { + TableAlias(Table table, Name alias, Predicate> wrapInParentheses) { this(table, alias, null, wrapInParentheses); } TableAlias(Table table, Name alias, Name[] fieldAliases) { - this(table, alias, fieldAliases, false); + this(table, alias, fieldAliases, c -> false); } - TableAlias(Table table, Name alias, Name[] fieldAliases, boolean wrapInParentheses) { + TableAlias(Table table, Name alias, Name[] fieldAliases, Predicate> wrapInParentheses) { super(table.getOptions(), alias, table.getSchema()); this.alias = new Alias<>(table, this, alias, fieldAliases, wrapInParentheses); diff --git a/jOOQ/src/main/java/org/jooq/impl/Tools.java b/jOOQ/src/main/java/org/jooq/impl/Tools.java index 72f328cc9a..5a4bbe977b 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Tools.java +++ b/jOOQ/src/main/java/org/jooq/impl/Tools.java @@ -103,7 +103,6 @@ import static org.jooq.impl.DSL.asterisk; import static org.jooq.impl.DSL.concat; import static org.jooq.impl.DSL.escape; import static org.jooq.impl.DSL.getDataType; -import static org.jooq.impl.DSL.jsonEntry; import static org.jooq.impl.DSL.keyword; import static org.jooq.impl.DSL.name; import static org.jooq.impl.DSL.noCondition; @@ -218,6 +217,8 @@ import java.util.concurrent.ForkJoinPool; import java.util.concurrent.ForkJoinPool.ManagedBlocker; import java.util.function.BiFunction; import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.IntFunction; import java.util.function.Predicate; import java.util.function.Supplier; import java.util.regex.Matcher; @@ -280,7 +281,6 @@ import org.jooq.Table; import org.jooq.TableField; import org.jooq.TableRecord; import org.jooq.UDT; -import org.jooq.UDTRecord; import org.jooq.UpdatableRecord; import org.jooq.XML; import org.jooq.conf.BackslashEscaping; @@ -1212,30 +1212,7 @@ final class Tools { // ------------------------------------------------------------------------ static final DataType[] dataTypes(Class[] types) { - if (types == null) - return null; - - DataType[] result = new DataType[types.length]; - - for (int i = 0; i < types.length; i++) - if (types[i] != null) - result[i] = getDataType(types[i]); - else - result[i] = getDataType(Object.class); - - return result; - } - - static final DataType[] dataTypes(Field[] fields) { - if (fields == null) - return null; - - DataType[] result = new DataType[fields.length]; - - for (int i = 0; i < fields.length; i++) - result[i] = fields[i].getDataType(); - - return result; + return map(types, t -> t != null ? getDataType(t) : getDataType(Object.class), DataType[]::new); } // ------------------------------------------------------------------------ @@ -1252,29 +1229,14 @@ final class Tools { } static final SortField[] sortFields(OrderField[] fields) { - if (fields == null) - return null; - if (fields instanceof SortField[]) return (SortField[]) fields; - - SortField[] result = new SortField[fields.length]; - for (int i = 0; i < fields.length; i++) - result[i] = sortField(fields[i]); - - return result; + else + return map(fields, o -> sortField(o), SortField[]::new); } static final List> sortFields(Collection> fields) { - if (fields == null) - return null; - - int size = fields.size(); - List> result = new ArrayList<>(size); - for (OrderField field : fields) - result.add(sortField(field)); - - return result; + return mapToList(fields, o -> sortField(o)); } static final String fieldNameString(int index) { @@ -1303,42 +1265,6 @@ final class Tools { return result; } - static final Name[] fieldNames(Field[] fields) { - if (fields == null) - return null; - - Name[] result = new Name[fields.length]; - - for (int i = 0; i < fields.length; i++) - result[i] = fields[i].getUnqualifiedName(); - - return result; - } - - static final List fieldNames(Collection> fields) { - if (fields == null) - return null; - - List result = new ArrayList<>(fields.size()); - - for (Field field : fields) - result.add(field.getUnqualifiedName()); - - return result; - } - - static final String[] fieldNameStrings(Field[] fields) { - if (fields == null) - return null; - - String[] result = new String[fields.length]; - - for (int i = 0; i < fields.length; i++) - result[i] = fields[i].getName(); - - return result; - } - static final Field[] fields(int length) { return fields(length, SQLDataType.OTHER); } @@ -1353,30 +1279,6 @@ final class Tools { return result; } - static final Field[] unqualified(Field[] fields) { - if (fields == null) - return null; - - Field[] result = new Field[fields.length]; - - for (int i = 0; i < fields.length; i++) - result[i] = unqualified(fields[i]); - - return result; - } - - static final List> unqualified(Collection> fields) { - if (fields == null) - return null; - - List> result = new ArrayList<>(fields.size()); - - for (Field field : fields) - result.add(unqualified(field)); - - return result; - } - static final Field unqualified(Field field) { return DSL.field(field.getUnqualifiedName(), field.getDataType()); } @@ -1386,28 +1288,8 @@ final class Tools { return i.transform(unqualified(i.getField())); } - static final SortField[] unqualified(SortField[] fields) { - if (fields == null) - return null; - - SortField[] result = new SortField[fields.length]; - - for (int i = 0; i < result.length; i++) - result[i] = unqualified(fields[i]); - - return result; - } - static final List> unaliasedFields(Collection> fields) { - if (fields == null) - return null; - - List> result = new ArrayList<>(fields.size()); - int i = 0; - for (Field field : fields) - result.add(DSL.field(fieldName(i++), field.getDataType()).as(field)); - - return result; + return mapToList(fields, (f, i) -> DSL.field(fieldName(i), f.getDataType()).as(f)); } static final ReferenceImpl aliasedKey(ForeignKey key, Table child, Table parent) { @@ -1426,19 +1308,7 @@ final class Tools { } static final List> aliasedFields(Collection> fields) { - return aliasedFields(0, fields); - } - - static final List> aliasedFields(int offset, Collection> fields) { - if (fields == null) - return null; - - List> result = new ArrayList<>(fields.size()); - int i = offset; - for (Field field : fields) - result.add(field.as(fieldName(i++))); - - return result; + return mapToList(fields, (f, i) -> f.as(fieldName(i))); } static final Field[] fieldsByName(String[] fieldNames) { @@ -1460,87 +1330,36 @@ final class Tools { @SuppressWarnings("unchecked") static final TableField[] fieldsByName(Table tableName, Field[] fieldNames) { - if (fieldNames == null) - return null; - - TableField[] result = new TableField[fieldNames.length]; - if (tableName == null) - for (int i = 0; i < fieldNames.length; i++) - result[i] = (TableField) DSL.field(fieldNames[i].getUnqualifiedName(), fieldNames[i].getDataType()); + return map(fieldNames, n -> (TableField) DSL.field(n.getUnqualifiedName(), n.getDataType()), TableField[]::new); else - for (int i = 0; i < fieldNames.length; i++) - result[i] = (TableField) DSL.field(tableName.getQualifiedName().append(fieldNames[i].getUnqualifiedName()), fieldNames[i].getDataType()); - - return result; + return map(fieldNames, n -> (TableField) DSL.field(tableName.getQualifiedName().append(n.getUnqualifiedName()), n.getDataType()), TableField[]::new); } static final Field[] fieldsByName(Name tableName, Name[] fieldNames) { - if (fieldNames == null) - return null; - - Field[] result = new Field[fieldNames.length]; - if (tableName == null) - for (int i = 0; i < fieldNames.length; i++) - result[i] = DSL.field(fieldNames[i]); + return map(fieldNames, n -> DSL.field(n), Field[]::new); else - for (int i = 0; i < fieldNames.length; i++) - result[i] = DSL.field(name(tableName, fieldNames[i])); - - return result; + return map(fieldNames, n -> DSL.field(name(tableName, n)), Field[]::new); } static final Field[] fieldsByName(String tableName, String[] fieldNames) { - if (fieldNames == null) - return null; - - Field[] result = new Field[fieldNames.length]; - if (StringUtils.isEmpty(tableName)) - for (int i = 0; i < fieldNames.length; i++) - result[i] = DSL.field(name(fieldNames[i])); + return map(fieldNames, n -> DSL.field(name(n)), Field[]::new); else - for (int i = 0; i < fieldNames.length; i++) - result[i] = DSL.field(name(tableName, fieldNames[i])); - - return result; + return map(fieldNames, n -> DSL.field(name(tableName, n)), Field[]::new); } static final Field[] fieldsByName(Name[] names) { - if (names == null) - return null; - - Field[] result = new Field[names.length]; - - for (int i = 0; i < names.length; i++) - result[i] = DSL.field(names[i]); - - return result; + return map(names, n -> DSL.field(n), Field[]::new); } static final Name[] names(String[] names) { - if (names == null) - return null; - - Name[] result = new Name[names.length]; - - for (int i = 0; i < names.length; i++) - result[i] = DSL.name(names[i]); - - return result; + return map(names, n -> DSL.name(n), Name[]::new); } static final List names(Collection names) { - if (names == null) - return null; - - List result = new ArrayList<>(names.size()); - - for (Object o : names) - result.add(o instanceof Name ? (Name) o : DSL.name(String.valueOf(o))); - - return result; + return mapToList(names, n -> n instanceof Name ? (Name) n : DSL.name(String.valueOf(n))); } private static final IllegalArgumentException fieldExpected(Object value) { @@ -1833,25 +1652,14 @@ final class Tools { @SuppressWarnings("unchecked") static final Field[] fieldsArray(T[] values) { - if (values == null) - return (Field[]) EMPTY_FIELD; - - Field[] result = new Field[values.length]; - for (int i = 0; i < values.length; i++) - result[i] = field(values[i]); - - return result; + return map(values, v -> field(v), Field[]::new); } static final List> fields(Object[] values, Field field) { - if (values == null || field == null) + if (field == null) return new ArrayList<>(); - - List> result = new ArrayList<>(values.length); - for (int i = 0; i < values.length; i++) - result.add(field(values[i], field)); - - return result; + else + return mapToList(values, v -> field(v, field)); } static final List> fields(Object[] values, Field[] fields) { @@ -1859,16 +1667,7 @@ final class Tools { } static final Field[] fieldsArray(Object[] values, Field[] fields) { - if (values == null || fields == null) - return EMPTY_FIELD; - - int length = Math.min(values.length, fields.length); - Field[] result = new Field[length]; - - for (int i = 0; i < length; i++) - result[i] = field(values[i], fields[i]); - - return result; + return map(values, (v, i) -> field(v, fields[i]), Field[]::new); } static final List> fields(Object[] values, DataType type) { @@ -1876,26 +1675,12 @@ final class Tools { } static final List> fields(Collection values, DataType type) { - if (values == null || type == null) - return new ArrayList<>(); - - List> result = new ArrayList<>(values.size()); - for (Object value : values) - result.add(field(value, type)); - - return result; + return mapToList(values, v -> field(v, type)); } @SuppressWarnings("unchecked") static final Field[] fieldsArray(Object[] values, DataType type) { - if (values == null) - return (Field[]) EMPTY_FIELD; - - Field[] result = new Field[values.length]; - for (int i = 0; i < result.length; i++) - result[i] = field(values[i], type); - - return result; + return map(values, v -> field(v, type), Field[]::new); } static final List> fields(Object[] values, DataType[] types) { @@ -1903,27 +1688,11 @@ final class Tools { } static final Field[] fieldsArray(Object[] values, DataType[] types) { - if (values == null || types == null) - return EMPTY_FIELD; - - int length = Math.min(values.length, types.length); - Field[] result = new Field[length]; - - for (int i = 0; i < length; i++) - result[i] = field(values[i], types[i]); - - return result; + return map(values, (v, i) -> field(v, types[i]), Field[]::new); } static final List> inline(T[] values) { - if (values == null) - return new ArrayList<>(); - - List> result = new ArrayList<>(values.length); - for (int i = 0; i < values.length; i++) - result.add(DSL.inline(values[i])); - - return result; + return mapToList(values, v -> DSL.inline(v)); } @SuppressWarnings("unchecked") @@ -2016,26 +1785,112 @@ final class Tools { return result; } - static final List> jsonEntries(Field... fields) { - if (fields == null) - return null; + /** + * Like Stream.of(array).map(mapper).toArray(constructor) but + * without the entire stream pipeline. + */ + static final U[] map(T[] array, Function mapper, IntFunction constructor) { + if (array == null) + return constructor.apply(0); - List> result = new ArrayList<>(fields.length); - for (Field field : fields) - result.add(jsonEntry(field)); + U[] result = constructor.apply(array.length); + for (int i = 0; i < array.length; i++) + result[i] = mapper.apply(array[i]); return result; } - static final T last(Collection collection) { - if (collection.isEmpty()) - return null; - else if (collection instanceof List) - return ((List) collection).get(collection.size() - 1); + /** + * Like Stream.of(array).map(mapper).toArray(constructor) but + * without the entire stream pipeline. + */ + static final U[] map(Collection collection, Function mapper, IntFunction constructor) { + if (collection == null) + return constructor.apply(0); - T last = null; - for (Iterator it = collection.iterator(); it.hasNext(); last = it.next()); - return last; + U[] result = constructor.apply(collection.size()); + int i = 0; + for (T t : collection) + result[i++] = mapper.apply(t); + + return result; + } + + /** + * Like + * Stream.of(array).zipWithIndex().map(mapper).toArray(constructor) + * but without the entire stream pipeline. + */ + static final U[] map(T[] array, ObjIntFunction mapper, IntFunction constructor) { + if (array == null) + return constructor.apply(0); + + U[] result = constructor.apply(array.length); + for (int i = 0; i < array.length; i++) + result[i] = mapper.apply(array[i], i); + + return result; + } + + /** + * Like Stream.of(array).map(mapper).toList() but + * without the entire stream pipeline. + */ + static final List mapToList(T[] array, Function mapper) { + if (array == null) + return emptyList(); + + List result = new ArrayList<>(array.length); + for (T t : array) + result.add(mapper.apply(t)); + + return result; + } + + /** + * Like Stream.of(array).map(mapper).toList() but + * without the entire stream pipeline. + */ + static final List mapToList(Collection collection, Function mapper) { + if (collection == null) + return emptyList(); + + List result = new ArrayList<>(collection.size()); + for (T t : collection) + result.add(mapper.apply(t)); + + return result; + } + + /** + * Like Stream.of(array).zipWithIndex().map(mapper).toList() + * but without the entire stream pipeline. + */ + static final List mapToList(T[] array, ObjIntFunction mapper) { + if (array == null) + return emptyList(); + + List result = new ArrayList<>(array.length); + for (int i = 0; i < array.length; i++) + result.add(mapper.apply(array[i], i)); + + return result; + } + + /** + * Like Stream.of(array).map(mapper).toList() but + * without the entire stream pipeline. + */ + static final List mapToList(Collection collection, ObjIntFunction mapper) { + if (collection == null) + return emptyList(); + + List result = new ArrayList<>(collection.size()); + int i = 0; + for (T t : collection) + result.add(mapper.apply(t, i++)); + + return result; } /** @@ -2140,6 +1995,17 @@ final class Tools { return null; } + static final T last(Collection collection) { + if (collection.isEmpty()) + return null; + else if (collection instanceof List) + return ((List) collection).get(collection.size() - 1); + + T last = null; + for (Iterator it = collection.iterator(); it.hasNext(); last = it.next()); + return last; + } + /** * Sets the statement's fetch size to the given value or * {@link org.jooq.conf.Settings#getFetchSize()} if {@code 0}. @@ -5267,16 +5133,6 @@ final class Tools { }; } - static final String[] enumLiterals(Class type) { - EnumType[] values = enums(type); - String[] result = new String[values.length]; - - for (int i = 0; i < values.length; i++) - result[i] = values[i].getLiteral(); - - return result; - } - static final E[] enums(Class type) { // Java implementation diff --git a/jOOQ/src/main/java/org/jooq/impl/Values.java b/jOOQ/src/main/java/org/jooq/impl/Values.java index 323df7e819..341a0b4214 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Values.java +++ b/jOOQ/src/main/java/org/jooq/impl/Values.java @@ -93,9 +93,10 @@ final class Values extends AbstractTable { /** * Generated UID */ - private static final long serialVersionUID = -637982217747670311L; - static final Set NO_SUPPORT_VALUES = SQLDialect.supportedUntil(FIREBIRD, MARIADB); - static final Set REQUIRE_ROWTYPE_CAST = SQLDialect.supportedBy(FIREBIRD); + private static final long serialVersionUID = -637982217747670311L; + static final Set NO_SUPPORT_VALUES = SQLDialect.supportedUntil(FIREBIRD, MARIADB); + static final Set REQUIRE_ROWTYPE_CAST = SQLDialect.supportedBy(FIREBIRD); + static final Set NO_SUPPORT_PARENTHESES = SQLDialect.supportedBy(); private final Row[] rows; private transient DataType[] types; @@ -157,12 +158,12 @@ final class Values extends AbstractTable { @Override public final Table as(Name alias) { - return new TableAlias<>(this, alias, true); + return new TableAlias<>(this, alias, c -> !NO_SUPPORT_PARENTHESES.contains(c.dialect())); } @Override public final Table as(Name alias, Name... fieldAliases) { - return new TableAlias<>(this, alias, fieldAliases, true); + return new TableAlias<>(this, alias, fieldAliases, c -> !NO_SUPPORT_PARENTHESES.contains(c.dialect())); } @Override diff --git a/jOOQ/src/main/java/org/jooq/impl/WithImpl.java b/jOOQ/src/main/java/org/jooq/impl/WithImpl.java index 6780138970..d8101acda8 100644 --- a/jOOQ/src/main/java/org/jooq/impl/WithImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/WithImpl.java @@ -299,12 +299,12 @@ implements @Override public final WithImpl with(String a, String... f) { - return with(DSL.name(a), Tools.names(f)); + return with(DSL.name(a), Tools.map(f, s -> DSL.name(s), Name[]::new)); } @Override public final WithImpl with(String a, Collection f) { - return with(DSL.name(a), Tools.names(f)); + return with(DSL.name(a), Tools.map(f, s -> DSL.name(s), Name[]::new)); } @Override