SQL: Fix issue with DataType for CASE with NULL (#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: #46032 (cherry picked from commit 8c1012efbbd3a300afd0dfb9b18250f15ea753f9)
This commit is contained in:
parent
5747badaa8
commit
3bee647e5b
|
@ -58,6 +58,7 @@ public class Case extends ConditionalFunction {
|
|||
for (IfConditional conditional : conditions) {
|
||||
dataType = DataTypeConversion.commonType(dataType, conditional.dataType());
|
||||
}
|
||||
dataType = DataTypeConversion.commonType(dataType, elseResult.dataType());
|
||||
}
|
||||
}
|
||||
return dataType;
|
||||
|
|
|
@ -6,19 +6,23 @@
|
|||
package org.elasticsearch.xpack.sql.expression.predicate.conditional;
|
||||
|
||||
import org.elasticsearch.xpack.sql.expression.Expression;
|
||||
import org.elasticsearch.xpack.sql.expression.Literal;
|
||||
import org.elasticsearch.xpack.sql.expression.function.scalar.FunctionTestUtils;
|
||||
import org.elasticsearch.xpack.sql.expression.predicate.operator.comparison.Equals;
|
||||
import org.elasticsearch.xpack.sql.tree.AbstractNodeTestCase;
|
||||
import org.elasticsearch.xpack.sql.tree.NodeSubclassTests;
|
||||
import org.elasticsearch.xpack.sql.tree.Source;
|
||||
import org.elasticsearch.xpack.sql.tree.SourceTests;
|
||||
import org.elasticsearch.xpack.sql.type.DataType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import static org.elasticsearch.xpack.sql.expression.function.scalar.FunctionTestUtils.randomIntLiteral;
|
||||
import static org.elasticsearch.xpack.sql.expression.function.scalar.FunctionTestUtils.randomStringLiteral;
|
||||
import static org.elasticsearch.xpack.sql.tree.Source.EMPTY;
|
||||
import static org.elasticsearch.xpack.sql.tree.SourceTests.randomSource;
|
||||
|
||||
/**
|
||||
|
@ -77,6 +81,42 @@ public class CaseTests extends AbstractNodeTestCase<Case, Expression> {
|
|||
assertEquals(new Case(c.source(), newChildren), c.replaceChildren(newChildren));
|
||||
}
|
||||
|
||||
public void testDataTypes() {
|
||||
// CASE WHEN 1 = 1 THEN NULL
|
||||
// ELSE 'default'
|
||||
// END
|
||||
Case c = new Case(EMPTY, Arrays.asList(
|
||||
new IfConditional(EMPTY, new Equals(EMPTY, Literal.of(EMPTY, 1), Literal.of(EMPTY, 1)), Literal.NULL),
|
||||
Literal.of(EMPTY, "default")));
|
||||
assertEquals(DataType.KEYWORD, c.dataType());
|
||||
|
||||
// CASE WHEN 1 = 1 THEN 'foo'
|
||||
// ELSE NULL
|
||||
// END
|
||||
c = new Case(EMPTY, Arrays.asList(
|
||||
new IfConditional(EMPTY, new Equals(EMPTY, Literal.of(EMPTY, 1), Literal.of(EMPTY, 1)), Literal.of(EMPTY, "foo")),
|
||||
Literal.NULL));
|
||||
assertEquals(DataType.KEYWORD, c.dataType());
|
||||
|
||||
// CASE WHEN 1 = 1 THEN NULL
|
||||
// ELSE NULL
|
||||
// END
|
||||
c = new Case(EMPTY, Arrays.asList(
|
||||
new IfConditional(EMPTY, new Equals(EMPTY, Literal.of(EMPTY, 1), Literal.of(EMPTY, 1)), Literal.NULL),
|
||||
Literal.NULL));
|
||||
assertEquals(DataType.NULL, c.dataType());
|
||||
|
||||
// CASE WHEN 1 = 1 THEN NULL
|
||||
// WHEN 2 = 2 THEN 'foo'
|
||||
// ELSE NULL
|
||||
// END
|
||||
c = new Case(EMPTY, Arrays.asList(
|
||||
new IfConditional(EMPTY, new Equals(EMPTY, Literal.of(EMPTY, 1), Literal.of(EMPTY, 1)), Literal.NULL),
|
||||
new IfConditional(EMPTY, new Equals(EMPTY, Literal.of(EMPTY, 2), Literal.of(EMPTY, 2)), Literal.of(EMPTY, "foo")),
|
||||
Literal.NULL));
|
||||
assertEquals(DataType.KEYWORD, c.dataType());
|
||||
}
|
||||
|
||||
private List<Expression> mutateChildren(Case c) {
|
||||
boolean removeConditional = randomBoolean();
|
||||
List<Expression> expressions = new ArrayList<>(c.children().size());
|
||||
|
|
Loading…
Reference in New Issue