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".
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.
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.
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".
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.
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.
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.
Whether the handle is attached AND still current.
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(parquet_table_col), | intent(in) | :: | self |
the handle. |
.true. when it can still be used.
This column's 1-based position in the table.
This column's 1-based position in the table.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(parquet_table_col), | intent(in) | :: | self |
the handle. |
1-based position.
This column's PK_* kind.
This column's PK_* kind, as resolved when the handle was made.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(parquet_table_col), | intent(in) | :: | self |
the handle. |
the PK_* constant.
This column's name.
This column's name.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(parquet_table_col), | intent(in) | :: | self |
the handle. |
||
| character(len=:), | intent(out), | allocatable | :: | nm |
receives the name. |
This column's values per row (1 for a scalar kind).
This column's values per row -- 1 for a scalar kind, the vector length otherwise.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(parquet_table_col), | intent(in) | :: | self |
the handle. |
values per row.
This column's unit string, or "".
This column's unit string, or "" when it has none.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(parquet_table_col), | intent(in) | :: | self |
the handle. |
||
| character(len=:), | intent(out), | allocatable | :: | u |
receives the unit, or "". |
Whether this column is RES_EMPTY/RES_PARTIAL/RES_FULL.
Whether this column is RES_EMPTY, RES_PARTIAL or RES_FULL.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(parquet_table_col), | intent(in) | :: | self |
the handle. |
one of the RES_* constants.
Claim this column's values as the caller's own, or unclaim.
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.
| Type | Intent | Optional | 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. |
Whether this column is claimed as holding the caller's values.
Whether this column is marked as holding values the caller wrote rather than the file's.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(parquet_table_col), | intent(in) | :: | self |
the handle. |
.true. when the slot holds the caller's own writes.
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