Reconstructs a SELECT SQL statement from a logical plan by unprojecting column expressions found in a [Projection] node. This requires scanning the plan tree for relevant Aggregate and Window nodes and matching column expressions to the appropriate agg or window expressions.
(
&self,
plan: &LogicalPlan,
p: &Projection,
select: &mut SelectBuilder,
)
| 230 | /// found in a [Projection] node. This requires scanning the plan tree for relevant Aggregate |
| 231 | /// and Window nodes and matching column expressions to the appropriate agg or window expressions. |
| 232 | fn reconstruct_select_statement( |
| 233 | &self, |
| 234 | plan: &LogicalPlan, |
| 235 | p: &Projection, |
| 236 | select: &mut SelectBuilder, |
| 237 | ) -> Result<()> { |
| 238 | let mut exprs = p.expr.clone(); |
| 239 | |
| 240 | // If an Unnest node is found within the select, find and unproject the unnest column |
| 241 | let flatten_alias = select.current_flatten_alias(); |
| 242 | if let Some(unnest) = find_unnest_node_within_select(plan) { |
| 243 | if let Some(ref alias) = flatten_alias { |
| 244 | exprs = exprs |
| 245 | .into_iter() |
| 246 | .map(|e| unproject_unnest_expr_as_flatten_value(e, unnest, alias)) |
| 247 | .collect::<Result<Vec<_>>>()?; |
| 248 | } else { |
| 249 | exprs = exprs |
| 250 | .into_iter() |
| 251 | .map(|e| unproject_unnest_expr(e, unnest)) |
| 252 | .collect::<Result<Vec<_>>>()?; |
| 253 | } |
| 254 | }; |
| 255 | |
| 256 | // Rewrite column references that point to FLATTEN table aliases: |
| 257 | // in Snowflake, FLATTEN output is accessed via .VALUE, not the |
| 258 | // original column name. |
| 259 | if !select.flatten_table_aliases_empty() { |
| 260 | exprs = exprs |
| 261 | .into_iter() |
| 262 | .map(|e| { |
| 263 | e.transform(|expr| { |
| 264 | if let Expr::Column(ref col) = expr |
| 265 | && let Some(ref relation) = col.relation |
| 266 | && select.is_flatten_table_alias(relation.table()) |
| 267 | { |
| 268 | return Ok(Transformed::yes(Expr::Column(Column::new( |
| 269 | Some(relation.clone()), |
| 270 | "VALUE", |
| 271 | )))); |
| 272 | } |
| 273 | Ok(Transformed::no(expr)) |
| 274 | }) |
| 275 | .map(|t| t.data) |
| 276 | }) |
| 277 | .collect::<Result<Vec<_>>>()?; |
| 278 | } |
| 279 | |
| 280 | match ( |
| 281 | find_agg_node_within_select(plan, true), |
| 282 | find_window_nodes_within_select(plan, None, true), |
| 283 | ) { |
| 284 | (Some(agg), window) => { |
| 285 | let window_option = window.as_deref(); |
| 286 | let items = exprs |
| 287 | .into_iter() |
| 288 | .map(|proj_expr| { |
| 289 | let unproj = unproject_agg_exprs(proj_expr, agg, window_option)?; |
no test coverage detected