Type-erased, whole-column value storage shared by parquet_table and (later) the
list/map/struct container column types.
parquet_column holds the values of ONE column of ONE table: a PK_* kind discriminator
plus exactly one allocated storage array (the active kind's), a sparse null bitmap, an
optional unit string, and the row count. Only the active kind's array is ever allocated, so
a column costs one array plus a handful of scalars regardless of how many kinds exist.
Three things are worth knowing before using it:
parquet_string_column's own validity; the temporal kinds carry their null state INSIDE
each element (matching parquet_temporal's deliberate design). is_null/set_null/
any_null hide this, and there is no public has_nulls.set_null/append_nulls and disappears
again on a whole-column set_all (or an explicit compact_validity).width * nrows bits, and every query and mutation comes in a row form and an (i, e)
element form. The two are deliberately asymmetric where they differ: a row QUERY
(is_null(i), row_validity) answers "any element of the row is null", while a whole-row
MUTATION (set_null(i), clear_null(i), append_nulls) acts on every element of it.
modify_nulls=.false. skips individual null ELEMENTS, not whole rows.integer(int64) throughout. This type is internal to the library and
never sees a caller's default-kind INTEGER, so it deliberately does not carry the
int32/int64 specific pairs the public API uses.Depends only on iso_fortran_env plus the two element-domain modules (parquet_strings,
parquet_temporal) -- never on parquet itself, so the container column types can consume
it symmetrically without a circular dependency.
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| integer(kind=int64), | public, | parameter | :: | parquet_validity_block_bits | = | BITS_PER_BLOCK |
Exposed for exactly one reason: so that nobody has to copy it. A caller filling one
column from several threads -- |
| integer, | public, | parameter | :: | PK_NONE | = | 0 |
no kind assigned yet (a default-initialized column) |
| integer, | public, | parameter | :: | PK_INT32 | = | 1 |
32-bit integer scalar column |
| integer, | public, | parameter | :: | PK_INT64 | = | 2 |
64-bit integer scalar column |
| integer, | public, | parameter | :: | PK_FLOAT32 | = | 3 |
32-bit real scalar column |
| integer, | public, | parameter | :: | PK_FLOAT64 | = | 4 |
64-bit real scalar column |
| integer, | public, | parameter | :: | PK_LOGICAL | = | 5 |
logical scalar column |
| integer, | public, | parameter | :: | PK_STRING | = | 6 |
variable-length string scalar column |
| integer, | public, | parameter | :: | PK_DATE | = | 7 |
date scalar column |
| integer, | public, | parameter | :: | PK_TIME | = | 8 |
time scalar column |
| integer, | public, | parameter | :: | PK_TIMESTAMP | = | 9 |
timestamp scalar column |
| integer, | public, | parameter | :: | PK_INT32_VEC | = | 11 |
32-bit integer vector column (width values per row) |
| integer, | public, | parameter | :: | PK_INT64_VEC | = | 12 |
64-bit integer vector column |
| integer, | public, | parameter | :: | PK_FLOAT32_VEC | = | 13 |
32-bit real vector column |
| integer, | public, | parameter | :: | PK_FLOAT64_VEC | = | 14 |
64-bit real vector column |
| integer, | public, | parameter | :: | PK_LOGICAL_VEC | = | 15 |
logical vector column |
| integer, | public, | parameter | :: | PK_STRING_VEC | = | 16 |
string vector column (one flat string store, stride width) |
| integer, | public, | parameter | :: | PK_DATE_VEC | = | 17 |
date vector column |
| integer, | public, | parameter | :: | PK_TIME_VEC | = | 18 |
time vector column |
| integer, | public, | parameter | :: | PK_TIMESTAMP_VEC | = | 19 |
timestamp vector column |
| integer, | public, | parameter | :: | PK_LIST | = | 21 |
reserved for a variable-length list column (feature_map_list_struct.md) |
| integer, | public, | parameter | :: | PK_MAP | = | 22 |
reserved for a map column (feature_map_list_struct.md) |
| integer, | public, | parameter | :: | PK_STRUCT | = | 23 |
reserved for a struct column (feature_map_list_struct.md) |
Whether the column holds at least one null, WITHOUT writing to it -- the read path's
form of any_null, and the one every shared reader must use.
Identical answer, and identical cost on every kind but one. A temporal column's cache
is read when it is clean and simply re-scanned when it is dirty, rather than being
refreshed: the memoisation is an optimisation for any_null, never part of the answer,
so giving it up costs a dirty column one O(n) walk per call and buys the property that
any number of threads may ask at once.
type(parquet_column), not class, for the reason the per-cell tier above records --
and a class actual may be passed to it freely, which is how the two bulk validity
walks in this module reach it while holding self by intent(in).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(parquet_column), | intent(in) | :: | col |
the column. |
.true. when at least one row is null.
Typed string_column: pointer to the embedded string store (PK_STRING/PK_STRING_VEC).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(parquet_column), | intent(in), | target | :: | col |
the column. |
|
| type(parquet_string_column), | intent(out), | pointer | :: | p |
alias to the string store. |
One column's values: a kind discriminator, one active storage array, sparse validity, an optional unit, and the row/width geometry.
| procedure, public :: init | Set kind/geometry and allocate empty storage. |
| procedure, public :: clear | Release all storage and reset to PK_NONE. |
| procedure, public :: deep_copy | Independent copy of values, validity and unit. |
| procedure, public :: move_from | Take over another column's storage, leaving it empty. |
| procedure, public :: kindof | The active PK_* discriminator. |
| procedure, public :: length | Number of rows stored. |
| procedure, public :: capacity | Rows the storage is allocated for (>= length()). |
| procedure, public :: colwidth | Values per row (1 for scalar kinds). |
| procedure, public :: validity_bytes | Bytes the null bitmap occupies (0 when sparse). |
| procedure, public :: has_validity_storage | Whether nulling would still have to allocate. |
| procedure, public :: ensure_validity | Allocate the validity storage up front. |
| procedure, public :: unit_string | Copy out the unit string ("" when unset). |
| procedure, public :: set_unit | Set (or clear) the unit string. |
| procedure, public :: any_null | Whether the column holds at least one null. |
| generic, public :: is_null => is_null_row, is_null_elem | Whether row |
| procedure, public :: row_validity | Build the whole per-row validity mask at once. |
| procedure, public :: element_validity | Build the whole per-ELEMENT validity mask at once. |
| generic, public :: set_null => set_null_row, set_null_elem | Marks row |
| generic, public :: clear_null => clear_null_row, clear_null_elem | Marks row |
| generic, public :: set_validity => set_validity_elems, set_validity_rows | Writes a whole validity mask in one pass. A rank-2 |
| procedure, public :: compact_validity | Drop the bitmap when no nulls remain. |
| generic, public :: reserve => reserve_i32, reserve_i64 | Grows the storage capacity to hold at least |
| procedure, public :: shrink_to_fit | Release capacity beyond the rows stored. |
| procedure, public :: append | Append another column of identical kind/width. |
| procedure, public :: append_row_of | Append one row of another column (internal; see below). |
| procedure, public :: append_nulls | Append n all-null rows. |
| procedure, public :: paste | Overwrite an existing row range from another column. |
| procedure, public :: delete_by_mask | Keep only rows whose mask entry is .true. |
| procedure, public :: reindex | Reorder rows by a permutation. |
| procedure, public :: reindex_trusted | INTERNAL -- reindex without the duplicate/range scan, for a permutation the caller has already established is one. Public only because Fortran offers no narrower visibility; see the interface below. |
| generic, public :: gather => gather_i32, gather_i64 | Keeps the listed rows, in the listed order. Unlike |
| procedure, public :: string_column | Pointer to the embedded string store. |
| generic, public :: get_at => get_at_i32, get_at_i64, get_at_f32, get_at_f64, get_at_bool, get_at_str, get_at_date, get_at_time, get_at_ts, get_at_i32v, get_at_i64v, get_at_f32v, get_at_f64v, get_at_boolv, get_at_strv, get_at_datev, get_at_timev, get_at_tsv | Read element i (or row i's vector) out. |
| generic, public :: set_at => set_at_i32, set_at_i64, set_at_f32, set_at_f64, set_at_bool, set_at_str, set_at_date, set_at_time, set_at_ts, set_at_i32v, set_at_i64v, set_at_f32v, set_at_f64v, set_at_boolv, set_at_strv, set_at_datev, set_at_timev, set_at_tsv | Write element i (or row i's vector). |
| generic, public :: get_elem => get_elem_i32v, get_elem_i64v, get_elem_f32v, get_elem_f64v, get_elem_boolv, get_elem_strv, get_elem_datev, get_elem_timev, get_elem_tsv | Read ONE element of row i's vector, without materialising the row. |
| generic, public :: set_elem => set_elem_i32v, set_elem_i64v, set_elem_f32v, set_elem_f64v, set_elem_boolv, set_elem_strv, set_elem_datev, set_elem_timev, set_elem_tsv | Write ONE element of row i's vector, without materialising the row. |
| generic, public :: set_all => set_all_i32, set_all_i64, set_all_f32, set_all_f64, set_all_bool, set_all_str, set_all_date, set_all_time, set_all_ts, set_all_i32v, set_all_i64v, set_all_f32v, set_all_f64v, set_all_boolv, set_all_strv, set_all_datev, set_all_timev, set_all_tsv | Replace every value in the column. |
| generic, public :: adopt => adopt_i32, adopt_i64, adopt_f32, adopt_f64, adopt_bool, adopt_date, adopt_time, adopt_ts, adopt_i32v, adopt_i64v, adopt_f32v, adopt_f64v, adopt_boolv, adopt_datev, adopt_timev, adopt_tsv | Take ownership of an array outright, without copying it. |
| generic, public :: data_ptr => data_ptr_i32, data_ptr_i64, data_ptr_f32, data_ptr_f64, data_ptr_bool, data_ptr_date, data_ptr_time, data_ptr_ts, data_ptr_i32v, data_ptr_i64v, data_ptr_f32v, data_ptr_f64v, data_ptr_boolv, data_ptr_datev, data_ptr_timev, data_ptr_tsv | Zero-copy typed pointer to the active storage. |
| generic, public :: append_values => append_values_i32, append_values_i64, append_values_f32, append_values_f64, append_values_bool, append_values_str, append_values_date, append_values_time, append_values_ts, append_values_i32v, append_values_i64v, append_values_f32v, append_values_f64v, append_values_boolv, append_values_strv, append_values_datev, append_values_timev, append_values_tsv | Append values, growing the column. |
Copies a human-readable name for a PK_* kind out (for error messages and callers that
dispatch on kindof).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer, | intent(in) | :: | kind |
a PK_* discriminator. |
||
| character(len=:), | intent(out), | allocatable | :: | name |
the kind's name. |