# 项目申报书

**项目名称**：moondelta-core — Delta Lake 表格式内核的 MoonBit 实现\
**参赛者**：张国迅（GitHub：xiguaAp6y3）\
**联系方式**：已通过赛事官方报名渠道提交（公开仓库不展示个人邮箱）\
**GitHub 仓库链接**：https://github.com/xiguaAp6y3/moondelta-core\
**项目方向**：MoonBit 数据基础设施，面向 lakehouse / ETL / 数据管道的 Delta 表读写\
**是否为移植项目**：否 —— 按 Delta Lake 协议规范原创实现

## 项目简介

MoonBit 已有 Parquet 编解码（`mizchi/parquet`）、Arrow IPC、DataFrame（MoonFrame）、对 CSV/Parquet 跑 SQL 的引擎（moonlake）、Iceberg 只读（moonice），但**没有"带事务日志的表"**：没有版本、快照、时间旅行，也没有把一批 Parquet 文件原子提交成新版本的机制。结果是文件能读、表还得自己拼——回滚、按版本审计、增量入湖只能手写 JSON 解析加目录扫描，或者把整段逻辑绕去 Python/Spark。

moondelta-core 补这一层：打开磁盘上的 Delta 表目录，回放 `_delta_log`，给出指定版本的文件清单，按分区与 min/max 统计剪枝，读取数据文件，并在受支持的列类型上 append 提交新版本。

## 通用性说明

- 与具体业务无关：凡是需要"版本化表"的场景都能直接复用——ETL 写出、外部表校验与迁移、CI 数据契约审计、增量入湖；
- 格式与生态一致：读写标准 Delta 目录，Spark / Databricks / delta-rs / DuckDB 可直接互通，已有表可以平移使用；
- 不绑定存储与运行时：库只处理目录与文件，不依赖 JVM/Rust 运行时，native 目标可用，后续可扩 wasm/js；
- 边界显式：不支持的 schema、压缩、写入类型在类型层与错误信息里明确拒绝，不静默降级——数据基础设施宁可拒绝，不可返回错数据。

## 预期使用场景

1. **MoonBit ETL 写出、Spark 直接读**：输入是清洗后的记录（Int64/String 列），操作 `create_table` + `append_rows`（写 Parquet 数据文件并提交新版本），输出标准 Delta 目录；Spark / Databricks / delta-rs 用 `spark.read.format("delta")` 直接读，MoonBit 侧不需要装 Spark。
2. **外部表校验与迁移**：输入 delta-rs 或 Databricks 产出的表（例如 COVID-19_NYT，157,865 行 6 列），操作 `snapshot_at(v)` + 扫描 + 读取，对比两个版本的文件清单、行数与值，输出校验报告或 CSV——迁移前确认数据没缺、历史对得上。
3. **CI 数据契约审计**：输入仓库里随代码提交的小型 Delta 表和两个版本号，操作按版本回放 + 分区/min-max 剪枝，输出"这次提交改了 N 个数据文件、影响 M 行、落在 dt=… 分区"的 Markdown artifact；纯读路径，不需要写权限。

## 拟实现的核心功能

- **事务日志解析与回放**：`_delta_log` 逐行 action（protocol / metaData / add / remove / commitInfo），版本发现与排序、`_last_checkpoint` 识别；
- **快照与时间旅行**：按版本顺序叠加 add/remove，同路径 add→remove→add 正确收敛；`snapshot_at(v)`、`history()`；
- **扫描规划**：分区等值过滤 + 文件级 min/max 统计剪枝，返回文件清单、跳过数、命中行数与字节数；
- **读取**：flat schema + UNCOMPRESSED/SNAPPY 数据文件；分区列按 `partitionValues` 补齐；
- **写入**：`create_table` + `append_rows`，写 Parquet 数据文件、提交新的 JSON 版本，统计信息（numRecords/min/max）随日志写入；
- **CLI 与工程化**：`delta inspect | history | scan | read | create`、可运行示例、10 个单元测试（含负向）、CI（check/build/test）、mooncakes.io 发布。

## 移植或参考说明

- **参考规范**：Delta Lake 协议规范 https://github.com/delta-io/delta （Apache-2.0），仅按规范实现，未复制 delta-rs / Spark 代码；测试数据来自 delta-rs 与 apache/parquet-testing（均 Apache-2.0），逐项来源与哈希见 `fixtures/README.md` 与 `THIRD_PARTY_NOTICES.md`；
- **实现方式**：从零手写约 2,172 行 MoonBit（核心库 1,414、CLI 373、测试 340、示例 45）；唯一运行时依赖为 `moonbitlang/x@0.5.5`；Parquet 编解码 vendored `mizchi/parquet@0.2.2`（Apache-2.0，删掉两个 DuckDB 演示子包，reader/writer 未改，NOTICE 记录来源与修改）；
- **实现路径**：不包 delta-rs/Spark（MoonBit 没有 JVM/Rust 绑定，且只是壳），也不自造列存（重复造轮子）；只做协议层，复用 Parquet 与 core JSON，sans-IO 核心 + 文件系统薄封装，日志回放可用真实 fixture 离线对拍；
- **边界与简化**：不实现嵌套 schema（struct/list/map）与 ZSTD/GZIP/BROTLI/LZ4；不解析 checkpoint parquet（checkpoint-only 表明确拒绝）；写入仅支持 Int32/Int64/String/Binary（Required/Optional），不写分区表；不做对象存储、删除向量、列映射、MERGE/UPDATE/DELETE、并发写冲突仲裁、SQL/DataFrame 层。

## 当前交付状态
- 手写 MoonBit 代码 2,172 行（核心库 1,414、CLI 373、测试 340、示例 45）；10 个具名测试全部通过，含负向用例（嵌套列拒绝、checkpoint-only 表拒绝）；
- 已实测：delta-rs `table_a` 13 个版本回放 → 120 个文件；Databricks 写出的 COVID-19_NYT 数据文件读取 157,865 行 6 列；`id>=60` 统计剪枝 120 → 60 个文件；create + append + 重新读回通过；
- `moon check` / `moon test`（native）通过，`moon package` 通过，CLI 六子命令与示例可运行（warning 全部来自 vendored parquet 上游代码）；GitHub Actions 流水线已通过（check / build / test 全绿）；
- 后续计划：发布 mooncakes.io v0.1.0、Double/Boolean 写入、ZSTD 解压与 checkpoint parquet 解析（季度扩展）。
