[fix](nereids) fix UnknownValue's reference in simplify range rule #44637 (#44771)

cherry pick from #44637
This commit is contained in:
yujun
2024-11-29 20:58:40 +08:00
committed by GitHub
parent e03517e4e5
commit 4d023cf0b2
9 changed files with 176 additions and 115 deletions

View File

@ -92,12 +92,12 @@ public class SimplifyRange implements ExpressionPatternRuleFactory {
/** rewrite */
public static Expression rewrite(CompoundPredicate expr, ExpressionRewriteContext context) {
ValueDesc valueDesc = expr.accept(new RangeInference(), context);
Expression exprForNonNull = valueDesc.toExpressionForNonNull();
if (exprForNonNull == null) {
Expression toExpr = valueDesc.toExpression();
if (toExpr == null) {
// this mean cannot simplify
return valueDesc.exprForNonNull;
return valueDesc.toExpr;
}
return exprForNonNull;
return toExpr;
}
private static class RangeInference extends ExpressionVisitor<ValueDesc, ExpressionRewriteContext> {
@ -197,18 +197,18 @@ public class SimplifyRange implements ExpressionPatternRuleFactory {
}
// use UnknownValue to wrap different references
return new UnknownValue(context, valuePerRefs, originExpr, exprOp);
return new UnknownValue(context, originExpr, valuePerRefs, exprOp);
}
}
private abstract static class ValueDesc {
ExpressionRewriteContext context;
Expression exprForNonNull;
Expression toExpr;
Expression reference;
public ValueDesc(ExpressionRewriteContext context, Expression reference, Expression exprForNonNull) {
public ValueDesc(ExpressionRewriteContext context, Expression reference, Expression toExpr) {
this.context = context;
this.exprForNonNull = exprForNonNull;
this.toExpr = toExpr;
this.reference = reference;
}
@ -220,28 +220,28 @@ public class SimplifyRange implements ExpressionPatternRuleFactory {
if (count == discrete.values.size()) {
return range;
}
Expression exprForNonNull = FoldConstantRuleOnFE.evaluate(
ExpressionUtils.or(range.exprForNonNull, discrete.exprForNonNull), context);
Expression toExpr = FoldConstantRuleOnFE.evaluate(
ExpressionUtils.or(range.toExpr, discrete.toExpr), context);
List<ValueDesc> sourceValues = reverseOrder
? ImmutableList.of(discrete, range)
: ImmutableList.of(range, discrete);
return new UnknownValue(context, sourceValues, exprForNonNull, ExpressionUtils::or);
return new UnknownValue(context, toExpr, sourceValues, ExpressionUtils::or);
}
public abstract ValueDesc intersect(ValueDesc other);
public static ValueDesc intersect(ExpressionRewriteContext context, RangeValue range, DiscreteValue discrete) {
DiscreteValue result = new DiscreteValue(context, discrete.reference, discrete.exprForNonNull);
DiscreteValue result = new DiscreteValue(context, discrete.reference, discrete.toExpr);
discrete.values.stream().filter(x -> range.range.contains(x)).forEach(result.values::add);
if (!result.values.isEmpty()) {
return result;
}
Expression originExprForNonNull = FoldConstantRuleOnFE.evaluate(
ExpressionUtils.and(range.exprForNonNull, discrete.exprForNonNull), context);
return new EmptyValue(context, range.reference, originExprForNonNull);
Expression originExpr = FoldConstantRuleOnFE.evaluate(
ExpressionUtils.and(range.toExpr, discrete.toExpr), context);
return new EmptyValue(context, range.reference, originExpr);
}
public abstract Expression toExpressionForNonNull();
public abstract Expression toExpression();
public static ValueDesc range(ExpressionRewriteContext context, ComparisonPredicate predicate) {
Literal value = (Literal) predicate.right();
@ -271,8 +271,8 @@ public class SimplifyRange implements ExpressionPatternRuleFactory {
private static class EmptyValue extends ValueDesc {
public EmptyValue(ExpressionRewriteContext context, Expression reference, Expression exprForNonNull) {
super(context, reference, exprForNonNull);
public EmptyValue(ExpressionRewriteContext context, Expression reference, Expression toExpr) {
super(context, reference, toExpr);
}
@Override
@ -286,7 +286,7 @@ public class SimplifyRange implements ExpressionPatternRuleFactory {
}
@Override
public Expression toExpressionForNonNull() {
public Expression toExpression() {
if (reference.nullable()) {
return new And(new IsNull(reference), new NullLiteral(BooleanType.INSTANCE));
} else {
@ -303,8 +303,8 @@ public class SimplifyRange implements ExpressionPatternRuleFactory {
private static class RangeValue extends ValueDesc {
Range<Literal> range;
public RangeValue(ExpressionRewriteContext context, Expression reference, Expression exprForNonNull) {
super(context, reference, exprForNonNull);
public RangeValue(ExpressionRewriteContext context, Expression reference, Expression toExpr) {
super(context, reference, toExpr);
}
@Override
@ -312,26 +312,25 @@ public class SimplifyRange implements ExpressionPatternRuleFactory {
if (other instanceof EmptyValue) {
return other.union(this);
}
try {
if (other instanceof RangeValue) {
Expression originExprForNonNull = FoldConstantRuleOnFE.evaluate(
ExpressionUtils.or(exprForNonNull, other.exprForNonNull), context);
RangeValue o = (RangeValue) other;
if (range.isConnected(o.range)) {
RangeValue rangeValue = new RangeValue(context, reference, originExprForNonNull);
rangeValue.range = range.span(o.range);
return rangeValue;
}
return new UnknownValue(context, ImmutableList.of(this, other),
originExprForNonNull, ExpressionUtils::or);
if (other instanceof RangeValue) {
Expression originExpr = FoldConstantRuleOnFE.evaluate(
ExpressionUtils.or(toExpr, other.toExpr), context);
RangeValue o = (RangeValue) other;
if (range.isConnected(o.range)) {
RangeValue rangeValue = new RangeValue(context, reference, originExpr);
rangeValue.range = range.span(o.range);
return rangeValue;
}
return union(context, this, (DiscreteValue) other, false);
} catch (Exception e) {
Expression originExprForNonNull = FoldConstantRuleOnFE.evaluate(
ExpressionUtils.or(exprForNonNull, other.exprForNonNull), context);
return new UnknownValue(context, ImmutableList.of(this, other),
originExprForNonNull, ExpressionUtils::or);
return new UnknownValue(context, originExpr,
ImmutableList.of(this, other), ExpressionUtils::or);
}
if (other instanceof DiscreteValue) {
return union(context, this, (DiscreteValue) other, false);
}
Expression originExpr = FoldConstantRuleOnFE.evaluate(
ExpressionUtils.or(toExpr, other.toExpr), context);
return new UnknownValue(context, originExpr,
ImmutableList.of(this, other), ExpressionUtils::or);
}
@Override
@ -339,29 +338,28 @@ public class SimplifyRange implements ExpressionPatternRuleFactory {
if (other instanceof EmptyValue) {
return other.intersect(this);
}
try {
if (other instanceof RangeValue) {
Expression originExprForNonNull = FoldConstantRuleOnFE.evaluate(
ExpressionUtils.and(exprForNonNull, other.exprForNonNull), context);
RangeValue o = (RangeValue) other;
if (range.isConnected(o.range)) {
RangeValue rangeValue = new RangeValue(context, reference, originExprForNonNull);
rangeValue.range = range.intersection(o.range);
return rangeValue;
}
return new EmptyValue(context, reference, originExprForNonNull);
if (other instanceof RangeValue) {
Expression originExpr = FoldConstantRuleOnFE.evaluate(
ExpressionUtils.and(toExpr, other.toExpr), context);
RangeValue o = (RangeValue) other;
if (range.isConnected(o.range)) {
RangeValue rangeValue = new RangeValue(context, reference, originExpr);
rangeValue.range = range.intersection(o.range);
return rangeValue;
}
return intersect(context, this, (DiscreteValue) other);
} catch (Exception e) {
Expression originExprForNonNull = FoldConstantRuleOnFE.evaluate(
ExpressionUtils.and(exprForNonNull, other.exprForNonNull), context);
return new UnknownValue(context, ImmutableList.of(this, other),
originExprForNonNull, ExpressionUtils::and);
return new EmptyValue(context, reference, originExpr);
}
if (other instanceof DiscreteValue) {
return intersect(context, this, (DiscreteValue) other);
}
Expression originExpr = FoldConstantRuleOnFE.evaluate(
ExpressionUtils.and(toExpr, other.toExpr), context);
return new UnknownValue(context, originExpr,
ImmutableList.of(this, other), ExpressionUtils::and);
}
@Override
public Expression toExpressionForNonNull() {
public Expression toExpression() {
List<Expression> result = Lists.newArrayList();
if (range.hasLowerBound()) {
if (range.lowerBoundType() == BoundType.CLOSED) {
@ -403,13 +401,13 @@ public class SimplifyRange implements ExpressionPatternRuleFactory {
Set<Literal> values;
public DiscreteValue(ExpressionRewriteContext context,
Expression reference, Expression exprForNonNull, Literal... values) {
this(context, reference, exprForNonNull, Arrays.asList(values));
Expression reference, Expression toExpr, Literal... values) {
this(context, reference, toExpr, Arrays.asList(values));
}
public DiscreteValue(ExpressionRewriteContext context,
Expression reference, Expression exprForNonNull, Collection<Literal> values) {
super(context, reference, exprForNonNull);
Expression reference, Expression toExpr, Collection<Literal> values) {
super(context, reference, toExpr);
this.values = Sets.newTreeSet(values);
}
@ -418,22 +416,21 @@ public class SimplifyRange implements ExpressionPatternRuleFactory {
if (other instanceof EmptyValue) {
return other.union(this);
}
try {
if (other instanceof DiscreteValue) {
Expression originExprForNonNull = FoldConstantRuleOnFE.evaluate(
ExpressionUtils.or(exprForNonNull, other.exprForNonNull), context);
DiscreteValue discreteValue = new DiscreteValue(context, reference, originExprForNonNull);
discreteValue.values.addAll(((DiscreteValue) other).values);
discreteValue.values.addAll(this.values);
return discreteValue;
}
return union(context, (RangeValue) other, this, true);
} catch (Exception e) {
Expression originExprForNonNull = FoldConstantRuleOnFE.evaluate(
ExpressionUtils.or(exprForNonNull, other.exprForNonNull), context);
return new UnknownValue(context, ImmutableList.of(this, other),
originExprForNonNull, ExpressionUtils::or);
if (other instanceof DiscreteValue) {
Expression originExpr = FoldConstantRuleOnFE.evaluate(
ExpressionUtils.or(toExpr, other.toExpr), context);
DiscreteValue discreteValue = new DiscreteValue(context, reference, originExpr);
discreteValue.values.addAll(((DiscreteValue) other).values);
discreteValue.values.addAll(this.values);
return discreteValue;
}
if (other instanceof RangeValue) {
return union(context, (RangeValue) other, this, true);
}
Expression originExpr = FoldConstantRuleOnFE.evaluate(
ExpressionUtils.or(toExpr, other.toExpr), context);
return new UnknownValue(context, originExpr,
ImmutableList.of(this, other), ExpressionUtils::or);
}
@Override
@ -441,30 +438,29 @@ public class SimplifyRange implements ExpressionPatternRuleFactory {
if (other instanceof EmptyValue) {
return other.intersect(this);
}
try {
if (other instanceof DiscreteValue) {
Expression originExprForNonNull = FoldConstantRuleOnFE.evaluate(
ExpressionUtils.and(exprForNonNull, other.exprForNonNull), context);
DiscreteValue discreteValue = new DiscreteValue(context, reference, originExprForNonNull);
discreteValue.values.addAll(((DiscreteValue) other).values);
discreteValue.values.retainAll(this.values);
if (discreteValue.values.isEmpty()) {
return new EmptyValue(context, reference, originExprForNonNull);
} else {
return discreteValue;
}
if (other instanceof DiscreteValue) {
Expression originExpr = FoldConstantRuleOnFE.evaluate(
ExpressionUtils.and(toExpr, other.toExpr), context);
DiscreteValue discreteValue = new DiscreteValue(context, reference, originExpr);
discreteValue.values.addAll(((DiscreteValue) other).values);
discreteValue.values.retainAll(this.values);
if (discreteValue.values.isEmpty()) {
return new EmptyValue(context, reference, originExpr);
} else {
return discreteValue;
}
return intersect(context, (RangeValue) other, this);
} catch (Exception e) {
Expression originExprForNonNull = FoldConstantRuleOnFE.evaluate(
ExpressionUtils.and(exprForNonNull, other.exprForNonNull), context);
return new UnknownValue(context, ImmutableList.of(this, other),
originExprForNonNull, ExpressionUtils::and);
}
if (other instanceof RangeValue) {
return intersect(context, (RangeValue) other, this);
}
Expression originExpr = FoldConstantRuleOnFE.evaluate(
ExpressionUtils.and(toExpr, other.toExpr), context);
return new UnknownValue(context, originExpr,
ImmutableList.of(this, other), ExpressionUtils::and);
}
@Override
public Expression toExpressionForNonNull() {
public Expression toExpression() {
// NOTICE: it's related with `InPredicateToEqualToRule`
// They are same processes, so must change synchronously.
if (values.size() == 1) {
@ -498,37 +494,70 @@ public class SimplifyRange implements ExpressionPatternRuleFactory {
mergeExprOp = null;
}
public UnknownValue(ExpressionRewriteContext context,
List<ValueDesc> sourceValues, Expression exprForNonNull, BinaryOperator<Expression> mergeExprOp) {
super(context, sourceValues.get(0).reference, exprForNonNull);
public UnknownValue(ExpressionRewriteContext context, Expression toExpr,
List<ValueDesc> sourceValues, BinaryOperator<Expression> mergeExprOp) {
super(context, getReference(sourceValues, toExpr), toExpr);
this.sourceValues = ImmutableList.copyOf(sourceValues);
this.mergeExprOp = mergeExprOp;
}
// reference is used to simplify multiple ValueDescs.
// when ValueDesc A op ValueDesc B, only A and B's references equals,
// can reduce them, like A op B = A.
// If A and B's reference not equal, A op B will always get UnknownValue(A op B).
//
// for example:
// 1. RangeValue(a < 10, reference=a) union RangeValue(a > 20, reference=a)
// = UnknownValue1(a < 10 or a > 20, reference=a)
// 2. RangeValue(a < 10, reference=a) union RangeValue(b > 20, reference=b)
// = UnknownValue2(a < 10 or b > 20, reference=(a < 10 or b > 20))
// then given EmptyValue(, reference=a) E,
// 1. since E and UnknownValue1's reference equals, then
// E union UnknownValue1 = E.union(UnknownValue1) = UnknownValue1,
// 2. since E and UnknownValue2's reference not equals, then
// E union UnknownValue2 = UnknownValue3(E union UnknownValue2, reference=E union UnknownValue2)
private static Expression getReference(List<ValueDesc> sourceValues, Expression toExpr) {
Expression reference = sourceValues.get(0).reference;
for (int i = 1; i < sourceValues.size(); i++) {
if (!reference.equals(sourceValues.get(i).reference)) {
return toExpr;
}
}
return reference;
}
@Override
public ValueDesc union(ValueDesc other) {
Expression originExprForNonNull = FoldConstantRuleOnFE.evaluate(
ExpressionUtils.or(exprForNonNull, other.exprForNonNull), context);
return new UnknownValue(context, ImmutableList.of(this, other), originExprForNonNull, ExpressionUtils::or);
Expression originExpr = FoldConstantRuleOnFE.evaluate(
ExpressionUtils.or(toExpr, other.toExpr), context);
return new UnknownValue(context, originExpr,
ImmutableList.of(this, other), ExpressionUtils::or);
}
@Override
public ValueDesc intersect(ValueDesc other) {
Expression originExprForNonNull = FoldConstantRuleOnFE.evaluate(
ExpressionUtils.and(exprForNonNull, other.exprForNonNull), context);
return new UnknownValue(context, ImmutableList.of(this, other), originExprForNonNull, ExpressionUtils::and);
Expression originExpr = FoldConstantRuleOnFE.evaluate(
ExpressionUtils.and(toExpr, other.toExpr), context);
return new UnknownValue(context, originExpr,
ImmutableList.of(this, other), ExpressionUtils::and);
}
@Override
public Expression toExpressionForNonNull() {
public Expression toExpression() {
if (sourceValues.isEmpty()) {
return exprForNonNull;
return toExpr;
}
Expression result = sourceValues.get(0).toExpressionForNonNull();
Expression result = sourceValues.get(0).toExpression();
for (int i = 1; i < sourceValues.size(); i++) {
result = mergeExprOp.apply(result, sourceValues.get(i).toExpressionForNonNull());
result = mergeExprOp.apply(result, sourceValues.get(i).toExpression());
}
return FoldConstantRuleOnFE.evaluate(result, context);
result = FoldConstantRuleOnFE.evaluate(result, context);
// ATTN: we must return original expr, because OrToIn is implemented with MutableState,
// newExpr will lose these states leading to dead loop by OrToIn -> SimplifyRange -> FoldConstantByFE
if (result.equals(toExpr)) {
return toExpr;
}
return result;
}
}
}

View File

@ -101,6 +101,7 @@ public class SimplifyRangeTest extends ExpressionRewrite {
assertRewrite("TA > 5 + 1 and TA > 10", "cast(TA as smallint) > 6 and TA > 10");
assertRewrite("(TA > 1 and TA > 10) or TA > 20", "TA > 10");
assertRewrite("(TA > 1 or TA > 10) and TA > 20", "TA > 20");
assertRewrite("(TA < 1 and TA > 10) or TA = 20 and TB > 10", "(TA is null and null) or TA = 20 and TB > 10");
assertRewrite("(TA + TB > 1 or TA + TB > 10) and TA + TB > 20", "TA + TB > 20");
assertRewrite("TA > 10 or TA > 10", "TA > 10");
assertRewrite("(TA > 10 or TA > 20) and (TB > 10 and TB < 20)", "TA > 10 and (TB > 10 and TB < 20) ");
@ -131,7 +132,10 @@ public class SimplifyRangeTest extends ExpressionRewrite {
assertRewrite("TA in (1) and TA in (3)", "TA is null and null");
assertRewrite("TA in (1) and TA in (1)", "TA = 1");
assertRewriteNotNull("(TA > 3 and TA < 1) and TB < 5", "FALSE");
assertRewrite("(TA > 3 and TA < 1) and (TA > 5 and TA = 4)", "TA is null and null");
assertRewrite("(TA > 3 and TA < 1) or (TA > 5 and TA = 4)", "TA is null and null");
assertRewrite("(TA > 3 and TA < 1) and TB < 5", "TA is null and null and TB < 5");
assertRewrite("(TA > 3 and TA < 1) and (TB < 5 and TB = 6)", "TA is null and null and TB is null");
assertRewrite("TA > 3 and TB < 5 and TA < 1", "TA is null and null and TB < 5");
assertRewrite("(TA > 3 and TA < 1) or TB < 5", "(TA is null and null) or TB < 5");
assertRewrite("((IA = 1 AND SC ='1') OR SC = '1212') AND IA =1", "((IA = 1 AND SC ='1') OR SC = '1212') AND IA =1");

View File

@ -19,6 +19,6 @@ PhysicalResultSink
--------------------------PhysicalDistribute[DistributionSpecHash]
----------------------------hashAgg[LOCAL]
------------------------------PhysicalProject
--------------------------------filter((((item.i_category = 'Men') AND (((((i_size IN ('economy', 'small') AND i_color IN ('maroon', 'smoke')) AND i_units IN ('Case', 'Ounce')) OR ((i_size IN ('economy', 'small') AND i_color IN ('firebrick', 'sienna')) AND i_units IN ('Cup', 'Each'))) OR ((i_color IN ('powder', 'sky') AND i_units IN ('Dozen', 'Lb')) AND i_size IN ('N/A', 'large'))) OR ((i_color IN ('papaya', 'peach') AND i_units IN ('Bundle', 'Carton')) AND i_size IN ('N/A', 'large')))) OR ((item.i_category = 'Women') AND (((((i_color IN ('forest', 'lime') AND i_units IN ('Pallet', 'Pound')) AND i_size IN ('economy', 'small')) OR ((i_color IN ('navy', 'slate') AND i_units IN ('Bunch', 'Gross')) AND i_size IN ('extra large', 'petite'))) OR ((i_color IN ('aquamarine', 'dark') AND i_units IN ('Tbl', 'Ton')) AND i_size IN ('economy', 'small'))) OR ((i_color IN ('frosted', 'plum') AND i_units IN ('Box', 'Dram')) AND i_size IN ('extra large', 'petite'))))))
--------------------------------filter((((item.i_category = 'Men') AND (((((i_size IN ('economy', 'small') AND i_color IN ('maroon', 'smoke')) AND i_units IN ('Case', 'Ounce')) OR ((i_color IN ('powder', 'sky') AND i_units IN ('Dozen', 'Lb')) AND i_size IN ('N/A', 'large'))) OR ((i_size IN ('economy', 'small') AND i_color IN ('firebrick', 'sienna')) AND i_units IN ('Cup', 'Each'))) OR ((i_color IN ('papaya', 'peach') AND i_units IN ('Bundle', 'Carton')) AND i_size IN ('N/A', 'large')))) OR ((item.i_category = 'Women') AND (((((i_color IN ('forest', 'lime') AND i_units IN ('Pallet', 'Pound')) AND i_size IN ('economy', 'small')) OR ((i_color IN ('navy', 'slate') AND i_units IN ('Bunch', 'Gross')) AND i_size IN ('extra large', 'petite'))) OR ((i_color IN ('aquamarine', 'dark') AND i_units IN ('Tbl', 'Ton')) AND i_size IN ('economy', 'small'))) OR ((i_color IN ('frosted', 'plum') AND i_units IN ('Box', 'Dram')) AND i_size IN ('extra large', 'petite'))))))
----------------------------------PhysicalOlapScan[item]

View File

@ -19,6 +19,6 @@ PhysicalResultSink
--------------------------PhysicalDistribute[DistributionSpecHash]
----------------------------hashAgg[LOCAL]
------------------------------PhysicalProject
--------------------------------filter((((item.i_category = 'Men') AND (((((i_size IN ('economy', 'small') AND i_color IN ('maroon', 'smoke')) AND i_units IN ('Case', 'Ounce')) OR ((i_size IN ('economy', 'small') AND i_color IN ('firebrick', 'sienna')) AND i_units IN ('Cup', 'Each'))) OR ((i_color IN ('powder', 'sky') AND i_units IN ('Dozen', 'Lb')) AND i_size IN ('N/A', 'large'))) OR ((i_color IN ('papaya', 'peach') AND i_units IN ('Bundle', 'Carton')) AND i_size IN ('N/A', 'large')))) OR ((item.i_category = 'Women') AND (((((i_color IN ('forest', 'lime') AND i_units IN ('Pallet', 'Pound')) AND i_size IN ('economy', 'small')) OR ((i_color IN ('navy', 'slate') AND i_units IN ('Bunch', 'Gross')) AND i_size IN ('extra large', 'petite'))) OR ((i_color IN ('aquamarine', 'dark') AND i_units IN ('Tbl', 'Ton')) AND i_size IN ('economy', 'small'))) OR ((i_color IN ('frosted', 'plum') AND i_units IN ('Box', 'Dram')) AND i_size IN ('extra large', 'petite'))))))
--------------------------------filter((((item.i_category = 'Men') AND (((((i_size IN ('economy', 'small') AND i_color IN ('maroon', 'smoke')) AND i_units IN ('Case', 'Ounce')) OR ((i_color IN ('powder', 'sky') AND i_units IN ('Dozen', 'Lb')) AND i_size IN ('N/A', 'large'))) OR ((i_size IN ('economy', 'small') AND i_color IN ('firebrick', 'sienna')) AND i_units IN ('Cup', 'Each'))) OR ((i_color IN ('papaya', 'peach') AND i_units IN ('Bundle', 'Carton')) AND i_size IN ('N/A', 'large')))) OR ((item.i_category = 'Women') AND (((((i_color IN ('forest', 'lime') AND i_units IN ('Pallet', 'Pound')) AND i_size IN ('economy', 'small')) OR ((i_color IN ('navy', 'slate') AND i_units IN ('Bunch', 'Gross')) AND i_size IN ('extra large', 'petite'))) OR ((i_color IN ('aquamarine', 'dark') AND i_units IN ('Tbl', 'Ton')) AND i_size IN ('economy', 'small'))) OR ((i_color IN ('frosted', 'plum') AND i_units IN ('Box', 'Dram')) AND i_size IN ('extra large', 'petite'))))))
----------------------------------PhysicalOlapScan[item]

View File

@ -19,6 +19,6 @@ PhysicalResultSink
--------------------------PhysicalDistribute[DistributionSpecHash]
----------------------------hashAgg[LOCAL]
------------------------------PhysicalProject
--------------------------------filter((((item.i_category = 'Men') AND (((((i_size IN ('economy', 'medium') AND i_color IN ('dodger', 'tan')) AND i_units IN ('Bunch', 'Tsp')) OR ((i_size IN ('economy', 'medium') AND i_color IN ('indian', 'spring')) AND i_units IN ('Carton', 'Unknown'))) OR ((i_color IN ('blue', 'chartreuse') AND i_units IN ('Each', 'Oz')) AND i_size IN ('N/A', 'large'))) OR ((i_color IN ('peru', 'saddle') AND i_units IN ('Gram', 'Pallet')) AND i_size IN ('N/A', 'large')))) OR ((item.i_category = 'Women') AND (((((i_color IN ('aquamarine', 'gainsboro') AND i_units IN ('Dozen', 'Ounce')) AND i_size IN ('economy', 'medium')) OR ((i_color IN ('chiffon', 'violet') AND i_units IN ('Pound', 'Ton')) AND i_size IN ('extra large', 'small'))) OR ((i_color IN ('blanched', 'tomato') AND i_units IN ('Case', 'Tbl')) AND i_size IN ('economy', 'medium'))) OR ((i_color IN ('almond', 'lime') AND i_units IN ('Box', 'Dram')) AND i_size IN ('extra large', 'small'))))))
--------------------------------filter((((item.i_category = 'Men') AND (((((i_size IN ('economy', 'medium') AND i_color IN ('dodger', 'tan')) AND i_units IN ('Bunch', 'Tsp')) OR ((i_color IN ('blue', 'chartreuse') AND i_units IN ('Each', 'Oz')) AND i_size IN ('N/A', 'large'))) OR ((i_size IN ('economy', 'medium') AND i_color IN ('indian', 'spring')) AND i_units IN ('Carton', 'Unknown'))) OR ((i_color IN ('peru', 'saddle') AND i_units IN ('Gram', 'Pallet')) AND i_size IN ('N/A', 'large')))) OR ((item.i_category = 'Women') AND (((((i_color IN ('aquamarine', 'gainsboro') AND i_units IN ('Dozen', 'Ounce')) AND i_size IN ('economy', 'medium')) OR ((i_color IN ('chiffon', 'violet') AND i_units IN ('Pound', 'Ton')) AND i_size IN ('extra large', 'small'))) OR ((i_color IN ('blanched', 'tomato') AND i_units IN ('Case', 'Tbl')) AND i_size IN ('economy', 'medium'))) OR ((i_color IN ('almond', 'lime') AND i_units IN ('Box', 'Dram')) AND i_size IN ('extra large', 'small'))))))
----------------------------------PhysicalOlapScan[item]

View File

@ -19,6 +19,6 @@ PhysicalResultSink
--------------------------PhysicalDistribute[DistributionSpecHash]
----------------------------hashAgg[LOCAL]
------------------------------PhysicalProject
--------------------------------filter((((item.i_category = 'Men') AND (((((i_size IN ('economy', 'medium') AND i_color IN ('dodger', 'tan')) AND i_units IN ('Bunch', 'Tsp')) OR ((i_size IN ('economy', 'medium') AND i_color IN ('indian', 'spring')) AND i_units IN ('Carton', 'Unknown'))) OR ((i_color IN ('blue', 'chartreuse') AND i_units IN ('Each', 'Oz')) AND i_size IN ('N/A', 'large'))) OR ((i_color IN ('peru', 'saddle') AND i_units IN ('Gram', 'Pallet')) AND i_size IN ('N/A', 'large')))) OR ((item.i_category = 'Women') AND (((((i_color IN ('aquamarine', 'gainsboro') AND i_units IN ('Dozen', 'Ounce')) AND i_size IN ('economy', 'medium')) OR ((i_color IN ('chiffon', 'violet') AND i_units IN ('Pound', 'Ton')) AND i_size IN ('extra large', 'small'))) OR ((i_color IN ('blanched', 'tomato') AND i_units IN ('Case', 'Tbl')) AND i_size IN ('economy', 'medium'))) OR ((i_color IN ('almond', 'lime') AND i_units IN ('Box', 'Dram')) AND i_size IN ('extra large', 'small'))))))
--------------------------------filter((((item.i_category = 'Men') AND (((((i_size IN ('economy', 'medium') AND i_color IN ('dodger', 'tan')) AND i_units IN ('Bunch', 'Tsp')) OR ((i_color IN ('blue', 'chartreuse') AND i_units IN ('Each', 'Oz')) AND i_size IN ('N/A', 'large'))) OR ((i_size IN ('economy', 'medium') AND i_color IN ('indian', 'spring')) AND i_units IN ('Carton', 'Unknown'))) OR ((i_color IN ('peru', 'saddle') AND i_units IN ('Gram', 'Pallet')) AND i_size IN ('N/A', 'large')))) OR ((item.i_category = 'Women') AND (((((i_color IN ('aquamarine', 'gainsboro') AND i_units IN ('Dozen', 'Ounce')) AND i_size IN ('economy', 'medium')) OR ((i_color IN ('chiffon', 'violet') AND i_units IN ('Pound', 'Ton')) AND i_size IN ('extra large', 'small'))) OR ((i_color IN ('blanched', 'tomato') AND i_units IN ('Case', 'Tbl')) AND i_size IN ('economy', 'medium'))) OR ((i_color IN ('almond', 'lime') AND i_units IN ('Box', 'Dram')) AND i_size IN ('extra large', 'small'))))))
----------------------------------PhysicalOlapScan[item]

View File

@ -19,6 +19,6 @@ PhysicalResultSink
--------------------------PhysicalDistribute[DistributionSpecHash]
----------------------------hashAgg[LOCAL]
------------------------------PhysicalProject
--------------------------------filter((((item.i_category = 'Men') AND (((((i_size IN ('economy', 'medium') AND i_color IN ('dodger', 'tan')) AND i_units IN ('Bunch', 'Tsp')) OR ((i_size IN ('economy', 'medium') AND i_color IN ('indian', 'spring')) AND i_units IN ('Carton', 'Unknown'))) OR ((i_color IN ('blue', 'chartreuse') AND i_units IN ('Each', 'Oz')) AND i_size IN ('N/A', 'large'))) OR ((i_color IN ('peru', 'saddle') AND i_units IN ('Gram', 'Pallet')) AND i_size IN ('N/A', 'large')))) OR ((item.i_category = 'Women') AND (((((i_color IN ('aquamarine', 'gainsboro') AND i_units IN ('Dozen', 'Ounce')) AND i_size IN ('economy', 'medium')) OR ((i_color IN ('chiffon', 'violet') AND i_units IN ('Pound', 'Ton')) AND i_size IN ('extra large', 'small'))) OR ((i_color IN ('blanched', 'tomato') AND i_units IN ('Case', 'Tbl')) AND i_size IN ('economy', 'medium'))) OR ((i_color IN ('almond', 'lime') AND i_units IN ('Box', 'Dram')) AND i_size IN ('extra large', 'small'))))))
--------------------------------filter((((item.i_category = 'Men') AND (((((i_size IN ('economy', 'medium') AND i_color IN ('dodger', 'tan')) AND i_units IN ('Bunch', 'Tsp')) OR ((i_color IN ('blue', 'chartreuse') AND i_units IN ('Each', 'Oz')) AND i_size IN ('N/A', 'large'))) OR ((i_size IN ('economy', 'medium') AND i_color IN ('indian', 'spring')) AND i_units IN ('Carton', 'Unknown'))) OR ((i_color IN ('peru', 'saddle') AND i_units IN ('Gram', 'Pallet')) AND i_size IN ('N/A', 'large')))) OR ((item.i_category = 'Women') AND (((((i_color IN ('aquamarine', 'gainsboro') AND i_units IN ('Dozen', 'Ounce')) AND i_size IN ('economy', 'medium')) OR ((i_color IN ('chiffon', 'violet') AND i_units IN ('Pound', 'Ton')) AND i_size IN ('extra large', 'small'))) OR ((i_color IN ('blanched', 'tomato') AND i_units IN ('Case', 'Tbl')) AND i_size IN ('economy', 'medium'))) OR ((i_color IN ('almond', 'lime') AND i_units IN ('Box', 'Dram')) AND i_size IN ('extra large', 'small'))))))
----------------------------------PhysicalOlapScan[item]

View File

@ -19,6 +19,6 @@ PhysicalResultSink
--------------------------PhysicalDistribute[DistributionSpecHash]
----------------------------hashAgg[LOCAL]
------------------------------PhysicalProject
--------------------------------filter((((item.i_category = 'Men') AND (((((i_size IN ('economy', 'medium') AND i_color IN ('dodger', 'tan')) AND i_units IN ('Bunch', 'Tsp')) OR ((i_size IN ('economy', 'medium') AND i_color IN ('indian', 'spring')) AND i_units IN ('Carton', 'Unknown'))) OR ((i_color IN ('blue', 'chartreuse') AND i_units IN ('Each', 'Oz')) AND i_size IN ('N/A', 'large'))) OR ((i_color IN ('peru', 'saddle') AND i_units IN ('Gram', 'Pallet')) AND i_size IN ('N/A', 'large')))) OR ((item.i_category = 'Women') AND (((((i_color IN ('aquamarine', 'gainsboro') AND i_units IN ('Dozen', 'Ounce')) AND i_size IN ('economy', 'medium')) OR ((i_color IN ('chiffon', 'violet') AND i_units IN ('Pound', 'Ton')) AND i_size IN ('extra large', 'small'))) OR ((i_color IN ('blanched', 'tomato') AND i_units IN ('Case', 'Tbl')) AND i_size IN ('economy', 'medium'))) OR ((i_color IN ('almond', 'lime') AND i_units IN ('Box', 'Dram')) AND i_size IN ('extra large', 'small'))))))
--------------------------------filter((((item.i_category = 'Men') AND (((((i_size IN ('economy', 'medium') AND i_color IN ('dodger', 'tan')) AND i_units IN ('Bunch', 'Tsp')) OR ((i_color IN ('blue', 'chartreuse') AND i_units IN ('Each', 'Oz')) AND i_size IN ('N/A', 'large'))) OR ((i_size IN ('economy', 'medium') AND i_color IN ('indian', 'spring')) AND i_units IN ('Carton', 'Unknown'))) OR ((i_color IN ('peru', 'saddle') AND i_units IN ('Gram', 'Pallet')) AND i_size IN ('N/A', 'large')))) OR ((item.i_category = 'Women') AND (((((i_color IN ('aquamarine', 'gainsboro') AND i_units IN ('Dozen', 'Ounce')) AND i_size IN ('economy', 'medium')) OR ((i_color IN ('chiffon', 'violet') AND i_units IN ('Pound', 'Ton')) AND i_size IN ('extra large', 'small'))) OR ((i_color IN ('blanched', 'tomato') AND i_units IN ('Case', 'Tbl')) AND i_size IN ('economy', 'medium'))) OR ((i_color IN ('almond', 'lime') AND i_units IN ('Box', 'Dram')) AND i_size IN ('extra large', 'small'))))))
----------------------------------PhysicalOlapScan[item]

View File

@ -0,0 +1,28 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
suite('test_simplify_range') {
def tbl_1 = 'test_simplify_range_tbl_1'
sql "DROP TABLE IF EXISTS ${tbl_1} FORCE"
sql "CREATE TABLE ${tbl_1}(a DECIMAL(16,8), b INT) PROPERTIES ('replication_num' = '1')"
sql "INSERT INTO ${tbl_1} VALUES(null, 10)"
test {
sql "SELECT a BETWEEN 100.02 and 40.123 OR a IN (54.0402) AND b < 10 FROM ${tbl_1}"
result([[null]])
}
sql "DROP TABLE IF EXISTS ${tbl_1} FORCE"
}