Writing a parquet_table back out to a parquet file.
Deliberately thin. The schema decides which columns are written, in what order, and under
what output names; the existing writer decides everything else -- type agreement, QC, row
groups, compression -- so this file adds no validation of its own beyond "the schema names a
column the table does not have". Reusing parquet_open_writer/parquet_write_column rather
than reimplementing them is what keeps a table write and a hand-written write path identical
in behaviour.
A schema-less write BUILDS a schema rather than taking a second path. build_table_schema
turns the resident columns' descriptors into an ordinary parquet_schema and everything below
proceeds as it always did. Two things fall out of that choice and are the reason for it: the
sidecar MAML costs nothing (the writer already emits one from whatever schema it was given),
and there is exactly one write loop to keep correct rather than two that can drift. The
generated schema declares col_size:/array_size: as auto, so the writer resolves them from
the data exactly as it would with no schema at all -- and because the sidecar is emitted at
CLOSE, it records the resolved values rather than auto.