pub type DegradedNestedStructs = (Vec<AnalyzedColumn>, Vec<NestedStructDef>, Vec<NestedStructDegradation>);Expand description
Degradation pass for nested-aggregate columns (json_agg(o.*),
row_to_json(u.*)). Must run before resolve::resolve_columns – every
caller that resolves AnalyzedColumns into a backend’s types needs this,
not just generate_with_backend_and_overrides: scythe-cli’s RBS
signature generation (generate_rbs_if_supported) calls
resolve::resolve_columns directly on a second, independent path, so it
must run this pass too or it silently bypasses the byte-identity
guarantee for any backend that hasn’t opted in.
For each entry in nested_structs, asks the backend whether it opts in
via CodegenBackend::generate_nested_struct_def:
Ok(Some(def)): the struct is supported. Its definition is collected to append to the backend’s output (the same channelgenerate_composite_defoutput goes through), and columns referencing it are left asjson_nested<...>.Ok(None)(the default): not supported. Every column referencing it is rewritten to plainjson, unless an array-shaped result targets a manifest that explicitly defines thejson_arrayscalar marker. That marker means “one JSON document whose top level is an array”; it is deliberately distinct fromarray<json>, which means a SQLjson[]column and may select a typed SQL-array reader.Err(_): a genuine failure, propagated rather than degraded.
Returns the (possibly rewritten) columns, one NestedStructDef per
struct the backend supports, and one NestedStructDegradation per
column that was rewritten instead (GH #147). The third element is the
only channel that says a rewrite happened at all: before it existed, a
column silently lost its structured shape and nothing – not the return
value, not a log line – told the caller. Every caller is expected to
surface it; GeneratedCode::degraded_nested_structs is where
generate_with_backend_and_overrides threads it for its own calls
below, and any other direct caller must do the same rather than drop it.
Skip calling this entirely when nested_structs is empty (the common
case) to keep that path zero-copy – see the callers in this file for
the pattern.
What degrade_unsupported_nested_structs returns: the columns after any
rewrite, the struct definitions the backend did produce, and one record per
column that lost its shape (GH #147).