Add rollup() and cube() for group by clause
This syntax is supported on at least DB2, Oracle, SQL Server, and Postgres. It's not supported on MySQL.
This commit is contained in:
parent
5b614ab454
commit
01d3485970
|
@ -157,6 +157,7 @@ COLLATE : [cC] [oO] [lL] [lL] [aA] [tT] [eE];
|
|||
CONCAT : [cC] [oO] [nN] [cC] [aA] [tT];
|
||||
COUNT : [cC] [oO] [uU] [nN] [tT];
|
||||
CROSS : [cC] [rR] [oO] [sS] [sS];
|
||||
CUBE : [cC] [uU] [bB] [eE];
|
||||
CURRENT : [cC] [uU] [rR] [rR] [eE] [nN] [tT];
|
||||
CURRENT_DATE : [cC] [uU] [rR] [rR] [eE] [nN] [tT] '_' [dD] [aA] [tT] [eE];
|
||||
CURRENT_INSTANT : [cC] [uU] [rR] [rR] [eE] [nN] [tT] '_' [iI] [nN] [sS] [tT] [aA] [nN] [tT]; //deprecated legacy
|
||||
|
@ -246,6 +247,7 @@ POWER : [pP] [oO] [wW] [eE] [rR];
|
|||
QUARTER : [qQ] [uU] [aA] [rR] [tT] [eE] [rR];
|
||||
REPLACE : [rR] [eE] [pP] [lL] [aA] [cC] [eE];
|
||||
RIGHT : [rR] [iI] [gG] [hH] [tT];
|
||||
ROLLUP : [rR] [oO] [lL] [lL] [uU] [pP];
|
||||
ROUND : [rR] [oO] [uU] [nN] [dD];
|
||||
SECOND : [sS] [eE] [cC] [oO] [nN] [dD];
|
||||
SELECT : [sS] [eE] [lL] [eE] [cC] [tT];
|
||||
|
|
|
@ -723,6 +723,8 @@ standardFunction
|
|||
| localTimeFunction
|
||||
| localDateTimeFunction
|
||||
| offsetDateTimeFunction
|
||||
| cube
|
||||
| rollup
|
||||
;
|
||||
|
||||
|
||||
|
@ -1041,6 +1043,14 @@ positionFunctionStringArgument
|
|||
: expression
|
||||
;
|
||||
|
||||
cube
|
||||
: CUBE LEFT_PAREN expression (COMMA expression)* RIGHT_PAREN
|
||||
;
|
||||
|
||||
rollup
|
||||
: ROLLUP LEFT_PAREN expression (COMMA expression)* RIGHT_PAREN
|
||||
;
|
||||
|
||||
/**
|
||||
* The `identifier` is used to provide "keyword as identifier" handling.
|
||||
*
|
||||
|
|
|
@ -341,6 +341,10 @@ public abstract class Dialect implements ConversionContext {
|
|||
|
||||
CommonFunctionFactory.aggregates(queryEngine);
|
||||
|
||||
//grouping functions cube() and rollup() supported on some databases
|
||||
|
||||
CommonFunctionFactory.groupings(queryEngine);
|
||||
|
||||
//the ANSI SQL-defined aggregate functions any() and every() are only
|
||||
//supported on one database, but can be emulated using sum() and case,
|
||||
//though there is a more natural mapping on some databases
|
||||
|
|
|
@ -1419,6 +1419,15 @@ public class CommonFunctionFactory {
|
|||
.register();
|
||||
}
|
||||
|
||||
public static void groupings(QueryEngine queryEngine) {
|
||||
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder("cube")
|
||||
.setMinArgumentCount(1)
|
||||
.register();
|
||||
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder("rollup")
|
||||
.setMinArgumentCount(1)
|
||||
.register();
|
||||
}
|
||||
|
||||
public static void aggregates(QueryEngine queryEngine) {
|
||||
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder("max")
|
||||
.setExactArgumentCount(1)
|
||||
|
|
|
@ -3002,6 +3002,36 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
|
|||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqmExpression visitCube(HqlParser.CubeContext ctx) {
|
||||
List<SqmTypedNode<?>> args = new ArrayList<>();
|
||||
for ( HqlParser.ExpressionContext arg: ctx.expression() ) {
|
||||
args.add( (SqmExpression) arg.accept( this ) );
|
||||
}
|
||||
//ignore DISTINCT
|
||||
return getFunctionDescriptor("cube").generateSqmExpression(
|
||||
args,
|
||||
resolveExpressableTypeBasic( Integer.class ),
|
||||
creationContext.getQueryEngine(),
|
||||
creationContext.getJpaMetamodel().getTypeConfiguration()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqmExpression visitRollup(HqlParser.RollupContext ctx) {
|
||||
List<SqmTypedNode<?>> args = new ArrayList<>();
|
||||
for ( HqlParser.ExpressionContext arg: ctx.expression() ) {
|
||||
args.add( (SqmExpression) arg.accept( this ) );
|
||||
}
|
||||
//ignore DISTINCT
|
||||
return getFunctionDescriptor("rollup").generateSqmExpression(
|
||||
args,
|
||||
resolveExpressableTypeBasic( Integer.class ),
|
||||
creationContext.getQueryEngine(),
|
||||
creationContext.getJpaMetamodel().getTypeConfiguration()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqmExpression visitSubstringFunction(HqlParser.SubstringFunctionContext ctx) {
|
||||
final SqmExpression source = (SqmExpression) ctx.expression().accept( this );
|
||||
|
|
|
@ -954,4 +954,18 @@ public class FunctionTests extends SessionFactoryBasedFunctionalTest {
|
|||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGroupingFunctions() {
|
||||
inTransaction(
|
||||
session -> {
|
||||
session.createQuery("select max(e.theDouble), e.gender, e.theInt from EntityOfBasics e group by e.gender, e.theInt")
|
||||
.list();
|
||||
session.createQuery("select avg(e.theDouble), e.gender, e.theInt from EntityOfBasics e group by rollup(e.gender, e.theInt)")
|
||||
.list();
|
||||
session.createQuery("select sum(e.theDouble), e.gender, e.theInt from EntityOfBasics e group by cube(e.gender, e.theInt)")
|
||||
.list();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue