github-actions[bot] commented on code in PR #62589: URL: https://github.com/apache/doris/pull/62589#discussion_r3240798438
########## fe/fe-core/src/main/java/org/apache/doris/nereids/glue/translator/RuntimeFilterPartitionPruneClassifier.java: ########## @@ -0,0 +1,281 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package org.apache.doris.nereids.glue.translator; + +import org.apache.doris.analysis.Expr; +import org.apache.doris.analysis.FunctionCallExpr; +import org.apache.doris.analysis.LiteralExpr; +import org.apache.doris.analysis.SlotRef; +import org.apache.doris.catalog.Column; +import org.apache.doris.catalog.ListPartitionItem; +import org.apache.doris.catalog.OlapTable; +import org.apache.doris.catalog.PartitionInfo; +import org.apache.doris.catalog.PartitionItem; +import org.apache.doris.catalog.PartitionKey; +import org.apache.doris.catalog.PartitionType; +import org.apache.doris.catalog.RangePartitionItem; +import org.apache.doris.nereids.exceptions.AnalysisException; +import org.apache.doris.nereids.trees.expressions.Expression; +import org.apache.doris.nereids.trees.expressions.Slot; +import org.apache.doris.nereids.trees.expressions.functions.Monotonic; +import org.apache.doris.nereids.trees.expressions.literal.Literal; +import org.apache.doris.planner.OlapScanNode; +import org.apache.doris.planner.PlanNode; +import org.apache.doris.thrift.TTargetExprMonotonicity; + +import com.google.common.collect.Range; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Classifies whether one runtime-filter target can safely drive BE-side partition pruning. + * + * <p>This is the single FE gate for RF partition pruning. It intentionally reasons about the + * final legacy target expression that will be sent to BE, so late-added casts and partition + * expression domains cannot bypass the safety checks. + */ +final class RuntimeFilterPartitionPruneClassifier { + private RuntimeFilterPartitionPruneClassifier() { + } + + static Classification classify(Expr targetExpr, Expression nereidsTargetExpr, PlanNode scanNode) { + if (!(scanNode instanceof OlapScanNode)) { + return Classification.unsupported("target scan is not an OlapScanNode"); + } + + OlapScanNode olapScanNode = (OlapScanNode) scanNode; + OlapTable table = olapScanNode.getOlapTable(); + if (table == null) { + return Classification.unsupported("target scan has no OlapTable"); + } + + PartitionInfo partitionInfo = table.getPartitionInfo(); + PartitionType partType = partitionInfo.getType(); + if (partType != PartitionType.RANGE && partType != PartitionType.LIST) { + return Classification.unsupported("partition type is not RANGE or LIST"); + } + if (hasUnsupportedAutomaticPartitionExpression(partitionInfo)) { + return Classification.unsupported("automatic partition expression boundary is not modeled"); + } + + if (targetExpr instanceof SlotRef) { + SlotRef slotRef = (SlotRef) targetExpr; + if (!isPartitionColumnSlot(slotRef, partitionInfo.getPartitionColumns())) { Review Comment: This accepts any partition column for RANGE targets, but `OlapScanNode.addRangeBoundaries()` serializes a `TPartitionBoundary` only for `partColumns.get(0)`. For a table such as `PARTITION BY RANGE(k1, k2)`, a runtime filter on `k2` reaches this branch, `RuntimeFilter.toThrift()` emits per-partition monotonicity for the scan, and `OlapScanNode` still sends only the `k1` boundary. BE then looks up `slot_to_boundaries` for the `k2` slot in `RuntimeFilterPartitionPruner::prune_by_runtime_filters()` and returns `InternalError("target slot is not a partition boundary slot")`, so a valid join on the second RANGE partition column fails when RF partition pruning is enabled. This is distinct from the earlier first-column multi-range projection thread: even with the conservative first-column projection, non-first RANGE partition targets need to be rejected here (or FE must serialize correct boundaries for that slot) and covered by a regression test. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected] --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
