Skip to content

Commit

Permalink
[#1634] Fix ending builder for setOnExpressionSubqueries
Browse files Browse the repository at this point in the history
  • Loading branch information
beikov committed Nov 21, 2022
1 parent c397e5f commit 96ad2f7
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1519,7 +1519,7 @@ public BuilderType setWhereExpression(String expression) {
public MultipleSubqueryInitiator<BuilderType> setWhereExpressionSubqueries(String expression) {
prepareForModification(ClauseType.WHERE);
Predicate predicate = expressionFactory.createBooleanExpression(expression, true);
return whereManager.restrictSetExpressionSubqueries((BuilderType) this, predicate);
return whereManager.restrictSetExpressionSubqueries((BuilderType) this, predicate, null);
}

public PredicateBuilder where() {
Expand Down Expand Up @@ -1761,7 +1761,7 @@ public MultipleSubqueryInitiator<BuilderType> setHavingExpressionSubqueries(Stri
throw new IllegalStateException("Having without group by");
}
Predicate predicate = expressionFactory.createBooleanExpression(expression, true);
return havingManager.restrictSetExpressionSubqueries((BuilderType) this, predicate);
return havingManager.restrictSetExpressionSubqueries((BuilderType) this, predicate, null);
}

public PredicateBuilder having() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
import com.blazebit.persistence.SimpleCaseWhenStarterBuilder;
import com.blazebit.persistence.SubqueryBuilder;
import com.blazebit.persistence.SubqueryInitiator;
import com.blazebit.persistence.impl.builder.expression.ExpressionBuilder;
import com.blazebit.persistence.impl.builder.expression.ExpressionBuilderEndedListener;
import com.blazebit.persistence.impl.builder.predicate.JoinOnOrBuilderImpl;
import com.blazebit.persistence.impl.builder.predicate.PredicateBuilderEndedListener;
import com.blazebit.persistence.impl.builder.predicate.PredicateBuilderEndedListenerImpl;
Expand All @@ -39,7 +41,7 @@
* @author Moritz Becker
* @since 1.0.0
*/
public class JoinOnBuilderImpl<T> extends PredicateManager<JoinOnBuilderImpl<T>> implements JoinOnBuilder<T>, PredicateBuilder, PredicateBuilderEndedListener, SubqueryBuilderListener<T> {
public class JoinOnBuilderImpl<T> extends PredicateManager<JoinOnBuilderImpl<T>> implements JoinOnBuilder<T>, PredicateBuilder, PredicateBuilderEndedListener, SubqueryBuilderListener<T>, ExpressionBuilderEndedListener {

private final T result;
private final PredicateBuilderEndedListener listener;
Expand Down Expand Up @@ -148,7 +150,7 @@ public T setOnExpression(String expression) {
@Override
public MultipleSubqueryInitiator<T> setOnExpressionSubqueries(String expression) {
Predicate predicate = expressionFactory.createBooleanExpression(expression, false);
return restrictSetExpressionSubqueries(result, predicate);
return restrictSetExpressionSubqueries(result, predicate, this);
}

@Override
Expand All @@ -163,6 +165,11 @@ public T end() {
return result;
}

@Override
public void onBuilderEnded(ExpressionBuilder builder) {
listener.onBuilderEnded(this);
}

@Override
public void onBuilderEnded(PredicateBuilder builder) {
predicateBuilderListener.onBuilderEnded(builder);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,11 +147,11 @@ <X> MultipleSubqueryInitiator<RestrictionBuilder<X>> restrictSubqueries(X builde
return initiator;
}

<X> MultipleSubqueryInitiator<X> restrictExpressionSubqueries(X builder, Predicate predicate) {
<X> MultipleSubqueryInitiator<X> restrictExpressionSubqueries(X result, Predicate predicate) {
rootPredicate.verifyBuilderEnded();
parameterManager.collectParameterRegistrations(predicate, getClauseType(), subqueryInitFactory.getQueryBuilder());

MultipleSubqueryInitiator<X> initiator = new MultipleSubqueryInitiatorImpl<X>(builder, predicate, new ExpressionBuilderEndedListener() {
MultipleSubqueryInitiator<X> initiator = new MultipleSubqueryInitiatorImpl<X>(result, predicate, new ExpressionBuilderEndedListener() {

@Override
public void onBuilderEnded(ExpressionBuilder builder) {
Expand All @@ -164,18 +164,21 @@ public void onBuilderEnded(ExpressionBuilder builder) {
return initiator;
}

<X> MultipleSubqueryInitiator<X> restrictSetExpressionSubqueries(X builder, Predicate predicate) {
<X> MultipleSubqueryInitiator<X> restrictSetExpressionSubqueries(X result, Predicate predicate, final ExpressionBuilderEndedListener listener) {
rootPredicate.verifyBuilderEnded();
parameterManager.collectParameterRegistrations(predicate, getClauseType(), subqueryInitFactory.getQueryBuilder());

MultipleSubqueryInitiator<X> initiator = new MultipleSubqueryInitiatorImpl<X>(builder, predicate, new ExpressionBuilderEndedListener() {
MultipleSubqueryInitiator<X> initiator = new MultipleSubqueryInitiatorImpl<X>(result, predicate, new ExpressionBuilderEndedListener() {

@Override
public void onBuilderEnded(ExpressionBuilder builder) {
List<Predicate> children = rootPredicate.getPredicate().getChildren();
children.clear();
children.add((Predicate) builder.getExpression());
currentMultipleSubqueryInitiator = null;
if (listener != null) {
listener.onBuilderEnded(builder);
}
}

}, subqueryInitFactory, getClauseType());
Expand Down Expand Up @@ -406,7 +409,7 @@ public PredicateBuilder setExpression(String expression) {
@Override
public MultipleSubqueryInitiator<PredicateBuilder> setExpressionSubqueries(String expression) {
Predicate predicate = expressionFactory.createBooleanExpression(expression, false);
return restrictSetExpressionSubqueries((PredicateBuilder) this, predicate);
return restrictSetExpressionSubqueries((PredicateBuilder) this, predicate, null);
}

public void verifyEnded() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,7 @@ public WindowBuilderImpl<T> setWhereExpression(String expression) {
@SuppressWarnings("unchecked")
public MultipleSubqueryInitiator<WindowBuilderImpl<T>> setWhereExpressionSubqueries(String expression) {
Predicate predicate = expressionFactory.createBooleanExpression(expression, true);
return restrictSetExpressionSubqueries(this, predicate);
return restrictSetExpressionSubqueries(this, predicate, null);
}

public PredicateBuilder where() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,4 +191,44 @@ public void testLeftJoinOnWithExpressionString() {
crit.setParameter("param", "%dld");
crit.getResultList();
}

// For issue #1634
@Test
public void testSetOnExpressionSubqueries() {
CriteriaBuilder<Document> crit = cbf.create(em, Document.class, "d");
crit.innerJoinOn("d.partners", "p").setOnExpressionSubqueries("a1 + a2 > 0")
.with("a1")
.from(Document.class, "dSub")
.select("MAX(dSub.id)")
.end()
.with("a2")
.from(Document.class, "dSub")
.select("MIN(dSub.id)")
.end()
.end()
.select("d.id");

final String expected = "SELECT d.id FROM Document d JOIN d.partners p" + onClause("(SELECT MAX(dSub.id) FROM Document dSub) + (SELECT MIN(dSub.id) FROM Document dSub) > 0");
assertEquals(expected, crit.getQueryString());
}

@Test
public void testOnExpressionSubqueries() {
CriteriaBuilder<Document> crit = cbf.create(em, Document.class, "d");
crit.innerJoinOn("d.partners", "p").onExpressionSubqueries("a1 + a2 > 0")
.with("a1")
.from(Document.class, "dSub")
.select("MAX(dSub.id)")
.end()
.with("a2")
.from(Document.class, "dSub")
.select("MIN(dSub.id)")
.end()
.end()
.end()
.select("d.id");

final String expected = "SELECT d.id FROM Document d JOIN d.partners p" + onClause("(SELECT MAX(dSub.id) FROM Document dSub) + (SELECT MIN(dSub.id) FROM Document dSub) > 0");
assertEquals(expected, crit.getQueryString());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -544,6 +544,44 @@ public void testWhereSizeMultiple() {
final String expected = "SELECT d.id, d.name FROM Document d LEFT JOIN d.partners partners_1 LEFT JOIN d.versions versions_1 GROUP BY d.id, d.name HAVING COUNT(DISTINCT versions_1) > 2 AND COUNT(DISTINCT partners_1) < 1";
assertEquals(expected, crit.getQueryString());
}

@Test
public void testSetWhereExpressionSubqueries() {
CriteriaBuilder<Document> crit = cbf.create(em, Document.class, "d");
crit.setWhereExpressionSubqueries("a1 + a2 > 0")
.with("a1")
.from(Document.class, "dSub")
.select("MAX(dSub.id)")
.end()
.with("a2")
.from(Document.class, "dSub")
.select("MIN(dSub.id)")
.end()
.end()
.select("d.id");

final String expected = "SELECT d.id FROM Document d WHERE (SELECT MAX(dSub.id) FROM Document dSub) + (SELECT MIN(dSub.id) FROM Document dSub) > 0";
assertEquals(expected, crit.getQueryString());
}

@Test
public void testWhereExpressionSubqueries() {
CriteriaBuilder<Document> crit = cbf.create(em, Document.class, "d");
crit.whereExpressionSubqueries("a1 + a2 > 0")
.with("a1")
.from(Document.class, "dSub")
.select("MAX(dSub.id)")
.end()
.with("a2")
.from(Document.class, "dSub")
.select("MIN(dSub.id)")
.end()
.end()
.select("d.id");

final String expected = "SELECT d.id FROM Document d WHERE (SELECT MAX(dSub.id) FROM Document dSub) + (SELECT MIN(dSub.id) FROM Document dSub) > 0";
assertEquals(expected, crit.getQueryString());
}

private void verifyBuilderChainingException(CriteriaBuilder<Document> crit){
verifyException(crit, BuilderChainingException.class, r -> r.whereCase());
Expand Down

0 comments on commit 96ad2f7

Please sign in to comment.