db-12 — Verification

How to reproduce the green status on a clean machine.

Prerequisites

  • macOS or Linux with Apple Clang / clang ≥ 14 / gcc ≥ 11 supporting C++20.
  • cmake ≥ 3.20.
  • Rust toolchain ≥ 1.74 (rustup default stable).
  • Go ≥ 1.22.
  • shasum, cmp, awk (default on macOS; coreutils on Linux).
  • bash — the scripts are written to bash 3.2 (what macOS ships) on purpose, so /bin/bash works; bash 5.x is fine too.

No network access required. No external crates, modules, or libraries.

One command

cd db-12-sql-frontend
scripts/verify.sh        # builds + unit tests in all three langs
scripts/cross_test.sh    # cross-language sha256 match against fixtures

Both should print === OK === / === ALL OK === and exit 0.

Per-language drill-down

Rust

cd db-12-sql-frontend/src/rust
cargo test --quiet
cargo build --release

Expected: 11 passed; 0 failed. The sqlctl binary lands in target/release/sqlctl.

Go

cd db-12-sql-frontend/src/go
go test ./...
go build ./cmd/sqlctl

Expected: ok github.com/10xdev/dse/db12 <duration>. Eleven tests pass, including TestFixtureAHash and TestFixtureBHash which assert the frozen 181-byte / 486-byte sha256 values for the two fixtures.

C++

cd db-12-sql-frontend/src/cpp
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build -j
ctest --test-dir build --output-on-failure

Expected: 100% tests passed, 0 tests failed out of 1 and test_sqlfront12 prints OK. The single ctest target runs all 11 inline assertions, including the two frozen-hash fixture tests.

What "green" means

A green run guarantees:

  • All 33 unit tests pass (11 each in Rust, Go, C++).

  • The Rust serializer, the Go serializer, and the C++ serializer all agree on the frozen reference hashes:

    FixtureBytessha256
    a_basic.sql181071b40fd5d0c684695c5a8499be6fe970ed4533af16f71dcc4c455091b576d15
    b_full.sql486e219f1ee4ae69f194cca7b9791aa2e34ecdb2680956dbf8a94618fa8093aa962
  • The CLIs in all three languages report the same sha256 as shasum -a 256 over their stdout — they aren't lying about their own hash.

  • The error path is also identical: the three implementations all report parse error at line 1 col 8: expected identifier for the malformed input SELECT FROM t;.

When verification fails

  • Cross-language sha256 mismatch on a fixture. The wire format drifted in exactly one language. Things to suspect, in order of likelihood:

    1. New operator added to Op in one language only — emits a new tag byte the others don't recognize.
    2. String length prefix width changed (u32u64).
    3. Endianness slip on i64 LE (someone used binary.BigEndian in Go, or htonl in C++).
    4. Iteration order divergence — most likely on SELECT named-column lists or UPDATE SET assignments. Both must follow parse order (insertion order); a HashMap somewhere would break this.
  • Cross-language sha256 match but mismatch against the frozen value. All three implementations drifted together — the wire format genuinely changed. Update the frozen hashes in scripts/cross_test.sh, src/go/sql_test.go, and src/cpp/tests/test_sqlfront12.cc in the same commit, and update the table in CONCEPTS.md.

  • Rust passes, Go fails frozen-hash test. Most likely an encoding/binary byte-order slip (BigEndian vs LittleEndian) or a missing i64/int64 conversion on a literal.

  • Rust + Go pass, C++ ctest reports zero tests. Confirm the add_test line is in CMakeLists.txt after the add_executable for test_sqlfront12. Do not add add_subdirectory(../db-NN) — db-12 has no upstream lab dependencies, and any such call leaks upstream add_test calls into our ctest output.

  • cross_test.sh fails with WANT: command not found or bad array subscript. The script is calling associative-array syntax under bash 3.2. The shipped cross_test.sh uses a want_hash() case function precisely to avoid this; if the failure recurs after an edit, search for declare -A or ${WANT[ and replace with the function form.

  • Fixture hash changes after editing a .sql file. Any byte change — including a trailing newline or replacing the en-dash in a comment line with a hyphen — changes the input, which changes the AST in subtle ways (different identifier bytes, different literal contents), which changes the output hash. The fixtures are frozen for the lifetime of the lab; if you want to add coverage, add a new fixture and a new frozen hash rather than editing these.