Skip to content

Commit 8514ea4

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)
1 parent fca1e5c commit 8514ea4

File tree

3 files changed

+105
-13
lines changed

3 files changed

+105
-13
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: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@
6464

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

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

8686
@Override
87-
public Predicate visit(ScalarOperator scalarOperator, Void context) {
87+
public Predicate visit(ScalarOperator scalarOperator, PaimonPredicateContext context) {
8888
return null;
8989
}
9090

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

114127
@Override
115-
public Predicate visitIsNullPredicate(IsNullPredicateOperator operator, Void context) {
128+
public Predicate visitIsNullPredicate(IsNullPredicateOperator operator, PaimonPredicateContext context) {
116129
String columnName = getColumnName(operator.getChild(0));
117130
if (columnName == null) {
118131
return null;
@@ -126,7 +139,7 @@ public Predicate visitIsNullPredicate(IsNullPredicateOperator operator, Void con
126139
}
127140

128141
@Override
129-
public Predicate visitBinaryPredicate(BinaryPredicateOperator operator, Void context) {
142+
public Predicate visitBinaryPredicate(BinaryPredicateOperator operator, PaimonPredicateContext context) {
130143
String columnName = getColumnName(operator.getChild(0));
131144
if (columnName == null) {
132145
return null;
@@ -158,12 +171,12 @@ public Predicate visitBinaryPredicate(BinaryPredicateOperator operator, Void con
158171
}
159172

160173
@Override
161-
public Predicate visitLargeInPredicate(LargeInPredicateOperator operator, Void context) {
174+
public Predicate visitLargeInPredicate(LargeInPredicateOperator operator, PaimonPredicateContext context) {
162175
throw new UnsupportedOperationException("not support large in predicate in the PaimonPredicateConverter");
163176
}
164177

165178
@Override
166-
public Predicate visitInPredicate(InPredicateOperator operator, Void context) {
179+
public Predicate visitInPredicate(InPredicateOperator operator, PaimonPredicateContext context) {
167180
String columnName = getColumnName(operator.getChild(0));
168181
if (columnName == null) {
169182
return null;
@@ -190,7 +203,7 @@ public Predicate visitInPredicate(InPredicateOperator operator, Void context) {
190203
}
191204

192205
@Override
193-
public Predicate visitLikePredicateOperator(LikePredicateOperator operator, Void context) {
206+
public Predicate visitLikePredicateOperator(LikePredicateOperator operator, PaimonPredicateContext context) {
194207
String columnName = getColumnName(operator.getChild(0));
195208
if (columnName == null) {
196209
return null;
@@ -364,4 +377,4 @@ public String visitCastOperator(CastOperator operator, Void context) {
364377
return operator.getChild(0).accept(this, context);
365378
}
366379
}
367-
}
380+
}

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
Assertions.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)