Repository: pola-rs/polars
File: crates/polars-mem-engine/src/planner/lp.rs (Rust)

Code before:
            use polars_plan::plans::MintermIter;

            // Split into AND-minterms and convert each independently.
            let n_minterms = MintermIter::new(e.node(), expr_arena).count();
            let parts: Vec<String> = MintermIter::new(e.node(), expr_arena)
                .filter_map(|node| {
                    polars_plan::plans::python::pyarrow::predicate_to_pa(
                        node,
                        expr_arena,
                        Default::default(),
                    )
                })
                .collect();
            let fully_converted = parts.len() == n_minterms;

            let predicate_pa = match parts.len() {
                0 => None,
                1 => Some(parts.into_iter().next().unwrap()),
                _ => Some(format!("({})", parts.join(" & "))),
            };

            verbose_print_sensitive(|| {
                format!(
                    "python_scan_predicate: \
                    predicate node: {}, \
                    converted pyarrow predicate: {}",
                    ExprIRDisplay::display_node(e.node(), expr_arena),
                    predicate_pa.as_deref().unwrap_or("<conversion failed>")
                )
            });

            if let Some(eval_str) = predicate_pa {
                options.predicate = PythonPredicate::PyArrow(eval_str);
                if fully_converted {
                    // All minterms converted; pyarrow handles the full filter.
                    None
                } else {
                    // Partial conversion: keep the full predicate as a
                    // physical post-filter for correctness.
                    Some(create_physical_expr(
                        &e,
                        expr_arena,
                        &options.schema,
                        state,
                    )?)
                }
            } else {
                // Nothing converted; fall through to physical predicate.
                Some(create_physical_expr(
                    &e,
                    expr_arena,

Review comment (suggestion):
```suggestion
                    converted pyarrow predicate: {} (is_full_predicate: {fully_converted})",
```


Code after:
            use polars_plan::plans::MintermIter;

            // Split into AND-minterms and convert each independently.
            let mut residual_predicate_nodes: Vec<Node> = vec![];
            let parts: Vec<String> = MintermIter::new(e.node(), expr_arena)
                .filter_map(|node| {
                    let result = polars_plan::plans::python::pyarrow::predicate_to_pa(
                        node,
                        expr_arena,
                        Default::default(),
                    );
                    if result.is_none() {
                        residual_predicate_nodes.push(node);
                    }
                    result
                })
                .collect();

            let predicate_pa = match parts.len() {
                0 => None,
                1 => Some(parts.into_iter().next().unwrap()),
                _ => Some(format!("({})", parts.join(" & "))),
            };

            let residual_predicate_expr_ir = if let Some(eval_str) = predicate_pa {
                options.predicate = PythonPredicate::PyArrow(eval_str);

                residual_predicate_nodes
                    .into_iter()
                    .fold(None, |acc, node| {
                        Some(acc.map_or(node, |acc_node| {
                            expr_arena.add(AExpr::BinaryExpr {
                                left: acc_node,
                                op: Operator::And,
                                right: node,
                            })
                        }))
                    })
                    .map(|node| ExprIR::from_node(node, expr_arena))
            } else {
                Some(e.clone())
            };

            verbose_print_sensitive(|| {
                let predicate_pa_verbose_msg = match &options.predicate {
                    PythonPredicate::PyArrow(p) => p,
                    _ => "<conversion failed>",
                };

                format!(
                    "python_scan_predicate: \