DATAJDBC-490 - Support condition grouping.
We now support condition groups (WHERE (a = b OR b = c) AND (e = f)) with the SQL AST via Condition.group(). Original pull request: #193.
This commit is contained in:
committed by
Jens Schauder
parent
7956e2c915
commit
0156fdd0bf
@@ -48,9 +48,19 @@ public interface Condition extends Segment {
|
||||
/**
|
||||
* Creates a {@link Condition} that negates this {@link Condition}.
|
||||
*
|
||||
* @return the negated {@link Condition}.
|
||||
* @return the negated {@link Condition}.
|
||||
*/
|
||||
default Condition not() {
|
||||
return new Not(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps a {@link Condition} into a condition group that groups the nested {@link Condition} using parentheses.
|
||||
*
|
||||
* @return the grouped {@link Condition}.
|
||||
* @since 2.0
|
||||
*/
|
||||
default Condition group() {
|
||||
return new ConditionGroup(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.relational.core.sql;
|
||||
|
||||
/**
|
||||
* Condition group wrapping a nested {@link Condition} with parentheses.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @since 2.0
|
||||
*/
|
||||
public class ConditionGroup extends MultipleCondition implements Condition {
|
||||
|
||||
ConditionGroup(Condition condition) {
|
||||
super("", condition);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return "(" + super.toString() + ")";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright 2019-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.relational.core.sql.render;
|
||||
|
||||
import org.springframework.data.relational.core.sql.Condition;
|
||||
import org.springframework.data.relational.core.sql.ConditionGroup;
|
||||
import org.springframework.data.relational.core.sql.Visitable;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Renderer for {@link ConditionGroup}. Uses a {@link RenderTarget} to call back for render results.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @since 2.0
|
||||
*/
|
||||
class ConditionGroupVisitor extends TypedSubtreeVisitor<ConditionGroup> {
|
||||
|
||||
private final RenderContext context;
|
||||
private final RenderTarget target;
|
||||
|
||||
private @Nullable ConditionVisitor conditionVisitor;
|
||||
|
||||
ConditionGroupVisitor(RenderContext context, RenderTarget target) {
|
||||
this.context = context;
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.relational.core.sql.render.TypedSubtreeVisitor#enterNested(org.springframework.data.relational.core.sql.Visitable)
|
||||
*/
|
||||
@Override
|
||||
Delegation enterNested(Visitable segment) {
|
||||
|
||||
DelegatingVisitor visitor = getDelegation(segment);
|
||||
|
||||
return visitor != null ? Delegation.delegateTo(visitor) : Delegation.retain();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private DelegatingVisitor getDelegation(Visitable segment) {
|
||||
|
||||
if (segment instanceof Condition) {
|
||||
return conditionVisitor = new ConditionVisitor(context);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.relational.core.sql.render.TypedSubtreeVisitor#leaveNested(org.springframework.data.relational.core.sql.Visitable)
|
||||
*/
|
||||
@Override
|
||||
Delegation leaveNested(Visitable segment) {
|
||||
|
||||
if (conditionVisitor != null) {
|
||||
target.onRendered("(" + conditionVisitor.getRenderedPart() + ")");
|
||||
conditionVisitor = null;
|
||||
}
|
||||
|
||||
return super.leaveNested(segment);
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,7 @@ package org.springframework.data.relational.core.sql.render;
|
||||
import org.springframework.data.relational.core.sql.AndCondition;
|
||||
import org.springframework.data.relational.core.sql.Comparison;
|
||||
import org.springframework.data.relational.core.sql.Condition;
|
||||
import org.springframework.data.relational.core.sql.ConditionGroup;
|
||||
import org.springframework.data.relational.core.sql.In;
|
||||
import org.springframework.data.relational.core.sql.IsNull;
|
||||
import org.springframework.data.relational.core.sql.Like;
|
||||
@@ -41,7 +42,7 @@ import org.springframework.lang.Nullable;
|
||||
class ConditionVisitor extends TypedSubtreeVisitor<Condition> implements PartRenderer {
|
||||
|
||||
private final RenderContext context;
|
||||
private StringBuilder builder = new StringBuilder();
|
||||
private final StringBuilder builder = new StringBuilder();
|
||||
|
||||
ConditionVisitor(RenderContext context) {
|
||||
this.context = context;
|
||||
@@ -86,6 +87,10 @@ class ConditionVisitor extends TypedSubtreeVisitor<Condition> implements PartRen
|
||||
return new InVisitor(context, builder::append);
|
||||
}
|
||||
|
||||
if (segment instanceof ConditionGroup) {
|
||||
return new ConditionGroupVisitor(context, builder::append);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -37,12 +37,39 @@ public class ConditionRendererUnitTests {
|
||||
@Test // DATAJDBC-309
|
||||
public void shouldRenderEquals() {
|
||||
|
||||
String sql = SqlRenderer
|
||||
.toString(StatementBuilder.select(left).from(table).where(left.isEqualTo(right)).build());
|
||||
String sql = SqlRenderer.toString(StatementBuilder.select(left).from(table).where(left.isEqualTo(right)).build());
|
||||
|
||||
assertThat(sql).endsWith("WHERE my_table.left = my_table.right");
|
||||
}
|
||||
|
||||
@Test // DATAJDBC-490
|
||||
public void shouldRenderEqualsGroup() {
|
||||
|
||||
String sql = SqlRenderer
|
||||
.toString(StatementBuilder.select(left).from(table).where(left.isEqualTo(right).group()).build());
|
||||
|
||||
assertThat(sql).endsWith("WHERE (my_table.left = my_table.right)");
|
||||
}
|
||||
|
||||
@Test // DATAJDBC-490
|
||||
public void shouldRenderAndGroup() {
|
||||
|
||||
String sql = SqlRenderer.toString(StatementBuilder.select(left).from(table)
|
||||
.where(left.isEqualTo(right).and(left.isGreater(right)).group()).build());
|
||||
|
||||
assertThat(sql).endsWith("WHERE (my_table.left = my_table.right AND my_table.left > my_table.right)");
|
||||
}
|
||||
|
||||
@Test // DATAJDBC-490
|
||||
public void shouldRenderAndGroupOr() {
|
||||
|
||||
String sql = SqlRenderer.toString(StatementBuilder.select(left).from(table)
|
||||
.where(left.isEqualTo(right).and(left.isGreater(right)).group().or(left.like(right))).build());
|
||||
|
||||
assertThat(sql).endsWith(
|
||||
"WHERE (my_table.left = my_table.right AND my_table.left > my_table.right) OR my_table.left LIKE my_table.right");
|
||||
}
|
||||
|
||||
@Test // DATAJDBC-309
|
||||
public void shouldRenderNotEquals() {
|
||||
|
||||
@@ -76,8 +103,7 @@ public class ConditionRendererUnitTests {
|
||||
@Test // DATAJDBC-309
|
||||
public void shouldRenderIsGreater() {
|
||||
|
||||
String sql = SqlRenderer
|
||||
.toString(StatementBuilder.select(left).from(table).where(left.isGreater(right)).build());
|
||||
String sql = SqlRenderer.toString(StatementBuilder.select(left).from(table).where(left.isGreater(right)).build());
|
||||
|
||||
assertThat(sql).endsWith("WHERE my_table.left > my_table.right");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user