@@ -63,6 +63,7 @@ use crate::planner::LogicalPlan;
6363use crate :: storage:: { StatisticsMetaCache , TableCache , Transaction , ViewCache } ;
6464use crate :: types:: index:: RuntimeIndexProbe ;
6565use crate :: types:: tuple:: Tuple ;
66+ use crate :: types:: value:: DataValue ;
6667
6768pub ( crate ) type ExecutionCaches < ' a > = ( & ' a TableCache , & ' a ViewCache , & ' a StatisticsMetaCache ) ;
6869pub ( crate ) type ExecId = usize ;
@@ -264,6 +265,7 @@ impl<'a, T: Transaction + 'a> ExecNode<'a, T> {
264265pub ( crate ) struct ExecArena < ' a , T : Transaction + ' a > {
265266 nodes : Vec < ExecNode < ' a , T > > ,
266267 result : ExecResult ,
268+ projection_tmp : Vec < DataValue > ,
267269 cache : Option < ExecutionCaches < ' a > > ,
268270 transaction : * mut T ,
269271 runtime_probe_stack : Vec < RuntimeIndexProbe > ,
@@ -274,6 +276,7 @@ impl<'a, T: Transaction + 'a> Default for ExecArena<'a, T> {
274276 Self {
275277 nodes : Vec :: new ( ) ,
276278 result : ExecResult :: default ( ) ,
279+ projection_tmp : Vec :: new ( ) ,
277280 cache : None ,
278281 transaction : std:: ptr:: null_mut ( ) ,
279282 runtime_probe_stack : Vec :: new ( ) ,
@@ -344,6 +347,21 @@ impl<'a, T: Transaction + 'a> ExecArena<'a, T> {
344347 & mut self . result . tuple
345348 }
346349
350+ #[ inline]
351+ pub ( crate ) fn with_projection_tmp < R , E > (
352+ & mut self ,
353+ f : impl FnOnce ( & Tuple , & mut Vec < DataValue > ) -> Result < R , E > ,
354+ ) -> Result < R , E > {
355+ let ExecArena {
356+ result,
357+ projection_tmp,
358+ ..
359+ } = self ;
360+ let ret = f ( & result. tuple , projection_tmp) ?;
361+ std:: mem:: swap ( & mut result. tuple . values , projection_tmp) ;
362+ Ok ( ret)
363+ }
364+
347365 #[ inline]
348366 pub ( crate ) fn resume ( & mut self ) {
349367 self . result . status = Some ( ExecStatus :: Continue ) ;
0 commit comments