use of org.hibernate.query.sqm.FrameMode in project hibernate-orm by hibernate.
the class SemanticQueryBuilder method applyOverClause.
private SqmExpression<?> applyOverClause(HqlParser.OverClauseContext ctx, SqmFunction<?> function) {
final List<SqmExpression<?>> partitions;
final List<SqmSortSpecification> orderList;
final FrameMode mode;
final FrameKind startKind;
final SqmExpression<?> startExpression;
final FrameKind endKind;
final SqmExpression<?> endExpression;
final FrameExclusion exclusion;
int index = 2;
if (ctx.getChild(index) instanceof HqlParser.PartitionClauseContext) {
final ParseTree subCtx = ctx.getChild(index);
partitions = new ArrayList<>((subCtx.getChildCount() >> 1) - 1);
for (int i = 2; i < subCtx.getChildCount(); i += 2) {
partitions.add((SqmExpression<?>) subCtx.getChild(i).accept(this));
}
index++;
} else {
partitions = Collections.emptyList();
}
if (index < ctx.getChildCount() && ctx.getChild(index) instanceof HqlParser.OrderByClauseContext) {
orderList = visitOrderByClause((HqlParser.OrderByClauseContext) ctx.getChild(index)).getSortSpecifications();
index++;
} else {
orderList = Collections.emptyList();
}
if (index < ctx.getChildCount() && ctx.getChild(index) instanceof HqlParser.FrameClauseContext) {
final ParseTree frameCtx = ctx.getChild(index);
switch(((TerminalNode) frameCtx.getChild(0)).getSymbol().getType()) {
case HqlParser.RANGE:
mode = FrameMode.RANGE;
break;
case HqlParser.ROWS:
mode = FrameMode.ROWS;
break;
case HqlParser.GROUPS:
mode = FrameMode.GROUPS;
break;
default:
throw new IllegalArgumentException("Unexpected frame mode: " + frameCtx.getChild(0));
}
final int frameStartIndex;
if (frameCtx.getChild(1) instanceof TerminalNode) {
frameStartIndex = 2;
endKind = getFrameKind(frameCtx.getChild(4));
endExpression = endKind == FrameKind.OFFSET_FOLLOWING || endKind == FrameKind.OFFSET_PRECEDING ? (SqmExpression<?>) frameCtx.getChild(4).getChild(0).accept(this) : null;
} else {
frameStartIndex = 1;
endKind = FrameKind.CURRENT_ROW;
endExpression = null;
}
startKind = getFrameKind(frameCtx.getChild(frameStartIndex));
startExpression = startKind == FrameKind.OFFSET_FOLLOWING || startKind == FrameKind.OFFSET_PRECEDING ? (SqmExpression<?>) frameCtx.getChild(frameStartIndex).getChild(0).accept(this) : null;
final ParseTree lastChild = frameCtx.getChild(frameCtx.getChildCount() - 1);
if (lastChild instanceof HqlParser.FrameExclusionContext) {
switch(((TerminalNode) lastChild.getChild(1)).getSymbol().getType()) {
case HqlParser.CURRENT:
exclusion = FrameExclusion.CURRENT_ROW;
break;
case HqlParser.GROUP:
exclusion = FrameExclusion.GROUP;
break;
case HqlParser.TIES:
exclusion = FrameExclusion.TIES;
break;
case HqlParser.NO:
exclusion = FrameExclusion.NO_OTHERS;
break;
default:
throw new IllegalArgumentException("Unexpected frame exclusion: " + lastChild);
}
} else {
exclusion = FrameExclusion.NO_OTHERS;
}
} else {
mode = FrameMode.ROWS;
startKind = FrameKind.UNBOUNDED_PRECEDING;
startExpression = null;
endKind = FrameKind.CURRENT_ROW;
endExpression = null;
exclusion = FrameExclusion.NO_OTHERS;
}
return new SqmOver<>(function, partitions, orderList, mode, startKind, startExpression, endKind, endExpression, exclusion);
}
Aggregations