Skip to content

Commit e364515

Browse files
committed
1 parent a3a5346 commit e364515

File tree

6 files changed

+115
-34
lines changed

6 files changed

+115
-34
lines changed

project/jimmer-sql-kotlin/src/test/kotlin/org/babyfish/jimmer/sql/kt/dto/BookSpecificationTest.kt

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,9 @@ class BookSpecificationTest : AbstractQueryTest() {
8484
}
8585
) {
8686
sql(
87-
"""select tb_1_.ID, tb_1_.NAME, tb_1_.EDITION, tb_1_.PRICE, tb_1_.STORE_ID
87+
"""select
88+
|--->tb_1_.ID, tb_1_.NAME, tb_1_.EDITION, tb_1_.PRICE, tb_1_.STORE_ID
8889
|from BOOK tb_1_
89-
|inner join BOOK_AUTHOR_MAPPING tb_3_ on tb_1_.ID = tb_3_.BOOK_ID
9090
|where
9191
|--->tb_1_.NAME = ?
9292
|and
@@ -100,11 +100,25 @@ class BookSpecificationTest : AbstractQueryTest() {
100100
|and
101101
|--->tb_1_.STORE_ID in (?, ?)
102102
|and
103-
|--->tb_1_.STORE_ID not in (?, ?)
103+
|--->not exists(
104+
|--->--->select 1
105+
|--->--->from BOOK_STORE tb_3_
106+
|--->--->inner join BOOK tb_4_ on tb_3_.ID = tb_4_.STORE_ID
107+
|--->--->where tb_4_.ID = tb_1_.ID and tb_3_.ID in (?, ?)
108+
|--->)
104109
|and
105-
|--->tb_3_.AUTHOR_ID in (?, ?, ?)
110+
|--->exists(
111+
|--->--->select 1
112+
|--->--->from AUTHOR tb_5_
113+
|--->--->inner join BOOK_AUTHOR_MAPPING tb_6_ on tb_5_.ID = tb_6_.AUTHOR_ID
114+
|--->--->where tb_6_.BOOK_ID = tb_1_.ID and tb_5_.ID in (?, ?, ?)
115+
|--->)
106116
|and
107-
|--->tb_3_.AUTHOR_ID not in (?, ?)""".trimMargin()
117+
|--->not exists(
118+
|--->--->select 1 from AUTHOR tb_8_
119+
|--->--->inner join BOOK_AUTHOR_MAPPING tb_9_ on tb_8_.ID = tb_9_.AUTHOR_ID
120+
|--->--->where tb_9_.BOOK_ID = tb_1_.ID and tb_8_.ID in (?, ?)
121+
|--->)""".trimMargin()
108122
).variables(
109123
"GraphQL in Action",
110124
3,

project/jimmer-sql-kotlin/src/test/kotlin/org/babyfish/jimmer/sql/kt/dto/DepartmentSpecificationTest.kt

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,23 @@ class DepartmentSpecificationTest : AbstractQueryTest() {
4040
}
4141
) {
4242
sql(
43-
"select tb_1_.ID, tb_1_.NAME, tb_1_.DELETED_TIME " +
43+
"select " +
44+
"--->tb_1_.ID, tb_1_.NAME, tb_1_.DELETED_TIME " +
4445
"from DEPARTMENT tb_1_ " +
45-
"inner join EMPLOYEE tb_2_ on tb_1_.ID = tb_2_.DEPARTMENT_ID " +
46-
"where tb_1_.ID = ? " +
47-
"and tb_2_.ID in (?, ?) " +
48-
"and tb_1_.DELETED_TIME is null"
46+
"where " +
47+
"--->tb_1_.ID = ? " +
48+
"and " +
49+
"--->exists(" +
50+
"--->--->select 1 from EMPLOYEE tb_2_ " +
51+
"--->--->where " +
52+
"--->--->--->tb_2_.DEPARTMENT_ID = tb_1_.ID " +
53+
"--->--->and " +
54+
"--->--->--->tb_2_.ID in (?, ?) " +
55+
"--->--->and " +
56+
"--->--->--->tb_2_.DELETED_UUID is null" +
57+
"--->) " +
58+
"and " +
59+
"tb_1_.DELETED_TIME is null"
4960
).variables(3L, 4L, 5L)
5061
}
5162
}

project/jimmer-sql/src/main/java/org/babyfish/jimmer/sql/ast/impl/AssociatedPredicate.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,18 +27,18 @@ public class AssociatedPredicate extends AbstractPredicate implements VirtualPre
2727

2828
private final Function<Table<?>, Predicate> block;
2929

30-
public AssociatedPredicate(Table<?> parenTable, ImmutableProp prop, Function<Table<?>, Predicate> block) {
31-
if (prop.getDeclaringType() != parenTable.getImmutableType()) {
32-
if (!prop.getDeclaringType().isAssignableFrom(parenTable.getImmutableType())) {
30+
public AssociatedPredicate(Table<?> parentTable, ImmutableProp prop, Function<Table<?>, Predicate> block) {
31+
if (prop.getDeclaringType() != parentTable.getImmutableType()) {
32+
if (!prop.getDeclaringType().isAssignableFrom(parentTable.getImmutableType())) {
3333
throw new IllegalArgumentException(
3434
"The property \"" +
3535
prop +
3636
"\" does not belong to the current type \"" +
37-
parenTable.getImmutableType() +
37+
parentTable.getImmutableType() +
3838
"\""
3939
);
4040
}
41-
prop = parenTable.getImmutableType().getProp(prop.getName());
41+
prop = parentTable.getImmutableType().getProp(prop.getName());
4242
}
4343
if (!prop.isAssociation(TargetLevel.PERSISTENT)) {
4444
if (prop.isTransient()) {
@@ -55,11 +55,11 @@ public AssociatedPredicate(Table<?> parenTable, ImmutableProp prop, Function<Tab
5555
"\"" +
5656
prop +
5757
"\" is not association property of \"" +
58-
parenTable.getImmutableType() +
58+
parentTable.getImmutableType() +
5959
"\""
6060
);
6161
}
62-
this.parenTable = parenTable;
62+
this.parenTable = parentTable;
6363
this.prop = prop;
6464
this.block = block;
6565
}

project/jimmer-sql/src/main/java/org/babyfish/jimmer/sql/ast/query/specification/PredicateApplier.java

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import org.babyfish.jimmer.sql.ast.*;
77
import org.babyfish.jimmer.sql.ast.impl.AbstractMutableStatementImpl;
88
import org.babyfish.jimmer.sql.ast.impl.query.MutableSubQueryImpl;
9+
import org.babyfish.jimmer.sql.ast.impl.table.TableImplementor;
910
import org.babyfish.jimmer.sql.ast.impl.table.TableProxies;
1011
import org.babyfish.jimmer.sql.ast.query.MutableQuery;
1112
import org.babyfish.jimmer.sql.ast.table.Table;
@@ -220,26 +221,45 @@ public void valueNotIn(ImmutableProp prop, Collection<?> values) {
220221
ctx.statement().where(ctx.get(prop).notIn((Collection<Object>) values));
221222
}
222223

223-
@SuppressWarnings("unchecked")
224224
public void associatedIdEq(ImmutableProp[] props, Object associatedId) {
225225
if (associatedId == null) {
226226
return;
227227
}
228228
Context ctx = this.context;
229229
Predicate[] predicates = new Predicate[props.length];
230230
for (int i = predicates.length - 1; i >= 0; --i) {
231-
predicates[i] = ctx.table().getAssociatedId(props[i]).eq(associatedId);
231+
ImmutableProp prop = props[i];
232+
if (prop.isReferenceList(TargetLevel.ENTITY)) {
233+
predicates[i] = ctx.table().exists(
234+
prop,
235+
target -> target.getId().eq(associatedId)
236+
);
237+
} else {
238+
predicates[i] = ctx.table().getAssociatedId(props[i]).eq(associatedId);
239+
}
232240
}
233241
ctx.statement().where(Predicate.or(predicates));
234242
}
235243

236-
@SuppressWarnings("unchecked")
237244
public void associatedIdNe(ImmutableProp prop, Object associatedId) {
238245
if (associatedId == null) {
239246
return;
240247
}
241248
Context ctx = this.context;
242-
ctx.statement().where(ctx.table().getAssociatedId(prop).ne(associatedId));
249+
Table<?> parentTable = ctx.statement().getTable();
250+
Table<?> table;
251+
MutableSubQueryImpl subQuery;
252+
if (parentTable instanceof TableImplementor<?>) {
253+
subQuery = new MutableSubQueryImpl(ctx.statement(), prop.getTargetType());
254+
table = subQuery.getTable();
255+
} else {
256+
TableProxy<?> proxy = TableProxies.fluent(prop.getTargetType().getJavaClass());
257+
subQuery = new MutableSubQueryImpl(ctx.statement(), proxy);
258+
table = proxy;
259+
}
260+
subQuery.where(table.inverseGetAssociatedId(prop).eq(parentTable.getId()));
261+
subQuery.where(table.getId().eq(associatedId));
262+
ctx.statement().where(subQuery.notExists());
243263
}
244264

245265
@SuppressWarnings("unchecked")
@@ -252,10 +272,9 @@ public void associatedIdIn(ImmutableProp[] props, Collection<?> associatedIds) {
252272
for (int i = predicates.length - 1; i >= 0; --i) {
253273
ImmutableProp prop = props[i];
254274
if (prop.isReferenceList(TargetLevel.ENTITY)) {
255-
ImmutableProp targetIdProp = prop.getTargetType().getIdProp();
256275
predicates[i] = ctx.table().exists(
257276
prop,
258-
target -> target.get(targetIdProp).in((Collection<Object>) associatedIds)
277+
target -> target.getId().in((Collection<Object>) associatedIds)
259278
);
260279
} else {
261280
predicates[i] = ctx.table().getAssociatedId(prop).in((Collection<Object>) associatedIds);
@@ -270,7 +289,20 @@ public void associatedIdNotIn(ImmutableProp prop, Collection<?> associatedIds) {
270289
return;
271290
}
272291
Context ctx = this.context;
273-
ctx.statement().where(ctx.table().getAssociatedId(prop).notIn((Collection<Object>) associatedIds));
292+
Table<?> parentTable = ctx.statement().getTable();
293+
Table<?> table;
294+
MutableSubQueryImpl subQuery;
295+
if (parentTable instanceof TableImplementor<?>) {
296+
subQuery = new MutableSubQueryImpl(ctx.statement(), prop.getTargetType());
297+
table = subQuery.getTable();
298+
} else {
299+
TableProxy<?> proxy = TableProxies.fluent(prop.getTargetType().getJavaClass());
300+
subQuery = new MutableSubQueryImpl(ctx.statement(), proxy);
301+
table = proxy;
302+
}
303+
subQuery.where(table.inverseGetAssociatedId(prop).eq(parentTable.getId()));
304+
subQuery.where(table.getId().in((Collection<Object>) associatedIds));
305+
ctx.statement().where(subQuery.notExists());
274306
}
275307

276308
private static class Context {

project/jimmer-sql/src/test/java/org/babyfish/jimmer/sql/dto/BookSpecificationTest.java

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -92,10 +92,9 @@ public void testSpecification2WithValues() {
9292
.select(table),
9393
ctx -> {
9494
ctx.sql(
95-
"select tb_1_.ID, tb_1_.NAME, tb_1_.EDITION, tb_1_.PRICE, tb_1_.STORE_ID " +
95+
"select " +
96+
"--->tb_1_.ID, tb_1_.NAME, tb_1_.EDITION, tb_1_.PRICE, tb_1_.STORE_ID " +
9697
"from BOOK tb_1_ " +
97-
"inner join BOOK_AUTHOR_MAPPING tb_3_ " +
98-
"--->on tb_1_.ID = tb_3_.BOOK_ID " +
9998
"where " +
10099
"--->tb_1_.NAME = ? " +
101100
"and " +
@@ -109,11 +108,26 @@ public void testSpecification2WithValues() {
109108
"and " +
110109
"--->tb_1_.STORE_ID in (?, ?) " +
111110
"and " +
112-
"--->tb_1_.STORE_ID not in (?, ?) " +
111+
"--->not exists(" +
112+
"--->--->select 1 " +
113+
"--->--->from BOOK_STORE tb_3_ " +
114+
"--->--->inner join BOOK tb_4_ on tb_3_.ID = tb_4_.STORE_ID " +
115+
"--->--->where tb_4_.ID = tb_1_.ID and tb_3_.ID in (?, ?)" +
116+
"--->) " +
113117
"and " +
114-
"--->tb_3_.AUTHOR_ID in (?, ?, ?) " +
118+
"--->exists(" +
119+
"--->--->select 1 " +
120+
"--->--->from AUTHOR tb_5_ " +
121+
"--->--->inner join BOOK_AUTHOR_MAPPING tb_6_ on tb_5_.ID = tb_6_.AUTHOR_ID " +
122+
"--->--->where tb_6_.BOOK_ID = tb_1_.ID and tb_5_.ID in (?, ?, ?)" +
123+
"--->) " +
115124
"and " +
116-
"--->tb_3_.AUTHOR_ID not in (?, ?) " +
125+
"--->not exists(" +
126+
"--->--->select 1 " +
127+
"--->--->from AUTHOR tb_8_ " +
128+
"--->--->inner join BOOK_AUTHOR_MAPPING tb_9_ on tb_8_.ID = tb_9_.AUTHOR_ID " +
129+
"--->--->where tb_9_.BOOK_ID = tb_1_.ID and tb_8_.ID in (?, ?)" +
130+
"--->) " +
117131
"order by tb_1_.ID asc"
118132
).variables(
119133
"GraphQL in Action",

project/jimmer-sql/src/test/java/org/babyfish/jimmer/sql/dto/DepartmentSpecificationTest.java

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,21 @@ public void testWithNonEmptySpecification() {
4747
ctx.sql(
4848
"select tb_1_.ID, tb_1_.NAME, tb_1_.DELETED_MILLIS " +
4949
"from DEPARTMENT tb_1_ " +
50-
"inner join EMPLOYEE tb_2_ on tb_1_.ID = tb_2_.DEPARTMENT_ID " +
51-
"where tb_1_.ID = ? " +
52-
"and tb_2_.ID in (?, ?) " +
50+
"where " +
51+
"--->tb_1_.ID = ? " +
52+
"and " +
53+
"--->exists(" +
54+
"--->--->select 1 " +
55+
"--->--->from EMPLOYEE tb_2_ " +
56+
"--->--->where " +
57+
"--->--->--->tb_2_.DEPARTMENT_ID = tb_1_.ID " +
58+
"--->--->and " +
59+
"--->--->--->tb_2_.ID in (?, ?) " +
60+
"--->--->and " +
61+
"--->--->--->tb_2_.DELETED_MILLIS = ?" +
62+
"--->) " +
5363
"and tb_1_.DELETED_MILLIS = ?"
54-
).variables(3L, 4L, 5L, 0L);
64+
).variables(3L, 4L, 5L, 0L, 0L);
5565
}
5666
);
5767
}

0 commit comments

Comments
 (0)