parquet

    Parquet reader/writer for MoonBit.

    moonbit
    parquet
    Download zip
    Author
    Version
    0.2.2
    License
    Apache-2.0
    Last updated
    6 days ago
    Downloads
    1K

    Dependencies

    #mizchi/parquet

    Parquet reader/writer for MoonBit.

    #Status

    • Reader passes the vendored apache-parquet-testing fixtures used in this repo:
      • delta_binary_packed
      • delta_byte_array
      • delta_encoding_optional_column
      • delta_encoding_required_column
      • int32_with_null_pages
      • fixed_length_byte_array
      • datapage_v2_empty_datapage.snappy.parquet
      • int96_from_spark
      • alltypes_plain
      • alltypes_dictionary
    • Writer currently supports flat schemas with Int32, Int64, String, and Binary, with Required / Optional repetition.
    • DuckDB interoperability is checked both ways:
      • DuckDB-written parquet can be read by this implementation.
      • MoonBit-written parquet can be read by DuckDB.

    #Benchmark

    Measured on 2026-03-09 on Apple M5, macOS 26.2, Darwin arm64.

    Reproduce:

    just bench-compare-all just bench-compare-rust

    Comparison table from just bench-compare-all:

    benchmarkmoon(js)moon(wasm-gc)moon(native)rust
    read delta binary packed benchmark512.22 us127.01 us645.99 us203.85 us
    read int32 null pages benchmark17.34 us10.85 us43.60 us7.61 us
    read fixed length byte array benchmark87.17 us10.41 us54.68 usunsupported
    read alltypes plain benchmark20.49 us12.02 us45.42 us19.57 us
    read alltypes dictionary benchmark16.83 us11.04 us42.53 us17.31 us
    read int96 from spark benchmark10.90 us3.52 us16.19 us3.28 us
    read empty snappy datapage v2 benchmark3.46 us1.72 us6.27 us2.58 us

    Notes:

    • Rust is the local baseline in tools/rust-bench, built on top of Apache's parquet crate.
    • fixed_length_byte_array is marked unsupported because the current Rust benchmark tool does not read that fixture.
    • On this machine, wasm-gc is the fastest MoonBit target for the read-side microbenchmarks above.

    #Development

    just # check + test just target=js bench just target=wasm-gc bench just target=native bench just bench-compare-all just e2e-duckdb moon info

    #Browser Playground

    The repository includes a browser playground that generates parquet on DuckDB WASM and lets you try SQL against it immediately.

    just playground-install just playground-dev

    Production build:

    just playground-build just playground-build-pages

    In the UI, you can edit schema JSON / rows JSON / SQL, generate parquet bytes with mizchi/parquet, and execute read_parquet('playground.parquet') on the DuckDB WASM backend (mizchi/duckdb, a fork of f4ah6o/duckdb that builds on current MoonBit).

    GitHub Pages:

    https://mizchi.github.io/parquet/

    #License

    Apache-2.0

    ParquetError

    pub(all) suberror ParquetError {
    InvalidData(String)
    Unsupported(String)
    Io(String)
    } derive(Eq,
    Debug
    )

    ParquetError::equal

    ParquetError::not_equal

    fn ParquetError::not_equal(x : ParquetError, y : ParquetError) -> Bool

    ParquetError::output

    fn ParquetError::output(self : ParquetError, logger : &Logger) -> Unit

    ParquetError::to_string

    fn ParquetError::to_string(self : ParquetError) -> String

    Column

    pub struct Column {
    name : String
    column_type : ColumnType
    repetition : Repetition
    } derive(Eq,
    Debug
    )

    impl Show for Column

    Column::column_type

    fn Column::column_type(self : Column) -> ColumnType

    Column::equal

    fn Column::equal(Column, Column) -> Bool

    Column::name

    fn Column::name(self : Column) -> String

    Column::not_equal

    fn Column::not_equal(x : Column, y : Column) -> Bool

    Column::output

    fn Column::output(self : Column, logger : &Logger) -> Unit

    Column::repetition

    fn Column::repetition(self : Column) -> Repetition

    Column::to_repr

    Column::to_string

    fn Column::to_string(self : Column) -> String

    ColumnType

    pub(all) enum ColumnType {
    Boolean
    Int32
    Int64
    TimestampMicros
    Float
    Double
    String
    Binary
    } derive(Eq,
    Debug
    )

    impl Show for ColumnType

    ColumnType::equal

    fn ColumnType::equal(ColumnType, ColumnType) -> Bool

    ColumnType::not_equal

    fn ColumnType::not_equal(x : ColumnType, y : ColumnType) -> Bool

    ColumnType::output

    fn ColumnType::output(self : ColumnType, logger : &Logger) -> Unit

    ColumnType::to_string

    fn ColumnType::to_string(self : ColumnType) -> String

    ParquetColumnData

    pub(all) enum ParquetColumnData {
    Values(Array[Value])
    BooleanValues(Array[Bool])
    Int32Values(Array[Int])
    NullableInt32Values(Array[Int?])
    Int64Values(Array[Int64])
    NullableInt64Values(Array[Int64?])
    TimestampMicrosValues(Array[Int64])
    NullableTimestampMicrosValues(Array[Int64?])
    FloatValues(Array[Float])
    DoubleValues(Array[Double])
    Utf8Values(Array[Bytes])
    NullableUtf8Values(Array[Bytes?])
    BinaryValues(Array[Bytes])
    NullableBinaryValues(Array[Bytes?])
    } derive(Eq,
    Debug
    )

    ParquetColumnData::equal

    ParquetColumnData::length

    fn ParquetColumnData::length(self : ParquetColumnData) -> Int

    ParquetColumnData::not_equal

    fn ParquetColumnData::not_equal(x : ParquetColumnData, y : ParquetColumnData) -> Bool

    ParquetColumnData::output

    fn ParquetColumnData::output(self : ParquetColumnData, logger : &Logger) -> Unit

    ParquetColumnData::to_string

    fn ParquetColumnData::to_string(self : ParquetColumnData) -> String

    ParquetColumnarFile

    pub struct ParquetColumnarFile {
    columns : Array[Column]
    column_data : Array[ParquetColumnData]
    row_count : Int
    column_values_cache : Array[Array[Value]]?
    created_by : String?
    } derive(
    Debug
    )

    ParquetColumnarFile::column_data

    ParquetColumnarFile::column_values

    ParquetColumnarFile::columns

    ParquetColumnarFile::created_by

    fn ParquetColumnarFile::created_by(self : ParquetColumnarFile) -> String?

    ParquetColumnarFile::equal

    ParquetColumnarFile::not_equal

    ParquetColumnarFile::output

    fn ParquetColumnarFile::output(self : ParquetColumnarFile, logger : &Logger) -> Unit

    ParquetColumnarFile::row_count

    fn ParquetColumnarFile::row_count(self : ParquetColumnarFile) -> Int

    ParquetColumnarFile::to_string

    fn ParquetColumnarFile::to_string(self : ParquetColumnarFile) -> String

    ParquetFile

    pub struct ParquetFile {
    columns : Array[Column]
    row_count : Int
    column_data : Array[ParquetColumnData]
    rows_cache : Array[Array[Value]]?
    created_by : String?
    } derive(
    Debug
    )

    impl Eq for ParquetFile
    impl Show for ParquetFile

    ParquetFile::column_data

    fn ParquetFile::column_data(self : ParquetFile) -> Array[ParquetColumnData]

    ParquetFile::columns

    fn ParquetFile::columns(self : ParquetFile) -> Array[Column]

    ParquetFile::created_by

    fn ParquetFile::created_by(self : ParquetFile) -> String?

    ParquetFile::equal

    fn ParquetFile::equal(self : ParquetFile, other : ParquetFile) -> Bool

    ParquetFile::not_equal

    fn ParquetFile::not_equal(x : ParquetFile, y : ParquetFile) -> Bool

    ParquetFile::output

    fn ParquetFile::output(self : ParquetFile, logger : &Logger) -> Unit

    ParquetFile::row_count

    fn ParquetFile::row_count(self : ParquetFile) -> Int

    ParquetFile::rows

    fn ParquetFile::rows(self : ParquetFile) -> Array[Array[Value]]

    ParquetFile::to_string

    fn ParquetFile::to_string(self : ParquetFile) -> String

    Repetition

    pub(all) enum Repetition {
    Required
    Optional
    Repeated
    } derive(Eq,
    Debug
    )

    impl Show for Repetition

    Repetition::equal

    fn Repetition::equal(Repetition, Repetition) -> Bool

    Repetition::not_equal

    fn Repetition::not_equal(x : Repetition, y : Repetition) -> Bool

    Repetition::output

    fn Repetition::output(self : Repetition, logger : &Logger) -> Unit

    Repetition::to_string

    fn Repetition::to_string(self : Repetition) -> String

    Value

    pub(all) enum Value {
    Boolean(Bool)
    Int32(Int)
    Int64(Int64)
    TimestampMicros(Int64)
    Float(Float)
    Double(Double)
    String(String)
    Binary(Bytes)
    Null
    } derive(Eq,
    Debug
    )

    impl Show for Value

    Value::equal

    fn Value::equal(Value, Value) -> Bool

    Value::not_equal

    fn Value::not_equal(x : Value, y : Value) -> Bool

    Value::output

    fn Value::output(self : Value, logger : &Logger) -> Unit

    Value::to_repr

    Value::to_string

    fn Value::to_string(self : Value) -> String

    new_column

    fn new_column(name : String, column_type : ColumnType, repetition : Repetition) -> Column

    new_parquet_columnar_file

    fn new_parquet_columnar_file(columns : Array[Column], column_data : Array[ParquetColumnData], row_count : Int, created_by : String?) -> ParquetColumnarFile

    new_parquet_file

    fn new_parquet_file(columns : Array[Column], rows : Array[Array[Value]], created_by : String?) -> ParquetFile

    read_bytes

    fn read_bytes(data : Bytes) -> ParquetFile raise ParquetError

    Read a parquet document from bytes.

    read_bytes_columnar

    fn read_bytes_columnar(data : Bytes) -> ParquetColumnarFile raise ParquetError

    Read a parquet document from bytes without row materialization.

    read_file

    fn read_file(path : String) -> ParquetFile raise ParquetError

    Read a parquet file from disk.

    read_file_columnar

    fn read_file_columnar(path : String) -> ParquetColumnarFile raise ParquetError

    Read a parquet file from disk without row materialization.

    write_bytes

    fn write_bytes(file : ParquetFile) -> Bytes raise ParquetError

    Encode a parquet document to bytes.

    The current writer supports flat schemas of Int32, Int64, String, and Binary, with Required or Optional repetition.

    write_file

    fn write_file(path : String, file : ParquetFile) -> Unit raise ParquetError

    Encode a parquet document and write it to disk.

    Powered by MoonBit

    Site sourceReport issuePackagesBuild queueSkillsStatistics

    © 2026 mooncakes.io