Skip to content

Commit 8c1012e

Browse files
authored
SQL: Fix issue with DataType for CASE with NULL (elastic#46173)
Previously, if the DataType of all the WHEN conditions of a CASE statement is NULL, then it was set to NULL even if the ELSE clause has a non-NULL data type, e.g.: ``` CASE WHEN a = 1 THEN NULL WHEN a = 5 THEN NULL ELSE 'foo' ``` Fixes: elastic#46032
1 parent d4dd78c commit 8c1012e

File tree

2 files changed

+41
-0
lines changed
  • x-pack/plugin/sql/src
    • main/java/org/elasticsearch/xpack/sql/expression/predicate/conditional
    • test/java/org/elasticsearch/xpack/sql/expression/predicate/conditional

2 files changed

+41
-0
lines changed

x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/predicate/conditional/Case.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ public DataType dataType() {
5858
for (IfConditional conditional : conditions) {
5959
dataType = DataTypeConversion.commonType(dataType, conditional.dataType());
6060
}
61+
dataType = DataTypeConversion.commonType(dataType, elseResult.dataType());
6162
}
6263
}
6364
return dataType;

x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/expression/predicate/conditional/CaseTests.java

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,23 @@
66
package org.elasticsearch.xpack.sql.expression.predicate.conditional;
77

88
import org.elasticsearch.xpack.sql.expression.Expression;
9+
import org.elasticsearch.xpack.sql.expression.Literal;
910
import org.elasticsearch.xpack.sql.expression.function.scalar.FunctionTestUtils;
1011
import org.elasticsearch.xpack.sql.expression.predicate.operator.comparison.Equals;
1112
import org.elasticsearch.xpack.sql.tree.AbstractNodeTestCase;
1213
import org.elasticsearch.xpack.sql.tree.NodeSubclassTests;
1314
import org.elasticsearch.xpack.sql.tree.Source;
1415
import org.elasticsearch.xpack.sql.tree.SourceTests;
16+
import org.elasticsearch.xpack.sql.type.DataType;
1517

1618
import java.util.ArrayList;
19+
import java.util.Arrays;
1720
import java.util.List;
1821
import java.util.Objects;
1922

2023
import static org.elasticsearch.xpack.sql.expression.function.scalar.FunctionTestUtils.randomIntLiteral;
2124
import static org.elasticsearch.xpack.sql.expression.function.scalar.FunctionTestUtils.randomStringLiteral;
25+
import static org.elasticsearch.xpack.sql.tree.Source.EMPTY;
2226
import static org.elasticsearch.xpack.sql.tree.SourceTests.randomSource;
2327

2428
/**
@@ -77,6 +81,42 @@ public void testReplaceChildren() {
7781
assertEquals(new Case(c.source(), newChildren), c.replaceChildren(newChildren));
7882
}
7983

84+
public void testDataTypes() {
85+
// CASE WHEN 1 = 1 THEN NULL
86+
// ELSE 'default'
87+
// END
88+
Case c = new Case(EMPTY, Arrays.asList(
89+
new IfConditional(EMPTY, new Equals(EMPTY, Literal.of(EMPTY, 1), Literal.of(EMPTY, 1)), Literal.NULL),
90+
Literal.of(EMPTY, "default")));
91+
assertEquals(DataType.KEYWORD, c.dataType());
92+
93+
// CASE WHEN 1 = 1 THEN 'foo'
94+
// ELSE NULL
95+
// END
96+
c = new Case(EMPTY, Arrays.asList(
97+
new IfConditional(EMPTY, new Equals(EMPTY, Literal.of(EMPTY, 1), Literal.of(EMPTY, 1)), Literal.of(EMPTY, "foo")),
98+
Literal.NULL));
99+
assertEquals(DataType.KEYWORD, c.dataType());
100+
101+
// CASE WHEN 1 = 1 THEN NULL
102+
// ELSE NULL
103+
// END
104+
c = new Case(EMPTY, Arrays.asList(
105+
new IfConditional(EMPTY, new Equals(EMPTY, Literal.of(EMPTY, 1), Literal.of(EMPTY, 1)), Literal.NULL),
106+
Literal.NULL));
107+
assertEquals(DataType.NULL, c.dataType());
108+
109+
// CASE WHEN 1 = 1 THEN NULL
110+
// WHEN 2 = 2 THEN 'foo'
111+
// ELSE NULL
112+
// END
113+
c = new Case(EMPTY, Arrays.asList(
114+
new IfConditional(EMPTY, new Equals(EMPTY, Literal.of(EMPTY, 1), Literal.of(EMPTY, 1)), Literal.NULL),
115+
new IfConditional(EMPTY, new Equals(EMPTY, Literal.of(EMPTY, 2), Literal.of(EMPTY, 2)), Literal.of(EMPTY, "foo")),
116+
Literal.NULL));
117+
assertEquals(DataType.KEYWORD, c.dataType());
118+
}
119+
80120
private List<Expression> mutateChildren(Case c) {
81121
boolean removeConditional = randomBoolean();
82122
List<Expression> expressions = new ArrayList<>(c.children().size());

0 commit comments

Comments
 (0)