@@ -583,6 +583,56 @@ pub(crate) fn build_parquet_read_plan(
583583 } ) )
584584}
585585
586+ /// Builds a unified [`ParquetReadPlan`] for a set of projection expressions
587+ ///
588+ /// Unlike [`build_parquet_read_plan`] (which is used for filter pushdown and
589+ /// returns `None` when an expression references unsupported nested types or
590+ /// missing columns), this function always succeeds. It collects every column
591+ /// that *can* be resolved in the file and produces a leaf-level projection
592+ /// mask. Columns missing from the file are silently skipped since the projection
593+ /// layer handles those by inserting nulls.
594+ pub ( crate ) fn build_projection_read_plan (
595+ exprs : impl IntoIterator < Item = Arc < dyn PhysicalExpr > > ,
596+ file_schema : & Schema ,
597+ schema_descr : & SchemaDescriptor ,
598+ ) -> ParquetReadPlan {
599+ let mut all_root_indices = Vec :: new ( ) ;
600+ let mut all_struct_accesses = Vec :: new ( ) ;
601+
602+ for expr in exprs {
603+ let mut checker = PushdownChecker :: new ( file_schema, true ) ;
604+ let _ = expr. visit ( & mut checker) ;
605+ let columns = checker. into_sorted_columns ( ) ;
606+
607+ all_root_indices. extend_from_slice ( & columns. required_columns ) ;
608+ all_struct_accesses. extend ( columns. struct_field_accesses ) ;
609+ }
610+
611+ all_root_indices. sort_unstable ( ) ;
612+ all_root_indices. dedup ( ) ;
613+
614+ let leaf_indices = {
615+ let mut out =
616+ leaf_indices_for_roots ( all_root_indices. iter ( ) . copied ( ) , schema_descr) ;
617+ let struct_leaf_indices =
618+ resolve_struct_field_leaves ( & all_struct_accesses, file_schema, schema_descr) ;
619+
620+ out. extend_from_slice ( & struct_leaf_indices) ;
621+ out. sort_unstable ( ) ;
622+ out. dedup ( ) ;
623+
624+ out
625+ } ;
626+
627+ let projected_schema =
628+ build_filter_schema ( file_schema, & all_root_indices, & all_struct_accesses) ;
629+
630+ ParquetReadPlan {
631+ leaf_indices,
632+ projected_schema,
633+ }
634+ }
635+
586636fn leaf_indices_for_roots < I > (
587637 root_indices : I ,
588638 schema_descr : & SchemaDescriptor ,
0 commit comments