expand_projection#

UnnestExpr.expand_projection(input_schema: Schema | None) List[Expr][source]#

Desugar into one aliased struct-field access per struct field.

unnest(expr) where expr resolves to struct<f0: t0, f1: t1, ...> expands to:

expr.struct.field_by_index(0).alias("f0"),
expr.struct.field_by_index(1).alias("f1"),
...

Fields are accessed by index (never by name) so the expansion is unambiguous even for structs with duplicate field names — though such structs are rejected below, since both fields would target the same output column and one would silently win. The N entries share the single inner Expr subtree, so CommonSubExprElimination hoists it into a temp column evaluated once per block.

The struct type is resolved via Expr.get_type: self-typed expressions (a UDF with a declared return_dtype) resolve without a schema; schema-dependent expressions (col("s")) need input_schema. If the type cannot be resolved when the plan is built — e.g. unnest(col("s")) downstream of an opaque map_batches — this raises rather than deferring to runtime.