|
20 | 20 | import com.starrocks.analysis.BinaryType; |
21 | 21 | import com.starrocks.analysis.Expr; |
22 | 22 | import com.starrocks.analysis.LiteralExpr; |
| 23 | +import com.starrocks.catalog.ListPartitionInfo; |
23 | 24 | import com.starrocks.catalog.Type; |
24 | 25 | import com.starrocks.common.AnalysisException; |
25 | 26 | import com.starrocks.common.Pair; |
@@ -83,17 +84,27 @@ public class ListPartitionPruner implements PartitionPruner { |
83 | 84 | private final Set<Long> allPartitions; |
84 | 85 | private final List<ColumnRefOperator> partitionColumnRefs; |
85 | 86 | private final List<Long> specifyPartitionIds; |
| 87 | + private final ListPartitionInfo listPartitionInfo; |
86 | 88 |
|
87 | 89 | public ListPartitionPruner( |
88 | 90 | Map<ColumnRefOperator, ConcurrentNavigableMap<LiteralExpr, Set<Long>>> columnToPartitionValuesMap, |
89 | 91 | Map<ColumnRefOperator, Set<Long>> columnToNullPartitions, |
90 | 92 | 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) { |
91 | 101 | this.columnToPartitionValuesMap = columnToPartitionValuesMap; |
92 | 102 | this.columnToNullPartitions = columnToNullPartitions; |
93 | 103 | this.partitionConjuncts = partitionConjuncts; |
94 | 104 | this.allPartitions = getAllPartitions(); |
95 | 105 | this.partitionColumnRefs = getPartitionColumnRefs(); |
96 | 106 | this.specifyPartitionIds = specifyPartitionIds; |
| 107 | + this.listPartitionInfo = listPartitionInfo; |
97 | 108 | } |
98 | 109 |
|
99 | 110 | private Set<Long> getAllPartitions() { |
@@ -335,7 +346,17 @@ private Set<Long> evalBinaryPredicate(BinaryPredicateOperator binaryPredicate) { |
335 | 346 | matches.removeAll(nullPartitions); |
336 | 347 | // remove partition matches literal |
337 | 348 | 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 | + } |
339 | 360 | } |
340 | 361 | return matches; |
341 | 362 | case LE: |
@@ -448,7 +469,18 @@ private Set<Long> evalInPredicate(InPredicateOperator inPredicate) { |
448 | 469 | Set<Long> partitions = partitionValueMap.get(literal); |
449 | 470 | if (partitions != null) { |
450 | 471 | 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 | + } |
452 | 484 | } else { |
453 | 485 | matches.addAll(partitions); |
454 | 486 | } |
|
0 commit comments