Skip to content

Commit 0abc3fa

Browse files
committed
Checks and tests for invalid case expressions
1 parent 11acc1a commit 0abc3fa

File tree

7 files changed

+59
-12
lines changed

7 files changed

+59
-12
lines changed

src/main/java/org/mybatis/dynamic/sql/select/SearchedCaseDSL.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import java.util.List;
2121

2222
import org.mybatis.dynamic.sql.AndOrCriteriaGroup;
23+
import org.mybatis.dynamic.sql.BasicColumn;
2324
import org.mybatis.dynamic.sql.BindableColumn;
2425
import org.mybatis.dynamic.sql.ColumnAndConditionCriterion;
2526
import org.mybatis.dynamic.sql.CriteriaGroup;
@@ -63,12 +64,12 @@ private WhenDSL initialize(SqlCriterion sqlCriterion) {
6364
return new WhenDSL(sqlCriterion);
6465
}
6566

66-
public SearchedCaseDSL elseConstant(String elseValue) {
67+
public SearchedCaseEnder elseConstant(String elseValue) {
6768
this.elseValue = elseValue;
68-
return this;
69+
return new SearchedCaseEnder();
6970
}
7071

71-
public SearchedCaseModel end() {
72+
public BasicColumn end() {
7273
return new SearchedCaseModel.Builder()
7374
.withElseValue(elseValue)
7475
.withWhenConditions(whenConditions)
@@ -91,6 +92,12 @@ protected WhenDSL getThis() {
9192
}
9293
}
9394

95+
public class SearchedCaseEnder {
96+
public BasicColumn end() {
97+
return SearchedCaseDSL.this.end();
98+
}
99+
}
100+
94101
public static SearchedCaseDSL searchedCase() {
95102
return new SearchedCaseDSL();
96103
}

src/main/java/org/mybatis/dynamic/sql/select/SearchedCaseModel.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import org.mybatis.dynamic.sql.render.RenderingContext;
2929
import org.mybatis.dynamic.sql.select.render.SearchedCaseRenderer;
3030
import org.mybatis.dynamic.sql.util.FragmentAndParameters;
31+
import org.mybatis.dynamic.sql.util.Validator;
3132

3233
public class SearchedCaseModel implements BasicColumn {
3334
private final List<SearchedWhenCondition> whenConditions;
@@ -38,6 +39,7 @@ private SearchedCaseModel(Builder builder) {
3839
whenConditions = builder.whenConditions;
3940
alias = builder.alias;
4041
elseValue = builder.elseValue;
42+
Validator.assertNotEmpty(whenConditions, "ERROR.40"); //$NON-NLS-1$
4143
}
4244

4345
public Stream<SearchedWhenCondition> whenConditions() {
@@ -74,8 +76,8 @@ public String thenValue() {
7476
return thenValue;
7577
}
7678

77-
protected SearchedWhenCondition(SqlCriterion initialCriterion, List<AndOrCriteriaGroup> subCriteria,
78-
String thenValue) {
79+
public SearchedWhenCondition(SqlCriterion initialCriterion, List<AndOrCriteriaGroup> subCriteria,
80+
String thenValue) {
7981
super(initialCriterion, subCriteria);
8082
this.thenValue = Objects.requireNonNull(thenValue);
8183
}

src/main/java/org/mybatis/dynamic/sql/select/SimpleCaseDSL.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import java.util.List;
2121
import java.util.Objects;
2222

23+
import org.mybatis.dynamic.sql.BasicColumn;
2324
import org.mybatis.dynamic.sql.BindableColumn;
2425
import org.mybatis.dynamic.sql.VisitableCondition;
2526

@@ -43,12 +44,12 @@ public WhenFinisher when(VisitableCondition<T> condition,
4344
return new WhenFinisher(condition, subsequentConditions);
4445
}
4546

46-
public SimpleCaseDSL<T> elseConstant(String value) {
47+
public SimpleCaseEnder elseConstant(String value) {
4748
elseValue = value;
48-
return this;
49+
return new SimpleCaseEnder();
4950
}
5051

51-
public SimpleCaseModel<T> end() {
52+
public BasicColumn end() {
5253
return new SimpleCaseModel.Builder<T>()
5354
.withColumn(column)
5455
.withWhenConditions(whenConditions)
@@ -70,6 +71,12 @@ public SimpleCaseDSL<T> thenConstant(String value) {
7071
}
7172
}
7273

74+
public class SimpleCaseEnder {
75+
public BasicColumn end() {
76+
return SimpleCaseDSL.this.end();
77+
}
78+
}
79+
7380
public static <T> SimpleCaseDSL<T> simpleCase(BindableColumn<T> column) {
7481
return new SimpleCaseDSL<>(column);
7582
}

src/main/java/org/mybatis/dynamic/sql/select/SimpleCaseModel.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import org.mybatis.dynamic.sql.render.RenderingContext;
2828
import org.mybatis.dynamic.sql.select.render.SimpleCaseRenderer;
2929
import org.mybatis.dynamic.sql.util.FragmentAndParameters;
30+
import org.mybatis.dynamic.sql.util.Validator;
3031

3132
public class SimpleCaseModel<T> implements BasicColumn {
3233
private final BindableColumn<T> column;
@@ -39,6 +40,7 @@ private SimpleCaseModel(Builder<T> builder) {
3940
whenConditions = builder.whenConditions;
4041
elseValue = builder.elseValue;
4142
alias = builder.alias;
43+
Validator.assertNotEmpty(whenConditions, "ERROR.40"); //$NON-NLS-1$
4244
}
4345

4446
public BindableColumn<T> column() {
@@ -85,7 +87,7 @@ public Object thenValue() {
8587
return thenValue;
8688
}
8789

88-
protected SimpleWhenCondition(List<VisitableCondition<T>> conditions, String thenValue) {
90+
public SimpleWhenCondition(List<VisitableCondition<T>> conditions, String thenValue) {
8991
this.conditions.addAll(conditions);
9092
this.thenValue = Objects.requireNonNull(thenValue);
9193
}

src/main/java/org/mybatis/dynamic/sql/select/render/SimpleCaseRenderer.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import org.mybatis.dynamic.sql.select.SimpleCaseModel;
2626
import org.mybatis.dynamic.sql.util.FragmentAndParameters;
2727
import org.mybatis.dynamic.sql.util.FragmentCollector;
28+
import org.mybatis.dynamic.sql.util.Validator;
2829
import org.mybatis.dynamic.sql.where.render.DefaultConditionVisitor;
2930

3031
public class SimpleCaseRenderer<T> {
@@ -83,6 +84,7 @@ private FragmentAndParameters renderConditions(SimpleCaseModel.SimpleWhenConditi
8384
}
8485

8586
private FragmentAndParameters renderCondition(VisitableCondition<T> condition) {
87+
Validator.assertTrue(condition.shouldRender(renderingContext), "ERROR.39"); //$NON-NLS-1$
8688
return condition.accept(conditionVisitor);
8789
}
8890

src/main/resources/org/mybatis/dynamic/sql/util/messages.properties

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,5 +55,6 @@ ERROR.35=Multi-select statements must have at least one "union" or "union all" e
5555
ERROR.36=You must either implement the "render" or "renderWithTableAlias" method in a column or function
5656
ERROR.37=The "{0}" function does not support conditions that fail to render
5757
ERROR.38=Bound values cannot be aliased
58-
ERROR.39=When clauses in searched case expressions must render
58+
ERROR.39=When clauses in case expressions must render (optional conditions are not supported)
59+
ERROR.40=Case expressions must have at least one "when" clause
5960
INTERNAL.ERROR=Internal Error {0}

src/test/java/examples/animal/data/CaseExpressionTest.java

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -310,14 +310,40 @@ void testSimpleCaseNoElse() {
310310
}
311311

312312
@Test
313-
void testInvalidCase() {
313+
void testInvalidSearchedCaseNoConditionsRender() {
314314
SelectModel model = select(animalName, searchedCase()
315-
.when(animalName,isEqualToWhenPresent((String) null)).thenConstant("Fred").end())
315+
.when(animalName, isEqualToWhenPresent((String) null)).thenConstant("Fred").end())
316316
.from(animalData)
317317
.build();
318318

319319
assertThatExceptionOfType(InvalidSqlException.class)
320320
.isThrownBy(() -> model.render(RenderingStrategies.MYBATIS3))
321321
.withMessage(Messages.getString("ERROR.39"));
322322
}
323+
324+
@Test
325+
void testInvalidSimpleCaseNoConditionsRender() {
326+
SelectModel model = select(simpleCase(animalName)
327+
.when(isEqualToWhenPresent((String) null)).thenConstant("Fred").end())
328+
.from(animalData)
329+
.build();
330+
331+
assertThatExceptionOfType(InvalidSqlException.class)
332+
.isThrownBy(() -> model.render(RenderingStrategies.MYBATIS3))
333+
.withMessage(Messages.getString("ERROR.39"));
334+
}
335+
336+
@Test
337+
void testInvalidSearchedCaseNoWhenConditions() {
338+
assertThatExceptionOfType(InvalidSqlException.class).isThrownBy(
339+
() -> searchedCase().end()
340+
).withMessage(Messages.getString("ERROR.40"));
341+
}
342+
343+
@Test
344+
void testInvalidSimpleCaseNoWhenConditions() {
345+
assertThatExceptionOfType(InvalidSqlException.class).isThrownBy(
346+
() -> simpleCase(id).end()
347+
).withMessage(Messages.getString("ERROR.40"));
348+
}
323349
}

0 commit comments

Comments
 (0)