Skip to content

Commit 76526c0

Browse files
[BugFix] fix list partition with multi value issue (backport #53746) (#53881)
Co-authored-by: stephen <91597003+stephen-shelby@users.noreply.github.com>
1 parent 2179aff commit 76526c0

3 files changed

Lines changed: 47 additions & 3 deletions

File tree

fe/fe-core/src/main/java/com/starrocks/catalog/ListPartitionInfo.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,18 @@ public Map<Long, List<String>> getIdToValues() {
213213
return idToValues;
214214
}
215215

216+
public boolean isSingleValuePartition(long id) {
217+
List<String> values = getIdToValues().get(id);
218+
if (values != null && values.size() == 1) {
219+
return true;
220+
}
221+
List<List<String>> multiValues = getIdToMultiValues().get(id);
222+
if (multiValues != null && multiValues.size() == 1) {
223+
return true;
224+
}
225+
return false;
226+
}
227+
216228
/**
217229
* serialize data to log
218230
*

fe/fe-core/src/main/java/com/starrocks/sql/optimizer/rewrite/OptOlapPartitionPruner.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ private static List<Long> listPartitionPrune(OlapTable olapTable, ListPartitionI
307307

308308
List<ScalarOperator> scalarOperatorList = Utils.extractConjuncts(operator.getPredicate());
309309
PartitionPruner partitionPruner = new ListPartitionPruner(columnToPartitionValuesMap,
310-
columnToNullPartitions, scalarOperatorList, specifyPartitionIds);
310+
columnToNullPartitions, scalarOperatorList, specifyPartitionIds, listPartitionInfo);
311311
try {
312312
List<Long> prune = partitionPruner.prune();
313313
if (prune == null && isTemporaryPartitionPrune) {

fe/fe-core/src/main/java/com/starrocks/sql/optimizer/rule/transformation/ListPartitionPruner.java

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import com.starrocks.analysis.BinaryType;
2121
import com.starrocks.analysis.Expr;
2222
import com.starrocks.analysis.LiteralExpr;
23+
import com.starrocks.catalog.ListPartitionInfo;
2324
import com.starrocks.catalog.Type;
2425
import com.starrocks.common.AnalysisException;
2526
import com.starrocks.common.Pair;
@@ -83,17 +84,27 @@ public class ListPartitionPruner implements PartitionPruner {
8384
private final Set<Long> allPartitions;
8485
private final List<ColumnRefOperator> partitionColumnRefs;
8586
private final List<Long> specifyPartitionIds;
87+
private final ListPartitionInfo listPartitionInfo;
8688

8789
public ListPartitionPruner(
8890
Map<ColumnRefOperator, ConcurrentNavigableMap<LiteralExpr, Set<Long>>> columnToPartitionValuesMap,
8991
Map<ColumnRefOperator, Set<Long>> columnToNullPartitions,
9092
List<ScalarOperator> partitionConjuncts, List<Long> specifyPartitionIds) {
93+
this(columnToPartitionValuesMap, columnToNullPartitions, partitionConjuncts, specifyPartitionIds, null);
94+
}
95+
96+
public ListPartitionPruner(
97+
Map<ColumnRefOperator, ConcurrentNavigableMap<LiteralExpr, Set<Long>>> columnToPartitionValuesMap,
98+
Map<ColumnRefOperator, Set<Long>> columnToNullPartitions,
99+
List<ScalarOperator> partitionConjuncts, List<Long> specifyPartitionIds,
100+
ListPartitionInfo listPartitionInfo) {
91101
this.columnToPartitionValuesMap = columnToPartitionValuesMap;
92102
this.columnToNullPartitions = columnToNullPartitions;
93103
this.partitionConjuncts = partitionConjuncts;
94104
this.allPartitions = getAllPartitions();
95105
this.partitionColumnRefs = getPartitionColumnRefs();
96106
this.specifyPartitionIds = specifyPartitionIds;
107+
this.listPartitionInfo = listPartitionInfo;
97108
}
98109

99110
private Set<Long> getAllPartitions() {
@@ -335,7 +346,17 @@ private Set<Long> evalBinaryPredicate(BinaryPredicateOperator binaryPredicate) {
335346
matches.removeAll(nullPartitions);
336347
// remove partition matches literal
337348
if (partitionValueMap.containsKey(literal)) {
338-
matches.removeAll(partitionValueMap.get(literal));
349+
if (listPartitionInfo == null) {
350+
// external table
351+
matches.removeAll(partitionValueMap.get(literal));
352+
} else {
353+
Set<Long> partitionIds = partitionValueMap.get(literal);
354+
for (Long id : partitionIds) {
355+
if (listPartitionInfo.isSingleValuePartition(id)) {
356+
matches.remove(id);
357+
}
358+
}
359+
}
339360
}
340361
return matches;
341362
case LE:
@@ -448,7 +469,18 @@ private Set<Long> evalInPredicate(InPredicateOperator inPredicate) {
448469
Set<Long> partitions = partitionValueMap.get(literal);
449470
if (partitions != null) {
450471
if (inPredicate.isNotIn()) {
451-
matches.removeAll(partitions);
472+
// external table, one partition column for one partition can only have one value
473+
if (listPartitionInfo == null) {
474+
matches.removeAll(partitions);
475+
} else {
476+
// for olap table, if one partition is multi value partition like PARTITION pCalifornia VALUES IN ("Los Angeles","San Francisco","San Diego")
477+
// and we have a not in predicate like city not in ("Los Angeles"), it's not safe to remove this partition
478+
for (Long id : partitions) {
479+
if (listPartitionInfo.isSingleValuePartition(id)) {
480+
matches.remove(id);
481+
}
482+
}
483+
}
452484
} else {
453485
matches.addAll(partitions);
454486
}

0 commit comments

Comments
 (0)