adriangb commented on code in PR #25760: URL: https://github.com/apache/datafusion/pull/25760#discussion_r4134256715
########## datafusion/physical-expr/src/filter.rs: ########## @@ -0,0 +1,358 @@ +// 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. + +//! [`PhysicalFilter`]: a filter that an operator applies to its rows. +//! +//! Many operators (`FilterExec`, file scans, joins) apply a boolean +//! [`PhysicalExpr`] as a filter. A [`PhysicalFilter`] holds that filter as an +//! ordered list of [`FilterConjunct`]s. Each conjunct carries the properties +//! that a consumer needs to decide how to apply it (for example, whether it +//! is required for correctness). +//! +//! A [`PhysicalFilter`] is *not* a [`PhysicalExpr`]. Use +//! [`PhysicalFilter::to_expr`] to get one expression (the `AND` of all +//! conjuncts) for code that only accepts expressions. + +use std::fmt; +use std::sync::Arc; + +use datafusion_common::Result; + +use crate::PhysicalExpr; +use crate::utils::{conjunction, conjunction_opt, split_conjunction}; + +/// One conjunct of a [`PhysicalFilter`]. +/// +/// A row passes the filter only if it passes all *required* conjuncts. A +/// consumer can skip an *optional* conjunct (for example, a dynamic filter +/// from a hash join) without an effect on the result, because another +/// operator removes the same rows again. +#[derive(Debug, Clone)] +pub struct FilterConjunct { + expr: Arc<dyn PhysicalExpr>, + optional: bool, +} + +impl FilterConjunct { + /// A conjunct that the consumer must apply. + pub fn required(expr: Arc<dyn PhysicalExpr>) -> Self { + Self { + expr, + optional: false, + } + } + + /// A conjunct that the consumer can skip without an effect on the result. + pub fn optional(expr: Arc<dyn PhysicalExpr>) -> Self { + Self { + expr, + optional: true, + } + } + + /// The boolean expression of this conjunct. + pub fn expr(&self) -> &Arc<dyn PhysicalExpr> { + &self.expr + } + + /// Consume this conjunct and return its expression. + pub fn into_expr(self) -> Arc<dyn PhysicalExpr> { + self.expr + } + + /// `true` if a consumer can skip this conjunct. + pub fn is_optional(&self) -> bool { + self.optional + } + + /// Replace the expression (for example, after a column remap) and keep + /// all other properties. + pub fn with_expr(self, expr: Arc<dyn PhysicalExpr>) -> Self { + Self { expr, ..self } + } +} + +impl From<Arc<dyn PhysicalExpr>> for FilterConjunct { + fn from(expr: Arc<dyn PhysicalExpr>) -> Self { + Self::required(expr) + } +} + +impl fmt::Display for FilterConjunct { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self.expr) + } +} + +/// A filter: an ordered list of [`FilterConjunct`]s. A row passes the filter Review Comment: We should note that order matters to the optimizer but not for evaluation - consumers can re-order filters. -- 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]
