When constructing a `UNION BY NAME`, we need to wrap inputs in an additional `Projection` to account for absence of columns in input schemas or differing projection orders.
(
schema: &Arc<DFSchema>,
inputs: Vec<Arc<LogicalPlan>>,
)
| 2954 | /// in an additional `Projection` to account for absence of columns |
| 2955 | /// in input schemas or differing projection orders. |
| 2956 | fn rewrite_inputs_from_schema( |
| 2957 | schema: &Arc<DFSchema>, |
| 2958 | inputs: Vec<Arc<LogicalPlan>>, |
| 2959 | ) -> Result<Vec<Arc<LogicalPlan>>> { |
| 2960 | let schema_width = schema.iter().count(); |
| 2961 | let mut wrapped_inputs = Vec::with_capacity(inputs.len()); |
| 2962 | for input in inputs { |
| 2963 | // Any columns that exist within the derived schema but do not exist |
| 2964 | // within an input's schema should be replaced with `NULL` aliased |
| 2965 | // to the appropriate column in the derived schema. |
| 2966 | let mut expr = Vec::with_capacity(schema_width); |
| 2967 | for column in schema.columns() { |
| 2968 | if input |
| 2969 | .schema() |
| 2970 | .has_column_with_unqualified_name(column.name()) |
| 2971 | { |
| 2972 | expr.push(Expr::Column(column)); |
| 2973 | } else { |
| 2974 | expr.push( |
| 2975 | Expr::Literal(ScalarValue::Null, None).alias(column.name()), |
| 2976 | ); |
| 2977 | } |
| 2978 | } |
| 2979 | wrapped_inputs.push(Arc::new(LogicalPlan::Projection( |
| 2980 | Projection::try_new_with_schema(expr, input, Arc::clone(schema))?, |
| 2981 | ))); |
| 2982 | } |
| 2983 | |
| 2984 | Ok(wrapped_inputs) |
| 2985 | } |
| 2986 | |
| 2987 | /// Constructs new Union instance deriving schema from inputs. |
| 2988 | /// |
nothing calls this directly
no test coverage detected