Skip to content

Commit 87cba00

Browse files
authored
Relax restriction around case-when operand (#3376)
The `CASE` expression requires the when-operand to be a `BooleanValue`, which is too strict. The operand must return a `Boolean` type, but it can be an `Value`, for example, this should work: ```sql create table t1(col1 bigint, col2 boolean, primary key(col1)); insert into t1 values (1, true), (2, false); select col2, coalesce(case when col2 then 42 end, 100) from t1; true, 42 false, 100 ``` This fixes #3374.
1 parent 10b8a68 commit 87cba00

File tree

2 files changed

+20
-3
lines changed

2 files changed

+20
-3
lines changed

fdb-relational-core/src/main/java/com/apple/foundationdb/relational/recordlayer/query/visitors/ExpressionVisitor.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
import com.apple.foundationdb.record.query.plan.cascades.predicates.CompatibleTypeEvolutionPredicate;
2626
import com.apple.foundationdb.record.query.plan.cascades.typing.Type;
2727
import com.apple.foundationdb.record.query.plan.cascades.values.AbstractArrayConstructorValue;
28-
import com.apple.foundationdb.record.query.plan.cascades.values.BooleanValue;
2928
import com.apple.foundationdb.record.query.plan.cascades.values.ConditionSelectorValue;
3029
import com.apple.foundationdb.record.query.plan.cascades.values.ExistsValue;
3130
import com.apple.foundationdb.record.query.plan.cascades.values.FieldValue;
@@ -311,12 +310,13 @@ public Expression visitScalarFunctionCall(@Nonnull RelationalParser.ScalarFuncti
311310
@Nonnull
312311
@Override
313312
public Expression visitCaseFunctionCall(@Nonnull RelationalParser.CaseFunctionCallContext ctx) {
314-
final ImmutableList.Builder<BooleanValue> implications = ImmutableList.builder();
313+
final ImmutableList.Builder<Value> implications = ImmutableList.builder();
315314
final ImmutableList.Builder<Value> pickerValues = ImmutableList.builder();
316315
for (final var caseAlternative : ctx.caseFuncAlternative()) {
317316
final var condition = visitFunctionArg(caseAlternative.condition);
317+
Assert.thatUnchecked(condition.getDataType().getCode().equals(DataType.Code.BOOLEAN));
318318
final var consequent = visitFunctionArg(caseAlternative.consequent);
319-
implications.add(Assert.castUnchecked(condition.getUnderlying(), BooleanValue.class));
319+
implications.add(condition.getUnderlying());
320320
pickerValues.add(consequent.getUnderlying());
321321
}
322322
if (ctx.ELSE() != null) {

yaml-tests/src/test/resources/case-when.yamsql

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,17 @@
2121
schema_template:
2222
create type as struct S(S1 bigint, S2 bigint)
2323
create table A(A1 bigint, A2 bigint, A3 bigint, primary key(A1))
24+
create table B(B1 bigint, B2 boolean, primary key(B1))
2425
---
2526
setup:
2627
steps:
2728
- query: insert into A values
2829
(1, 10, 10),
2930
(2, 11, 20),
3031
(3, 12, 30);
32+
- query: insert into B values
33+
(1, true),
34+
(2, false);
3135
---
3236
test_block:
3337
tests:
@@ -37,6 +41,19 @@ test_block:
3741
{ A1: 2, A2: 11, A3: 20 },
3842
{ A1: 3, A2: 12, A3: 30 } ]
3943
---
44+
test_block:
45+
tests:
46+
-
47+
- query: select a3, case when a3 > 15 then 'foo' else 'bar' end from A;
48+
- result: [ { A3: 10, 'bar' },
49+
{ A3: 20, 'foo' },
50+
{ A3: 30, 'foo' } ]
51+
-
52+
- query: select b2, case when b2 then 'foo' else 'bar' end from b;
53+
- supported_version: !current_version
54+
- result: [ { B2: true, 'foo' },
55+
{ B2: false, 'bar' } ]
56+
---
4057
setup:
4158
steps:
4259
- query: update A set A2 = case when A1 = 1 then 4444 end

0 commit comments

Comments
 (0)