[fix](Nereids) the rule of fold constant for logical operator (#20017)
the rule of constant folding on Logical Operator is: true and true -> true true and false -> false false and false -> false true and x -> x false and x -> false null and true -> null null and false -> false null and null -> null null and x -> null and x true or true -> true true or false -> true false or false -> false true or x -> true false or x -> false or x null or true -> true null or false -> null null or null -> null null or x -> null or x
This commit is contained in:
@ -218,50 +218,83 @@ public class FoldConstantRuleOnFE extends AbstractExpressionRewriteRule {
|
||||
@Override
|
||||
public Expression visitAnd(And and, ExpressionRewriteContext context) {
|
||||
List<Expression> nonTrueLiteral = Lists.newArrayList();
|
||||
int nullCount = 0;
|
||||
for (Expression e : and.children()) {
|
||||
e = e.accept(this, context);
|
||||
if (BooleanLiteral.FALSE.equals(e)) {
|
||||
return BooleanLiteral.FALSE;
|
||||
} else if (e instanceof NullLiteral) {
|
||||
return e;
|
||||
nullCount++;
|
||||
nonTrueLiteral.add(e);
|
||||
} else if (!BooleanLiteral.TRUE.equals(e)) {
|
||||
nonTrueLiteral.add(e);
|
||||
}
|
||||
}
|
||||
if (nonTrueLiteral.isEmpty()) {
|
||||
return BooleanLiteral.TRUE;
|
||||
|
||||
if (nullCount == 0) {
|
||||
switch (nonTrueLiteral.size()) {
|
||||
case 0:
|
||||
// true and true
|
||||
return BooleanLiteral.TRUE;
|
||||
case 1:
|
||||
// true and x
|
||||
return nonTrueLiteral.get(0);
|
||||
default:
|
||||
// x and y
|
||||
return and.withChildren(nonTrueLiteral);
|
||||
}
|
||||
} else if (nullCount == 1) {
|
||||
if (nonTrueLiteral.size() == 1) {
|
||||
// null and true
|
||||
return new NullLiteral(BooleanType.INSTANCE);
|
||||
}
|
||||
// null and x
|
||||
return and.withChildren(nonTrueLiteral);
|
||||
} else {
|
||||
// null and null
|
||||
return new NullLiteral(BooleanType.INSTANCE);
|
||||
}
|
||||
if (nonTrueLiteral.size() == 1) {
|
||||
return nonTrueLiteral.get(0);
|
||||
}
|
||||
return and.withChildren(nonTrueLiteral);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Expression visitOr(Or or, ExpressionRewriteContext context) {
|
||||
List<Expression> nonFalseLiteral = Lists.newArrayList();
|
||||
boolean hasNull = false;
|
||||
int nullCount = 0;
|
||||
for (Expression e : or.children()) {
|
||||
e = e.accept(this, context);
|
||||
if (BooleanLiteral.TRUE.equals(e)) {
|
||||
return BooleanLiteral.TRUE;
|
||||
} else if (e instanceof NullLiteral) {
|
||||
hasNull = true;
|
||||
nullCount++;
|
||||
nonFalseLiteral.add(e);
|
||||
} else if (!BooleanLiteral.FALSE.equals(e)) {
|
||||
nonFalseLiteral.add(e);
|
||||
}
|
||||
}
|
||||
if (nonFalseLiteral.isEmpty()) {
|
||||
if (hasNull) {
|
||||
return new NullLiteral(BooleanType.INSTANCE);
|
||||
} else {
|
||||
return BooleanLiteral.FALSE;
|
||||
|
||||
if (nullCount == 0) {
|
||||
switch (nonFalseLiteral.size()) {
|
||||
case 0:
|
||||
// false or false
|
||||
return BooleanLiteral.FALSE;
|
||||
case 1:
|
||||
// false or x
|
||||
return nonFalseLiteral.get(0);
|
||||
default:
|
||||
// x or y
|
||||
return or.withChildren(nonFalseLiteral);
|
||||
}
|
||||
} else if (nullCount == 1) {
|
||||
if (nonFalseLiteral.size() == 1) {
|
||||
// null or false
|
||||
return new NullLiteral(BooleanType.INSTANCE);
|
||||
}
|
||||
// null or x
|
||||
return or.withChildren(nonFalseLiteral);
|
||||
} else {
|
||||
// null or null
|
||||
return new NullLiteral(BooleanType.INSTANCE);
|
||||
}
|
||||
if (nonFalseLiteral.size() == 1) {
|
||||
return nonFalseLiteral.get(0);
|
||||
}
|
||||
return or.withChildren(nonFalseLiteral);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -112,10 +112,14 @@ public class FoldConstantTest extends ExpressionRewriteTestHelper {
|
||||
|
||||
assertRewriteAfterTypeCoercion("true and null", "null");
|
||||
assertRewriteAfterTypeCoercion("false and null", "false");
|
||||
assertRewriteAfterTypeCoercion("null and IA is null", "null and IA is null");
|
||||
assertRewriteAfterTypeCoercion("true or null", "true");
|
||||
assertRewriteAfterTypeCoercion("false or null", "null");
|
||||
assertRewriteAfterTypeCoercion("null or IA is null", "null or IA is null");
|
||||
|
||||
assertRewriteAfterTypeCoercion("null and null", "null");
|
||||
assertRewriteAfterTypeCoercion("null or null", "null");
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user