[#1273] Simulate GROUP_CONCAT() aggregate function using Oracle's LISTAGG() function, where available
This commit is contained in:
parent
003344ef32
commit
7acc26838a
@ -736,7 +736,6 @@ extends BaseTest<A, B, S, B2S, BS, L, X, DATE, BOOL, D, T, U, I, IPK, T658, T725
|
||||
case ASE:
|
||||
case DERBY:
|
||||
case INGRES:
|
||||
case POSTGRES:
|
||||
case SQLITE:
|
||||
case SQLSERVER:
|
||||
log.info("SKIPPING", "LISTAGG tests");
|
||||
@ -776,6 +775,7 @@ extends BaseTest<A, B, S, B2S, BS, L, X, DATE, BOOL, D, T, U, I, IPK, T658, T725
|
||||
case H2:
|
||||
case HSQLDB:
|
||||
case MYSQL:
|
||||
case POSTGRES:
|
||||
case SYBASE:
|
||||
log.info("SKIPPING", "LISTAGG window function tests");
|
||||
return;
|
||||
|
||||
@ -41,6 +41,7 @@ import static org.jooq.SQLDialect.H2;
|
||||
import static org.jooq.SQLDialect.HSQLDB;
|
||||
import static org.jooq.SQLDialect.MYSQL;
|
||||
import static org.jooq.SQLDialect.ORACLE;
|
||||
import static org.jooq.SQLDialect.POSTGRES;
|
||||
import static org.jooq.SQLDialect.SYBASE;
|
||||
|
||||
import java.util.Collection;
|
||||
@ -59,18 +60,18 @@ public interface GroupConcatOrderByStep extends GroupConcatSeparatorStep {
|
||||
/**
|
||||
* Add an <code>ORDER BY</code> clause to the query
|
||||
*/
|
||||
@Support({ CUBRID, DB2, H2, HSQLDB, MYSQL, ORACLE, SYBASE })
|
||||
@Support({ CUBRID, DB2, H2, HSQLDB, MYSQL, ORACLE, POSTGRES, SYBASE })
|
||||
GroupConcatSeparatorStep orderBy(Field<?>... fields);
|
||||
|
||||
/**
|
||||
* Add an <code>ORDER BY</code> clause to the query
|
||||
*/
|
||||
@Support({ CUBRID, DB2, H2, HSQLDB, MYSQL, ORACLE, SYBASE })
|
||||
@Support({ CUBRID, DB2, H2, HSQLDB, MYSQL, ORACLE, POSTGRES, SYBASE })
|
||||
GroupConcatSeparatorStep orderBy(SortField<?>... fields);
|
||||
|
||||
/**
|
||||
* Add an <code>ORDER BY</code> clause to the query
|
||||
*/
|
||||
@Support({ CUBRID, DB2, H2, HSQLDB, MYSQL, ORACLE, SYBASE })
|
||||
@Support({ CUBRID, DB2, H2, HSQLDB, MYSQL, ORACLE, POSTGRES, SYBASE })
|
||||
GroupConcatSeparatorStep orderBy(Collection<SortField<?>> fields);
|
||||
}
|
||||
|
||||
@ -41,6 +41,7 @@ import static org.jooq.SQLDialect.H2;
|
||||
import static org.jooq.SQLDialect.HSQLDB;
|
||||
import static org.jooq.SQLDialect.MYSQL;
|
||||
import static org.jooq.SQLDialect.ORACLE;
|
||||
import static org.jooq.SQLDialect.POSTGRES;
|
||||
import static org.jooq.SQLDialect.SYBASE;
|
||||
|
||||
import org.jooq.impl.Factory;
|
||||
@ -56,6 +57,6 @@ public interface GroupConcatSeparatorStep extends AggregateFunction<String> {
|
||||
/**
|
||||
* Specify the separator on the <code>GROUP_CONCAT</code> function
|
||||
*/
|
||||
@Support({ CUBRID, DB2, H2, HSQLDB, MYSQL, ORACLE, SYBASE })
|
||||
@Support({ CUBRID, DB2, H2, HSQLDB, MYSQL, ORACLE, POSTGRES, SYBASE })
|
||||
AggregateFunction<String> separator(String separator);
|
||||
}
|
||||
|
||||
@ -4263,7 +4263,7 @@ public class Factory implements FactoryOperations {
|
||||
*
|
||||
* @see #groupConcat(Field)
|
||||
*/
|
||||
@Support({ CUBRID, DB2, H2, HSQLDB, MYSQL, ORACLE, SYBASE })
|
||||
@Support({ CUBRID, DB2, H2, HSQLDB, MYSQL, ORACLE, POSTGRES, SYBASE })
|
||||
public static OrderedAggregateFunction<String> listAgg(Field<?> field) {
|
||||
return new Function<String>(Term.LIST_AGG, SQLDataType.VARCHAR, nullSafe(field));
|
||||
}
|
||||
@ -4284,7 +4284,7 @@ public class Factory implements FactoryOperations {
|
||||
*
|
||||
* @see #groupConcat(Field, String)
|
||||
*/
|
||||
@Support({ CUBRID, DB2, H2, HSQLDB, MYSQL, ORACLE, SYBASE })
|
||||
@Support({ CUBRID, DB2, H2, HSQLDB, MYSQL, ORACLE, POSTGRES, SYBASE })
|
||||
public static OrderedAggregateFunction<String> listAgg(Field<?> field, String separator) {
|
||||
Field<String> literal = literal("'" + separator.replace("'", "''") + "'");
|
||||
return new Function<String>(Term.LIST_AGG, SQLDataType.VARCHAR, nullSafe(field), literal);
|
||||
@ -4310,7 +4310,7 @@ public class Factory implements FactoryOperations {
|
||||
*
|
||||
* @see #listAgg(Field)
|
||||
*/
|
||||
@Support({ CUBRID, DB2, H2, HSQLDB, MYSQL, ORACLE, SYBASE })
|
||||
@Support({ CUBRID, DB2, H2, HSQLDB, MYSQL, ORACLE, POSTGRES, SYBASE })
|
||||
public static GroupConcatOrderByStep groupConcat(Field<?> field) {
|
||||
return new GroupConcat(nullSafe(field));
|
||||
}
|
||||
@ -4333,7 +4333,7 @@ public class Factory implements FactoryOperations {
|
||||
*
|
||||
* @see #listAgg(Field)
|
||||
*/
|
||||
@Support({ CUBRID, H2, HSQLDB, MYSQL, SYBASE })
|
||||
@Support({ CUBRID, H2, HSQLDB, MYSQL, POSTGRES, SYBASE })
|
||||
public static GroupConcatOrderByStep groupConcatDistinct(Field<?> field) {
|
||||
return new GroupConcat(nullSafe(field), true);
|
||||
}
|
||||
|
||||
@ -42,6 +42,7 @@ import static org.jooq.SQLDialect.DB2;
|
||||
import static org.jooq.SQLDialect.H2;
|
||||
import static org.jooq.SQLDialect.HSQLDB;
|
||||
import static org.jooq.SQLDialect.MYSQL;
|
||||
import static org.jooq.SQLDialect.POSTGRES;
|
||||
import static org.jooq.SQLDialect.SYBASE;
|
||||
import static org.jooq.impl.Factory.one;
|
||||
import static org.jooq.impl.Term.LIST_AGG;
|
||||
@ -172,8 +173,8 @@ class Function<T> extends AbstractField<T> implements
|
||||
if (term == LIST_AGG && asList(CUBRID, H2, HSQLDB, MYSQL).contains(context.getDialect())) {
|
||||
toSQLGroupConcat(context);
|
||||
}
|
||||
else if (term == LIST_AGG && asList(SYBASE).contains(context.getDialect())) {
|
||||
toSQLList(context);
|
||||
else if (term == LIST_AGG && asList(POSTGRES, SYBASE).contains(context.getDialect())) {
|
||||
toSQLStringAgg(context);
|
||||
}
|
||||
else if (term == LIST_AGG && asList(DB2).contains(context.getDialect())) {
|
||||
toSQLXMLAGG(context);
|
||||
@ -233,9 +234,9 @@ class Function<T> extends AbstractField<T> implements
|
||||
}
|
||||
|
||||
/**
|
||||
* [#1275] <code>LIST_AGG</code> simulation for CUBRID, HSQLDB, MySQL
|
||||
* [#1275] <code>LIST_AGG</code> simulation for Postgres, Sybase
|
||||
*/
|
||||
private void toSQLList(RenderContext context) {
|
||||
private void toSQLStringAgg(RenderContext context) {
|
||||
context.sql(getFNName(context.getDialect()));
|
||||
context.sql("(");
|
||||
|
||||
@ -243,7 +244,16 @@ class Function<T> extends AbstractField<T> implements
|
||||
context.keyword("distinct ");
|
||||
}
|
||||
|
||||
context.sql(arguments);
|
||||
// The explicit cast is needed in Postgres
|
||||
context.sql(((Field<?>) arguments.get(0)).cast(String.class));
|
||||
|
||||
if (arguments.size() > 1) {
|
||||
context.sql(", ");
|
||||
context.sql(arguments.get(1));
|
||||
}
|
||||
else {
|
||||
context.sql(", ''");
|
||||
}
|
||||
|
||||
if (!withinGroupOrderBy.isEmpty()) {
|
||||
context.keyword(" order by ")
|
||||
@ -251,6 +261,7 @@ class Function<T> extends AbstractField<T> implements
|
||||
}
|
||||
|
||||
context.sql(")");
|
||||
toSQLOverClause(context);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -118,6 +118,9 @@ enum Term {
|
||||
case ORACLE:
|
||||
return "listagg";
|
||||
|
||||
case POSTGRES:
|
||||
return "string_agg";
|
||||
|
||||
case SYBASE:
|
||||
return "list";
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user