parquet

Parquet reader/writer for MoonBit.

moonbit
parquet
moon add mizchi/parquet@0.2.1
Download zip
Author
Version
0.2.1
License
Apache-2.0
Last updated
3 months ago
Downloads
1K

Dependencies

README

#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

#License

Apache-2.0

#
ParquetError

pub(all) suberror ParquetError {
InvalidData(String)
Unsupported(String)
Io(String)
}

impl Eq for ParquetError

#
Column

pub struct Column {
name : String
column_type : ColumnType
repetition : Repetition
}

impl Eq for Column
impl Show for Column

#
Column::column_type

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

#
Column::name

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

#
Column::repetition

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

#
ColumnType

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

impl Eq for ColumnType
impl Show for ColumnType

#
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?])
}

#
ParquetColumnData::length

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

#
ParquetColumnarFile

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

#
ParquetColumnarFile::column_data

#
ParquetColumnarFile::column_values

#
ParquetColumnarFile::columns

#
ParquetColumnarFile::created_by

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

#
ParquetColumnarFile::row_count

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

#
ParquetFile

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

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::row_count

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

#
ParquetFile::rows

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

#
Repetition

pub(all) enum Repetition {
Required
Optional
Repeated
}

impl Eq for Repetition
impl Show for Repetition

#
Value

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

impl Eq for Value
impl Show for Value

#
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