HHH-16347 Disable alias and positional order-by items in OVER and WITHIN GROUP clauses

This commit is contained in:
Marco Belladelli 2023-04-17 13:47:22 +02:00
parent 6990346506
commit bb26212f24
No known key found for this signature in database
GPG Key ID: D1D0C3030AE3AA35
1 changed files with 40 additions and 11 deletions

View File

@ -1414,7 +1414,10 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
return expressions; return expressions;
} }
private SqmExpression<?> resolveOrderByOrGroupByExpression(ParseTree child, boolean definedCollate) { private SqmExpression<?> resolveOrderByOrGroupByExpression(
ParseTree child,
boolean definedCollate,
boolean allowPositionalOrAliases) {
final SqmCreationProcessingState processingState = getCurrentProcessingState(); final SqmCreationProcessingState processingState = getCurrentProcessingState();
final SqmQuery<?> processingQuery = processingState.getProcessingQuery(); final SqmQuery<?> processingQuery = processingState.getProcessingQuery();
final SqmQueryPart<?> queryPart; final SqmQueryPart<?> queryPart;
@ -1432,6 +1435,10 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
// This is syntactically disallowed // This is syntactically disallowed
throw new ParsingException( "COLLATE is not allowed for position based order-by or group-by items" ); throw new ParsingException( "COLLATE is not allowed for position based order-by or group-by items" );
} }
else if ( !allowPositionalOrAliases ) {
// This is syntactically disallowed
throw new ParsingException( "Position based order-by is not allowed in OVER or WITHIN GROUP clauses" );
}
final int position = Integer.parseInt( child.getText() ); final int position = Integer.parseInt( child.getText() );
@ -1508,8 +1515,9 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
} }
} }
else { else {
final Integer correspondingPosition = processingState.getPathRegistry() final Integer correspondingPosition = allowPositionalOrAliases ?
.findAliasedNodePosition( identifierText ); processingState.getPathRegistry().findAliasedNodePosition( identifierText ) :
null;
if ( correspondingPosition != null ) { if ( correspondingPosition != null ) {
if ( definedCollate ) { if ( definedCollate ) {
// This is syntactically disallowed // This is syntactically disallowed
@ -1546,7 +1554,7 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
@Override @Override
public SqmExpression<?> visitGroupByExpression(HqlParser.GroupByExpressionContext ctx) { public SqmExpression<?> visitGroupByExpression(HqlParser.GroupByExpressionContext ctx) {
return resolveOrderByOrGroupByExpression( ctx.getChild( 0 ), ctx.getChildCount() > 1 ); return resolveOrderByOrGroupByExpression( ctx.getChild( 0 ), ctx.getChildCount() > 1, true );
} }
@Override @Override
@ -1556,6 +1564,10 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
@Override @Override
public SqmOrderByClause visitOrderByClause(HqlParser.OrderByClauseContext ctx) { public SqmOrderByClause visitOrderByClause(HqlParser.OrderByClauseContext ctx) {
return visitOrderByClause( ctx, true );
}
private SqmOrderByClause visitOrderByClause(HqlParser.OrderByClauseContext ctx, boolean allowPositionalOrAliases) {
final int size = ctx.getChildCount(); final int size = ctx.getChildCount();
// Shift 1 bit instead of division by 2 // Shift 1 bit instead of division by 2
final int estimateExpressionsCount = ( size >> 1 ) - 1; final int estimateExpressionsCount = ( size >> 1 ) - 1;
@ -1563,9 +1575,10 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
for ( int i = 0; i < size; i++ ) { for ( int i = 0; i < size; i++ ) {
final ParseTree parseTree = ctx.getChild( i ); final ParseTree parseTree = ctx.getChild( i );
if ( parseTree instanceof HqlParser.SortSpecificationContext ) { if ( parseTree instanceof HqlParser.SortSpecificationContext ) {
orderByClause.addSortSpecification( orderByClause.addSortSpecification( visitSortSpecification(
visitSortSpecification( (HqlParser.SortSpecificationContext) parseTree ) (HqlParser.SortSpecificationContext) parseTree,
); allowPositionalOrAliases
) );
} }
} }
return orderByClause; return orderByClause;
@ -1573,7 +1586,16 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
@Override @Override
public SqmSortSpecification visitSortSpecification(HqlParser.SortSpecificationContext ctx) { public SqmSortSpecification visitSortSpecification(HqlParser.SortSpecificationContext ctx) {
final SqmExpression<?> sortExpression = visitSortExpression( (HqlParser.SortExpressionContext) ctx.getChild( 0 ) ); return visitSortSpecification( ctx, true );
}
private SqmSortSpecification visitSortSpecification(
HqlParser.SortSpecificationContext ctx,
boolean allowPositionalOrAliases) {
final SqmExpression<?> sortExpression = visitSortExpression(
(HqlParser.SortExpressionContext) ctx.getChild( 0 ),
allowPositionalOrAliases
);
if ( sortExpression == null ) { if ( sortExpression == null ) {
throw new ParsingException( "Could not resolve sort-expression : " + ctx.getChild( 0 ).getText() ); throw new ParsingException( "Could not resolve sort-expression : " + ctx.getChild( 0 ).getText() );
} }
@ -1629,7 +1651,11 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
@Override @Override
public SqmExpression<?> visitSortExpression(HqlParser.SortExpressionContext ctx) { public SqmExpression<?> visitSortExpression(HqlParser.SortExpressionContext ctx) {
return resolveOrderByOrGroupByExpression( ctx.getChild( 0 ), ctx.getChildCount() > 1 ); return visitSortExpression( ctx, true );
}
public SqmExpression<?> visitSortExpression(HqlParser.SortExpressionContext ctx, boolean allowPositionalOrAliases) {
return resolveOrderByOrGroupByExpression( ctx.getChild( 0 ), ctx.getChildCount() > 1, allowPositionalOrAliases );
} }
private SqmQuerySpec<?> currentQuerySpec() { private SqmQuerySpec<?> currentQuerySpec() {
@ -4602,7 +4628,7 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
} }
} }
if ( ctx != null ) { if ( ctx != null ) {
return visitOrderByClause( (HqlParser.OrderByClauseContext) ctx.getChild( 3 ) ); return visitOrderByClause( (HqlParser.OrderByClauseContext) ctx.getChild( 3 ), false );
} }
return null; return null;
} }
@ -4670,7 +4696,10 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
partitions = Collections.emptyList(); partitions = Collections.emptyList();
} }
if ( index < ctx.getChildCount() && ctx.getChild( index ) instanceof HqlParser.OrderByClauseContext ) { if ( index < ctx.getChildCount() && ctx.getChild( index ) instanceof HqlParser.OrderByClauseContext ) {
orderList = visitOrderByClause( (HqlParser.OrderByClauseContext) ctx.getChild( index ) ).getSortSpecifications(); orderList = visitOrderByClause(
(HqlParser.OrderByClauseContext) ctx.getChild( index ),
false
).getSortSpecifications();
index++; index++;
} }
else { else {