fix queries like 'select ... where ...' with no 'from' clause
this was another bug that resulted from the unnecessary use of the untypesafe getChild() method in SemanticQueryBuilder. It's really important that we migrate away from that, who knows how many other bugs are lurking?
This commit is contained in:
parent
c402431b9f
commit
296cbb88bd
|
@ -291,7 +291,7 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
|
||||||
Class<R> expectedResultType,
|
Class<R> expectedResultType,
|
||||||
SqmCreationOptions creationOptions,
|
SqmCreationOptions creationOptions,
|
||||||
SqmCreationContext creationContext) {
|
SqmCreationContext creationContext) {
|
||||||
return new SemanticQueryBuilder<R>( expectedResultType, creationOptions, creationContext ).visitStatement( hqlParseTree );
|
return new SemanticQueryBuilder<>( expectedResultType, creationOptions, creationContext ).visitStatement( hqlParseTree );
|
||||||
}
|
}
|
||||||
|
|
||||||
private final Class<R> expectedResultType;
|
private final Class<R> expectedResultType;
|
||||||
|
@ -843,7 +843,7 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
|
||||||
}
|
}
|
||||||
final String searchAttributeName = visitIdentifier( (HqlParser.IdentifierContext) ctx.getChild( ctx.getChildCount() - 1 ) );
|
final String searchAttributeName = visitIdentifier( (HqlParser.IdentifierContext) ctx.getChild( ctx.getChildCount() - 1 ) );
|
||||||
final HqlParser.SearchSpecificationsContext searchCtx = (HqlParser.SearchSpecificationsContext) ctx.getChild( 4 );
|
final HqlParser.SearchSpecificationsContext searchCtx = (HqlParser.SearchSpecificationsContext) ctx.getChild( 4 );
|
||||||
final List<JpaSearchOrder> searchOrders = new ArrayList<>( ( searchCtx.getChildCount() + 1 ) >> 1 );;
|
final List<JpaSearchOrder> searchOrders = new ArrayList<>( ( searchCtx.getChildCount() + 1 ) >> 1 );
|
||||||
final List<ParseTree> children = searchCtx.children;
|
final List<ParseTree> children = searchCtx.children;
|
||||||
final JpaCteCriteriaType<?> type = cteDefinition.getType();
|
final JpaCteCriteriaType<?> type = cteDefinition.getType();
|
||||||
for ( int i = 0; i < children.size(); i += 2 ) {
|
for ( int i = 0; i < children.size(); i += 2 ) {
|
||||||
|
@ -913,9 +913,9 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SqmQueryPart<Object> visitQuerySpecExpression(HqlParser.QuerySpecExpressionContext ctx) {
|
public SqmQueryPart<?> visitQuerySpecExpression(HqlParser.QuerySpecExpressionContext ctx) {
|
||||||
final List<ParseTree> children = ctx.children;
|
final List<ParseTree> children = ctx.children;
|
||||||
final SqmQueryPart<Object> queryPart = visitQuery( (HqlParser.QueryContext) children.get( 0 ) );
|
final SqmQueryPart<?> queryPart = visitQuery( (HqlParser.QueryContext) children.get( 0 ) );
|
||||||
if ( children.size() > 1 ) {
|
if ( children.size() > 1 ) {
|
||||||
visitQueryOrder( queryPart, (HqlParser.QueryOrderContext) children.get( 1 ) );
|
visitQueryOrder( queryPart, (HqlParser.QueryOrderContext) children.get( 1 ) );
|
||||||
}
|
}
|
||||||
|
@ -1115,28 +1115,14 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SqmQuerySpec<Object> visitQuery(HqlParser.QueryContext ctx) {
|
public SqmQuerySpec<?> visitQuery(HqlParser.QueryContext ctx) {
|
||||||
//noinspection unchecked
|
final SqmQuerySpec<?> sqmQuerySpec = currentQuerySpec();
|
||||||
final SqmQuerySpec<Object> sqmQuerySpec = (SqmQuerySpec<Object>) currentQuerySpec();
|
|
||||||
final int fromIndex;
|
|
||||||
if ( ctx.getChild( 0 ) instanceof HqlParser.FromClauseContext ) {
|
|
||||||
fromIndex = 0;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
fromIndex = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// visit from-clause first!!!
|
// visit from-clause first!!!
|
||||||
visitFromClause( (HqlParser.FromClauseContext) ctx.getChild( fromIndex ) );
|
visitFromClause( ctx.fromClause() );
|
||||||
|
|
||||||
final SqmSelectClause selectClause;
|
final SqmSelectClause selectClause;
|
||||||
if ( fromIndex == 1 ) {
|
if ( ctx.selectClause() == null ) {
|
||||||
selectClause = visitSelectClause( (HqlParser.SelectClauseContext) ctx.getChild( 0 ) );
|
|
||||||
}
|
|
||||||
else if ( ctx.getChild( ctx.getChildCount() - 1 ) instanceof HqlParser.SelectClauseContext ) {
|
|
||||||
selectClause = visitSelectClause( (HqlParser.SelectClauseContext) ctx.getChild( ctx.getChildCount() - 1 ) );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if ( creationOptions.useStrictJpaCompliance() ) {
|
if ( creationOptions.useStrictJpaCompliance() ) {
|
||||||
throw new StrictJpaComplianceViolation(
|
throw new StrictJpaComplianceViolation(
|
||||||
"Encountered implicit select-clause, but strict JPQL compliance was requested",
|
"Encountered implicit select-clause, but strict JPQL compliance was requested",
|
||||||
|
@ -1146,24 +1132,22 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
|
||||||
log.debugf( "Encountered implicit select clause : %s", ctx.getText() );
|
log.debugf( "Encountered implicit select clause : %s", ctx.getText() );
|
||||||
selectClause = buildInferredSelectClause( sqmQuerySpec.getFromClause() );
|
selectClause = buildInferredSelectClause( sqmQuerySpec.getFromClause() );
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
selectClause = visitSelectClause( ctx.selectClause() );
|
||||||
|
}
|
||||||
sqmQuerySpec.setSelectClause( selectClause );
|
sqmQuerySpec.setSelectClause( selectClause );
|
||||||
|
|
||||||
int currentIndex = fromIndex + 1;
|
|
||||||
final SqmWhereClause whereClause = new SqmWhereClause( creationContext.getNodeBuilder() );
|
final SqmWhereClause whereClause = new SqmWhereClause( creationContext.getNodeBuilder() );
|
||||||
if ( currentIndex < ctx.getChildCount() && ctx.getChild( currentIndex ) instanceof HqlParser.WhereClauseContext ) {
|
if ( ctx.whereClause() != null ) {
|
||||||
whereClause.setPredicate( (SqmPredicate) ctx.getChild( currentIndex++ ).accept( this ) );
|
whereClause.setPredicate( (SqmPredicate) ctx.whereClause().accept( this ) );
|
||||||
}
|
}
|
||||||
sqmQuerySpec.setWhereClause( whereClause );
|
sqmQuerySpec.setWhereClause( whereClause );
|
||||||
|
|
||||||
if ( currentIndex < ctx.getChildCount() && ctx.getChild( currentIndex ) instanceof HqlParser.GroupByClauseContext ) {
|
if ( ctx.groupByClause() != null ) {
|
||||||
sqmQuerySpec.setGroupByClauseExpressions(
|
sqmQuerySpec.setGroupByClauseExpressions( visitGroupByClause( ctx.groupByClause() ) );
|
||||||
visitGroupByClause( (HqlParser.GroupByClauseContext) ctx.getChild( currentIndex++ ) )
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
if ( currentIndex < ctx.getChildCount() && ctx.getChild( currentIndex ) instanceof HqlParser.HavingClauseContext ) {
|
if ( ctx.havingClause() != null ) {
|
||||||
sqmQuerySpec.setHavingClausePredicate(
|
sqmQuerySpec.setHavingClausePredicate( visitHavingClause( ctx.havingClause() ) );
|
||||||
visitHavingClause( (HqlParser.HavingClauseContext) ctx.getChild( currentIndex ) )
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return sqmQuerySpec;
|
return sqmQuerySpec;
|
||||||
|
|
|
@ -1604,4 +1604,36 @@ public class FunctionTests {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIn(SessionFactoryScope scope) {
|
||||||
|
scope.inTransaction(
|
||||||
|
session -> {
|
||||||
|
assertEquals( 1,
|
||||||
|
session.createQuery("select 1 where 1 in (:list)")
|
||||||
|
.setParameterList("list",List.of(1,2))
|
||||||
|
.list().size() );
|
||||||
|
assertEquals( 0,
|
||||||
|
session.createQuery("select 1 where 1 in (:list)")
|
||||||
|
.setParameterList("list",List.of(0,3,2))
|
||||||
|
.list().size() );
|
||||||
|
assertEquals( 0,
|
||||||
|
session.createQuery("select 1 where 1 in (:list)")
|
||||||
|
.setParameterList("list",List.of())
|
||||||
|
.list().size() );
|
||||||
|
assertEquals( 1,
|
||||||
|
session.createQuery("select 1 where 1 in :list")
|
||||||
|
.setParameterList("list",List.of(1,2))
|
||||||
|
.list().size() );
|
||||||
|
assertEquals( 0,
|
||||||
|
session.createQuery("select 1 where 1 in :list")
|
||||||
|
.setParameterList("list",List.of(0,3,2))
|
||||||
|
.list().size() );
|
||||||
|
assertEquals( 0,
|
||||||
|
session.createQuery("select 1 where 1 in :list")
|
||||||
|
.setParameterList("list",List.of())
|
||||||
|
.list().size() );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue