[#893] Simulate ROLLUP function for MySQL, using the WITH ROLLUP modifier
This commit is contained in:
parent
7ae02553ea
commit
496aa5ee1d
@ -44,6 +44,7 @@ import static junit.framework.Assert.assertTrue;
|
||||
import static junit.framework.Assert.fail;
|
||||
import static org.jooq.SQLDialect.ASE;
|
||||
import static org.jooq.SQLDialect.DB2;
|
||||
import static org.jooq.SQLDialect.MYSQL;
|
||||
import static org.jooq.SQLDialect.SQLSERVER;
|
||||
import static org.jooq.SQLDialect.SYBASE;
|
||||
import static org.jooq.impl.Factory.cast;
|
||||
@ -2985,7 +2986,6 @@ public abstract class jOOQAbstractTest<
|
||||
case H2:
|
||||
case HSQLDB:
|
||||
case INGRES:
|
||||
case MYSQL:
|
||||
case POSTGRES:
|
||||
case SQLITE:
|
||||
log.info("SKIPPING", "Group by CUBE / ROLLUP tests");
|
||||
@ -2993,11 +2993,62 @@ public abstract class jOOQAbstractTest<
|
||||
}
|
||||
|
||||
Result<Record> result;
|
||||
Field<Integer> groupingId = groupingId(TBook_ID(), TBook_AUTHOR_ID());
|
||||
|
||||
// Simple ROLLUP clause
|
||||
// --------------------
|
||||
result = create().select(
|
||||
TBook_ID(),
|
||||
TBook_AUTHOR_ID())
|
||||
.from(TBook())
|
||||
.groupBy(rollup(
|
||||
TBook_ID(),
|
||||
TBook_AUTHOR_ID()))
|
||||
.fetch();
|
||||
|
||||
System.out.println(result.format());
|
||||
assertEquals(9, result.size());
|
||||
|
||||
if (getDialect() == DB2) {
|
||||
assertEquals(Arrays.asList(null, 1, 2, 3, 4, 1, 2, 3, 4), result.getValues(0));
|
||||
assertEquals(Arrays.asList(null, null, null, null, null, 1, 1, 2, 2), result.getValues(1));
|
||||
}
|
||||
else {
|
||||
assertEquals(Arrays.asList(1, 1, 2, 2, 3, 3, 4, 4, null), result.getValues(0));
|
||||
assertEquals(Arrays.asList(1, null, 1, null, 2, null, 2, null, null), result.getValues(1));
|
||||
}
|
||||
|
||||
if (getDialect() == MYSQL) {
|
||||
log.info("SKIPPING", "CUBE and GROUPING SETS tests");
|
||||
return;
|
||||
}
|
||||
|
||||
// ROLLUP clause
|
||||
// -------------
|
||||
Field<Integer> groupingId = groupingId(TBook_ID(), TBook_AUTHOR_ID());
|
||||
if (asList(DB2, SYBASE).contains(getDialect()))
|
||||
groupingId = one();
|
||||
|
||||
result = create().select(
|
||||
TBook_ID(),
|
||||
TBook_AUTHOR_ID(),
|
||||
grouping(TBook_ID()),
|
||||
groupingId)
|
||||
.from(TBook())
|
||||
.groupBy(rollup(
|
||||
TBook_ID(),
|
||||
TBook_AUTHOR_ID()))
|
||||
.orderBy(
|
||||
TBook_ID().asc().nullsFirst(),
|
||||
TBook_AUTHOR_ID().asc().nullsFirst()).fetch();
|
||||
|
||||
assertEquals(9, result.size());
|
||||
assertEquals(Arrays.asList(null, 1, 1, 2, 2, 3, 3, 4, 4), result.getValues(0));
|
||||
assertEquals(Arrays.asList(null, null, 1, null, 1, null, 2, null, 2), result.getValues(1));
|
||||
assertEquals(Arrays.asList(1, 0, 0, 0, 0, 0, 0, 0, 0), result.getValues(2));
|
||||
|
||||
if (!asList(DB2, SYBASE).contains(getDialect()))
|
||||
assertEquals(Arrays.asList(3, 1, 0, 1, 0, 1, 0, 1, 0), result.getValues(3));
|
||||
|
||||
// CUBE clause
|
||||
// -----------
|
||||
result = create().select(
|
||||
@ -3021,29 +3072,6 @@ public abstract class jOOQAbstractTest<
|
||||
if (!asList(DB2, SYBASE).contains(getDialect()))
|
||||
assertEquals(Arrays.asList(3, 2, 2, 1, 0, 1, 0, 1, 0, 1, 0), result.getValues(3));
|
||||
|
||||
// ROLLUP clause
|
||||
// -------------
|
||||
result = create().select(
|
||||
TBook_ID(),
|
||||
TBook_AUTHOR_ID(),
|
||||
grouping(TBook_ID()),
|
||||
groupingId)
|
||||
.from(TBook())
|
||||
.groupBy(rollup(
|
||||
TBook_ID(),
|
||||
TBook_AUTHOR_ID()))
|
||||
.orderBy(
|
||||
TBook_ID().asc().nullsFirst(),
|
||||
TBook_AUTHOR_ID().asc().nullsFirst()).fetch();
|
||||
|
||||
assertEquals(9, result.size());
|
||||
assertEquals(Arrays.asList(null, 1, 1, 2, 2, 3, 3, 4, 4), result.getValues(0));
|
||||
assertEquals(Arrays.asList(null, null, 1, null, 1, null, 2, null, 2), result.getValues(1));
|
||||
assertEquals(Arrays.asList(1, 0, 0, 0, 0, 0, 0, 0, 0), result.getValues(2));
|
||||
|
||||
if (!asList(DB2, SYBASE).contains(getDialect()))
|
||||
assertEquals(Arrays.asList(3, 1, 0, 1, 0, 1, 0, 1, 0), result.getValues(3));
|
||||
|
||||
// GROUPING SETS clause
|
||||
// --------------------
|
||||
result = create().select(
|
||||
|
||||
@ -1765,6 +1765,7 @@ public class Factory implements Configuration {
|
||||
* This has been observed to work with the following databases:
|
||||
* <ul>
|
||||
* <li>DB2</li>
|
||||
* <li>MySQL (simulated using the GROUP BY .. WITH ROLLUP clause)</li>
|
||||
* <li>Oracle</li>
|
||||
* <li>SQL Server</li>
|
||||
* <li>Sybase SQL Anywhere</li>
|
||||
@ -1781,7 +1782,7 @@ public class Factory implements Configuration {
|
||||
* @return A field to be used in a <code>GROUP BY</code> clause
|
||||
*/
|
||||
public static Field<?> rollup(Field<?>... fields) {
|
||||
return function("rollup", Object.class, fields);
|
||||
return new Rollup(fields);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
107
jOOQ/src/main/java/org/jooq/impl/Rollup.java
Normal file
107
jOOQ/src/main/java/org/jooq/impl/Rollup.java
Normal file
@ -0,0 +1,107 @@
|
||||
/**
|
||||
* Copyright (c) 2009-2011, Lukas Eder, lukas.eder@gmail.com
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed to you under the Apache License, Version 2.0
|
||||
* (the "License"); You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* . Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* . Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* . Neither the name "jOOQ" nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.impl.Factory.function;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.jooq.Attachable;
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Configuration;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.RenderContext;
|
||||
|
||||
/**
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
class Rollup extends AbstractFunction<Object> {
|
||||
|
||||
/**
|
||||
* Generated UID
|
||||
*/
|
||||
private static final long serialVersionUID = -5820608758939548704L;
|
||||
|
||||
Rollup(Field<?>... fields) {
|
||||
super("rollup", SQLDataType.OTHER, fields);
|
||||
}
|
||||
|
||||
@Override
|
||||
final Field<Object> getFunction0(Configuration configuration) {
|
||||
switch (configuration.getDialect()) {
|
||||
case MYSQL:
|
||||
return new WithRollup();
|
||||
|
||||
default:
|
||||
return function("rollup", Object.class, getArguments());
|
||||
}
|
||||
}
|
||||
|
||||
private class WithRollup extends AbstractField<Object> {
|
||||
|
||||
/**
|
||||
* Generated UID
|
||||
*/
|
||||
private static final long serialVersionUID = -1298546875559286735L;
|
||||
|
||||
WithRollup() {
|
||||
super("rollup", SQLDataType.OTHER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final List<Attachable> getAttachables() {
|
||||
return Rollup.this.getAttachables();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void toSQL(RenderContext context) {
|
||||
context.sql(new FieldList(Arrays.asList(getArguments())))
|
||||
.sql(" with rollup");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void bind(BindContext context) throws SQLException {
|
||||
context.bind(getArguments());
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean isNullLiteral() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user