Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

package org.apache.doris.nereids.rules.expression.rules;

import org.apache.doris.common.Pair;
import org.apache.doris.nereids.rules.expression.ExpressionRewriteContext;
import org.apache.doris.nereids.trees.expressions.And;
import org.apache.doris.nereids.trees.expressions.EqualTo;
Expand Down Expand Up @@ -198,7 +199,8 @@ private ValueDesc processCompound(ExpressionRewriteContext context, List<Express
}
boolean convertIsNullToEmptyValue = isAnd && hasNullExpression && hasIsNullExpression;
boolean convertNotIsNullToRangeAll = !isAnd && hasNullExpression && hasNotIsNullExpression;
Map<Expression, ValueDescCollector> groupByReference = Maps.newLinkedHashMap();
Map<Pair<Expression, Integer>, ValueDescCollector> groupByReference = Maps.newLinkedHashMap();
int nextUniqueNum = 1;
for (Expression predicate : predicates) {
// given an expression A, no matter A is nullable or not,
// 'A is null and null' can represent as EmptyValue(A),
Expand All @@ -213,13 +215,25 @@ private ValueDesc processCompound(ExpressionRewriteContext context, List<Express
} else {
valueDesc = predicate.accept(this, context);
}

int uniqueNum = 0;

// for compound value with diff source value reference like 'a > 1 and b > 1',
// don't merge it with other values, so give them a unique num > 0.
// for other value desc, their unique num is always 0.
if (valueDesc instanceof CompoundValue && !((CompoundValue) valueDesc).isSameReference) {
nextUniqueNum++;
uniqueNum = nextUniqueNum;
}

Expression reference = valueDesc.reference;
groupByReference.computeIfAbsent(reference, key -> new ValueDescCollector()).add(valueDesc);
groupByReference.computeIfAbsent(Pair.of(reference, uniqueNum),
key -> new ValueDescCollector()).add(valueDesc);
}

List<ValueDesc> valuePerRefs = Lists.newArrayList();
for (Entry<Expression, ValueDescCollector> referenceValues : groupByReference.entrySet()) {
Expression reference = referenceValues.getKey();
for (Entry<Pair<Expression, Integer>, ValueDescCollector> referenceValues : groupByReference.entrySet()) {
Expression reference = referenceValues.getKey().first;
ValueDescCollector collector = referenceValues.getValue();
ValueDesc mergedValue;
if (isAnd) {
Expand Down Expand Up @@ -465,10 +479,7 @@ private Optional<ValueDesc> mergeCompoundValues(ExpressionRewriteContext context
// if A's range is bigger than B, then A or (B and C) = A
// if A or B is true/all, then A or (B and C) = A or C
for (CompoundValue compoundValue : collector.compoundValues) {
if (isAnd != compoundValue.isAnd
&& compoundValue.reference.equals(reference)
// no process the compose value which reference different
&& compoundValue.sourceValues.get(0).reference.equals(reference)) {
if (isAnd != compoundValue.isAnd && compoundValue.reference.equals(reference)) {
ImmutableList.Builder<ValueDesc> newSourceValuesBuilder
= ImmutableList.builderWithExpectedSize(compoundValue.sourceValues.size());
boolean skipWholeCompoundValue = false;
Expand Down Expand Up @@ -1223,6 +1234,7 @@ public static class CompoundValue extends ValueDesc {
private final Set<Class<? extends ValueDesc>> subClasses;
private final boolean hasNullable;
private final boolean hasNoneNullable;
private final boolean isSameReference;

/** constructor */
public CompoundValue(ExpressionRewriteContext context, Expression reference,
Expand All @@ -1234,20 +1246,24 @@ public CompoundValue(ExpressionRewriteContext context, Expression reference,
this.subClasses.add(getClass());
boolean hasNullable = false;
boolean hasNonNullable = false;
boolean isSameReference = true;
for (ValueDesc sourceValue : sourceValues) {
if (sourceValue instanceof CompoundValue) {
CompoundValue compoundSource = (CompoundValue) sourceValue;
this.subClasses.addAll(compoundSource.subClasses);
hasNullable = hasNullable || compoundSource.hasNullable;
hasNonNullable = hasNonNullable || compoundSource.hasNoneNullable;
isSameReference = isSameReference && compoundSource.isSameReference;
} else {
this.subClasses.add(sourceValue.getClass());
hasNullable = hasNullable || sourceValue.nullable();
hasNonNullable = hasNonNullable || !sourceValue.nullable();
}
isSameReference = isSameReference && sourceValue.getReference().equals(reference);
}
this.hasNullable = hasNullable;
this.hasNoneNullable = hasNonNullable;
this.isSameReference = isSameReference;
}

public List<ValueDesc> getSourceValues() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,16 @@ public void testSimplifyDateTime() {
"(CA is null and null) OR CB < timestamp '2024-01-05 00:50:00'");
}

@Test
public void testMixTypes() {
executor = new ExpressionRuleExecutor(ImmutableList.of(
bottomUp(SimplifyRange.INSTANCE)
));
assertRewrite("(TA > 1 and FALSE or FALSE and SA > 'aaaa') and TB is null", "FALSE");
assertRewrite("(TA > 1 and FALSE or FALSE and SA > 'aaaa') and (TA > 1 and FALSE or FALSE and SA > 'aaaa') and TB is null",
"FALSE");
}

private ValueDesc getValueDesc(String expression) {
Expression parseExpression = replaceUnboundSlot(PARSER.parseExpression(expression), commonMem);
parseExpression = typeCoercion(parseExpression);
Expand Down
Loading