diff --git a/jOOQ/src/main/java/org/jooq/impl/DSL.java b/jOOQ/src/main/java/org/jooq/impl/DSL.java index 6f87525283..97362c4593 100644 --- a/jOOQ/src/main/java/org/jooq/impl/DSL.java +++ b/jOOQ/src/main/java/org/jooq/impl/DSL.java @@ -3092,8 +3092,8 @@ public class DSL { } /** - * function() can be used to access native functions that are - * not yet or insufficiently supported by jOOQ. + * function() can be used to access native or user-defined + * functions that are not yet or insufficiently supported by jOOQ. *

* NOTE: When inserting plain SQL into jOOQ objects, you must * guarantee syntax integrity. You may also create the possibility of @@ -3110,8 +3110,8 @@ public class DSL { } /** - * function() can be used to access native functions that are - * not yet or insufficiently supported by jOOQ. + * function() can be used to access native or user-defined + * functions that are not yet or insufficiently supported by jOOQ. *

* NOTE: When inserting plain SQL into jOOQ objects, you must * guarantee syntax integrity. You may also create the possibility of @@ -3127,6 +3127,32 @@ public class DSL { return new Function(name, type, nullSafe(arguments)); } + /** + * function() 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 + */ + @Support + public static Field function(Name name, Class type, Field... arguments) { + return function(name, getDataType(type), nullSafe(arguments)); + } + + /** + * function() 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 + */ + @Support + public static Field function(Name name, DataType type, Field... arguments) { + return new Function(name, type, nullSafe(arguments)); + } + /** * Create a new condition holding plain SQL. *

diff --git a/jOOQ/src/main/java/org/jooq/impl/Function.java b/jOOQ/src/main/java/org/jooq/impl/Function.java index bc9c3a967a..6bf5d4347a 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Function.java +++ b/jOOQ/src/main/java/org/jooq/impl/Function.java @@ -55,6 +55,7 @@ import org.jooq.AggregateFunction; import org.jooq.BindContext; import org.jooq.DataType; import org.jooq.Field; +import org.jooq.Name; import org.jooq.OrderedAggregateFunction; import org.jooq.QueryPart; import org.jooq.RenderContext; @@ -92,8 +93,12 @@ class Function extends AbstractField implements private static final long serialVersionUID = 347252741712134044L; - private final QueryPartList arguments; + // Mutually exclusive attributes: super.getName(), this.name, this.term + private final Name name; private final Term term; + + // Other attributes + private final QueryPartList arguments; private final boolean distinct; private final SortFieldList withinGroupOrderBy; private final SortFieldList keepDenseRankOrderBy; @@ -120,10 +125,15 @@ class Function extends AbstractField implements this(term, false, type, arguments); } + Function(Name name, DataType type, QueryPart... arguments) { + this(name, false, type, arguments); + } + Function(String name, boolean distinct, DataType type, QueryPart... arguments) { super(name, type); this.term = null; + this.name = null; this.distinct = distinct; this.arguments = new QueryPartList(arguments); this.keepDenseRankOrderBy = new SortFieldList(); @@ -136,6 +146,7 @@ class Function extends AbstractField implements super(term.name().toLowerCase(), type); this.term = term; + this.name = null; this.distinct = distinct; this.arguments = new QueryPartList(arguments); this.keepDenseRankOrderBy = new SortFieldList(); @@ -144,6 +155,27 @@ class Function extends AbstractField implements this.orderBy = new SortFieldList(); } + Function(Name name, boolean distinct, DataType type, QueryPart... arguments) { + super(last(name.getName()), type); + + this.term = null; + this.name = name; + this.distinct = distinct; + this.arguments = new QueryPartList(arguments); + this.keepDenseRankOrderBy = new SortFieldList(); + this.withinGroupOrderBy = new SortFieldList(); + this.partitionBy = new QueryPartList>(); + this.orderBy = new SortFieldList(); + } + + private static String last(String... strings) { + if (strings != null && strings.length > 0) { + return strings[strings.length - 1]; + } + + return null; + } + // ------------------------------------------------------------------------- // XXX QueryPart API // ------------------------------------------------------------------------- @@ -238,7 +270,7 @@ class Function extends AbstractField implements * [#1275] LIST_AGG simulation for Postgres, Sybase */ private void toSQLStringAgg(RenderContext context) { - context.sql(getFNName(context.configuration().dialect())); + toSQLFunctionName(context); context.sql("("); if (distinct) { @@ -269,7 +301,7 @@ class Function extends AbstractField implements * [#1273] LIST_AGG simulation for MySQL and CUBRID */ private final void toSQLGroupConcat(RenderContext context) { - context.sql(getFNName(context.configuration().dialect())); + toSQLFunctionName(context); context.sql("("); if (distinct) { @@ -377,7 +409,7 @@ class Function extends AbstractField implements * Render function arguments and argument modifiers */ private final void toSQLArguments(RenderContext context) { - context.sql(getFNName(context.configuration().dialect())); + toSQLFunctionName(context); context.sql("("); if (distinct) { @@ -408,12 +440,15 @@ class Function extends AbstractField implements context.sql(")"); } - private final String getFNName(SQLDialect dialect) { - if (term != null) { - return term.translate(dialect); + private final void toSQLFunctionName(RenderContext ctx) { + if (name != null) { + ctx.sql(name); + } + else if (term != null) { + ctx.sql(term.translate(ctx.configuration().dialect())); } else { - return getName(); + ctx.sql(getName()); } }