use of org.hibernate.query.sqm.tree.expression.SqmExpression 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);
}
use of org.hibernate.query.sqm.tree.expression.SqmExpression in project hibernate-orm by hibernate.
the class SemanticQueryBuilder method resolveOrderByOrGroupByExpression.
private SqmExpression<?> resolveOrderByOrGroupByExpression(ParseTree child, boolean definedCollate) {
if (child instanceof TerminalNode) {
if (definedCollate) {
// This is syntactically disallowed
throw new ParsingException("COLLATE is not allowed for position based order-by or group-by items");
}
final int position = Integer.parseInt(child.getText());
// make sure this selection exists
final SqmAliasedNode<?> nodeByPosition = getCurrentProcessingState().getPathRegistry().findAliasedNodeByPosition(position);
if (nodeByPosition == null) {
throw new ParsingException("Numeric literal '" + position + "' used in group-by does not match a registered select-item");
}
return new SqmAliasedNodeRef(position, integerDomainType, creationContext.getNodeBuilder());
} else if (child instanceof HqlParser.IdentifierContext) {
final String identifierText = visitIdentifier((HqlParser.IdentifierContext) child);
final Integer correspondingPosition = getCurrentProcessingState().getPathRegistry().findAliasedNodePosition(identifierText);
if (correspondingPosition != null) {
if (definedCollate) {
// This is syntactically disallowed
throw new ParsingException("COLLATE is not allowed for alias based order-by or group-by items");
}
return new SqmAliasedNodeRef(correspondingPosition, integerDomainType, creationContext.getNodeBuilder());
}
final SqmFrom<?, ?> sqmFrom = getCurrentProcessingState().getPathRegistry().findFromByAlias(identifierText, true);
if (sqmFrom != null) {
if (definedCollate) {
// This is syntactically disallowed
throw new ParsingException("COLLATE is not allowed for alias based order-by or group-by items");
}
// this will group-by all of the sub-parts in the from-element's model part
return sqmFrom;
}
final DotIdentifierConsumer dotIdentifierConsumer = dotIdentifierConsumerStack.getCurrent();
dotIdentifierConsumer.consumeIdentifier(identifierText, true, true);
return (SqmExpression<?>) dotIdentifierConsumer.getConsumedPart();
}
return (SqmExpression<?>) child.accept(this);
}
use of org.hibernate.query.sqm.tree.expression.SqmExpression in project hibernate-orm by hibernate.
the class SemanticQueryBuilder method visitTrimFunction.
@Override
public SqmExpression<?> visitTrimFunction(HqlParser.TrimFunctionContext ctx) {
final SqmExpression<?> source = (SqmExpression<?>) ctx.getChild(ctx.getChildCount() - 2).accept(this);
final SqmTrimSpecification trimSpec;
final SqmLiteral<Character> trimChar;
int index = 2;
ParseTree parseTree = ctx.getChild(index);
if (parseTree instanceof HqlParser.TrimSpecificationContext) {
trimSpec = visitTrimSpecification((HqlParser.TrimSpecificationContext) parseTree);
index = 3;
} else {
trimSpec = visitTrimSpecification(null);
}
parseTree = ctx.getChild(index);
if (parseTree instanceof HqlParser.TrimCharacterContext) {
trimChar = visitTrimCharacter((HqlParser.TrimCharacterContext) parseTree);
} else {
trimChar = visitTrimCharacter(null);
}
return getFunctionDescriptor("trim").generateSqmExpression(asList(trimSpec, trimChar, source), null, creationContext.getQueryEngine(), creationContext.getJpaMetamodel().getTypeConfiguration());
}
use of org.hibernate.query.sqm.tree.expression.SqmExpression in project hibernate-orm by hibernate.
the class SemanticQueryBuilder method visitGroupByClause.
@Override
public List<SqmExpression<?>> visitGroupByClause(HqlParser.GroupByClauseContext ctx) {
final int size = ctx.getChildCount();
// Shift 1 bit instead of division by 2
final int estimateExpressionsCount = (size >> 1) - 1;
final List<SqmExpression<?>> expressions = new ArrayList<>(estimateExpressionsCount);
for (int i = 0; i < size; i++) {
final ParseTree parseTree = ctx.getChild(i);
if (parseTree instanceof HqlParser.GroupByExpressionContext) {
expressions.add((SqmExpression<?>) parseTree.accept(this));
}
}
return expressions;
}
use of org.hibernate.query.sqm.tree.expression.SqmExpression in project hibernate-orm by hibernate.
the class SemanticQueryBuilder method visitCollateFunction.
@Override
public Object visitCollateFunction(HqlParser.CollateFunctionContext ctx) {
if (creationOptions.useStrictJpaCompliance()) {
throw new StrictJpaComplianceViolation(StrictJpaComplianceViolation.Type.COLLATIONS);
}
final SqmExpression<?> expressionToCollate = (SqmExpression<?>) ctx.getChild(2).accept(this);
final SqmCollation castTargetExpression = (SqmCollation) ctx.getChild(4).accept(this);
return getFunctionDescriptor("collate").generateSqmExpression(asList(expressionToCollate, castTargetExpression), // why not string?
null, creationContext.getQueryEngine(), creationContext.getJpaMetamodel().getTypeConfiguration());
}
Aggregations