[fix](Nereids) simplify range produce true when reference is nullable (#28386)

if reference is nullable, even if range is all, we should not return
true, but should return reference is not null. for example,

before simplify: c1 > 5 or c1 < 10
after simplify:
    c1 is nullable: c1 IS NOT NULL
    c1 is not nullable: TRUE
This commit is contained in:
morrySnow
2023-12-14 18:10:17 +08:00
committed by GitHub
parent 23941ef305
commit 429a3ed4df
2 changed files with 42 additions and 5 deletions

View File

@ -28,8 +28,10 @@ import org.apache.doris.nereids.trees.expressions.Expression;
import org.apache.doris.nereids.trees.expressions.GreaterThan;
import org.apache.doris.nereids.trees.expressions.GreaterThanEqual;
import org.apache.doris.nereids.trees.expressions.InPredicate;
import org.apache.doris.nereids.trees.expressions.IsNull;
import org.apache.doris.nereids.trees.expressions.LessThan;
import org.apache.doris.nereids.trees.expressions.LessThanEqual;
import org.apache.doris.nereids.trees.expressions.Not;
import org.apache.doris.nereids.trees.expressions.Or;
import org.apache.doris.nereids.trees.expressions.literal.BooleanLiteral;
import org.apache.doris.nereids.trees.expressions.literal.Literal;
@ -204,7 +206,7 @@ public class SimplifyRange extends AbstractExpressionRewriteRule {
public static ValueDesc intersect(RangeValue range, DiscreteValue discrete) {
DiscreteValue result = new DiscreteValue(discrete.reference, discrete.expr);
discrete.values.stream().filter(x -> range.range.contains(x)).forEach(result.values::add);
if (result.values.size() > 0) {
if (!result.values.isEmpty()) {
return result;
}
return new EmptyValue(range.reference, ExpressionUtils.and(range.expr, discrete.expr));
@ -333,12 +335,19 @@ public class SimplifyRange extends AbstractExpressionRewriteRule {
result.add(new LessThan(reference, range.upperEndpoint()));
}
}
return result.isEmpty() ? BooleanLiteral.TRUE : ExpressionUtils.and(result);
if (!result.isEmpty()) {
return ExpressionUtils.and(result);
} else if (reference.nullable()) {
// when reference is nullable, we should filter null slot.
return new Not(new IsNull(reference));
} else {
return BooleanLiteral.TRUE;
}
}
@Override
public String toString() {
return range == null ? "UnknwonRange" : range.toString();
return range == null ? "UnknownRange" : range.toString();
}
}