struct RecursiveUnnestRewriter<'a> {
root_expr: &'a Expr,
top_most_unnest: Option<Unnest>,
consecutive_unnest: Vec<Option<Unnest>>,
inner_projection_exprs: &'a mut Vec<Expr>,
columns_unnestings: &'a mut IndexMap<Column, Option<Vec<ColumnUnnestList>>>,
transformed_root_exprs: Option<Vec<Expr>>,
}Fields§
§root_expr: &'a Expr§top_most_unnest: Option<Unnest>§consecutive_unnest: Vec<Option<Unnest>>§inner_projection_exprs: &'a mut Vec<Expr>§columns_unnestings: &'a mut IndexMap<Column, Option<Vec<ColumnUnnestList>>>§transformed_root_exprs: Option<Vec<Expr>>Implementations§
Source§impl RecursiveUnnestRewriter<'_>
impl RecursiveUnnestRewriter<'_>
Sourcefn get_latest_consecutive_unnest(&self) -> Vec<Unnest>
fn get_latest_consecutive_unnest(&self) -> Vec<Unnest>
This struct stores the history of expr during its tree-traversal with a notation of [None,Unnest(exprA),Unnest(exprB),None,None] then this function will returns [Unnest(exprA),Unnest(exprB)]
The first item will be the inner most expr
fn transform( &mut self, level: usize, alias_name: String, expr_in_unnest: &Expr, struct_allowed: bool, input_schema: &DFSchema, ) -> Result<Vec<Expr>>
Trait Implementations§
Source§impl TreeNodeRewriterWithPayload for RecursiveUnnestRewriter<'_>
impl TreeNodeRewriterWithPayload for RecursiveUnnestRewriter<'_>
Source§fn f_down(
&mut self,
expr: Expr,
input_schema: &DFSchema,
) -> Result<Transformed<Expr>>
fn f_down( &mut self, expr: Expr, input_schema: &DFSchema, ) -> Result<Transformed<Expr>>
This downward traversal needs to keep track of:
- Whether or not some unnest expr has been visited from the top util the current node
- If some unnest expr has been visited, maintain a stack of such information, this is used to detect if some recursive unnest expr exists (e.g unnest(unnest(unnest(3d column))))
Source§fn f_up(
&mut self,
expr: Expr,
input_schema: &DFSchema,
) -> Result<Transformed<Expr>>
fn f_up( &mut self, expr: Expr, input_schema: &DFSchema, ) -> Result<Transformed<Expr>>
The rewriting only happens when the traversal has reached the top-most unnest expr within a sequence of consecutive unnest exprs node
For example an expr of unnest(unnest(column1)) + unnest(unnest(unnest(column2)))
┌──────────────────┐
│ binaryexpr │
│ │
└──────────────────┘
f_down / / │ │
/ / f_up │ │
/ / f_down│ │f_up
unnest │ │
│ │
f_down / / f_up(rewriting) │ │
/ /
/ / unnest
unnest
f_down / / f_up(rewriting)
f_down / /f_up / /
/ / / /
/ / unnest
column1
f_down / /f_up
/ /
/ /
column2type Node = Expr
type Payload<'a> = &'a DFSchema
Auto Trait Implementations§
impl<'a> Freeze for RecursiveUnnestRewriter<'a>
impl<'a> !RefUnwindSafe for RecursiveUnnestRewriter<'a>
impl<'a> Send for RecursiveUnnestRewriter<'a>
impl<'a> Sync for RecursiveUnnestRewriter<'a>
impl<'a> Unpin for RecursiveUnnestRewriter<'a>
impl<'a> !UnwindSafe for RecursiveUnnestRewriter<'a>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
Converts
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
Converts
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more