@@ -146,6 +146,7 @@ config_namespace! {
146146 ///
147147 /// let factory = VortexFormatFactory::new().with_options(VortexTableOptions {
148148 /// projection_pushdown: true,
149+ /// predicate_pushdown: true,
149150 /// scan_concurrency: Some(8),
150151 /// ..Default::default()
151152 /// });
@@ -165,6 +166,12 @@ config_namespace! {
165166 /// the scan. When disabled, Vortex reads only the referenced columns and
166167 /// all expressions are evaluated after the scan.
167168 pub projection_pushdown: bool , default = false
169+ /// Whether to enable predicate pushdown into the underlying Vortex scan.
170+ ///
171+ /// When enabled, supported filters are evaluated during the scan. When
172+ /// disabled, DataFusion evaluates filters after the scan, while
173+ /// `VortexSource` can still use the full predicate for file pruning.
174+ pub predicate_pushdown: bool , default = true
168175 /// The intra-partition scan concurrency, controlling the number of row splits to process
169176 /// concurrently per-thread within each file.
170177 ///
@@ -198,6 +205,7 @@ impl Eq for VortexTableOptions {}
198205///
199206/// let factory = Arc::new(VortexFormatFactory::new().with_options(VortexTableOptions {
200207/// projection_pushdown: true,
208+ /// predicate_pushdown: true,
201209/// ..Default::default()
202210/// }));
203211///
@@ -263,6 +271,7 @@ impl VortexFormatFactory {
263271 ///
264272 /// let factory = VortexFormatFactory::new().with_options(VortexTableOptions {
265273 /// projection_pushdown: true,
274+ /// predicate_pushdown: true,
266275 /// ..Default::default()
267276 /// });
268277 /// # let _ = factory;
@@ -617,14 +626,9 @@ impl FileFormat for VortexFormat {
617626 }
618627
619628 fn file_source ( & self , table_schema : TableSchema ) -> Arc < dyn FileSource > {
620- let mut source = VortexSource :: new ( table_schema, self . session . clone ( ) )
621- . with_projection_pushdown ( self . opts . projection_pushdown ) ;
622-
623- if let Some ( scan_concurrency) = self . opts . scan_concurrency {
624- source = source. with_scan_concurrency ( scan_concurrency) ;
625- }
626-
627- Arc :: new ( source) as _
629+ Arc :: new (
630+ VortexSource :: new ( table_schema, self . session . clone ( ) ) . with_options ( self . opts . clone ( ) ) ,
631+ ) as _
628632 }
629633}
630634
@@ -682,7 +686,7 @@ mod tests {
682686 (c1 VARCHAR NOT NULL, c2 INT NOT NULL) \
683687 STORED AS vortex \
684688 LOCATION 'table/' \
685- OPTIONS( footer_initial_read_size_bytes '12345', scan_concurrency '3' );",
689+ OPTIONS( footer_initial_read_size_bytes '12345', predicate_pushdown 'false', scan_concurrency '3' );",
686690 )
687691 . await ?
688692 . collect ( )
@@ -699,4 +703,24 @@ mod tests {
699703 let format = VortexFormat :: new_with_options ( VortexSession :: default ( ) , opts) ;
700704 assert_eq ! ( format. options( ) . footer_initial_read_size_bytes, 12345 ) ;
701705 }
706+
707+ #[ test]
708+ fn format_plumbs_source_options ( ) -> anyhow:: Result < ( ) > {
709+ let opts = VortexTableOptions {
710+ projection_pushdown : true ,
711+ predicate_pushdown : false ,
712+ scan_concurrency : Some ( 3 ) ,
713+ ..Default :: default ( )
714+ } ;
715+ let format = VortexFormat :: new_with_options ( VortexSession :: default ( ) , opts. clone ( ) ) ;
716+ let table_schema = TableSchema :: from_file_schema ( Arc :: new ( Schema :: empty ( ) ) ) ;
717+
718+ let source = format. file_source ( table_schema) ;
719+ let source = source
720+ . downcast_ref :: < VortexSource > ( )
721+ . ok_or_else ( || anyhow:: anyhow!( "expected VortexSource" ) ) ?;
722+
723+ assert_eq ! ( source. options( ) , & opts) ;
724+ Ok ( ( ) )
725+ }
702726}
0 commit comments