Plans an expression coalescing multiple table functions. Each table function is followed by its row ordinality. The entire expression is followed by the coalesced row ordinality. The returned Scope will set all item's table_name's to the `table_name` parameter if it is `Some`. If `None`, they will be the name of each table function. The returned `Vec ` is the number of (non-ordinality) col
(
qcx: &QueryContext,
functions: impl IntoIterator<Item = &'a Function<Aug>>,
table_name: Option<FullItemName>,
)
| 3164 | /// |
| 3165 | /// And a `Vec<usize>` of `[1, 2]`. |
| 3166 | fn plan_rows_from_internal<'a>( |
| 3167 | qcx: &QueryContext, |
| 3168 | functions: impl IntoIterator<Item = &'a Function<Aug>>, |
| 3169 | table_name: Option<FullItemName>, |
| 3170 | ) -> Result<(HirRelationExpr, Scope, Vec<usize>), PlanError> { |
| 3171 | let mut functions = functions.into_iter(); |
| 3172 | let mut num_cols = Vec::new(); |
| 3173 | |
| 3174 | // Join together each of the table functions in turn. The last column is |
| 3175 | // always the column to join against and is maintained to be the coalescence |
| 3176 | // of the row number column for all prior functions. |
| 3177 | let (mut left_expr, mut left_scope) = |
| 3178 | plan_table_function_internal(qcx, functions.next().unwrap(), true, table_name.clone())?; |
| 3179 | num_cols.push(left_scope.len() - 1); |
| 3180 | // Create the coalesced ordinality column. |
| 3181 | left_expr = left_expr.map(vec![HirScalarExpr::column(left_scope.len() - 1)]); |
| 3182 | left_scope |
| 3183 | .items |
| 3184 | .push(ScopeItem::from_column_name(ORDINALITY_COL_NAME)); |
| 3185 | |
| 3186 | for function in functions { |
| 3187 | // The right hand side of a join must be planned in a new scope. |
| 3188 | let qcx = qcx.empty_derived_context(); |
| 3189 | let (right_expr, mut right_scope) = |
| 3190 | plan_table_function_internal(&qcx, function, true, table_name.clone())?; |
| 3191 | num_cols.push(right_scope.len() - 1); |
| 3192 | let left_col = left_scope.len() - 1; |
| 3193 | let right_col = left_scope.len() + right_scope.len() - 1; |
| 3194 | let on = HirScalarExpr::call_binary( |
| 3195 | HirScalarExpr::column(left_col), |
| 3196 | HirScalarExpr::column(right_col), |
| 3197 | expr_func::Eq, |
| 3198 | ); |
| 3199 | left_expr = left_expr |
| 3200 | .join(right_expr, on, JoinKind::FullOuter) |
| 3201 | .map(vec![HirScalarExpr::call_variadic( |
| 3202 | Coalesce, |
| 3203 | vec![ |
| 3204 | HirScalarExpr::column(left_col), |
| 3205 | HirScalarExpr::column(right_col), |
| 3206 | ], |
| 3207 | )]); |
| 3208 | |
| 3209 | // Project off the previous iteration's coalesced column, but keep both of this |
| 3210 | // iteration's ordinality columns. |
| 3211 | left_expr = left_expr.project( |
| 3212 | (0..left_col) // non-coalesced ordinality columns from left function |
| 3213 | .chain(left_col + 1..right_col + 2) // non-ordinality columns from right function |
| 3214 | .collect(), |
| 3215 | ); |
| 3216 | // Move the coalesced ordinality column. |
| 3217 | right_scope.items.push(left_scope.items.pop().unwrap()); |
| 3218 | |
| 3219 | left_scope.items.extend(right_scope.items); |
| 3220 | } |
| 3221 | |
| 3222 | Ok((left_expr, left_scope, num_cols)) |
| 3223 | } |
no test coverage detected