Skip to main content

DegradedNestedStructs

Type Alias DegradedNestedStructs 

Source
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 channel generate_composite_def output goes through), and columns referencing it are left as json_nested<...>.
  • Ok(None) (the default): not supported. Every column referencing it is rewritten to plain json, unless an array-shaped result targets a manifest that explicitly defines the json_array scalar marker. That marker means “one JSON document whose top level is an array”; it is deliberately distinct from array<json>, which means a SQL json[] 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).