Hi Andrey,
Thank you for the detailed review and test cases. I've addressed all three points in v6:
Point 1 (domain at root): collect_composite_type_versions() now resolves domain types at the root level, not just for nested attributes. This ensures the type tree walk works correctly when the record variable itself is a domain over composite.
Point 2 (missing pfree): Added pfree() calls for compTypeOids and compTypeVersions before NULLing them in the record-clear path.
Point 3 (Cases 5 and 6 i.e dot assignment and SELECT INTO fields): These bypassed assign_record_var() because they modify the ExpandedRecord in place via expanded_record_set_field(). The fix was to restructure check_record_type_not_altered() into a two-level check:
i) Outermost type: Always checked using erh->er_tupdesc_id, which is set when the ExpandedRecord is created. This works for all code paths (whole assignment, field assignment, SELECT INTO) without needing a snapshot.
ii) Nested types: Checked against the snapshot when available (taken at assign_record_var() and instantiate_empty_record_variable()).
I also added a fast-path optimization in snapshot_record_composite_types() to avoid repeated type tree walks when a record is assigned in a loop — it skips the snapshot if the outermost type's tupDesc_identifier hasn't changed since the last snapshot.
Added both new test cases (Cases 5 and 6) to the regression. All 248 core regression tests and all 13 PL/pgSQL tests pass.
Regards,
Surya Poondla