Include the WITH clause AST in the FromElement so that column references can be analyzed
This commit is contained in:
parent
05e6a41e5f
commit
0c0248d448
|
@ -509,7 +509,7 @@ public class HqlSqlWalker extends HqlSqlBaseWalker implements ErrorReporter, Par
|
|||
SqlGenerator sql = new SqlGenerator( getSessionFactoryHelper().getFactory() );
|
||||
sql.whereExpr( hqlSqlWithNode.getFirstChild() );
|
||||
|
||||
fromElement.setWithClauseFragment( "(" + sql.getSQL() + ")" );
|
||||
fromElement.setWithClauseFragment( hqlSqlWithNode.getFirstChild(), "(" + sql.getSQL() + ")" );
|
||||
}
|
||||
catch (SemanticException e) {
|
||||
throw e;
|
||||
|
|
|
@ -13,6 +13,7 @@ import java.util.List;
|
|||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import antlr.collections.AST;
|
||||
import org.hibernate.QueryException;
|
||||
import org.hibernate.engine.internal.JoinSequence;
|
||||
import org.hibernate.hql.internal.CollectionProperties;
|
||||
|
@ -69,6 +70,7 @@ public class FromElement extends HqlSqlWalkerNode implements DisplayableNode, Pa
|
|||
private boolean useWhereFragment = true;
|
||||
private List<FromElement> destinations;
|
||||
private boolean manyToMany;
|
||||
private AST withClauseAst;
|
||||
private String withClauseFragment;
|
||||
private boolean dereferencedBySuperclassProperty;
|
||||
private boolean dereferencedBySubclassProperty;
|
||||
|
@ -627,11 +629,16 @@ public class FromElement extends HqlSqlWalkerNode implements DisplayableNode, Pa
|
|||
isAllPropertyFetch = fetch;
|
||||
}
|
||||
|
||||
public AST getWithClauseAst() {
|
||||
return withClauseAst;
|
||||
}
|
||||
|
||||
public String getWithClauseFragment() {
|
||||
return withClauseFragment;
|
||||
}
|
||||
|
||||
public void setWithClauseFragment(String withClauseFragment) {
|
||||
public void setWithClauseFragment(AST ast, String withClauseFragment) {
|
||||
this.withClauseAst = ast;
|
||||
this.withClauseFragment = withClauseFragment;
|
||||
}
|
||||
|
||||
|
|
|
@ -103,24 +103,6 @@ public class JoinProcessor implements SqlTokenTypes {
|
|||
}
|
||||
}
|
||||
|
||||
private <T extends AST> List<T> findAllNodes(AST node, Class<T> clazz) {
|
||||
ArrayList<T> found = new ArrayList<>();
|
||||
doFindAllNodes( node, clazz, found );
|
||||
return found;
|
||||
}
|
||||
|
||||
private <T extends AST> void doFindAllNodes(AST node, Class<T> clazz, List<T> found) {
|
||||
if ( clazz.isAssignableFrom( node.getClass() ) ) {
|
||||
found.add( (T) node );
|
||||
}
|
||||
if ( node.getFirstChild() != null ) {
|
||||
doFindAllNodes( node.getFirstChild(), clazz, found );
|
||||
}
|
||||
if ( node.getNextSibling() != null ) {
|
||||
doFindAllNodes( node.getNextSibling(), clazz, found );
|
||||
}
|
||||
}
|
||||
|
||||
private Set<String> findQueryReferencedTables(QueryNode query) {
|
||||
if ( !walker.getSessionFactoryHelper()
|
||||
.getFactory()
|
||||
|
@ -150,16 +132,15 @@ public class JoinProcessor implements SqlTokenTypes {
|
|||
Set<String> result = new HashSet<>();
|
||||
|
||||
// Find tables referenced by FromReferenceNodes
|
||||
List<FromReferenceNode> fromReferenceNodes = findAllNodes( query, FromReferenceNode.class );
|
||||
for ( FromReferenceNode node : fromReferenceNodes ) {
|
||||
String[] tables = node.getReferencedTables();
|
||||
if ( tables != null ) {
|
||||
for ( String table : tables ) {
|
||||
result.add( table );
|
||||
}
|
||||
collectReferencedTables( new ASTIterator( query ), result );
|
||||
for (FromElement fromElement : (List<FromElement>) query.getFromClause().getFromElements()) {
|
||||
AST withClauseAst = fromElement.getWithClauseAst();
|
||||
if ( withClauseAst != null ) {
|
||||
collectReferencedTables( new ASTIterator( withClauseAst ), result );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Find tables referenced by fromElementsForLoad
|
||||
if ( query.getSelectClause() != null ) {
|
||||
for ( Object element : query.getSelectClause().getFromElementsForLoad() ) {
|
||||
|
@ -178,6 +159,21 @@ public class JoinProcessor implements SqlTokenTypes {
|
|||
return result;
|
||||
}
|
||||
|
||||
private void collectReferencedTables(ASTIterator iterator, Set<String> result) {
|
||||
while ( iterator.hasNext() ) {
|
||||
AST node = iterator.nextNode();
|
||||
if ( node instanceof FromReferenceNode ) {
|
||||
FromReferenceNode fromReferenceNode = (FromReferenceNode) node;
|
||||
String[] tables = fromReferenceNode.getReferencedTables();
|
||||
if ( tables != null ) {
|
||||
for ( String table : tables ) {
|
||||
result.add( table );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void processJoins(QueryNode query) {
|
||||
final FromClause fromClause = query.getFromClause();
|
||||
|
||||
|
|
|
@ -54,6 +54,13 @@ public class HHH13670Test extends BaseCoreFunctionalTestCase {
|
|||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDereferenceSuperClassAttributeInWithClause() {
|
||||
doInJPA(this::sessionFactory, em -> {
|
||||
em.createQuery("SELECT subB_0.id FROM SubB subB_0 LEFT JOIN subB_0.other subA_0 ON subA_0.id = subB_0.parent.id", Tuple.class).getResultList();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRootTypeJoinWithGroupJoins() {
|
||||
doInJPA(this::sessionFactory, em -> {
|
||||
|
@ -99,13 +106,6 @@ public class HHH13670Test extends BaseCoreFunctionalTestCase {
|
|||
return new Class<?>[] { Super.class, SubA.class, SubB.class };
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(Configuration configuration) {
|
||||
super.afterConfigurationBuilt( configuration );
|
||||
// Uncomment to fix tests
|
||||
// configuration.setProperty( AvailableSettings.OMIT_JOIN_OF_SUPERCLASS_TABLES, "false" );
|
||||
}
|
||||
|
||||
@Entity(name = "Super")
|
||||
@Inheritance(strategy = InheritanceType.JOINED)
|
||||
public static class Super<SubType extends Super> {
|
||||
|
@ -134,6 +134,9 @@ public class HHH13670Test extends BaseCoreFunctionalTestCase {
|
|||
@Entity(name = "SubB")
|
||||
public static class SubB extends Super<SubA> {
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
Super other;
|
||||
|
||||
SubB() {}
|
||||
|
||||
SubB(Long id, Super parent) {
|
||||
|
|
Loading…
Reference in New Issue