parquet_columns Module

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:

  • Validity is kind-dispatched, not uniform. Numeric and logical kinds carry a column-level null bitmap; the string kinds delegate to the embedded 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.
  • Validity is sparse. A column with no nulls allocates NO bitmap at all -- only a logical scalar. The bitmap appears on the first set_null/append_nulls and disappears again on a whole-column set_all (or an explicit compact_validity).
  • Validity is per ELEMENT, and a vector row is not one bit. The bitmap is 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.
  • Row indices are 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.



Variables

Type Visibility Attributes Name Initial
integer(kind=int64), public, parameter :: parquet_validity_block_bits = BITS_PER_BLOCK

BITS_PER_BLOCK, published.

Exposed for exactly one reason: so that nobody has to copy it. A caller filling one column from several threads -- parquet_tables' parallel single-column read is the one that exists -- must keep two threads off the same bitmap block, because updating a block is a read-modify-write and a lost update silently moves a null to the wrong row. Computing that alignment needs this number, and a second copy of it living in another module could drift from this one with nothing to report it. This is a fact about the storage layout, not a knob: it is a parameter, and changing it changes only how the same bits are grouped.

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)


Interfaces

interface

  • public module function parquet_column_any_null(col) result(res)

    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).

    Arguments

    Type IntentOptional Attributes Name
    type(parquet_column), intent(in) :: col

    the column.

    Return Value logical

    .true. when at least one row is null.

interface

  • public module subroutine parquet_column_string_column(col, p)

    Typed string_column: pointer to the embedded string store (PK_STRING/PK_STRING_VEC).

    Arguments

    Type IntentOptional Attributes Name
    type(parquet_column), intent(in), target :: col

    the column.

    type(parquet_string_column), intent(out), pointer :: p

    alias to the string store.

public interface parquet_column_get_at

  • private interface parquet_column_get_at_i32()

    Arguments

    None
  • private interface parquet_column_get_at_i64()

    Arguments

    None
  • private interface parquet_column_get_at_f32()

    Arguments

    None
  • private interface parquet_column_get_at_f64()

    Arguments

    None
  • private interface parquet_column_get_at_bool()

    Arguments

    None
  • private interface parquet_column_get_at_str()

    Arguments

    None
  • private interface parquet_column_get_at_date()

    Arguments

    None
  • private interface parquet_column_get_at_time()

    Arguments

    None
  • private interface parquet_column_get_at_ts()

    Arguments

    None
  • private interface parquet_column_get_at_i32v()

    Arguments

    None
  • private interface parquet_column_get_at_i64v()

    Arguments

    None
  • private interface parquet_column_get_at_f32v()

    Arguments

    None
  • private interface parquet_column_get_at_f64v()

    Arguments

    None
  • private interface parquet_column_get_at_boolv()

    Arguments

    None
  • private interface parquet_column_get_at_strv()

    Arguments

    None
  • private interface parquet_column_get_at_datev()

    Arguments

    None
  • private interface parquet_column_get_at_timev()

    Arguments

    None
  • private interface parquet_column_get_at_tsv()

    Arguments

    None

public interface parquet_column_set_at

  • private interface parquet_column_set_at_i32()

    Arguments

    None
  • private interface parquet_column_set_at_i64()

    Arguments

    None
  • private interface parquet_column_set_at_f32()

    Arguments

    None
  • private interface parquet_column_set_at_f64()

    Arguments

    None
  • private interface parquet_column_set_at_bool()

    Arguments

    None
  • private interface parquet_column_set_at_str()

    Arguments

    None
  • private interface parquet_column_set_at_date()

    Arguments

    None
  • private interface parquet_column_set_at_time()

    Arguments

    None
  • private interface parquet_column_set_at_ts()

    Arguments

    None
  • private interface parquet_column_set_at_i32v()

    Arguments

    None
  • private interface parquet_column_set_at_i64v()

    Arguments

    None
  • private interface parquet_column_set_at_f32v()

    Arguments

    None
  • private interface parquet_column_set_at_f64v()

    Arguments

    None
  • private interface parquet_column_set_at_boolv()

    Arguments

    None
  • private interface parquet_column_set_at_strv()

    Arguments

    None
  • private interface parquet_column_set_at_datev()

    Arguments

    None
  • private interface parquet_column_set_at_timev()

    Arguments

    None
  • private interface parquet_column_set_at_tsv()

    Arguments

    None

public interface parquet_column_get_elem

  • private interface parquet_column_get_elem_i32v()

    Arguments

    None
  • private interface parquet_column_get_elem_i64v()

    Arguments

    None
  • private interface parquet_column_get_elem_f32v()

    Arguments

    None
  • private interface parquet_column_get_elem_f64v()

    Arguments

    None
  • private interface parquet_column_get_elem_boolv()

    Arguments

    None
  • private interface parquet_column_get_elem_strv()

    Arguments

    None
  • private interface parquet_column_get_elem_datev()

    Arguments

    None
  • private interface parquet_column_get_elem_timev()

    Arguments

    None
  • private interface parquet_column_get_elem_tsv()

    Arguments

    None

public interface parquet_column_set_elem

  • private interface parquet_column_set_elem_i32v()

    Arguments

    None
  • private interface parquet_column_set_elem_i64v()

    Arguments

    None
  • private interface parquet_column_set_elem_f32v()

    Arguments

    None
  • private interface parquet_column_set_elem_f64v()

    Arguments

    None
  • private interface parquet_column_set_elem_boolv()

    Arguments

    None
  • private interface parquet_column_set_elem_strv()

    Arguments

    None
  • private interface parquet_column_set_elem_datev()

    Arguments

    None
  • private interface parquet_column_set_elem_timev()

    Arguments

    None
  • private interface parquet_column_set_elem_tsv()

    Arguments

    None

public interface parquet_column_data_ptr

  • private interface parquet_column_data_ptr_i32()

    Arguments

    None
  • private interface parquet_column_data_ptr_i64()

    Arguments

    None
  • private interface parquet_column_data_ptr_f32()

    Arguments

    None
  • private interface parquet_column_data_ptr_f64()

    Arguments

    None
  • private interface parquet_column_data_ptr_bool()

    Arguments

    None
  • private interface parquet_column_data_ptr_date()

    Arguments

    None
  • private interface parquet_column_data_ptr_time()

    Arguments

    None
  • private interface parquet_column_data_ptr_ts()

    Arguments

    None
  • private interface parquet_column_data_ptr_i32v()

    Arguments

    None
  • private interface parquet_column_data_ptr_i64v()

    Arguments

    None
  • private interface parquet_column_data_ptr_f32v()

    Arguments

    None
  • private interface parquet_column_data_ptr_f64v()

    Arguments

    None
  • private interface parquet_column_data_ptr_boolv()

    Arguments

    None
  • private interface parquet_column_data_ptr_datev()

    Arguments

    None
  • private interface parquet_column_data_ptr_timev()

    Arguments

    None
  • private interface parquet_column_data_ptr_tsv()

    Arguments

    None

public interface parquet_column_is_null

  • private interface parquet_column_is_null_row()

    Arguments

    None
  • private interface parquet_column_is_null_elem()

    Arguments

    None

public interface parquet_column_set_null

  • private interface parquet_column_set_null_row()

    Arguments

    None
  • private interface parquet_column_set_null_elem()

    Arguments

    None

public interface parquet_column_clear_null

  • private interface parquet_column_clear_null_row()

    Arguments

    None
  • private interface parquet_column_clear_null_elem()

    Arguments

    None

Derived Types

type, public ::  parquet_column

One column's values: a kind discriminator, one active storage array, sparse validity, an optional unit, and the row/width geometry.

Type-Bound Procedures

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 i (or, with e, element e of row i) is null. On a vector kind the row form answers "ANY element of the row is null"; see the module doc.

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 i null, or with e just element e of it.

generic, public :: clear_null => clear_null_row, clear_null_elem

Marks row i valid, or with e just element e of it.

generic, public :: set_validity => set_validity_elems, set_validity_rows

Writes a whole validity mask in one pass. A rank-2 (width, nrows) mask is per ELEMENT; a rank-1 (nrows) mask is per ROW, marking every element of a .false. row null -- the same row/element pairing %set_null and %is_null already use.

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 n rows without changing the row count.

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 reindex the list may be any length, and unlike delete_by_mask it may reorder -- see the interface below.

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.


Subroutines

public subroutine parquet_kind_name(kind, name)

Copies a human-readable name for a PK_* kind out (for error messages and callers that dispatch on kindof).

Arguments

Type IntentOptional Attributes Name
integer, intent(in) :: kind

a PK_* discriminator.

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

the kind's name.