parquet_table_col Derived Type

type, public :: parquet_table_col

A resolved handle on ONE column of a parquet_table: the slot, its kind and the table's row scope, captured once so a per-element loop stops resolving a name on every access.

Made with t%column(name) or t%column(j) and used as call c%get(i, value). It is a VIEW, not a copy -- writes through it change the table -- and it points at the table's column store, never at the table itself, so the table needs no target attribute.

A handle does not survive a structural change, and says so rather than reading the wrong column: it stamps the table's %generation() when it is made and refuses once they differ. %is_valid() is the non-aborting way to ask. Re-fetching costs one lookup.

No finalizer, deliberately -- the same decision parquet_table_row now carries, and for the same reasons. The handle owns nothing and frees nothing, and a finalizer could not catch the case that matters (a cache freed with its table leaves associated() answering .true., not .false.). It is not free either: intrinsic assignment to or from a finalizable type runs the finalizer twice, which c = t%column(name) would pay on every handle it makes.

No allocatable components, mandatory. A per-thread handle declared in a block inside a parallel region is an obvious thing to write, and this project has recorded both an ifx segfault and a gfortran uninitialised-private() bug for types in that position that carry one. See CLAUDE.md's "New parquet_table state goes on the CACHE".


Type-Bound Procedures

generic, public :: get => col_get_i32_i32, col_get_i32_i64, col_get_i64_i32, col_get_i64_i64, col_get_f32_i32, col_get_f32_i64, col_get_f64_i32, col_get_f64_i64, col_get_bool_i32, col_get_bool_i64, col_get_str_i32, col_get_str_i64, col_get_date_i32, col_get_date_i64, col_get_time_i32, col_get_time_i64, col_get_ts_i32, col_get_ts_i64, col_get_i32v_i32, col_get_i32v_i64, col_get_i64v_i32, col_get_i64v_i64, col_get_f32v_i32, col_get_f32v_i64, col_get_f64v_i32, col_get_f64v_i64, col_get_boolv_i32, col_get_boolv_i64, col_get_strv_i32, col_get_strv_i64, col_get_datev_i32, col_get_datev_i64, col_get_timev_i32, col_get_timev_i64, col_get_tsv_i32, col_get_tsv_i64, col_get_i32v_e32, col_get_i32v_e64, col_get_i64v_e32, col_get_i64v_e64, col_get_f32v_e32, col_get_f32v_e64, col_get_f64v_e32, col_get_f64v_e64, col_get_boolv_e32, col_get_boolv_e64, col_get_strv_e32, col_get_strv_e64, col_get_datev_e32, col_get_datev_e64, col_get_timev_e32, col_get_timev_e64, col_get_tsv_e32, col_get_tsv_e64

Copies one row's value into the caller's variable, widening exactly as the table's own %get_element does. No name, no lookup -- the handle already knows the slot. Given e as well, copies ONE ELEMENT of that row without materialising the rest, which the name form cannot do at all.

  • private interface col_get_i32_i32()

    Arguments

    None
  • private interface col_get_i32_i64()

    Arguments

    None
  • private interface col_get_i64_i32()

    Arguments

    None
  • private interface col_get_i64_i64()

    Arguments

    None
  • private interface col_get_f32_i32()

    Arguments

    None
  • private interface col_get_f32_i64()

    Arguments

    None
  • private interface col_get_f64_i32()

    Arguments

    None
  • private interface col_get_f64_i64()

    Arguments

    None
  • private interface col_get_bool_i32()

    Arguments

    None
  • private interface col_get_bool_i64()

    Arguments

    None
  • private interface col_get_str_i32()

    Arguments

    None
  • private interface col_get_str_i64()

    Arguments

    None
  • private interface col_get_date_i32()

    Arguments

    None
  • private interface col_get_date_i64()

    Arguments

    None
  • private interface col_get_time_i32()

    Arguments

    None
  • private interface col_get_time_i64()

    Arguments

    None
  • private interface col_get_ts_i32()

    Arguments

    None
  • private interface col_get_ts_i64()

    Arguments

    None
  • private interface col_get_i32v_i32()

    Arguments

    None
  • private interface col_get_i32v_i64()

    Arguments

    None
  • private interface col_get_i64v_i32()

    Arguments

    None
  • private interface col_get_i64v_i64()

    Arguments

    None
  • private interface col_get_f32v_i32()

    Arguments

    None
  • private interface col_get_f32v_i64()

    Arguments

    None
  • private interface col_get_f64v_i32()

    Arguments

    None
  • private interface col_get_f64v_i64()

    Arguments

    None
  • private interface col_get_boolv_i32()

    Arguments

    None
  • private interface col_get_boolv_i64()

    Arguments

    None
  • private interface col_get_strv_i32()

    Arguments

    None
  • private interface col_get_strv_i64()

    Arguments

    None
  • private interface col_get_datev_i32()

    Arguments

    None
  • private interface col_get_datev_i64()

    Arguments

    None
  • private interface col_get_timev_i32()

    Arguments

    None
  • private interface col_get_timev_i64()

    Arguments

    None
  • private interface col_get_tsv_i32()

    Arguments

    None
  • private interface col_get_tsv_i64()

    Arguments

    None
  • private interface col_get_i32v_e32()

    Arguments

    None
  • private interface col_get_i32v_e64()

    Arguments

    None
  • private interface col_get_i64v_e32()

    Arguments

    None
  • private interface col_get_i64v_e64()

    Arguments

    None
  • private interface col_get_f32v_e32()

    Arguments

    None
  • private interface col_get_f32v_e64()

    Arguments

    None
  • private interface col_get_f64v_e32()

    Arguments

    None
  • private interface col_get_f64v_e64()

    Arguments

    None
  • private interface col_get_boolv_e32()

    Arguments

    None
  • private interface col_get_boolv_e64()

    Arguments

    None
  • private interface col_get_strv_e32()

    Arguments

    None
  • private interface col_get_strv_e64()

    Arguments

    None
  • private interface col_get_datev_e32()

    Arguments

    None
  • private interface col_get_datev_e64()

    Arguments

    None
  • private interface col_get_timev_e32()

    Arguments

    None
  • private interface col_get_timev_e64()

    Arguments

    None
  • private interface col_get_tsv_e32()

    Arguments

    None
  • private interface col_get_tsv_e64()

    Arguments

    None

generic, public :: set => col_set_i32_i32, col_set_i32_i64, col_set_i64_i32, col_set_i64_i64, col_set_f32_i32, col_set_f32_i64, col_set_f64_i32, col_set_f64_i64, col_set_bool_i32, col_set_bool_i64, col_set_str_i32, col_set_str_i64, col_set_date_i32, col_set_date_i64, col_set_time_i32, col_set_time_i64, col_set_ts_i32, col_set_ts_i64, col_set_i32v_i32, col_set_i32v_i64, col_set_i64v_i32, col_set_i64v_i64, col_set_f32v_i32, col_set_f32v_i64, col_set_f64v_i32, col_set_f64v_i64, col_set_boolv_i32, col_set_boolv_i64, col_set_strv_i32, col_set_strv_i64, col_set_datev_i32, col_set_datev_i64, col_set_timev_i32, col_set_timev_i64, col_set_tsv_i32, col_set_tsv_i64, col_set_i32v_e32, col_set_i32v_e64, col_set_i64v_e32, col_set_i64v_e64, col_set_f32v_e32, col_set_f32v_e64, col_set_f64v_e32, col_set_f64v_e64, col_set_boolv_e32, col_set_boolv_e64, col_set_strv_e32, col_set_strv_e64, col_set_datev_e32, col_set_datev_e64, col_set_timev_e32, col_set_timev_e64, col_set_tsv_e32, col_set_tsv_e64

Writes one row's value. The kind must match the column's exactly (a write never widens), and writing a value CLEARS that row's null. The TABLE is updated -- a handle is a view of it, not a copy. Given e as well, writes ONE ELEMENT and clears that element's null rather than the whole row's.

  • private interface col_set_i32_i32()

    Arguments

    None
  • private interface col_set_i32_i64()

    Arguments

    None
  • private interface col_set_i64_i32()

    Arguments

    None
  • private interface col_set_i64_i64()

    Arguments

    None
  • private interface col_set_f32_i32()

    Arguments

    None
  • private interface col_set_f32_i64()

    Arguments

    None
  • private interface col_set_f64_i32()

    Arguments

    None
  • private interface col_set_f64_i64()

    Arguments

    None
  • private interface col_set_bool_i32()

    Arguments

    None
  • private interface col_set_bool_i64()

    Arguments

    None
  • private interface col_set_str_i32()

    Arguments

    None
  • private interface col_set_str_i64()

    Arguments

    None
  • private interface col_set_date_i32()

    Arguments

    None
  • private interface col_set_date_i64()

    Arguments

    None
  • private interface col_set_time_i32()

    Arguments

    None
  • private interface col_set_time_i64()

    Arguments

    None
  • private interface col_set_ts_i32()

    Arguments

    None
  • private interface col_set_ts_i64()

    Arguments

    None
  • private interface col_set_i32v_i32()

    Arguments

    None
  • private interface col_set_i32v_i64()

    Arguments

    None
  • private interface col_set_i64v_i32()

    Arguments

    None
  • private interface col_set_i64v_i64()

    Arguments

    None
  • private interface col_set_f32v_i32()

    Arguments

    None
  • private interface col_set_f32v_i64()

    Arguments

    None
  • private interface col_set_f64v_i32()

    Arguments

    None
  • private interface col_set_f64v_i64()

    Arguments

    None
  • private interface col_set_boolv_i32()

    Arguments

    None
  • private interface col_set_boolv_i64()

    Arguments

    None
  • private interface col_set_strv_i32()

    Arguments

    None
  • private interface col_set_strv_i64()

    Arguments

    None
  • private interface col_set_datev_i32()

    Arguments

    None
  • private interface col_set_datev_i64()

    Arguments

    None
  • private interface col_set_timev_i32()

    Arguments

    None
  • private interface col_set_timev_i64()

    Arguments

    None
  • private interface col_set_tsv_i32()

    Arguments

    None
  • private interface col_set_tsv_i64()

    Arguments

    None
  • private interface col_set_i32v_e32()

    Arguments

    None
  • private interface col_set_i32v_e64()

    Arguments

    None
  • private interface col_set_i64v_e32()

    Arguments

    None
  • private interface col_set_i64v_e64()

    Arguments

    None
  • private interface col_set_f32v_e32()

    Arguments

    None
  • private interface col_set_f32v_e64()

    Arguments

    None
  • private interface col_set_f64v_e32()

    Arguments

    None
  • private interface col_set_f64v_e64()

    Arguments

    None
  • private interface col_set_boolv_e32()

    Arguments

    None
  • private interface col_set_boolv_e64()

    Arguments

    None
  • private interface col_set_strv_e32()

    Arguments

    None
  • private interface col_set_strv_e64()

    Arguments

    None
  • private interface col_set_datev_e32()

    Arguments

    None
  • private interface col_set_datev_e64()

    Arguments

    None
  • private interface col_set_timev_e32()

    Arguments

    None
  • private interface col_set_timev_e64()

    Arguments

    None
  • private interface col_set_tsv_e32()

    Arguments

    None
  • private interface col_set_tsv_e64()

    Arguments

    None

generic, public :: is_null => col_is_null_i32, col_is_null_i64, col_is_null_e32, col_is_null_e64

Whether row i of this column is null, or -- given e as well -- element e of it. On a *_VEC column the row form answers "ANY element of the row is null".

  • private interface col_is_null_i32()

    Arguments

    None
  • private interface col_is_null_i64()

    Arguments

    None
  • private interface col_is_null_e32()

    Arguments

    None
  • private interface col_is_null_e64()

    Arguments

    None

generic, public :: set_null => col_set_null_i32, col_set_null_i64, col_set_null_e32, col_set_null_e64

Marks row i null, or -- given e -- element e of it. Naming only a row marks every element of it, exactly as the table's own %set_null does.

  • private interface col_set_null_i32()

    Arguments

    None
  • private interface col_set_null_i64()

    Arguments

    None
  • private interface col_set_null_e32()

    Arguments

    None
  • private interface col_set_null_e64()

    Arguments

    None

generic, public :: clear_null => col_clear_null_i32, col_clear_null_i64, col_clear_null_e32, col_clear_null_e64

Clears row i's null, or -- given e -- element e of it. The stored VALUE is whatever was there; clearing a null does not write one.

  • private interface col_clear_null_i32()

    Arguments

    None
  • private interface col_clear_null_i64()

    Arguments

    None
  • private interface col_clear_null_e32()

    Arguments

    None
  • private interface col_clear_null_e64()

    Arguments

    None

generic, public :: ref => col_ref_i32, col_ref_i64, col_ref_f32, col_ref_f64, col_ref_bool, col_ref_date, col_ref_time, col_ref_ts, col_ref_i32v, col_ref_i64v, col_ref_f32v, col_ref_f64v, col_ref_boolv, col_ref_datev, col_ref_timev, col_ref_tsv, col_ref_strcol

Points p at this column's live storage -- the %col pointer, without the name lookup. Same rules: the kind must match exactly (a pointer never widens), a write through p changes the table, and REORDERING one column through its pointer breaks the table's row alignment with nothing to report it.

  • private interface col_ref_i32()

    Arguments

    None
  • private interface col_ref_i64()

    Arguments

    None
  • private interface col_ref_f32()

    Arguments

    None
  • private interface col_ref_f64()

    Arguments

    None
  • private interface col_ref_bool()

    Arguments

    None
  • private interface col_ref_date()

    Arguments

    None
  • private interface col_ref_time()

    Arguments

    None
  • private interface col_ref_ts()

    Arguments

    None
  • private interface col_ref_i32v()

    Arguments

    None
  • private interface col_ref_i64v()

    Arguments

    None
  • private interface col_ref_f32v()

    Arguments

    None
  • private interface col_ref_f64v()

    Arguments

    None
  • private interface col_ref_boolv()

    Arguments

    None
  • private interface col_ref_datev()

    Arguments

    None
  • private interface col_ref_timev()

    Arguments

    None
  • private interface col_ref_tsv()

    Arguments

    None
  • private interface col_ref_strcol()

    Arguments

    None

procedure, public :: is_valid => col_is_valid

Whether the handle is attached AND still current.

  • interface

    private module function col_is_valid(self) result(ok)

    Whether the handle is attached to a table AND still current -- one predicate, because a caller can do nothing useful with a handle that is one and not the other.

    Arguments

    Type IntentOptional Attributes Name
    class(parquet_table_col), intent(in) :: self

    the handle.

    Return Value logical

    .true. when it can still be used.

procedure, public :: index => col_index

This column's 1-based position in the table.

  • interface

    private module function col_index(self) result(j)

    This column's 1-based position in the table.

    Arguments

    Type IntentOptional Attributes Name
    class(parquet_table_col), intent(in) :: self

    the handle.

    Return Value integer

    1-based position.

procedure, public :: kind => col_kind

This column's PK_* kind.

  • interface

    private module function col_kind(self) result(k)

    This column's PK_* kind, as resolved when the handle was made.

    Arguments

    Type IntentOptional Attributes Name
    class(parquet_table_col), intent(in) :: self

    the handle.

    Return Value integer

    the PK_* constant.

procedure, public :: name => col_name

This column's name.

  • interface

    private module subroutine col_name(self, nm)

    This column's name.

    Arguments

    Type IntentOptional Attributes Name
    class(parquet_table_col), intent(in) :: self

    the handle.

    character(len=:), intent(out), allocatable :: nm

    receives the name.

procedure, public :: width => col_width

This column's values per row (1 for a scalar kind).

  • interface

    private module function col_width(self) result(wdt)

    This column's values per row -- 1 for a scalar kind, the vector length otherwise.

    Arguments

    Type IntentOptional Attributes Name
    class(parquet_table_col), intent(in) :: self

    the handle.

    Return Value integer

    values per row.

procedure, public :: unit => col_unit

This column's unit string, or "".

  • interface

    private module subroutine col_unit(self, u)

    This column's unit string, or "" when it has none.

    Arguments

    Type IntentOptional Attributes Name
    class(parquet_table_col), intent(in) :: self

    the handle.

    character(len=:), intent(out), allocatable :: u

    receives the unit, or "".

procedure, public :: residency => col_residency

Whether this column is RES_EMPTY/RES_PARTIAL/RES_FULL.

  • interface

    private module function col_residency(self) result(r)

    Whether this column is RES_EMPTY, RES_PARTIAL or RES_FULL.

    Arguments

    Type IntentOptional Attributes Name
    class(parquet_table_col), intent(in) :: self

    the handle.

    Return Value integer

    one of the RES_* constants.

procedure, public :: set_user_populated => col_set_user_populated

Claim this column's values as the caller's own, or unclaim.

  • interface

    private module subroutine col_set_user_populated(self, flag)

    Marks this column as holding values the CALLER wrote, or clears that mark.

    The handle form of %set_user_populated, and the one the case it exists for actually reaches for: %ref is a handle method, so a caller who edits through the pointer it hands out already has the handle. See parquet_table%set_user_populated for the rule.

    Arguments

    Type IntentOptional Attributes Name
    class(parquet_table_col), intent(in) :: self

    the handle.

    logical, intent(in) :: flag

    .true. = the caller's own values; .false. = the file's.

procedure, public :: is_user_populated => col_is_user_populated

Whether this column is claimed as holding the caller's values.

  • interface

    private module function col_is_user_populated(self) result(ok)

    Whether this column is marked as holding values the caller wrote rather than the file's.

    Arguments

    Type IntentOptional Attributes Name
    class(parquet_table_col), intent(in) :: self

    the handle.

    Return Value logical

    .true. when the slot holds the caller's own writes.

Source Code

    type :: parquet_table_col
        private
        type(parquet_table_cache), pointer :: cache => null() !! the table's column store.
        integer :: slot = 0                        !! 1-based index into cache%cols.
        integer :: colkind = PK_NONE               !! the kind resolved when the handle was made.
        integer(int64) :: gen = -1_int64           !! cache%generation when this handle was made.
        type(table_scope) :: scope                 !! the table's row scope, by value.
    contains

        procedure, private :: col_get_i32_i32 !! %get specific, i32 value, int32 row index.
        procedure, private :: col_get_i32_i64 !! %get specific, i32 value, int64 row index.
        procedure, private :: col_get_i64_i32 !! %get specific, i64 value, int32 row index.
        procedure, private :: col_get_i64_i64 !! %get specific, i64 value, int64 row index.
        procedure, private :: col_get_f32_i32 !! %get specific, f32 value, int32 row index.
        procedure, private :: col_get_f32_i64 !! %get specific, f32 value, int64 row index.
        procedure, private :: col_get_f64_i32 !! %get specific, f64 value, int32 row index.
        procedure, private :: col_get_f64_i64 !! %get specific, f64 value, int64 row index.
        procedure, private :: col_get_bool_i32 !! %get specific, bool value, int32 row index.
        procedure, private :: col_get_bool_i64 !! %get specific, bool value, int64 row index.
        procedure, private :: col_get_str_i32 !! %get specific, str value, int32 row index.
        procedure, private :: col_get_str_i64 !! %get specific, str value, int64 row index.
        procedure, private :: col_get_date_i32 !! %get specific, date value, int32 row index.
        procedure, private :: col_get_date_i64 !! %get specific, date value, int64 row index.
        procedure, private :: col_get_time_i32 !! %get specific, time value, int32 row index.
        procedure, private :: col_get_time_i64 !! %get specific, time value, int64 row index.
        procedure, private :: col_get_ts_i32 !! %get specific, ts value, int32 row index.
        procedure, private :: col_get_ts_i64 !! %get specific, ts value, int64 row index.
        procedure, private :: col_get_i32v_i32 !! %get specific, i32v value, int32 row index.
        procedure, private :: col_get_i32v_i64 !! %get specific, i32v value, int64 row index.
        procedure, private :: col_get_i64v_i32 !! %get specific, i64v value, int32 row index.
        procedure, private :: col_get_i64v_i64 !! %get specific, i64v value, int64 row index.
        procedure, private :: col_get_f32v_i32 !! %get specific, f32v value, int32 row index.
        procedure, private :: col_get_f32v_i64 !! %get specific, f32v value, int64 row index.
        procedure, private :: col_get_f64v_i32 !! %get specific, f64v value, int32 row index.
        procedure, private :: col_get_f64v_i64 !! %get specific, f64v value, int64 row index.
        procedure, private :: col_get_boolv_i32 !! %get specific, boolv value, int32 row index.
        procedure, private :: col_get_boolv_i64 !! %get specific, boolv value, int64 row index.
        procedure, private :: col_get_strv_i32 !! %get specific, strv value, int32 row index.
        procedure, private :: col_get_strv_i64 !! %get specific, strv value, int64 row index.
        procedure, private :: col_get_datev_i32 !! %get specific, datev value, int32 row index.
        procedure, private :: col_get_datev_i64 !! %get specific, datev value, int64 row index.
        procedure, private :: col_get_timev_i32 !! %get specific, timev value, int32 row index.
        procedure, private :: col_get_timev_i64 !! %get specific, timev value, int64 row index.
        procedure, private :: col_get_tsv_i32 !! %get specific, tsv value, int32 row index.
        procedure, private :: col_get_tsv_i64 !! %get specific, tsv value, int64 row index.
        procedure, private :: col_get_i32v_e32 !! %get specific, one i32v element, int32 indices.
        procedure, private :: col_get_i32v_e64 !! %get specific, one i32v element, int64 indices.
        procedure, private :: col_get_i64v_e32 !! %get specific, one i64v element, int32 indices.
        procedure, private :: col_get_i64v_e64 !! %get specific, one i64v element, int64 indices.
        procedure, private :: col_get_f32v_e32 !! %get specific, one f32v element, int32 indices.
        procedure, private :: col_get_f32v_e64 !! %get specific, one f32v element, int64 indices.
        procedure, private :: col_get_f64v_e32 !! %get specific, one f64v element, int32 indices.
        procedure, private :: col_get_f64v_e64 !! %get specific, one f64v element, int64 indices.
        procedure, private :: col_get_boolv_e32 !! %get specific, one boolv element, int32 indices.
        procedure, private :: col_get_boolv_e64 !! %get specific, one boolv element, int64 indices.
        procedure, private :: col_get_strv_e32 !! %get specific, one strv element, int32 indices.
        procedure, private :: col_get_strv_e64 !! %get specific, one strv element, int64 indices.
        procedure, private :: col_get_datev_e32 !! %get specific, one datev element, int32 indices.
        procedure, private :: col_get_datev_e64 !! %get specific, one datev element, int64 indices.
        procedure, private :: col_get_timev_e32 !! %get specific, one timev element, int32 indices.
        procedure, private :: col_get_timev_e64 !! %get specific, one timev element, int64 indices.
        procedure, private :: col_get_tsv_e32 !! %get specific, one tsv element, int32 indices.
        procedure, private :: col_get_tsv_e64 !! %get specific, one tsv element, int64 indices.
        !> Copies one row's value into the caller's variable, widening exactly as the table's
        !! own `%get_element` does. No name, no lookup -- the handle already knows the slot.
        !! Given `e` as well, copies ONE ELEMENT of that row without materialising the rest,
        !! which the name form cannot do at all.
        generic :: get => col_get_i32_i32, col_get_i32_i64, col_get_i64_i32, col_get_i64_i64, col_get_f32_i32, col_get_f32_i64, &
            col_get_f64_i32, col_get_f64_i64, col_get_bool_i32, col_get_bool_i64, col_get_str_i32, col_get_str_i64, &
            col_get_date_i32, col_get_date_i64, col_get_time_i32, col_get_time_i64, col_get_ts_i32, col_get_ts_i64, &
            col_get_i32v_i32, col_get_i32v_i64, col_get_i64v_i32, col_get_i64v_i64, col_get_f32v_i32, col_get_f32v_i64, &
            col_get_f64v_i32, col_get_f64v_i64, col_get_boolv_i32, col_get_boolv_i64, col_get_strv_i32, col_get_strv_i64, &
            col_get_datev_i32, col_get_datev_i64, col_get_timev_i32, col_get_timev_i64, col_get_tsv_i32, col_get_tsv_i64, &
            col_get_i32v_e32, col_get_i32v_e64, col_get_i64v_e32, col_get_i64v_e64, col_get_f32v_e32, col_get_f32v_e64, &
            col_get_f64v_e32, col_get_f64v_e64, col_get_boolv_e32, col_get_boolv_e64, col_get_strv_e32, col_get_strv_e64, &
            col_get_datev_e32, col_get_datev_e64, col_get_timev_e32, col_get_timev_e64, col_get_tsv_e32, col_get_tsv_e64
        procedure, private :: col_set_i32_i32 !! %set specific, i32 value, int32 row index.
        procedure, private :: col_set_i32_i64 !! %set specific, i32 value, int64 row index.
        procedure, private :: col_set_i64_i32 !! %set specific, i64 value, int32 row index.
        procedure, private :: col_set_i64_i64 !! %set specific, i64 value, int64 row index.
        procedure, private :: col_set_f32_i32 !! %set specific, f32 value, int32 row index.
        procedure, private :: col_set_f32_i64 !! %set specific, f32 value, int64 row index.
        procedure, private :: col_set_f64_i32 !! %set specific, f64 value, int32 row index.
        procedure, private :: col_set_f64_i64 !! %set specific, f64 value, int64 row index.
        procedure, private :: col_set_bool_i32 !! %set specific, bool value, int32 row index.
        procedure, private :: col_set_bool_i64 !! %set specific, bool value, int64 row index.
        procedure, private :: col_set_str_i32 !! %set specific, str value, int32 row index.
        procedure, private :: col_set_str_i64 !! %set specific, str value, int64 row index.
        procedure, private :: col_set_date_i32 !! %set specific, date value, int32 row index.
        procedure, private :: col_set_date_i64 !! %set specific, date value, int64 row index.
        procedure, private :: col_set_time_i32 !! %set specific, time value, int32 row index.
        procedure, private :: col_set_time_i64 !! %set specific, time value, int64 row index.
        procedure, private :: col_set_ts_i32 !! %set specific, ts value, int32 row index.
        procedure, private :: col_set_ts_i64 !! %set specific, ts value, int64 row index.
        procedure, private :: col_set_i32v_i32 !! %set specific, i32v value, int32 row index.
        procedure, private :: col_set_i32v_i64 !! %set specific, i32v value, int64 row index.
        procedure, private :: col_set_i64v_i32 !! %set specific, i64v value, int32 row index.
        procedure, private :: col_set_i64v_i64 !! %set specific, i64v value, int64 row index.
        procedure, private :: col_set_f32v_i32 !! %set specific, f32v value, int32 row index.
        procedure, private :: col_set_f32v_i64 !! %set specific, f32v value, int64 row index.
        procedure, private :: col_set_f64v_i32 !! %set specific, f64v value, int32 row index.
        procedure, private :: col_set_f64v_i64 !! %set specific, f64v value, int64 row index.
        procedure, private :: col_set_boolv_i32 !! %set specific, boolv value, int32 row index.
        procedure, private :: col_set_boolv_i64 !! %set specific, boolv value, int64 row index.
        procedure, private :: col_set_strv_i32 !! %set specific, strv value, int32 row index.
        procedure, private :: col_set_strv_i64 !! %set specific, strv value, int64 row index.
        procedure, private :: col_set_datev_i32 !! %set specific, datev value, int32 row index.
        procedure, private :: col_set_datev_i64 !! %set specific, datev value, int64 row index.
        procedure, private :: col_set_timev_i32 !! %set specific, timev value, int32 row index.
        procedure, private :: col_set_timev_i64 !! %set specific, timev value, int64 row index.
        procedure, private :: col_set_tsv_i32 !! %set specific, tsv value, int32 row index.
        procedure, private :: col_set_tsv_i64 !! %set specific, tsv value, int64 row index.
        procedure, private :: col_set_i32v_e32 !! %set specific, one i32v element, int32 indices.
        procedure, private :: col_set_i32v_e64 !! %set specific, one i32v element, int64 indices.
        procedure, private :: col_set_i64v_e32 !! %set specific, one i64v element, int32 indices.
        procedure, private :: col_set_i64v_e64 !! %set specific, one i64v element, int64 indices.
        procedure, private :: col_set_f32v_e32 !! %set specific, one f32v element, int32 indices.
        procedure, private :: col_set_f32v_e64 !! %set specific, one f32v element, int64 indices.
        procedure, private :: col_set_f64v_e32 !! %set specific, one f64v element, int32 indices.
        procedure, private :: col_set_f64v_e64 !! %set specific, one f64v element, int64 indices.
        procedure, private :: col_set_boolv_e32 !! %set specific, one boolv element, int32 indices.
        procedure, private :: col_set_boolv_e64 !! %set specific, one boolv element, int64 indices.
        procedure, private :: col_set_strv_e32 !! %set specific, one strv element, int32 indices.
        procedure, private :: col_set_strv_e64 !! %set specific, one strv element, int64 indices.
        procedure, private :: col_set_datev_e32 !! %set specific, one datev element, int32 indices.
        procedure, private :: col_set_datev_e64 !! %set specific, one datev element, int64 indices.
        procedure, private :: col_set_timev_e32 !! %set specific, one timev element, int32 indices.
        procedure, private :: col_set_timev_e64 !! %set specific, one timev element, int64 indices.
        procedure, private :: col_set_tsv_e32 !! %set specific, one tsv element, int32 indices.
        procedure, private :: col_set_tsv_e64 !! %set specific, one tsv element, int64 indices.
        !> Writes one row's value. The kind must match the column's exactly (a write never
        !! widens), and writing a value CLEARS that row's null. The TABLE is updated -- a
        !! handle is a view of it, not a copy. Given `e` as well, writes ONE ELEMENT and
        !! clears that element's null rather than the whole row's.
        generic :: set => col_set_i32_i32, col_set_i32_i64, col_set_i64_i32, col_set_i64_i64, col_set_f32_i32, col_set_f32_i64, &
            col_set_f64_i32, col_set_f64_i64, col_set_bool_i32, col_set_bool_i64, col_set_str_i32, col_set_str_i64, &
            col_set_date_i32, col_set_date_i64, col_set_time_i32, col_set_time_i64, col_set_ts_i32, col_set_ts_i64, &
            col_set_i32v_i32, col_set_i32v_i64, col_set_i64v_i32, col_set_i64v_i64, col_set_f32v_i32, col_set_f32v_i64, &
            col_set_f64v_i32, col_set_f64v_i64, col_set_boolv_i32, col_set_boolv_i64, col_set_strv_i32, col_set_strv_i64, &
            col_set_datev_i32, col_set_datev_i64, col_set_timev_i32, col_set_timev_i64, col_set_tsv_i32, col_set_tsv_i64, &
            col_set_i32v_e32, col_set_i32v_e64, col_set_i64v_e32, col_set_i64v_e64, col_set_f32v_e32, col_set_f32v_e64, &
            col_set_f64v_e32, col_set_f64v_e64, col_set_boolv_e32, col_set_boolv_e64, col_set_strv_e32, col_set_strv_e64, &
            col_set_datev_e32, col_set_datev_e64, col_set_timev_e32, col_set_timev_e64, col_set_tsv_e32, col_set_tsv_e64
        procedure, private :: col_is_null_i32  !! %is_null specific, whole row, int32 index.
        procedure, private :: col_is_null_i64  !! %is_null specific, whole row, int64 index.
        procedure, private :: col_is_null_e32  !! %is_null specific, one element, int32 indices.
        procedure, private :: col_is_null_e64  !! %is_null specific, one element, int64 indices.
        !> Whether row `i` of this column is null, or -- given `e` as well -- element `e` of it.
        !! On a *_VEC column the row form answers "ANY element of the row is null".
        generic :: is_null => col_is_null_i32, col_is_null_i64, col_is_null_e32, col_is_null_e64
        procedure, private :: col_set_null_i32  !! %set_null specific, whole row, int32 index.
        procedure, private :: col_set_null_i64  !! %set_null specific, whole row, int64 index.
        procedure, private :: col_set_null_e32  !! %set_null specific, one element, int32 indices.
        procedure, private :: col_set_null_e64  !! %set_null specific, one element, int64 indices.
        !> Marks row `i` null, or -- given `e` -- element `e` of it. Naming only a row marks
        !! every element of it, exactly as the table's own %set_null does.
        generic :: set_null => col_set_null_i32, col_set_null_i64, col_set_null_e32, col_set_null_e64
        procedure, private :: col_clear_null_i32  !! %clear_null specific, whole row, int32 index.
        procedure, private :: col_clear_null_i64  !! %clear_null specific, whole row, int64 index.
        procedure, private :: col_clear_null_e32  !! %clear_null specific, one element, int32 indices.
        procedure, private :: col_clear_null_e64  !! %clear_null specific, one element, int64 indices.
        !> Clears row `i`'s null, or -- given `e` -- element `e` of it. The stored VALUE is
        !! whatever was there; clearing a null does not write one.
        generic :: clear_null => col_clear_null_i32, col_clear_null_i64, col_clear_null_e32, col_clear_null_e64


        procedure, private :: col_ref_i32 !! %ref specific, i32 storage.
        procedure, private :: col_ref_i64 !! %ref specific, i64 storage.
        procedure, private :: col_ref_f32 !! %ref specific, f32 storage.
        procedure, private :: col_ref_f64 !! %ref specific, f64 storage.
        procedure, private :: col_ref_bool !! %ref specific, bool storage.
        procedure, private :: col_ref_date !! %ref specific, date storage.
        procedure, private :: col_ref_time !! %ref specific, time storage.
        procedure, private :: col_ref_ts !! %ref specific, ts storage.
        procedure, private :: col_ref_i32v !! %ref specific, i32v storage.
        procedure, private :: col_ref_i64v !! %ref specific, i64v storage.
        procedure, private :: col_ref_f32v !! %ref specific, f32v storage.
        procedure, private :: col_ref_f64v !! %ref specific, f64v storage.
        procedure, private :: col_ref_boolv !! %ref specific, boolv storage.
        procedure, private :: col_ref_datev !! %ref specific, datev storage.
        procedure, private :: col_ref_timev !! %ref specific, timev storage.
        procedure, private :: col_ref_tsv !! %ref specific, tsv storage.
        procedure, private :: col_ref_strcol !! %ref specific, the packed string store.
        !> Points `p` at this column's live storage -- the `%col` pointer, without the name
        !! lookup. Same rules: the kind must match exactly (a pointer never widens), a write
        !! through `p` changes the table, and REORDERING one column through its pointer
        !! breaks the table's row alignment with nothing to report it.
        generic :: ref => col_ref_i32, col_ref_i64, col_ref_f32, col_ref_f64, col_ref_bool, col_ref_date, col_ref_time, &
            col_ref_ts, col_ref_i32v, col_ref_i64v, col_ref_f32v, col_ref_f64v, col_ref_boolv, col_ref_datev, col_ref_timev, &
            col_ref_tsv, col_ref_strcol
        procedure :: is_valid => col_is_valid   !! Whether the handle is attached AND still current.
        procedure :: index => col_index         !! This column's 1-based position in the table.
        procedure :: kind => col_kind           !! This column's PK_* kind.
        procedure :: name => col_name           !! This column's name.
        procedure :: width => col_width         !! This column's values per row (1 for a scalar kind).
        procedure :: unit => col_unit           !! This column's unit string, or "".
        procedure :: residency => col_residency !! Whether this column is RES_EMPTY/RES_PARTIAL/RES_FULL.
        procedure :: set_user_populated => col_set_user_populated !! Claim this column's values as the caller's own, or unclaim.
        procedure :: is_user_populated => col_is_user_populated !! Whether this column is claimed as holding the caller's values.
        ! NO `final` -- see the type's own doc-comment. This is a decision, not an omission.
    end type parquet_table_col