Skip to content

Commit cc90c44

Browse files
liaowanyoumergify[bot]
authored andcommitted
[BugFix] If the operator is AND, return the predicates that are not null for paimon (#66038)
(cherry picked from commit 9313d06) # Conflicts: # fe/fe-core/src/main/java/com/starrocks/connector/paimon/PaimonPredicateConverter.java
1 parent b0061d8 commit cc90c44

File tree

3 files changed

+112
-11
lines changed

3 files changed

+112
-11
lines changed
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Copyright 2021-present StarRocks, Inc. All rights reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// https://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
package com.starrocks.connector.paimon;
15+
16+
import com.starrocks.sql.optimizer.operator.scalar.CompoundPredicateOperator;
17+
18+
public class PaimonPredicateContext {
19+
private CompoundPredicateOperator parentPredicateOperator;
20+
21+
public CompoundPredicateOperator getParentPredicateOperator() {
22+
return parentPredicateOperator;
23+
}
24+
25+
public void setParentPredicateOperator(
26+
CompoundPredicateOperator parentPredicateOperator) {
27+
this.parentPredicateOperator = parentPredicateOperator;
28+
}
29+
}

fe/fe-core/src/main/java/com/starrocks/connector/paimon/PaimonPredicateConverter.java

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@
6363

6464
import static org.apache.paimon.data.Timestamp.fromLocalDateTime;
6565

66-
public class PaimonPredicateConverter extends ScalarOperatorVisitor<Predicate, Void> {
66+
public class PaimonPredicateConverter extends ScalarOperatorVisitor<Predicate, PaimonPredicateContext> {
6767
private static final Logger LOG = LogManager.getLogger(PaimonPredicateConverter.class);
6868
private final PredicateBuilder builder;
6969
private final List<String> fieldNames;
@@ -83,35 +83,48 @@ public Predicate convert(ScalarOperator operator) {
8383
}
8484

8585
@Override
86-
public Predicate visit(ScalarOperator scalarOperator, Void context) {
86+
public Predicate visit(ScalarOperator scalarOperator, PaimonPredicateContext context) {
8787
return null;
8888
}
8989

9090
@Override
91-
public Predicate visitCompoundPredicate(CompoundPredicateOperator operator, Void context) {
91+
public Predicate visitCompoundPredicate(CompoundPredicateOperator operator, PaimonPredicateContext context) {
9292
CompoundPredicateOperator.CompoundType op = operator.getCompoundType();
9393
if (op == CompoundPredicateOperator.CompoundType.NOT) {
9494
if (operator.getChild(0) instanceof LikePredicateOperator) {
9595
return null;
9696
}
97-
Predicate expression = operator.getChild(0).accept(this, null);
98-
97+
PaimonPredicateContext paimonPredicateContext = new PaimonPredicateContext();
98+
paimonPredicateContext.setParentPredicateOperator(operator);
99+
Predicate expression = operator.getChild(0).accept(this, paimonPredicateContext);
99100
if (expression != null) {
100101
return expression.negate().orElse(null);
101102
}
102103
} else {
103-
Predicate left = operator.getChild(0).accept(this, null);
104-
Predicate right = operator.getChild(1).accept(this, null);
104+
Predicate left = operator.getChild(0).accept(this, context);
105+
Predicate right = operator.getChild(1).accept(this, context);
106+
CompoundPredicateOperator parentPredicateOperator = null;
107+
if (context != null && context.getParentPredicateOperator() != null) {
108+
parentPredicateOperator = context.getParentPredicateOperator();
109+
}
105110
if (left != null && right != null) {
106111
return (op == CompoundPredicateOperator.CompoundType.OR) ? PredicateBuilder.or(left, right) :
107112
PredicateBuilder.and(left, right);
113+
} else if (parentPredicateOperator != null &&
114+
parentPredicateOperator.getCompoundType() == CompoundPredicateOperator.CompoundType.NOT) {
115+
return null;
116+
} else if (left != null && op == CompoundPredicateOperator.CompoundType.AND) {
117+
//if op=and, return the predicates that are not null.
118+
return left;
119+
} else if (right != null && op == CompoundPredicateOperator.CompoundType.AND) {
120+
return right;
108121
}
109122
}
110123
return null;
111124
}
112125

113126
@Override
114-
public Predicate visitIsNullPredicate(IsNullPredicateOperator operator, Void context) {
127+
public Predicate visitIsNullPredicate(IsNullPredicateOperator operator, PaimonPredicateContext context) {
115128
String columnName = getColumnName(operator.getChild(0));
116129
if (columnName == null) {
117130
return null;
@@ -125,7 +138,7 @@ public Predicate visitIsNullPredicate(IsNullPredicateOperator operator, Void con
125138
}
126139

127140
@Override
128-
public Predicate visitBinaryPredicate(BinaryPredicateOperator operator, Void context) {
141+
public Predicate visitBinaryPredicate(BinaryPredicateOperator operator, PaimonPredicateContext context) {
129142
String columnName = getColumnName(operator.getChild(0));
130143
if (columnName == null) {
131144
return null;
@@ -157,7 +170,16 @@ public Predicate visitBinaryPredicate(BinaryPredicateOperator operator, Void con
157170
}
158171

159172
@Override
173+
<<<<<<< HEAD
160174
public Predicate visitInPredicate(InPredicateOperator operator, Void context) {
175+
=======
176+
public Predicate visitLargeInPredicate(LargeInPredicateOperator operator, PaimonPredicateContext context) {
177+
throw new UnsupportedOperationException("not support large in predicate in the PaimonPredicateConverter");
178+
}
179+
180+
@Override
181+
public Predicate visitInPredicate(InPredicateOperator operator, PaimonPredicateContext context) {
182+
>>>>>>> 9313d06954 ([BugFix] If the operator is AND, return the predicates that are not null for paimon (#66038))
161183
String columnName = getColumnName(operator.getChild(0));
162184
if (columnName == null) {
163185
return null;
@@ -184,7 +206,7 @@ public Predicate visitInPredicate(InPredicateOperator operator, Void context) {
184206
}
185207

186208
@Override
187-
public Predicate visitLikePredicateOperator(LikePredicateOperator operator, Void context) {
209+
public Predicate visitLikePredicateOperator(LikePredicateOperator operator, PaimonPredicateContext context) {
188210
String columnName = getColumnName(operator.getChild(0));
189211
if (columnName == null) {
190212
return null;
@@ -375,4 +397,4 @@ public String visitCastOperator(CastOperator operator, Void context) {
375397
return operator.getChild(0).accept(this, context);
376398
}
377399
}
378-
}
400+
}

fe/fe-core/src/test/java/com/starrocks/connector/paimon/PaimonPredicateConverterTest.java

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import com.starrocks.analysis.BinaryType;
1919
import com.starrocks.catalog.Type;
2020
import com.starrocks.sql.optimizer.operator.scalar.BinaryPredicateOperator;
21+
import com.starrocks.sql.optimizer.operator.scalar.CaseWhenOperator;
2122
import com.starrocks.sql.optimizer.operator.scalar.CastOperator;
2223
import com.starrocks.sql.optimizer.operator.scalar.ColumnRefOperator;
2324
import com.starrocks.sql.optimizer.operator.scalar.CompoundPredicateOperator;
@@ -400,4 +401,53 @@ public void testPaimonCastPredicate() {
400401
result = CONVERTER.convert(new BinaryPredicateOperator(BinaryType.EQ, cast99, d));
401402
Assert.assertNull(result);
402403
}
404+
405+
@Test
406+
public void testOrWithFunction() {
407+
// (f0 = 44 and (case when f0 = 44 then 'test' end) = 'test')
408+
// OR (f0 <= 46 and (case when f0 = 44 then 'test' end) = 'test')
409+
// OR((case when f0 = 44 then 'test' end) = 'test' and f1 like 'ttt%')
410+
// return f0 = 44 OR f0 <= 46 OR f0 <= 20
411+
BinaryPredicateOperator op2 = new BinaryPredicateOperator(
412+
BinaryType.EQ, F0, ConstantOperator.createInt(44));
413+
CaseWhenOperator caseWhenOperator = new CaseWhenOperator(IntegerType.INT, op2, null,
414+
Lists.newArrayList(op2, ConstantOperator.createVarchar("test")));
415+
BinaryPredicateOperator test =
416+
new BinaryPredicateOperator(BinaryType.EQ, caseWhenOperator, ConstantOperator.createVarchar("test"));
417+
ScalarOperator op20 = new CompoundPredicateOperator(CompoundPredicateOperator.CompoundType.AND, op2,
418+
test.clone());
419+
420+
BinaryPredicateOperator op12 = new BinaryPredicateOperator(
421+
BinaryType.LE, F0, ConstantOperator.createInt(46));
422+
ScalarOperator op21 = new CompoundPredicateOperator(CompoundPredicateOperator.CompoundType.AND, op12,
423+
test.clone());
424+
425+
ConstantOperator value = ConstantOperator.createVarchar("ttt%");
426+
ScalarOperator op13 = new LikePredicateOperator(LikePredicateOperator.LikeType.LIKE, F1, value);
427+
ScalarOperator op22 = new CompoundPredicateOperator(CompoundPredicateOperator.CompoundType.AND,
428+
test.clone(), op13);
429+
430+
CompoundPredicateOperator compoundPredicateOperator =
431+
new CompoundPredicateOperator(CompoundPredicateOperator.CompoundType.OR, op20, op21);
432+
CompoundPredicateOperator compoundPredicateOperator1 =
433+
new CompoundPredicateOperator(CompoundPredicateOperator.CompoundType.OR, compoundPredicateOperator,
434+
op22);
435+
CompoundPredicate convert = (CompoundPredicate) CONVERTER.convert(compoundPredicateOperator1);
436+
Assertions.assertTrue(
437+
"Or([Or([Equal(f0, 44), LessOrEqual(f0, 46)]), StartsWith(f1, ttt)])".equals(convert.toString()));
438+
439+
// (case when f0 = 44 then 'test' end) = 'test'
440+
// OR (f0 <= 46 and (case when f0 = 44 then 'test' end) = 'test')
441+
// return null
442+
ScalarOperator op40 = new CompoundPredicateOperator(CompoundPredicateOperator.CompoundType.OR, test.clone(),
443+
op21.clone());
444+
CompoundPredicate convert1 = (CompoundPredicate) CONVERTER.convert(op40.clone());
445+
Assertions.assertTrue(convert1 == null);
446+
447+
// NOT ((case when f0 = 44 then 'test' end) = 'test' and f1 like 'ttt%')
448+
// return null
449+
ScalarOperator op52 = new CompoundPredicateOperator(CompoundPredicateOperator.CompoundType.NOT, op22.clone());
450+
Predicate convert2 = CONVERTER.convert(op52);
451+
Assertions.assertTrue(convert2 == null);
452+
}
403453
}

0 commit comments

Comments
 (0)