cherry pick from #44637
This commit is contained in:
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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");
|
||||
|
||||
@ -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]
|
||||
|
||||
|
||||
@ -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]
|
||||
|
||||
|
||||
@ -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]
|
||||
|
||||
|
||||
@ -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]
|
||||
|
||||
|
||||
@ -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]
|
||||
|
||||
|
||||
@ -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]
|
||||
|
||||
|
||||
@ -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"
|
||||
}
|
||||
Reference in New Issue
Block a user