Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
beikov committed Jul 15, 2024
1 parent aaf9962 commit a8f979f
Show file tree
Hide file tree
Showing 9 changed files with 60 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,14 @@ public interface DbmsDialect {
* @since 1.5.0
*/
public boolean supportsNestedCorrelations();

/**
* Returns true if the dbms supports correlations in the JOIN ON clause, false otherwise.
*
* @return Whether correlations are supported by the dbms in the JOIN ON clause
* @since 1.6.12
*/
public boolean supportsCorrelationInJoinOnClause();

/**
* Returns true if the dbms supports the with clause in modification queries, false otherwise.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1018,9 +1018,9 @@ private JoinResult correlate(JoinResult result, String rootAlias, Expression cor
alias = aliasManager.generateRootAlias(alias);
}
JoinAliasInfo rootAliasInfo = new JoinAliasInfo(alias, alias, true, true, aliasManager);
JoinNode joinNode = JoinNode.createEntityJoinNode(result.baseNode, JoinType.LEFT, result.baseNode.getEntityType(), rootAliasInfo, false);
result.baseNode.addEntityJoin(joinNode);
JoinNode joinNode = JoinNode.createEntityJoinNode(result.baseNode, JoinType.INNER, result.baseNode.getEntityType(), rootAliasInfo, false);
rootAliasInfo.setJoinNode(joinNode);
rootNodes.add(joinNode);
explicitJoinNodes.add(joinNode);
// register root alias in aliasManager
aliasManager.registerAliasInfo(rootAliasInfo);
Expand Down Expand Up @@ -1963,6 +1963,9 @@ private boolean shouldEmulateEntityJoin(JoinNode node) {
if (node.getJoinType() != JoinType.INNER) {
return false;
}
if (!mainQuery.dbmsDialect.supportsCorrelationInJoinOnClause() && node.isEntityJoinNode() && node.getAliasInfo().getAliasOwner() != node.getParent().getAliasInfo().getAliasOwner()) {
return true;
}
// in Hibernate < 5.1, we weren't able to refer to non-driving table aliases in the ON clause which can be worked around by emulating through a cross join
if (!mainQuery.jpaProvider.supportsNonDrivingAliasInOnClause()) {
// But this only works when the parent join node has no RIGHT or FULL joins
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,11 @@ public boolean supportsNestedCorrelations() {
return true;
}

@Override
public boolean supportsCorrelationInJoinOnClause() {
return true;
}

protected String getWindowFunctionDummyOrderBy() {
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,4 +153,11 @@ public Character getDefaultEscapeCharacter() {
public boolean supportsArbitraryLengthMultiset() {
return true;
}

@Override
public boolean supportsCorrelationInJoinOnClause() {
// It's not possible to do `from Document d where exists (select 1 from Person p join Document d2 on d = d2)`
// i.e. refer to the join alias of the outer query from the ON condition within a subquery
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,11 @@ public boolean supportsNestedCorrelations() {
return delegate.supportsNestedCorrelations();
}

@Override
public boolean supportsCorrelationInJoinOnClause() {
return delegate.supportsCorrelationInJoinOnClause();
}

@Override
public boolean supportsWithClauseInModificationQuery() {
return delegate.supportsWithClauseInModificationQuery();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,14 @@ public void testSubqueryCorrelatesArrayExpression() {
.from("Document[_ MEMBER OF d.owner.ownedDocuments AND LENGTH(d.owner.name) > 0]", "dSub")
.where("dSub").notEqExpression("d")
.end();
String expectedQuery = "SELECT d FROM Document d WHERE EXISTS (SELECT 1 FROM Document dSub, Document d_owner_base JOIN d_owner_base.owner owner_1 WHERE dSub MEMBER OF owner_1.ownedDocuments AND LENGTH(owner_1.name) > 0 AND d.id = d_owner_base.id AND dSub <> d)";

String expectedSubQuery;
if (jpaProvider.supportsEntityJoin()) {
expectedSubQuery = "SELECT 1 FROM Document dSub JOIN Document d_owner_base" + onClause("d.id = d_owner_base.id") + " JOIN d_owner_base.owner owner_1 WHERE dSub MEMBER OF owner_1.ownedDocuments AND LENGTH(owner_1.name) > 0 AND dSub <> d";
} else {
expectedSubQuery = "SELECT 1 FROM Document dSub, Document d_owner_base JOIN d_owner_base.owner owner_1 WHERE dSub MEMBER OF owner_1.ownedDocuments AND LENGTH(owner_1.name) > 0 AND d.id = d_owner_base.id AND dSub <> d";
}
String expectedQuery = "SELECT d FROM Document d WHERE EXISTS (" + expectedSubQuery + ")";
assertEquals(expectedQuery, crit.getQueryString());
crit.getResultList();
}
Expand All @@ -365,7 +372,14 @@ public void testSubqueryCorrelatesArrayExpressionEntityEqual() {
.from("Document[_ MEMBER OF d.owner.ownedDocuments AND LENGTH(d.owner.name) > 0]", "dSub")
.where("dSub").notEqExpression("d")
.end();
String expectedQuery = "SELECT d FROM Document d WHERE EXISTS (SELECT 1 FROM Document dSub, Document d_owner_base JOIN d_owner_base.owner owner_1 WHERE dSub MEMBER OF owner_1.ownedDocuments AND LENGTH(owner_1.name) > 0 AND d = d_owner_base AND dSub <> d)";

String expectedSubQuery;
if (jpaProvider.supportsEntityJoin()) {
expectedSubQuery = "SELECT 1 FROM Document dSub JOIN Document d_owner_base" + onClause("d = d_owner_base") + " JOIN d_owner_base.owner owner_1 WHERE dSub MEMBER OF owner_1.ownedDocuments AND LENGTH(owner_1.name) > 0 AND dSub <> d";
} else {
expectedSubQuery = "SELECT 1 FROM Document dSub, Document d_owner_base JOIN d_owner_base.owner owner_1 WHERE dSub MEMBER OF owner_1.ownedDocuments AND LENGTH(owner_1.name) > 0 AND d = d_owner_base AND dSub <> d";
}
String expectedQuery = "SELECT d FROM Document d WHERE EXISTS (" + expectedSubQuery + ")";
assertEquals(expectedQuery, crit.getQueryString());
crit.getResultList();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -252,17 +252,22 @@ public void implicitJoinTreatedImplicitCorrelation() {
.select("1")
.where("TREAT(p.children.container.child AS PolymorphicSub1).id").eqExpression("sub1.id")
.end();
assertEquals(
"SELECT p FROM PolymorphicBase p " +
"WHERE EXISTS (" +
"SELECT 1 FROM PolymorphicSub1 sub1, PolymorphicBase p_children_base " +
String expectedSubQuery;
if (jpaProvider.supportsEntityJoin()) {
expectedSubQuery = "SELECT 1 FROM PolymorphicSub1 sub1 JOIN PolymorphicBase p_children_base" + onClause("p.id = p_children_base.id") + " " +
"LEFT JOIN p_children_base.children children_1 " +
"LEFT JOIN children_1.container container_1 " +
"LEFT JOIN container_1.child child_1 " +
"WHERE " + treatRoot("child_1", PolymorphicSub1.class, "id") + " = sub1.id";
} else {
expectedSubQuery = "SELECT 1 FROM PolymorphicSub1 sub1, PolymorphicBase p_children_base " +
"LEFT JOIN p_children_base.children children_1 " +
"LEFT JOIN children_1.container container_1 " +
"LEFT JOIN container_1.child child_1 " +
"WHERE p.id = p_children_base.id " +
"AND " + treatRoot("child_1", PolymorphicSub1.class, "id") + " = sub1.id)",
crit.getQueryString()
);
"AND " + treatRoot("child_1", PolymorphicSub1.class, "id") + " = sub1.id";
}
assertEquals("SELECT p FROM PolymorphicBase p WHERE EXISTS (" + expectedSubQuery + ")", crit.getQueryString());
crit.getResultList();
}
}
2 changes: 1 addition & 1 deletion core/testsuite/src/test/resources/logging.properties
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ handlers = java.util.logging.ConsoleHandler
org.hibernate.level = SEVERE
org.hibernate.tool.hbm2ddl.level = OFF
org.hibernate.tool.schema.internal.ExceptionHandlerLoggedImpl.level = ALL
#org.hibernate.SQL.level = ALL
org.hibernate.SQL.level = ALL
#org.hibernate.type.descriptor.sql.level = ALL
#org.hibernate.tool.hbm2ddl.level = ALL
#org.hibernate.pretty.level = ALL
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2014 - 2023 Blazebit.
* Copyright 2014 - 2024 Blazebit.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down

0 comments on commit a8f979f

Please sign in to comment.