SQL: Fix issue with folding of CASE/IIF (#49449)
Add extra checks to prevent ConstantFolding rule to try to fold the CASE/IIF functions early before the SimplifyCase rule gets applied. Fixes: #49387 (cherry picked from commit f35c9725350e35985d8dd3001870084e1784a5ca)
This commit is contained in:
parent
49bb5fb642
commit
0c4491964b
|
@ -116,12 +116,21 @@ public class Case extends ConditionalFunction {
|
|||
|
||||
/**
|
||||
* All foldable conditions that fold to FALSE should have
|
||||
* been removed by the {@link Optimizer}.
|
||||
* been removed by the {@link Optimizer}#SimplifyCase.
|
||||
*/
|
||||
@Override
|
||||
public boolean foldable() {
|
||||
return (conditions.isEmpty() && elseResult.foldable()) ||
|
||||
(conditions.size() == 1 && conditions.get(0).condition().foldable() && conditions.get(0).result().foldable());
|
||||
if (conditions.isEmpty() && elseResult.foldable()) {
|
||||
return true;
|
||||
}
|
||||
if (conditions.size() == 1 && conditions.get(0).condition().foldable()) {
|
||||
if (conditions.get(0).condition().fold() == Boolean.TRUE) {
|
||||
return conditions().get(0).result().foldable();
|
||||
} else {
|
||||
return elseResult().foldable();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -671,6 +671,8 @@ public class OptimizerTests extends ESTestCase {
|
|||
new IfConditional(EMPTY, new Equals(EMPTY, TWO, ONE), Literal.of(EMPTY, "bar2")),
|
||||
new IfConditional(EMPTY, new GreaterThan(EMPTY, getFieldAttribute(), ONE), Literal.of(EMPTY, "foo2")),
|
||||
Literal.of(EMPTY, "default")));
|
||||
assertFalse(c.foldable());
|
||||
|
||||
Expression e = new SimplifyCase().rule(c);
|
||||
assertEquals(Case.class, e.getClass());
|
||||
c = (Case) e;
|
||||
|
@ -696,13 +698,15 @@ public class OptimizerTests extends ESTestCase {
|
|||
// ELSE 'default'
|
||||
// END
|
||||
|
||||
SimplifyCase rule = new SimplifyCase();
|
||||
Case c = new Case(EMPTY, Arrays.asList(
|
||||
new IfConditional(EMPTY, new Equals(EMPTY, getFieldAttribute(), ONE), Literal.of(EMPTY, "foo1")),
|
||||
new IfConditional(EMPTY, new Equals(EMPTY, ONE, ONE), Literal.of(EMPTY, "bar1")),
|
||||
new IfConditional(EMPTY, new Equals(EMPTY, TWO, ONE), Literal.of(EMPTY, "bar2")),
|
||||
new IfConditional(EMPTY, new GreaterThan(EMPTY, getFieldAttribute(), ONE), Literal.of(EMPTY, "foo2")),
|
||||
Literal.of(EMPTY, "default")));
|
||||
assertFalse(c.foldable());
|
||||
|
||||
SimplifyCase rule = new SimplifyCase();
|
||||
Expression e = rule.rule(c);
|
||||
assertEquals(Case.class, e.getClass());
|
||||
c = (Case) e;
|
||||
|
@ -713,7 +717,7 @@ public class OptimizerTests extends ESTestCase {
|
|||
assertEquals(TypeResolution.TYPE_RESOLVED, c.typeResolved());
|
||||
}
|
||||
|
||||
public void testSimplifyCaseConditionsFoldCompletely() {
|
||||
public void testSimplifyCaseConditionsFoldCompletely_FoldableElse() {
|
||||
// CASE WHEN 1 = 2 THEN 'foo1'
|
||||
// WHEN 1 = 1 THEN 'foo2'
|
||||
// ELSE 'default'
|
||||
|
@ -723,11 +727,13 @@ public class OptimizerTests extends ESTestCase {
|
|||
//
|
||||
// 'foo2'
|
||||
|
||||
SimplifyCase rule = new SimplifyCase();
|
||||
Case c = new Case(EMPTY, Arrays.asList(
|
||||
new IfConditional(EMPTY, new Equals(EMPTY, ONE, TWO), Literal.of(EMPTY, "foo1")),
|
||||
new IfConditional(EMPTY, new Equals(EMPTY, ONE, ONE), Literal.of(EMPTY, "foo2")),
|
||||
Literal.of(EMPTY, "default")));
|
||||
assertFalse(c.foldable());
|
||||
|
||||
SimplifyCase rule = new SimplifyCase();
|
||||
Expression e = rule.rule(c);
|
||||
assertEquals(Case.class, e.getClass());
|
||||
c = (Case) e;
|
||||
|
@ -738,9 +744,34 @@ public class OptimizerTests extends ESTestCase {
|
|||
assertEquals(TypeResolution.TYPE_RESOLVED, c.typeResolved());
|
||||
}
|
||||
|
||||
public void testSimplifyIif_ConditionTrue() {
|
||||
public void testSimplifyCaseConditionsFoldCompletely_NonFoldableElse() {
|
||||
// CASE WHEN 1 = 2 THEN 'foo1'
|
||||
// ELSE myField
|
||||
// END
|
||||
//
|
||||
// ==>
|
||||
//
|
||||
// myField (non-foldable)
|
||||
|
||||
Case c = new Case(EMPTY, Arrays.asList(
|
||||
new IfConditional(EMPTY, new Equals(EMPTY, ONE, TWO), Literal.of(EMPTY, "foo1")),
|
||||
getFieldAttribute("myField")));
|
||||
assertFalse(c.foldable());
|
||||
|
||||
SimplifyCase rule = new SimplifyCase();
|
||||
Expression e = rule.rule(c);
|
||||
assertEquals(Case.class, e.getClass());
|
||||
c = (Case) e;
|
||||
assertEquals(0, c.conditions().size());
|
||||
assertFalse(c.foldable());
|
||||
assertEquals("myField", Expressions.name(c.elseResult()));
|
||||
}
|
||||
|
||||
public void testSimplifyIif_ConditionTrue_FoldableResult() {
|
||||
SimplifyCase rule = new SimplifyCase();
|
||||
Iif iif = new Iif(EMPTY, new Equals(EMPTY, ONE, ONE), Literal.of(EMPTY, "foo"), Literal.of(EMPTY, "bar"));
|
||||
assertTrue(iif.foldable());
|
||||
|
||||
Expression e = rule.rule(iif);
|
||||
assertEquals(Iif.class, e.getClass());
|
||||
iif = (Iif) e;
|
||||
|
@ -750,9 +781,26 @@ public class OptimizerTests extends ESTestCase {
|
|||
assertEquals(TypeResolution.TYPE_RESOLVED, iif.typeResolved());
|
||||
}
|
||||
|
||||
public void testSimplifyIif_ConditionFalse() {
|
||||
public void testSimplifyIif_ConditionTrue_NonFoldableResult() {
|
||||
SimplifyCase rule = new SimplifyCase();
|
||||
Iif iif = new Iif(EMPTY, new Equals(EMPTY, ONE, ONE), getFieldAttribute("myField"), Literal.of(EMPTY, "bar"));
|
||||
assertFalse(iif.foldable());
|
||||
|
||||
Expression e = rule.rule(iif);
|
||||
assertEquals(Iif.class, e.getClass());
|
||||
iif = (Iif) e;
|
||||
assertEquals(1, iif.conditions().size());
|
||||
assertFalse(iif.foldable());
|
||||
assertTrue(iif.conditions().get(0).condition().foldable());
|
||||
assertEquals(Boolean.TRUE, iif.conditions().get(0).condition().fold());
|
||||
assertEquals("myField", Expressions.name(iif.conditions().get(0).result()));
|
||||
}
|
||||
|
||||
public void testSimplifyIif_ConditionFalse_FoldableResult() {
|
||||
SimplifyCase rule = new SimplifyCase();
|
||||
Iif iif = new Iif(EMPTY, new Equals(EMPTY, ONE, TWO), Literal.of(EMPTY, "foo"), Literal.of(EMPTY, "bar"));
|
||||
assertTrue(iif.foldable());
|
||||
|
||||
Expression e = rule.rule(iif);
|
||||
assertEquals(Iif.class, e.getClass());
|
||||
iif = (Iif) e;
|
||||
|
@ -762,6 +810,19 @@ public class OptimizerTests extends ESTestCase {
|
|||
assertEquals(TypeResolution.TYPE_RESOLVED, iif.typeResolved());
|
||||
}
|
||||
|
||||
public void testSimplifyIif_ConditionFalse_NonFoldableResult() {
|
||||
SimplifyCase rule = new SimplifyCase();
|
||||
Iif iif = new Iif(EMPTY, new Equals(EMPTY, ONE, TWO), Literal.of(EMPTY, "foo"), getFieldAttribute("myField"));
|
||||
assertFalse(iif.foldable());
|
||||
|
||||
Expression e = rule.rule(iif);
|
||||
assertEquals(Iif.class, e.getClass());
|
||||
iif = (Iif) e;
|
||||
assertEquals(0, iif.conditions().size());
|
||||
assertFalse(iif.foldable());
|
||||
assertEquals("myField", Expressions.name(iif.elseResult()));
|
||||
}
|
||||
|
||||
//
|
||||
// Logical simplifications
|
||||
//
|
||||
|
|
Loading…
Reference in New Issue