Search in sources :

Example 1 with FrameKind

use of org.hibernate.query.sqm.FrameKind 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);
}
Also used : FrameExclusion(org.hibernate.query.sqm.FrameExclusion) FrameKind(org.hibernate.query.sqm.FrameKind) SqmSortSpecification(org.hibernate.query.sqm.tree.select.SqmSortSpecification) SqmExpression(org.hibernate.query.sqm.tree.expression.SqmExpression) HqlParser(org.hibernate.grammars.hql.HqlParser) FrameMode(org.hibernate.query.sqm.FrameMode) TerminalNode(org.antlr.v4.runtime.tree.TerminalNode) SqmOver(org.hibernate.query.sqm.tree.expression.SqmOver) ParseTree(org.antlr.v4.runtime.tree.ParseTree)

Aggregations

ParseTree (org.antlr.v4.runtime.tree.ParseTree)1 TerminalNode (org.antlr.v4.runtime.tree.TerminalNode)1 HqlParser (org.hibernate.grammars.hql.HqlParser)1 FrameExclusion (org.hibernate.query.sqm.FrameExclusion)1 FrameKind (org.hibernate.query.sqm.FrameKind)1 FrameMode (org.hibernate.query.sqm.FrameMode)1 SqmExpression (org.hibernate.query.sqm.tree.expression.SqmExpression)1 SqmOver (org.hibernate.query.sqm.tree.expression.SqmOver)1 SqmSortSpecification (org.hibernate.query.sqm.tree.select.SqmSortSpecification)1