ddxdb
Write calculus directly in SQL and let the database evaluate the derivative, row by row, alongside everything else:
SELECT i, grad(x * y, x) AS dfdx, grad(x * y, y) AS dfdy FROM g
grad and jvp are markers, not row functions. They are rewritten away into
ordinary derivative SQL before the engine sees them, so what runs is a plain
expression — the relational equivalent of jax.vmap(jax.grad(f)), with the rows
as the batch dimension.
This is the Python distribution of ddx, a
thin wrapper over the ddx-core engine.
Install
pip install ddxdb # everything below except Context
pip install "ddxdb[datafusion]" # + the DataFusion Context
rewrite_sql is the whole library
Text in, text out — so it works with any engine that accepts SQL. Pass the result wherever you would have passed the original:
import ddxdb
ddxdb.rewrite_sql("SELECT grad(sin(x), x) AS d FROM t")
# 'SELECT (cos(x)) AS d FROM t'
con.sql(ddxdb.rewrite_sql(q, "duckdb")) # DuckDB
session.sql(ddxdb.rewrite_sql(q, "spark")) # Spark
ctx.sql(ddxdb.rewrite_sql(q)) # DataFusion
Accepted dialects: generic, datafusion, postgres, ansi, snowflake,
oracle, duckdb, mysql, sqlite, bigquery, redshift, hive, spark,
databricks, mssql, teradata, clickhouse.
Pick the one that matches the engine you will run on, not just the one that parses your SQL. The dialect also decides which column an identifier names, and engines disagree three ways:
unquoted X means |
so "X" is |
|
|---|---|---|
| Postgres, DataFusion, generic, ansi | "x" |
a different column |
| Snowflake, Oracle | "X" |
the same column |
| DuckDB, Spark, MySQL, SQLite, BigQuery, Redshift, Hive, Databricks, SQL Server, Teradata | any casing | the same column |
| ClickHouse | X exactly |
the same column, and "x" is not |
Getting this wrong does not raise. grad("X" * "X", X) is 2X on Snowflake and
0 on Postgres — both correct, for different engines — so ddx keeps a table
rather than a default, and refuses a dialect whose rule it has not established.
Because the rewrite happens in your process, on your connection, it sees
your temp tables, session settings, and open transaction. DuckDB's in-database
ddx('<sql>') table function cannot: it executes on a separate inner
connection.
Context, for DataFusion
A real SessionContext subclass whose .sql() rewrites first — every inherited
method, property and constructor argument works unchanged:
ctx = ddxdb.Context()
ctx.sql("SELECT grad(x * x, x) AS d FROM t").collect() # → 2x
It lives in ddxdb.datafusion (a subclass needs its base class at import time,
so it cannot sit beside rewrite_sql without dragging DataFusion in) and is
re-exported as ddxdb.Context, imported on first use. import ddxdb still needs
no engine.
There is sugar for DataFusion and not for other engines because DataFusion is ddx's integration target. Everything else uses the one-liner above, which is why there are no per-engine helpers here to drift out of date.
What you can write
+ - * /; the chain rule for the trig / inverse-trig / exp / log / hyperbolic
set plus abs; power with a constant base or exponent. Higher order falls out
of nesting — grad(grad(f, x), x) just works. Differentiating through an
aggregate is linearity, so the marker goes inside it, which is what makes a
gradient-descent step expressible in SQL:
SELECT theta - 0.01 * AVG(grad(loss, theta)) FROM batch
A marker rewrites in place, so it is legal anywhere a scalar expression is — including inside a recursive CTE, which is how a whole training loop fits in one query.
One other function
ddxdb.differentiate_sql("x * y", "x") # 'y' — the derivative as text
The escape hatch, for assembling SQL where a marker cannot reach — inside a
recursive term you are building programmatically, or a query some other tool
emits. Everything else should use rewrite_sql.
Errors are typed
An unsupported construct is always an error, never a silently wrong number — this is a numerical-correctness library, and a plausible-looking wrong derivative is the worst thing it could produce. The kind of failure is a class, so you can catch the one you can act on:
try:
ddxdb.rewrite_sql(query)
except ddxdb.UnsupportedExpression:
... # no rule for something in there — fall back
except ddxdb.AmbiguousColumn:
... # the query needs a qualifier — a fix the caller makes
All of them derive from ddxdb.DdxError. The full set is
UnsupportedExpression, InvalidMarker, AmbiguousColumn,
ProjectionBoundary and SqlParseError.
One thing to know
grad does not see through a CTE or a view. Differentiation stops at column
references, so a column computed upstream is a constant to it:
WITH v AS (SELECT x, sin(x) AS s FROM t)
SELECT grad(s * x, x) FROM v -- ds/dx is treated as 0
That is defensible relational semantics and a real trap, so ddx refuses the
worst case rather than quietly dropping the term: referencing a computed CTE
alias as a non-wrt term raises ProjectionBoundary and tells you to
differentiate inside the CTE instead. Differentiating with respect to such an
alias is fine — every occurrence is then the differentiation leaf, and
grad(s * s, s) is exactly 2s.
Development
pip install maturin pytest
maturin develop --uv
python -m pytest tests/
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ddxdb-0.1.0.tar.gz.
File metadata
- Download URL: ddxdb-0.1.0.tar.gz
- Upload date:
- Size: 83.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f0e599fb5fb7a3d02e9b0a9949d02c10f6f8d83774938a0ae267b71811aeeb8c
|
|
| MD5 |
234344e622383131d9282c3070db33d7
|
|
| BLAKE2b-256 |
4aaa2ca0b87cfb34adcc39a74bdd43f7d99379f89b022a81006d732a3b06c09e
|
Provenance
The following attestation bundles were made for ddxdb-0.1.0.tar.gz:
Publisher:
publish-pypi.yml on xqlsystems/ddx
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ddxdb-0.1.0.tar.gz -
Subject digest:
f0e599fb5fb7a3d02e9b0a9949d02c10f6f8d83774938a0ae267b71811aeeb8c - Sigstore transparency entry: 2399442751
- Sigstore integration time:
-
Permalink:
xqlsystems/ddx@4eb4802a7c03358fd03e2dbb678b13185ed0b675 -
Branch / Tag:
refs/tags/ddxdb-v0.1.0 - Owner: https://github.com/xqlsystems
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@4eb4802a7c03358fd03e2dbb678b13185ed0b675 -
Trigger Event:
push
-
Statement type:
File details
Details for the file ddxdb-0.1.0-cp310-abi3-win_amd64.whl.
File metadata
- Download URL: ddxdb-0.1.0-cp310-abi3-win_amd64.whl
- Upload date:
- Size: 3.5 MB
- Tags: CPython 3.10+, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
63a16b7ec672bcd02fbfcdd040311f312a67c155cc48e08fbd6deddcca1cd8ef
|
|
| MD5 |
5002a7792195f43f4f41f736b67e40db
|
|
| BLAKE2b-256 |
43d16961143411dfaef0cad1a4626d763bd767bc79031b30f0c47fd4e91c4735
|
Provenance
The following attestation bundles were made for ddxdb-0.1.0-cp310-abi3-win_amd64.whl:
Publisher:
publish-pypi.yml on xqlsystems/ddx
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ddxdb-0.1.0-cp310-abi3-win_amd64.whl -
Subject digest:
63a16b7ec672bcd02fbfcdd040311f312a67c155cc48e08fbd6deddcca1cd8ef - Sigstore transparency entry: 2399443034
- Sigstore integration time:
-
Permalink:
xqlsystems/ddx@4eb4802a7c03358fd03e2dbb678b13185ed0b675 -
Branch / Tag:
refs/tags/ddxdb-v0.1.0 - Owner: https://github.com/xqlsystems
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@4eb4802a7c03358fd03e2dbb678b13185ed0b675 -
Trigger Event:
push
-
Statement type:
File details
Details for the file ddxdb-0.1.0-cp310-abi3-manylinux_2_28_x86_64.whl.
File metadata
- Download URL: ddxdb-0.1.0-cp310-abi3-manylinux_2_28_x86_64.whl
- Upload date:
- Size: 3.5 MB
- Tags: CPython 3.10+, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6e93db2a1a5f8f6224588e2eeed5ef04c81f558a2fc0511b3492d349096ba9d0
|
|
| MD5 |
df1fb59d951a0c7cefc31405b5320f0c
|
|
| BLAKE2b-256 |
914941e73bee5a2660527fafd038cc8143021c5053b451d7851cd3583f751b32
|
Provenance
The following attestation bundles were made for ddxdb-0.1.0-cp310-abi3-manylinux_2_28_x86_64.whl:
Publisher:
publish-pypi.yml on xqlsystems/ddx
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ddxdb-0.1.0-cp310-abi3-manylinux_2_28_x86_64.whl -
Subject digest:
6e93db2a1a5f8f6224588e2eeed5ef04c81f558a2fc0511b3492d349096ba9d0 - Sigstore transparency entry: 2399442947
- Sigstore integration time:
-
Permalink:
xqlsystems/ddx@4eb4802a7c03358fd03e2dbb678b13185ed0b675 -
Branch / Tag:
refs/tags/ddxdb-v0.1.0 - Owner: https://github.com/xqlsystems
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@4eb4802a7c03358fd03e2dbb678b13185ed0b675 -
Trigger Event:
push
-
Statement type:
File details
Details for the file ddxdb-0.1.0-cp310-abi3-manylinux_2_28_aarch64.whl.
File metadata
- Download URL: ddxdb-0.1.0-cp310-abi3-manylinux_2_28_aarch64.whl
- Upload date:
- Size: 3.3 MB
- Tags: CPython 3.10+, manylinux: glibc 2.28+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0426efa947bd30d45fc13474748d4f19d408ecd66e963732cfcd1e12671f57ee
|
|
| MD5 |
4a0d3927a41a0f79590a3e48b9315f17
|
|
| BLAKE2b-256 |
9749829aca68593e983dc36d8cc7e196c86bf38dcca2be34592c5448dc584fe1
|
Provenance
The following attestation bundles were made for ddxdb-0.1.0-cp310-abi3-manylinux_2_28_aarch64.whl:
Publisher:
publish-pypi.yml on xqlsystems/ddx
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ddxdb-0.1.0-cp310-abi3-manylinux_2_28_aarch64.whl -
Subject digest:
0426efa947bd30d45fc13474748d4f19d408ecd66e963732cfcd1e12671f57ee - Sigstore transparency entry: 2399442870
- Sigstore integration time:
-
Permalink:
xqlsystems/ddx@4eb4802a7c03358fd03e2dbb678b13185ed0b675 -
Branch / Tag:
refs/tags/ddxdb-v0.1.0 - Owner: https://github.com/xqlsystems
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@4eb4802a7c03358fd03e2dbb678b13185ed0b675 -
Trigger Event:
push
-
Statement type:
File details
Details for the file ddxdb-0.1.0-cp310-abi3-macosx_11_0_arm64.whl.
File metadata
- Download URL: ddxdb-0.1.0-cp310-abi3-macosx_11_0_arm64.whl
- Upload date:
- Size: 3.2 MB
- Tags: CPython 3.10+, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2b10d60df3157c21d05f8ec6853894f1c80b678b84710c47df53db9b9651b316
|
|
| MD5 |
92c33d8919cc3637cb3cf447f4fb819f
|
|
| BLAKE2b-256 |
4a3189c30685778d9f08dac083e39524f074193e5e40d415181bbde82d8ae8d3
|
Provenance
The following attestation bundles were made for ddxdb-0.1.0-cp310-abi3-macosx_11_0_arm64.whl:
Publisher:
publish-pypi.yml on xqlsystems/ddx
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ddxdb-0.1.0-cp310-abi3-macosx_11_0_arm64.whl -
Subject digest:
2b10d60df3157c21d05f8ec6853894f1c80b678b84710c47df53db9b9651b316 - Sigstore transparency entry: 2399443077
- Sigstore integration time:
-
Permalink:
xqlsystems/ddx@4eb4802a7c03358fd03e2dbb678b13185ed0b675 -
Branch / Tag:
refs/tags/ddxdb-v0.1.0 - Owner: https://github.com/xqlsystems
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@4eb4802a7c03358fd03e2dbb678b13185ed0b675 -
Trigger Event:
push
-
Statement type:
File details
Details for the file ddxdb-0.1.0-cp310-abi3-macosx_10_12_x86_64.whl.
File metadata
- Download URL: ddxdb-0.1.0-cp310-abi3-macosx_10_12_x86_64.whl
- Upload date:
- Size: 3.4 MB
- Tags: CPython 3.10+, macOS 10.12+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ccf461525832c1ee5dd0de496c217a61304d8f7eada22cfe782739e549bdbf34
|
|
| MD5 |
51daeff9fa64efde17200a90322dfe68
|
|
| BLAKE2b-256 |
6b73cf42bb08b6f2d880c6c6789d41253b04d7bff9d6ca771c8209d4d90cf3b1
|
Provenance
The following attestation bundles were made for ddxdb-0.1.0-cp310-abi3-macosx_10_12_x86_64.whl:
Publisher:
publish-pypi.yml on xqlsystems/ddx
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ddxdb-0.1.0-cp310-abi3-macosx_10_12_x86_64.whl -
Subject digest:
ccf461525832c1ee5dd0de496c217a61304d8f7eada22cfe782739e549bdbf34 - Sigstore transparency entry: 2399443161
- Sigstore integration time:
-
Permalink:
xqlsystems/ddx@4eb4802a7c03358fd03e2dbb678b13185ed0b675 -
Branch / Tag:
refs/tags/ddxdb-v0.1.0 - Owner: https://github.com/xqlsystems
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@4eb4802a7c03358fd03e2dbb678b13185ed0b675 -
Trigger Event:
push
-
Statement type: