Wormhole
A semantic layer runtime written in Zig. Define dimensions, measures and joins once, then query them from Python on DuckDB, PySpark or pandas through one native library.
- SQL engines (DuckDB, Spark): Wormhole compiles the query to engine SQL.
- pandas: Wormhole executes the plan itself on Arrow buffers in Zig (
Wormhole.query), checked against DuckDB with a differential test.
Models are boring-semantic-layer style YAML and queries are its declarative query dicts
(dimensions, measures, filters, order_by, limit, time_grain, time_range).
Status
| Piece | State |
|---|---|
| Expression parser, SQL emitter (DuckDB + Spark dialects), C ABI, Python wrapper | working |
DuckDB conformance (spec/, 32 queries) |
32/32 |
| PySpark conformance | 32/32 |
| pandas conformance (native Arrow executor) | 32/32 |
| Differential test, executor vs DuckDB SQL (random data, nulls, non-ASCII) | 0 mismatches |
Wheels (tools/build_wheels.py: Linux x86_64/aarch64, macOS x86_64/arm64, Windows) |
built in CI, Linux wheel install-tested |
Benchmarks (tests/bench.py) |
below |
Try it
pip install ziglang==0.16.0 duckdb pyyaml pyarrow
python -m ziglang build -Doptimize=ReleaseSafe
python tests/conformance_duckdb.py
import sys; sys.path.insert(0, "python")
from wormhole import Wormhole
wh = Wormhole("spec/models/flights.yml")
print(wh.emit_sql({
"model": "flights_joined",
"dimensions": ["carriers.name"],
"measures": ["flight_count", "delay_per_flight"],
"filters": [{"field": "flights_joined.origin", "operator": "in", "values": ["JFK", "LGA"]}],
"order_by": [["flight_count", "desc"]],
"limit": 5,
})) # SQL for DuckDB; pass dialect="spark" for Spark SQL
Layout
src/expr.zig scalar expression parser and SQL writer
src/sql.zig manifest + query -> SQL (DuckDB, Spark)
src/c_api.zig C ABI (include/wormhole.h)
python/wormhole ctypes wrapper and YAML -> manifest translation
spec/ shared conformance suite; expected results recorded from boring-semantic-layer on DuckDB
tests/ conformance runners
docs/design.md design note
Known v1 limits
- Joins:
type: one(many-to-one, LEFT) only. Nojoin_many, self-joins, or nested joins. - Measures:
count,sum,mean,min,max,nunique, and arithmetic over other measures. Mixed forms such as_.x.sum() / _.count()are rejected when the YAML is loaded. - A filter may not mix dimension and measure fields;
having=is not supported yet. order_byalways sorts NULLs last.- A filter on a name that is neither a dimension nor a measure is treated as a raw column of the model's table, so a typo there surfaces as an engine error.
References: sm8 (Scala) and boring-semantic-layer (Python).
Packaging
python tools/build_wheels.py cross-compiles libwormhole with zig build and writes one py3-none-<platform> wheel per target into dist/ (Linux wheels target glibc 2.17). Wheels contain no compiled Python extension, so one wheel serves every Python 3 version. The distribution name is wormhole-semantic because wormhole on PyPI belongs to another project; you still import wormhole. Nothing is published to PyPI yet.
Benchmarks
python tests/bench.py (2,000,000 flight rows, median of 3 runs, ms, one machine, single-threaded executor):
| query | wormhole native (pandas) | wormhole SQL on DuckDB, from DataFrames | wormhole SQL on DuckDB tables | boring-semantic-layer on DuckDB |
|---|---|---|---|---|
| count by carrier | 45 | 337 | 20 | 26 |
| aggregates by origin | 90 | 388 | 28 | 37 |
| two dimensions | 126 | 377 | 29 | 36 |
| filter in | 79 | 346 | 25 | 36 |
Reading it: on pandas data the native executor is 3 to 8 times faster than handing the same DataFrames to DuckDB on each call, because DuckDB converts them every time. Once the data sits in DuckDB tables, DuckDB is 3 to 4 times faster than the native executor (which does not use multiple threads yet), and Wormhole's SQL runs as fast as boring-semantic-layer's.
Metadata
Release files for wormhole-semantic 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| wormhole_semantic-0.1.0-py3-none-win_amd64.whl | Python 3 | none | Windows x86-64 | Details |
| wormhole_semantic-0.1.0-py3-none-manylinux_2_17_x86_64.whl | Python 3 | none | Linux glibc 2.17+ x86-64 | Details |
| wormhole_semantic-0.1.0-py3-none-manylinux_2_17_aarch64.whl | Python 3 | none | Linux glibc 2.17+ ARM64 | Details |
| wormhole_semantic-0.1.0-py3-none-macosx_11_0_x86_64.whl | Python 3 | none | macOS 11.0+ x86-64 | Details |
| wormhole_semantic-0.1.0-py3-none-macosx_11_0_arm64.whl | Python 3 | none | macOS 11.0+ ARM64 | Details |
Total release size: 1.6 MB
Release files / wormhole_semantic-0.1.0-py3-none-win_amd64.whl
| Download URL | wormhole_semantic-0.1.0-py3-none-win_amd64.whl |
|---|---|
| Size | 258.5 kB |
| Tags | Python 3 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
1c420bbc036377fc0bba7b83e1c7d7f1fb0fc7d7443b9fd2eaae1cdef7000e9b
|
|
BLAKE2b-256 checksum How to use checksums |
2ae7a12599419296270ac3d7297d6ddb2388406451cf8ccb79d7f3e99f156024
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 9, 2026.
Transparency logRelease files / wormhole_semantic-0.1.0-py3-none-manylinux_2_17_x86_64.whl
| Download URL | wormhole_semantic-0.1.0-py3-none-manylinux_2_17_x86_64.whl |
|---|---|
| Size | 544.0 kB |
| Tags | Linux glibc 2.17+ x86-64 Python 3 |
|
SHA-256 checksum How to use checksums |
c472997e3e4d9a63165304e3f26924c8e23a8095cf7f2ad550a432f21c990970
|
|
BLAKE2b-256 checksum How to use checksums |
5b10f388aca9a0619b350ac145ddd669a921150c16299362d982871d2e567873
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 9, 2026.
Transparency logRelease files / wormhole_semantic-0.1.0-py3-none-manylinux_2_17_aarch64.whl
| Download URL | wormhole_semantic-0.1.0-py3-none-manylinux_2_17_aarch64.whl |
|---|---|
| Size | 501.2 kB |
| Tags | Linux glibc 2.17+ ARM64 Python 3 |
|
SHA-256 checksum How to use checksums |
f6aceff25b63d2cb57aa4268bf574c58c45674535eb34d1d17693058995f3f22
|
|
BLAKE2b-256 checksum How to use checksums |
f7585883fb29e7cb8af51877d89cbf12008bc28ac48475a4ca36479d2e65ff3f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 9, 2026.
Transparency logRelease files / wormhole_semantic-0.1.0-py3-none-macosx_11_0_x86_64.whl
| Download URL | wormhole_semantic-0.1.0-py3-none-macosx_11_0_x86_64.whl |
|---|---|
| Size | 174.9 kB |
| Tags | Python 3 macOS 11.0+ x86-64 |
|
SHA-256 checksum How to use checksums |
f105e0169eb6cf7446adea91d2d3d0a5d636c70a3015f27ed92f3e54d71a9a37
|
|
BLAKE2b-256 checksum How to use checksums |
2f90728a2c4dfe243314b31b153eb8cd2bfe0fbb22239bf8abf839414a31bb3f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 9, 2026.
Transparency logRelease files / wormhole_semantic-0.1.0-py3-none-macosx_11_0_arm64.whl
| Download URL | wormhole_semantic-0.1.0-py3-none-macosx_11_0_arm64.whl |
|---|---|
| Size | 160.2 kB |
| Tags | Python 3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
ae361982e23cc5c0b3916aab22adb00242ee10ceba620c69855563fed503de9e
|
|
BLAKE2b-256 checksum How to use checksums |
fcd18601522132c736a91ead695000a31b43e1b0d9db8adc9838dd6c6e7f8439
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 9, 2026.
Transparency log