[jOOQ/jOOQ#12462] Overload DSL.function() to accept arguments also as Collection<? extends Field<?>>

This commit is contained in:
Lukas Eder 2024-06-03 09:26:17 +02:00
parent 55d044f50f
commit 3d171612d8
7 changed files with 113 additions and 14 deletions

View File

@ -2421,7 +2421,7 @@ implements
name != null ? name(name) : AbstractRoutine.this.getQualifiedName(ctx),
returnType,
false,
fields.toArray(EMPTY_FIELD)
fields
);
// [#3592] Decrease SQL -> PL/SQL context switches with Oracle Scalar Subquery Caching

View File

@ -15920,7 +15920,7 @@ public class DSL {
@Support
@PlainSQL
public static <T> Field<T> function(String name, Class<T> type, Field<?>... arguments) {
return function(name, getDataType(type), Tools.nullSafe(arguments));
return function(name, type, asList(arguments));
}
/**
@ -15941,7 +15941,7 @@ public class DSL {
@Support
@PlainSQL
public static <T> Field<T> function(String name, DataType<T> type, Field<?>... arguments) {
return new org.jooq.impl.Function<>(name, type, Tools.nullSafe(arguments));
return function(name, type, asList(arguments));
}
/**
@ -15963,7 +15963,7 @@ public class DSL {
@NotNull
@Support
public static <T> Field<T> function(Name name, Class<T> type, Field<?>... arguments) {
return function(name, getDataType(type), Tools.nullSafe(arguments));
return function(name, type, asList(arguments));
}
/**
@ -15977,6 +15977,92 @@ public class DSL {
@NotNull
@Support
public static <T> Field<T> function(Name name, DataType<T> type, Field<?>... arguments) {
return function(name, type, asList(arguments));
}
/**
* <code>function()</code> can be used to access native or user-defined
* functions that are not yet or insufficiently supported by jOOQ.
* <p>
* <b>NOTE</b>: When inserting plain SQL into jOOQ objects, you must
* guarantee syntax integrity. You may also create the possibility of
* malicious SQL injection. Be sure to properly use bind variables and/or
* escape literals when concatenated into SQL clauses!
* <p>
* <b>NOTE [#15286]</b>: It is strongly recommended to pass only
* {@link Class} references of types supported by jOOQ internally, i.e.
* types from {@link SQLDataType}. If you're using any custom data types by
* means of a {@link Converter} or {@link Binding}, it's better to pass that
* converted {@link DataType} reference explicitly to
* {@link #function(String, DataType, Field...)}.
*
* @param name The function name (without parentheses)
* @param type The function return type (a type that is supported by
* {@link SQLDataType})
* @param arguments The function arguments
* @see SQL
*/
@NotNull
@Support
@PlainSQL
public static <T> Field<T> function(String name, Class<T> type, Collection<? extends Field<?>> arguments) {
return function(name, getDataType(type), Tools.nullSafe(arguments));
}
/**
* <code>function()</code> can be used to access native or user-defined
* functions that are not yet or insufficiently supported by jOOQ.
* <p>
* <b>NOTE</b>: When inserting plain SQL into jOOQ objects, you must
* guarantee syntax integrity. You may also create the possibility of
* malicious SQL injection. Be sure to properly use bind variables and/or
* escape literals when concatenated into SQL clauses!
*
* @param name The function name (without parentheses)
* @param type The function return type
* @param arguments The function arguments
* @see SQL
*/
@NotNull
@Support
@PlainSQL
public static <T> Field<T> function(String name, DataType<T> type, Collection<? extends Field<?>> arguments) {
return new org.jooq.impl.Function<>(name, type, Tools.nullSafe(arguments));
}
/**
* <code>function()</code> can be used to access native or user-defined
* functions that are not yet or insufficiently supported by jOOQ.
* <p>
* <b>NOTE [#15286]</b>: It is strongly recommended to pass only
* {@link Class} references of types supported by jOOQ internally, i.e.
* types from {@link SQLDataType}. If you're using any custom data types by
* means of a {@link Converter} or {@link Binding}, it's better to pass that
* converted {@link DataType} reference explicitly to
* {@link #function(Name, DataType, Field...)}.
*
* @param name The function name (possibly qualified)
* @param type The function return type (a type that is supported by
* {@link SQLDataType})
* @param arguments The function arguments
*/
@NotNull
@Support
public static <T> Field<T> function(Name name, Class<T> type, Collection<? extends Field<?>> arguments) {
return function(name, getDataType(type), Tools.nullSafe(arguments));
}
/**
* <code>function()</code> can be used to access native or user-defined
* functions that are not yet or insufficiently supported by jOOQ.
*
* @param name The function name (possibly qualified)
* @param type The function return type
* @param arguments The function arguments
*/
@NotNull
@Support
public static <T> Field<T> function(Name name, DataType<T> type, Collection<? extends Field<?>> arguments) {
return new org.jooq.impl.Function<>(name, type, Tools.nullSafe(arguments));
}

View File

@ -40,6 +40,8 @@ package org.jooq.impl;
import static org.jooq.impl.DSL.unquotedName;
import static org.jooq.impl.Tools.EMPTY_FIELD;
import java.util.Collection;
import org.jooq.DataType;
import org.jooq.Field;
import org.jooq.Name;
@ -54,15 +56,15 @@ final class Function<T> extends AbstractFunction<T> {
private final QueryPartList<Field<?>> arguments;
Function(String name, DataType<T> type, Field<?>... arguments) {
Function(String name, DataType<T> type, Collection<? extends Field<?>> arguments) {
this(unquotedName(name), type, arguments);
}
Function(Name name, DataType<T> type, Field<?>... arguments) {
Function(Name name, DataType<T> type, Collection<? extends Field<?>> arguments) {
this(name, type, true, arguments);
}
Function(Name name, DataType<T> type, boolean applySchemaMapping, Field<?>... arguments) {
Function(Name name, DataType<T> type, boolean applySchemaMapping, Collection<? extends Field<?>> arguments) {
super(name, type, applySchemaMapping);
this.arguments = new QueryPartList<>(arguments);

View File

@ -105,15 +105,15 @@ final class Greatest<T> extends AbstractField<T> implements QOM.Greatest<T> {
}
case FIREBIRD:
ctx.visit(function(N_MAXVALUE, getDataType(), args.toArray(EMPTY_FIELD)));
ctx.visit(function(N_MAXVALUE, getDataType(), args));
return;
case SQLITE:
ctx.visit(function(N_MAX, getDataType(), args.toArray(EMPTY_FIELD)));
ctx.visit(function(N_MAX, getDataType(), args));
return;
default:
ctx.visit(function(N_GREATEST, getDataType(), args.toArray(EMPTY_FIELD)));
ctx.visit(function(N_GREATEST, getDataType(), args));
return;
}
}

View File

@ -105,15 +105,15 @@ final class Least<T> extends AbstractField<T> implements QOM.Least<T> {
}
case FIREBIRD:
ctx.visit(function(N_MINVALUE, getDataType(), args.toArray(EMPTY_FIELD)));
ctx.visit(function(N_MINVALUE, getDataType(), args));
return;
case SQLITE:
ctx.visit(function(N_MIN, getDataType(), args.toArray(EMPTY_FIELD)));
ctx.visit(function(N_MIN, getDataType(), args));
return;
default:
ctx.visit(function(N_LEAST, getDataType(), args.toArray(EMPTY_FIELD)));
ctx.visit(function(N_LEAST, getDataType(), args));
return;
}
}

View File

@ -13000,7 +13000,7 @@ final class DefaultParseContext extends AbstractScope implements ParseContext {
// [#10107] Completely ignore functions in the DDLDatabase
return isDDLDatabase()
? inline((Object) null)
: function(name, Object.class, arguments.toArray(EMPTY_FIELD));
: function(name, Object.class, arguments);
}

View File

@ -7380,6 +7380,17 @@ final class Tools {
: field;
}
static final List<Field<?>> nullSafe(Collection<? extends Field<?>> fields) {
if (fields == null)
return emptyList();
List<Field<?>> result = new ArrayList<>(fields.size());
for (Field<?> f : fields)
result.add(nullSafe(f));
return result;
}
static final Field<?>[] nullSafe(Field<?>... fields) {
if (fields == null)
return EMPTY_FIELD;