@@ -153,6 +153,8 @@ pub trait LazyBatchGenerator: Send + Sync + fmt::Debug + fmt::Display {
153153pub struct LazyMemoryExec {
154154 /// Schema representing the data
155155 schema : SchemaRef ,
156+ /// Optional projection for which columns to load
157+ projection : Option < Vec < usize > > ,
156158 /// Functions to generate batches for each partition
157159 batch_generators : Vec < Arc < RwLock < dyn LazyBatchGenerator > > > ,
158160 /// Plan properties cache storing equivalence properties, partitioning, and execution mode
@@ -165,6 +167,7 @@ impl LazyMemoryExec {
165167 /// Create a new lazy memory execution plan
166168 pub fn try_new (
167169 schema : SchemaRef ,
170+ projection : Option < Vec < usize > > ,
168171 generators : Vec < Arc < RwLock < dyn LazyBatchGenerator > > > ,
169172 ) -> Result < Self > {
170173 let boundedness = generators
@@ -189,6 +192,11 @@ impl LazyMemoryExec {
189192 } )
190193 . unwrap_or ( Boundedness :: Bounded ) ;
191194
195+ let schema = match projection. as_ref ( ) {
196+ Some ( columns) => Arc :: new ( schema. project ( columns) ?) ,
197+ None => schema,
198+ } ;
199+
192200 let cache = PlanProperties :: new (
193201 EquivalenceProperties :: new ( Arc :: clone ( & schema) ) ,
194202 Partitioning :: RoundRobinBatch ( generators. len ( ) ) ,
@@ -199,6 +207,7 @@ impl LazyMemoryExec {
199207
200208 Ok ( Self {
201209 schema,
210+ projection,
202211 batch_generators : generators,
203212 cache,
204213 metrics : ExecutionPlanMetricsSet :: new ( ) ,
@@ -320,6 +329,7 @@ impl ExecutionPlan for LazyMemoryExec {
320329
321330 let stream = LazyMemoryStream {
322331 schema : Arc :: clone ( & self . schema ) ,
332+ projection : self . projection . clone ( ) ,
323333 generator : Arc :: clone ( & self . batch_generators [ partition] ) ,
324334 baseline_metrics,
325335 } ;
@@ -338,6 +348,8 @@ impl ExecutionPlan for LazyMemoryExec {
338348/// Stream that generates record batches on demand
339349pub struct LazyMemoryStream {
340350 schema : SchemaRef ,
351+ /// Optional projection for which columns to load
352+ projection : Option < Vec < usize > > ,
341353 /// Generator to produce batches
342354 ///
343355 /// Note: Idiomatically, DataFusion uses plan-time parallelism - each stream
@@ -361,7 +373,14 @@ impl Stream for LazyMemoryStream {
361373 let batch = self . generator . write ( ) . generate_next_batch ( ) ;
362374
363375 let poll = match batch {
364- Ok ( Some ( batch) ) => Poll :: Ready ( Some ( Ok ( batch) ) ) ,
376+ Ok ( Some ( batch) ) => {
377+ // return just the columns requested
378+ let batch = match self . projection . as_ref ( ) {
379+ Some ( columns) => batch. project ( columns) ?,
380+ None => batch,
381+ } ;
382+ Poll :: Ready ( Some ( Ok ( batch) ) )
383+ }
365384 Ok ( None ) => Poll :: Ready ( None ) ,
366385 Err ( e) => Poll :: Ready ( Some ( Err ( e) ) ) ,
367386 } ;
@@ -434,8 +453,11 @@ mod lazy_memory_tests {
434453 schema : Arc :: clone ( & schema) ,
435454 } ;
436455
437- let exec =
438- LazyMemoryExec :: try_new ( schema, vec ! [ Arc :: new( RwLock :: new( generator) ) ] ) ?;
456+ let exec = LazyMemoryExec :: try_new (
457+ schema,
458+ None ,
459+ vec ! [ Arc :: new( RwLock :: new( generator) ) ] ,
460+ ) ?;
439461
440462 // Test schema
441463 assert_eq ! ( exec. schema( ) . fields( ) . len( ) , 1 ) ;
@@ -485,8 +507,11 @@ mod lazy_memory_tests {
485507 schema : Arc :: clone ( & schema) ,
486508 } ;
487509
488- let exec =
489- LazyMemoryExec :: try_new ( schema, vec ! [ Arc :: new( RwLock :: new( generator) ) ] ) ?;
510+ let exec = LazyMemoryExec :: try_new (
511+ schema,
512+ None ,
513+ vec ! [ Arc :: new( RwLock :: new( generator) ) ] ,
514+ ) ?;
490515
491516 // Test invalid partition
492517 let result = exec. execute ( 1 , Arc :: new ( TaskContext :: default ( ) ) ) ;
@@ -519,8 +544,11 @@ mod lazy_memory_tests {
519544 schema : Arc :: clone ( & schema) ,
520545 } ;
521546
522- let exec =
523- LazyMemoryExec :: try_new ( schema, vec ! [ Arc :: new( RwLock :: new( generator) ) ] ) ?;
547+ let exec = LazyMemoryExec :: try_new (
548+ schema,
549+ None ,
550+ vec ! [ Arc :: new( RwLock :: new( generator) ) ] ,
551+ ) ?;
524552 let task_ctx = Arc :: new ( TaskContext :: default ( ) ) ;
525553
526554 let stream = exec. execute ( 0 , task_ctx) ?;
0 commit comments