diff --git a/jOOQ/src/main/java/org/jooq/DSLContext.java b/jOOQ/src/main/java/org/jooq/DSLContext.java
index e88210e85a..0d008249e9 100644
--- a/jOOQ/src/main/java/org/jooq/DSLContext.java
+++ b/jOOQ/src/main/java/org/jooq/DSLContext.java
@@ -3377,6 +3377,27 @@ public interface DSLContext extends Scope , AutoCloseable {
@Support({ FIREBIRD, HSQLDB, POSTGRES })
WithAsStep with(String alias, String... fieldAliases);
+
+ /**
+ * Create a WITH clause to supply subsequent
+ * SELECT, UPDATE, INSERT,
+ * DELETE, and MERGE statements with
+ * {@link CommonTableExpression}s.
+ *
+ * The RECURSIVE keyword may be optional or unsupported in some
+ * databases, in case of which it will not be rendered. For optimal database
+ * interoperability and readability, however, it is suggested that you use
+ * {@link #with(String, String...)} for strictly non-recursive CTE and
+ * {@link #withRecursive(String, String...)} for strictly recursive CTE.
+ *
+ * This works in a similar way as {@link #with(String, String...)}, except
+ * that all column names are produced by a function that receives the CTE's
+ * {@link Select} columns as input.
+ */
+ @Support({ FIREBIRD, HSQLDB, POSTGRES })
+ WithAsStep with(String alias, Function super Field>, ? extends String> fieldNameFunction);
+
+
// [jooq-tools] START [with]
/**
@@ -3817,6 +3838,31 @@ public interface DSLContext extends Scope , AutoCloseable {
@Support({ FIREBIRD, H2, HSQLDB, POSTGRES })
WithAsStep withRecursive(String alias, String... fieldAliases);
+
+ /**
+ * Create a WITH clause to supply subsequent
+ * SELECT, UPDATE, INSERT,
+ * DELETE, and MERGE statements with
+ * {@link CommonTableExpression}s.
+ *
+ * The RECURSIVE keyword may be optional or unsupported in some
+ * databases, in case of which it will not be rendered. For optimal database
+ * interoperability and readability, however, it is suggested that you use
+ * {@link #with(String, String...)} for strictly non-recursive CTE
+ * and {@link #withRecursive(String, String...)} for strictly
+ * recursive CTE.
+ *
+ * Note that the {@link SQLDialect#H2} database only supports single-table,
+ * RECURSIVE common table expression lists.
+ *
+ * This works in a similar way as {@link #with(String, String...)}, except + * that all column names are produced by a function that receives the CTE's + * {@link Select} columns as input. + */ + @Support({ FIREBIRD, HSQLDB, POSTGRES }) + WithAsStep withRecursive(String alias, Function super Field>, ? extends String> fieldNameFunction); + + // [jooq-tools] START [with-recursive] /** diff --git a/jOOQ/src/main/java/org/jooq/Name.java b/jOOQ/src/main/java/org/jooq/Name.java index 7311a9189a..c8b696d38e 100644 --- a/jOOQ/src/main/java/org/jooq/Name.java +++ b/jOOQ/src/main/java/org/jooq/Name.java @@ -54,6 +54,8 @@ import static org.jooq.SQLDialect.POSTGRES; // ... // ... +import java.util.function.Function; + import javax.annotation.Generated; import org.jooq.conf.Settings; @@ -108,6 +110,23 @@ public interface Name extends QueryPart { @Support({ FIREBIRD, H2, HSQLDB, POSTGRES }) DerivedColumnList fields(String... fieldNames); + + /** + * Add a list of fields to this name to make this name a + * {@link DerivedColumnList}. + *
+ * The DerivedColumnList can then be used along with a
+ * subselect to form a {@link CommonTableExpression} to be used with
+ * WITH clauses.
+ *
+ * This works in a similar way as {@link #fields(String...)}, except
+ * that all column names are produced by a function that receives the CTE's
+ * {@link Select} columns as input.
+ */
+ @Support({ FIREBIRD, H2, HSQLDB, POSTGRES })
+ DerivedColumnList fields(Function super Field>, ? extends String> fieldNameFunction);
+
+
// [jooq-tools] START [fields]
/**
diff --git a/jOOQ/src/main/java/org/jooq/WithStep.java b/jOOQ/src/main/java/org/jooq/WithStep.java
index c12836ac99..8e58b7876d 100644
--- a/jOOQ/src/main/java/org/jooq/WithStep.java
+++ b/jOOQ/src/main/java/org/jooq/WithStep.java
@@ -51,6 +51,7 @@ import static org.jooq.SQLDialect.POSTGRES;
// ...
import java.util.Collection;
+import java.util.function.Function;
import javax.annotation.Generated;
@@ -92,6 +93,18 @@ public interface WithStep extends QueryPart {
@Support({ FIREBIRD, H2, HSQLDB, POSTGRES })
WithAsStep with(String alias, String... fieldAliases);
+
+ /**
+ * Add another common table expression to the WITH clause.
+ *
+ * This works in a similar way as {@link #with(String, String...)}, except
+ * that all column names are produced by a function that receives the CTE's
+ * {@link Select} columns as input.
+ */
+ @Support({ FIREBIRD, H2, HSQLDB, POSTGRES })
+ WithAsStep with(String alias, Function super Field>, ? extends String> fieldNameFunction);
+
+
// [jooq-tools] START [with]
/**
diff --git a/jOOQ/src/main/java/org/jooq/impl/CommonTableExpressionImpl.java b/jOOQ/src/main/java/org/jooq/impl/CommonTableExpressionImpl.java
index bd92eb69e7..48f5781263 100644
--- a/jOOQ/src/main/java/org/jooq/impl/CommonTableExpressionImpl.java
+++ b/jOOQ/src/main/java/org/jooq/impl/CommonTableExpressionImpl.java
@@ -57,11 +57,11 @@ final class CommonTableExpressionImpl
+ * The
+ * This works in a similar way as {@link #with(String, String...)}, except
+ * that all column names are produced by a function that receives the CTE's
+ * {@link Select} columns as input.
+ */
+ @Support({ FIREBIRD, HSQLDB, POSTGRES })
+ public static WithAsStep with(String alias, Function super Field>, ? extends String> fieldNameFunction) {
+ return new WithImpl(null, false).with(alias, fieldNameFunction);
+ }
+
+
// [jooq-tools] START [with]
/**
@@ -1189,6 +1212,33 @@ public class DSL {
return new WithImpl(null, true).with(alias, fieldAliases);
}
+
+ /**
+ * Create a
+ * The
+ * Note that the {@link SQLDialect#H2} database only supports single-table,
+ *
+ * This works in a similar way as {@link #with(String, String...)}, except
+ * that all column names are produced by a function that receives the CTE's
+ * {@link Select} columns as input.
+ */
+ @Support({ FIREBIRD, H2, HSQLDB, POSTGRES })
+ public static WithAsStep withRecursive(String alias, Function super Field>, ? extends String> fieldNameFunction) {
+ return new WithImpl(null, true).with(alias, fieldNameFunction);
+ }
+
+
// [jooq-tools] START [with-recursive]
/**
diff --git a/jOOQ/src/main/java/org/jooq/impl/DefaultDSLContext.java b/jOOQ/src/main/java/org/jooq/impl/DefaultDSLContext.java
index 1ea602e796..e5059a2a77 100644
--- a/jOOQ/src/main/java/org/jooq/impl/DefaultDSLContext.java
+++ b/jOOQ/src/main/java/org/jooq/impl/DefaultDSLContext.java
@@ -1387,6 +1387,13 @@ public class DefaultDSLContext extends AbstractScope implements DSLContext, Seri
return new WithImpl(configuration(), false).with(alias, fieldAliases);
}
+
+ @Override
+ public WithAsStep with(String alias, Function super Field>, ? extends String> fieldNameFunction) {
+ return new WithImpl(configuration(), false).with(alias, fieldNameFunction);
+ }
+
+
// [jooq-tools] START [with]
@Generated("This method was generated using jOOQ-tools")
@@ -1538,6 +1545,13 @@ public class DefaultDSLContext extends AbstractScope implements DSLContext, Seri
return new WithImpl(configuration(), true).with(alias, fieldAliases);
}
+
+ @Override
+ public WithAsStep withRecursive(String alias, Function super Field>, ? extends String> fieldNameFunction) {
+ return new WithImpl(configuration(), true).with(alias, fieldNameFunction);
+ }
+
+
// [jooq-tools] START [with-recursive]
@Generated("This method was generated using jOOQ-tools")
diff --git a/jOOQ/src/main/java/org/jooq/impl/DerivedColumnListImpl.java b/jOOQ/src/main/java/org/jooq/impl/DerivedColumnListImpl.java
index 8841d59e9b..5782a7383e 100644
--- a/jOOQ/src/main/java/org/jooq/impl/DerivedColumnListImpl.java
+++ b/jOOQ/src/main/java/org/jooq/impl/DerivedColumnListImpl.java
@@ -42,6 +42,8 @@ package org.jooq.impl;
import static org.jooq.impl.DSL.name;
+import java.util.function.Function;
+
import org.jooq.Clause;
import org.jooq.CommonTableExpression;
import org.jooq.Context;
@@ -68,6 +70,7 @@ import org.jooq.DerivedColumnList6;
import org.jooq.DerivedColumnList7;
import org.jooq.DerivedColumnList8;
import org.jooq.DerivedColumnList9;
+import org.jooq.Field;
import org.jooq.Select;
/**
@@ -107,20 +110,45 @@ implements
/**
* Gemerated UID
*/
- private static final long serialVersionUID = -369633206858851863L;
+ private static final long serialVersionUID = -369633206858851863L;
+
+ final String name;
+ final String[] fieldNames;
+
+ final Function super Field>, ? extends String> fieldNameFunction;
- final String name;
- final String[] fieldNames;
DerivedColumnListImpl(String name, String[] fieldNames) {
this.name = name;
this.fieldNames = fieldNames;
+
+ this.fieldNameFunction = null;
+
}
+
+ DerivedColumnListImpl(String name, Function super Field>, ? extends String> fieldNameFunction) {
+ this.name = name;
+ this.fieldNames = null;
+ this.fieldNameFunction = fieldNameFunction;
+ }
+
+
@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
public final CommonTableExpression as(Select select) {
- return new CommonTableExpressionImpl(this, select);
+ Select> s = select;
+
+
+ if (fieldNameFunction != null) {
+ return new CommonTableExpressionImpl(
+ new DerivedColumnListImpl(name, s.getSelect().stream().map(fieldNameFunction).toArray(String[]::new)),
+ s
+ );
+ }
+
+
+ return new CommonTableExpressionImpl(this, s);
}
@Override
diff --git a/jOOQ/src/main/java/org/jooq/impl/NameImpl.java b/jOOQ/src/main/java/org/jooq/impl/NameImpl.java
index 79cac5b6a8..8e9a3ac8a6 100644
--- a/jOOQ/src/main/java/org/jooq/impl/NameImpl.java
+++ b/jOOQ/src/main/java/org/jooq/impl/NameImpl.java
@@ -41,12 +41,14 @@
package org.jooq.impl;
import java.util.Arrays;
+import java.util.function.Function;
import javax.annotation.Generated;
import org.jooq.Clause;
import org.jooq.CommonTableExpression;
import org.jooq.Context;
+import org.jooq.Field;
import org.jooq.Name;
import org.jooq.Record;
import org.jooq.Select;
@@ -120,6 +122,15 @@ final class NameImpl extends AbstractQueryPart implements Name {
return new DerivedColumnListImpl(qualifiedName[0], fieldNames);
}
+
+
+ @Override
+ public final DerivedColumnListImpl fields(Function super Field>, ? extends String> fieldNameFunction) {
+ return new DerivedColumnListImpl(qualifiedName[0], fieldNameFunction);
+ }
+
+
+
// [jooq-tools] START [fields]
@Generated("This method was generated using jOOQ-tools")
diff --git a/jOOQ/src/main/java/org/jooq/impl/WithImpl.java b/jOOQ/src/main/java/org/jooq/impl/WithImpl.java
index 786eff8fde..5961dfc4a1 100644
--- a/jOOQ/src/main/java/org/jooq/impl/WithImpl.java
+++ b/jOOQ/src/main/java/org/jooq/impl/WithImpl.java
@@ -52,6 +52,7 @@ import static org.jooq.impl.DSL.zero;
import java.util.Arrays;
import java.util.Collection;
+import java.util.function.Function;
import javax.annotation.Generated;
@@ -158,17 +159,20 @@ implements
/**
* Generated UID
*/
- private static final long serialVersionUID = -1813359431778402705L;
- private static final Clause[] CLAUSES = { WITH };
+ private static final long serialVersionUID = -1813359431778402705L;
+ private static final Clause[] CLAUSES = { WITH };
- private final CommonTableExpressionList cte;
- private final boolean recursive;
- private Configuration configuration;
+ private final CommonTableExpressionList cte;
+ private final boolean recursive;
+ private Configuration configuration;
// Intermediary properties for CTE construction
- private String alias;
- private String[] fieldAliases;
+ private String alias;
+ private String[] fieldAliases;
+
+ private Function super Field>, ? extends String> fieldNameFunction;
+
WithImpl(Configuration configuration, boolean recursive) {
this.configuration = configuration;
@@ -205,11 +209,20 @@ implements
@Override
public final WithStep as(Select select) {
- cte.add(name(alias).fields(fieldAliases).as(select));
+
+
+ if (fieldNameFunction != null)
+ cte.add(name(alias).fields(fieldNameFunction).as(select));
+ else
+
+ cte.add(name(alias).fields(fieldAliases).as(select));
this.alias = null;
this.fieldAliases = null;
+ this.fieldNameFunction = null;
+
+
return this;
}
@@ -226,6 +239,16 @@ implements
return this;
}
+
+ @Override
+ public final WithAsStep with(String a, Function super Field>, ? extends String> f) {
+ this.alias = a;
+ this.fieldNameFunction = f;
+
+ return this;
+ }
+
+
// [jooq-tools] START [with]
@Override
WITH clause to supply subsequent
+ * SELECT, UPDATE, INSERT,
+ * DELETE, and MERGE statements with
+ * {@link CommonTableExpression}s.
+ * RECURSIVE keyword may be optional or unsupported in some
+ * databases, in case of which it will not be rendered. For optimal database
+ * interoperability and readability, however, it is suggested that you use
+ * {@link #with(String, String...)} for strictly non-recursive CTE and
+ * {@link #withRecursive(String, String...)} for strictly recursive CTE.
+ * WITH clause to supply subsequent
+ * SELECT, UPDATE, INSERT,
+ * DELETE, and MERGE statements with
+ * {@link CommonTableExpression}s.
+ * RECURSIVE keyword may be optional or unsupported in some
+ * databases, in case of which it will not be rendered. For optimal database
+ * interoperability and readability, however, it is suggested that you use
+ * {@link #with(String, String...)} for strictly non-recursive CTE
+ * and {@link #withRecursive(String, String...)} for strictly
+ * recursive CTE.
+ * RECURSIVE common table expression lists.
+ *