Skip to content

Commit 9fa1c55

Browse files
committed
add is null / is not null value desc
1 parent 65a3288 commit 9fa1c55

File tree

3 files changed

+96
-1
lines changed

3 files changed

+96
-1
lines changed

fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/AddMinMax.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
import org.apache.doris.nereids.rules.expression.rules.RangeInference.CompoundValue;
2626
import org.apache.doris.nereids.rules.expression.rules.RangeInference.DiscreteValue;
2727
import org.apache.doris.nereids.rules.expression.rules.RangeInference.EmptyValue;
28+
import org.apache.doris.nereids.rules.expression.rules.RangeInference.IsNotNullValue;
29+
import org.apache.doris.nereids.rules.expression.rules.RangeInference.IsNullValue;
2830
import org.apache.doris.nereids.rules.expression.rules.RangeInference.NotDiscreteValue;
2931
import org.apache.doris.nereids.rules.expression.rules.RangeInference.RangeValue;
3032
import org.apache.doris.nereids.rules.expression.rules.RangeInference.UnknownValue;
@@ -310,6 +312,16 @@ public Map<Expression, MinMaxValue> visitNotDiscreteValue(NotDiscreteValue value
310312
return ImmutableMap.of();
311313
}
312314

315+
@Override
316+
public Map<Expression, MinMaxValue> visitIsNullValue(IsNullValue value, Void context) {
317+
return ImmutableMap.of();
318+
}
319+
320+
@Override
321+
public Map<Expression, MinMaxValue> visitIsNotNullValue(IsNotNullValue value, Void context) {
322+
return ImmutableMap.of();
323+
}
324+
313325
@Override
314326
public Map<Expression, MinMaxValue> visitRangeValue(RangeValue value, Void context) {
315327
Expression reference = value.getReference();

fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/RangeInference.java

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import org.apache.doris.nereids.trees.expressions.LessThanEqual;
3131
import org.apache.doris.nereids.trees.expressions.Not;
3232
import org.apache.doris.nereids.trees.expressions.Or;
33+
import org.apache.doris.nereids.trees.expressions.literal.BooleanLiteral;
3334
import org.apache.doris.nereids.trees.expressions.literal.ComparableLiteral;
3435
import org.apache.doris.nereids.trees.expressions.literal.NullLiteral;
3536
import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
@@ -49,6 +50,7 @@
4950
import java.util.List;
5051
import java.util.Map;
5152
import java.util.Map.Entry;
53+
import java.util.Optional;
5254
import java.util.Set;
5355

5456
/**
@@ -144,11 +146,18 @@ public ValueDesc visitNot(Not not, ExpressionRewriteContext context) {
144146
ValueDesc childValue = not.child().accept(this, context);
145147
if (childValue instanceof DiscreteValue) {
146148
return new NotDiscreteValue(context, childValue.getReference(), ((DiscreteValue) childValue).values);
149+
} else if (childValue instanceof IsNullValue) {
150+
return new IsNotNullValue(context, childValue.getReference(), not);
147151
} else {
148152
return new UnknownValue(context, not);
149153
}
150154
}
151155

156+
@Override
157+
public ValueDesc visitIsNull(IsNull isNull, ExpressionRewriteContext context) {
158+
return new IsNullValue(context, isNull.child());
159+
}
160+
152161
@Override
153162
public ValueDesc visitAnd(And and, ExpressionRewriteContext context) {
154163
return simplify(context, ExpressionUtils.extractConjunction(and), true);
@@ -273,6 +282,13 @@ private ValueDesc intersectForSameReference(ExpressionRewriteContext context, Ex
273282
result.add(new NotDiscreteValue(context, reference, mergeNotDiscreteValues));
274283
}
275284
}
285+
if (collector.hasIsNullValue && collector.isNotNullValueOpt.isPresent()) {
286+
return new UnknownValue(context, BooleanLiteral.FALSE);
287+
} else if (collector.hasIsNullValue) {
288+
result.add(new IsNullValue(context, reference));
289+
} else {
290+
collector.isNotNullValueOpt.ifPresent(result::add);
291+
}
276292
result.addAll(collector.compoundValues);
277293
result.addAll(collector.unknownValues);
278294

@@ -341,6 +357,13 @@ private ValueDesc unionForSameReference(ExpressionRewriteContext context, Expres
341357
result.add(new NotDiscreteValue(context, reference, mergeNotDiscreteValues));
342358
}
343359

360+
if (collector.hasIsNullValue && collector.isNotNullValueOpt.isPresent()) {
361+
return new UnknownValue(context, BooleanLiteral.TRUE);
362+
} else if (collector.hasIsNullValue) {
363+
result.add(new IsNullValue(context, reference));
364+
} else {
365+
collector.isNotNullValueOpt.ifPresent(result::add);
366+
}
344367
result.addAll(collector.compoundValues);
345368
result.addAll(collector.unknownValues);
346369

@@ -365,12 +388,18 @@ public interface ValueDescVisitor<R, C> {
365388

366389
R visitNotDiscreteValue(NotDiscreteValue notDiscreteValue, C context);
367390

391+
R visitIsNullValue(IsNullValue isNullValue, C context);
392+
393+
R visitIsNotNullValue(IsNotNullValue isNotNullValue, C context);
394+
368395
R visitCompoundValue(CompoundValue compoundValue, C context);
369396

370397
R visitUnknownValue(UnknownValue unknownValue, C context);
371398
}
372399

373400
private static class ValueDescCollector {
401+
Optional<IsNotNullValue> isNotNullValueOpt = Optional.empty();
402+
boolean hasIsNullValue = false;
374403
boolean hasEmptyValue = false;
375404
List<RangeValue> rangeValues = Lists.newArrayList();
376405
List<DiscreteValue> discreteValues = Lists.newArrayList();
@@ -389,6 +418,13 @@ void add(ValueDesc value) {
389418
notDiscreteValues.add((NotDiscreteValue) value);
390419
} else if (value instanceof CompoundValue) {
391420
compoundValues.add((CompoundValue) value);
421+
} else if (value instanceof IsNullValue) {
422+
hasIsNullValue = true;
423+
} else if (value instanceof IsNotNullValue) {
424+
IsNotNullValue isNotNullValue = (IsNotNullValue) value;
425+
if (!isNotNullValueOpt.isPresent() || isNotNullValue.getNotExpression().isGeneratedIsNotNull()) {
426+
isNotNullValueOpt = Optional.of(isNotNullValue);
427+
}
392428
} else {
393429
Preconditions.checkArgument(value instanceof UnknownValue);
394430
unknownValues.add((UnknownValue) value);
@@ -532,7 +568,6 @@ public String toString() {
532568
}
533569

534570
/**
535-
* use `Set` to wrap `InPredicate`
536571
* for example:
537572
* a not in (1,2,3) => [1,2,3]
538573
*/
@@ -551,6 +586,42 @@ protected <R, C> R visit(ValueDescVisitor<R, C> visitor, C context) {
551586
}
552587
}
553588

589+
/**
590+
* a is null
591+
*/
592+
public static class IsNullValue extends ValueDesc {
593+
594+
public IsNullValue(ExpressionRewriteContext context, Expression reference) {
595+
super(context, reference);
596+
}
597+
598+
@Override
599+
protected <R, C> R visit(ValueDescVisitor<R, C> visitor, C context) {
600+
return visitor.visitIsNullValue(this, context);
601+
}
602+
}
603+
604+
/**
605+
* a is not null
606+
*/
607+
public static class IsNotNullValue extends ValueDesc {
608+
final Not not;
609+
610+
public IsNotNullValue(ExpressionRewriteContext context, Expression reference, Not not) {
611+
super(context, reference);
612+
this.not = not;
613+
}
614+
615+
public Not getNotExpression() {
616+
return this.not;
617+
}
618+
619+
@Override
620+
protected <R, C> R visit(ValueDescVisitor<R, C> visitor, C context) {
621+
return visitor.visitIsNotNullValue(this, context);
622+
}
623+
}
624+
554625
/**
555626
* Represents processing compound predicate.
556627
*/

fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/SimplifyRange.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
import org.apache.doris.nereids.rules.expression.rules.RangeInference.CompoundValue;
2525
import org.apache.doris.nereids.rules.expression.rules.RangeInference.DiscreteValue;
2626
import org.apache.doris.nereids.rules.expression.rules.RangeInference.EmptyValue;
27+
import org.apache.doris.nereids.rules.expression.rules.RangeInference.IsNotNullValue;
28+
import org.apache.doris.nereids.rules.expression.rules.RangeInference.IsNullValue;
2729
import org.apache.doris.nereids.rules.expression.rules.RangeInference.NotDiscreteValue;
2830
import org.apache.doris.nereids.rules.expression.rules.RangeInference.RangeValue;
2931
import org.apache.doris.nereids.rules.expression.rules.RangeInference.UnknownValue;
@@ -137,6 +139,16 @@ public Expression visitNotDiscreteValue(NotDiscreteValue value, Void context) {
137139
return new Not(getDiscreteExpression(value.reference, value.values));
138140
}
139141

142+
@Override
143+
public Expression visitIsNullValue(IsNullValue value, Void context) {
144+
return new IsNull(value.getReference());
145+
}
146+
147+
@Override
148+
public Expression visitIsNotNullValue(IsNotNullValue value, Void context) {
149+
return value.getNotExpression();
150+
}
151+
140152
@Override
141153
public Expression visitCompoundValue(CompoundValue value, Void context) {
142154
return getCompoundExpression(value.getExpressionRewriteContext(), value.getSourceValues(), value.isAnd());

0 commit comments

Comments
 (0)