Skip to content

Commit 119a83f

Browse files
committed
DATAJDBC-335 - Fix Select and Delete validators.
1 parent 0618ff7 commit 119a83f

File tree

4 files changed

+74
-2
lines changed

4 files changed

+74
-2
lines changed

spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/DeleteValidator.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
*/
1616
package org.springframework.data.relational.core.sql;
1717

18+
import org.springframework.lang.Nullable;
19+
1820
/**
1921
* Validator for {@link Delete} statements.
2022
* <p/>
@@ -25,6 +27,8 @@
2527
*/
2628
class DeleteValidator extends AbstractImportValidator {
2729

30+
private @Nullable Select selectFilter;
31+
2832
public static void validate(Delete select) {
2933
new DeleteValidator().doValidate(select);
3034
}
@@ -40,4 +44,30 @@ private void doValidate(Delete select) {
4044
}
4145
}
4246
}
47+
48+
@Override
49+
public void enter(Visitable segment) {
50+
51+
if (selectFilter != null) {
52+
return;
53+
}
54+
55+
if (segment instanceof Select) {
56+
this.selectFilter = (Select) segment;
57+
return;
58+
}
59+
60+
super.enter(segment);
61+
}
62+
63+
@Override
64+
public void leave(Visitable segment) {
65+
66+
if (this.selectFilter == segment) {
67+
this.selectFilter = null;
68+
return;
69+
}
70+
71+
super.leave(segment);
72+
}
4373
}

spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/SelectValidator.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import java.util.HashSet;
1919
import java.util.Set;
20+
import java.util.Stack;
2021

2122
/**
2223
* Validator for {@link Select} statements.
@@ -29,6 +30,8 @@
2930
*/
3031
class SelectValidator extends AbstractImportValidator {
3132

33+
private final Stack<Select> selects = new Stack<>();
34+
3235
private int selectFieldCount;
3336
private Set<Table> requiredBySelect = new HashSet<>();
3437
private Set<Table> requiredByOrderBy = new HashSet<>();
@@ -76,6 +79,14 @@ private void doValidate(Select select) {
7679
@Override
7780
public void enter(Visitable segment) {
7881

82+
if (segment instanceof Select) {
83+
selects.push((Select) segment);
84+
}
85+
86+
if (selects.size() > 1) {
87+
return;
88+
}
89+
7990
super.enter(segment);
8091

8192
if (segment instanceof AsteriskFromTable && parent instanceof Select) {
@@ -118,4 +129,18 @@ public void enter(Visitable segment) {
118129
});
119130
}
120131
}
132+
133+
@Override
134+
public void leave(Visitable segment) {
135+
136+
if (segment instanceof Select) {
137+
selects.remove(segment);
138+
}
139+
140+
if (selects.size() > 1) {
141+
return;
142+
}
143+
144+
super.leave(segment);
145+
}
121146
}

spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/DeleteValidatorUnitTests.java

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
import org.junit.Test;
2121

2222
/**
23-
* Unit tests for {@link SelectValidator}.
23+
* Unit tests for {@link DeleteValidator}.
2424
*
2525
* @author Mark Paluch
2626
*/
@@ -40,4 +40,21 @@ public void shouldReportMissingTableForDeleteViaWhere() {
4040
}).isInstanceOf(IllegalStateException.class)
4141
.hasMessageContaining("Required table [table] by a WHERE predicate not imported by FROM [bar]");
4242
}
43+
44+
@Test // DATAJDBC-335
45+
public void shouldIgnoreImportsFromSubselectsInWhereClause() {
46+
47+
Table foo = SQL.table("foo");
48+
Column bar = foo.column("bar");
49+
50+
Table floo = SQL.table("floo");
51+
Column bah = floo.column("bah");
52+
53+
Select subselect = Select.builder().select(bah).from(floo).build();
54+
55+
assertThatThrownBy(() -> {
56+
Delete.builder().from(foo).where(Conditions.in(bar, subselect)).build();
57+
}).isInstanceOf(IllegalStateException.class)
58+
.hasMessageContaining("Required table [floo] by a WHERE predicate not imported by FROM [foo]");
59+
}
4360
}

spring-data-relational/src/test/java/org/springframework/data/relational/core/sql/SelectValidatorUnitTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ public void shouldIgnoreImportsFromSubselectsInWhereClause() {
103103
assertThatThrownBy(() -> {
104104
Select.builder().select(bah).from(foo).where(Conditions.in(bar, subselect)).build();
105105
}).isInstanceOf(IllegalStateException.class)
106-
.hasMessageContaining("Required table [bah] by a SELECT column not imported by FROM [foo] or JOIN []");
106+
.hasMessageContaining("Required table [floo] by a SELECT column not imported by FROM [foo] or JOIN []");
107107
}
108108

109109
}

0 commit comments

Comments
 (0)