Skip to main content

ddxdb

Calculus in SQL: the derivative of a query with respect to a table's columns, as JAX takes the derivative of a function, computed by the engine.

from ddxdb import Context

ctx = Context()
ctx.sql("CREATE TABLE w (i BIGINT, val DOUBLE) AS VALUES (0, 1.0), (1, 2.0)")
ctx.sql("""
WITH f AS (SELECT SUM(val * val) AS l FROM w)
SELECT i, val, grad(f, val) AS df_dval FROM w     -- 2·val, row by row
""")

In a SELECT over a table, grad(f, val) is, at each row, the derivative of the number the CTE f computes with respect to that row's val (w.val when the SELECT reads several tables). The query is ordinary SQL; nothing in it is labelled for ddx, and the one function ddx gives a meaning to is ddx_stop_gradient(x), JAX's lax.stop_gradient.

A gradient is what an optimizer steps along, so a query scoring anything (a model's loss, a curve's misfit, an energy) can be optimized in SQL: a step, params - lr * grad(f)(params), is one expression.

jvp and vjp in SQL

Forward mode is jvp(e, table.column, tangent), a column of the SELECT that computes e: its tangent at each row along tangent, a CTE or table shaped like table (its dims, then the column's tangent), or a number, the same at every row, as jax.jvp returns it beside the value. Along 1, it is the derivative of an expression row by row: SELECT x, jvp(sin(x), t.x, 1) AS dx FROM t is cos(x). Along a table:

ctx.sql("""
WITH h AS (
  SELECT x.sample, w.out, tanh(SUM(x.val * w.val)) AS val
  FROM x JOIN w ON x.inp = w.inp GROUP BY x.sample, w.out),
dw AS (SELECT inp, out, 0.01 AS val FROM w)
SELECT sample, out, val, jvp(val, w.val, dw) AS val_tangent FROM h
""")

One SELECT's jvp columns share a tangent; tangents along two tables are two SELECTs, and add. vjp(f, column, cotangent) is the reverse: in a SELECT over a table, the pull-back to each row of a cotangent shaped like the CTE f's output. Calls nest: f, e's SELECT, or a tangent can read another call, so a jvp of a CTE of gradients is a Hessian-vector product, in SQL.

This is the Python distribution of ddx, a thin wrapper over the ddx-ad engine.

Install

pip install ddxdb                  # the programs, for any engine
pip install "ddxdb[datafusion]"    # + Context and ddxdb.ad, on DataFusion

Context, for DataFusion

A real SessionContext subclass whose .sql() runs grad first: every inherited method, property and constructor argument works unchanged. It lives in ddxdb.datafusion (a subclass needs its base class at import time) and is re-exported as ddxdb.Context, imported on first use, so import ddxdb needs no engine.

On a plain SessionContext, ddxdb.ad.sql(ctx, statement) does the same, and ddxdb.ad.sql_all runs several statements that take grad of one loss for the price of one backward pass.

Programs, and how they compose

ddxdb.ad.grad, vjp and jvp give the programs underneath, and each takes SQL or a program, and the columns to differentiate with respect to (wrt): a column as "table.column", or a list of them, which one backward pass differentiates together. They compose: ad.jvp(ctx, ad.grad(ctx, loss, wrt), wrt) gives Hessian-vector products, checked against jax.jvp(jax.grad(f)). Both kinds of program (BackwardProgram, ForwardProgram) list the tables you register before they run (inputs, as InputTables) and the tables they leave (value and gradients, as OutputTables). ad.run(ctx, program, inputs) runs one on its inputs (a cotangent or tangents, as DataFrames or Arrow tables, in the order of program.inputs) and returns what it computed, value and gradients, as DataFrames, tangents named {column}_tangent; nothing stays on the context:

hvp = ad.jvp(ctx, ad.grad(ctx, "SELECT SUM(val * val * val) AS l FROM w", "w.val"), "w.val")
out = ad.run(ctx, hvp, [ctx.sql("SELECT i, 1.0 AS val FROM w")])
out.gradients[0]   # i, val (the gradient), val_tangent (H·v)

Other engines

ddxdb.grad_plan(plan_bytes, wrt) differentiates the serialized Substrait plan an engine's producer writes, and ddxdb.run(backend, program) runs the result on any object with four methods, select_all, returns_rows, materialize and drop_table (the ddxdb.Backend protocol); vjp_plan and jvp_plan are the same for the other two. They are ddx-ad's own Rust, the same code the Rust adapter runs. Pass namespace="__ddx_mine_" to get the same program from the same plan every time.

The SQL calls run on another engine too: ddxdb.rewrite(backend, statements) runs the programs the statements' grad, vjp and jvp calls need on a backend that also has plan_sql (SQL to a serialized Substrait plan), and returns the statements rewritten to read what they computed. Run them on the engine inside the with block; the tables they read are dropped when it ends:

with ddxdb.rewrite(backend, [step_w, step_b]) as rewritten:
    for sql in rewritten.statements:
        engine.sql(sql)

What you can write

Inside the loss: + - * /; the chain rule for the trig / inverse-trig / exp / log / hyperbolic set plus abs; power with a constant base or exponent; joins, GROUP BY, SUM, AVG, MAX, MIN, CASE, greatest and least.

ddxdb.supported_functions()               # ['abs', 'acos', 'asin', ...]

The unary functions ddx has a rule for, read from the engine rather than restated.

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. All of them derive from ddxdb.DdxError:

  • UnsupportedExpression: no rule for something in the query.
  • NotScalar: grad of a query that is not a loss (one row, one column).
  • UnknownColumn: a column the loss does not read.
  • InvalidColumn: a column that cannot be differentiated (not a float, or in a table whose rows do not have unique dims).

Development

pip install maturin pytest
maturin develop --uv
python -m pytest tests/

Building compiles protoc from source for the substrait crate (it needs cmake and a C++ compiler), which takes a few minutes the first time.

License

Licensed under Apache-2.0, the same as the rest of ddx.

Metadata

Release files for ddxdb 0.3.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for ddxdb 0.3.2
File Size Uploaded Provenance
ddxdb-0.3.2.tar.gz 251.6 kB With provenance Details

Built distributions (wheels)

Table of built distributions (wheels) for ddxdb 0.3.2
File
ddxdb-0.3.2-cp310-abi3-win_amd64.whl CPython 3.10 abi3 Windows x86-64 Details
ddxdb-0.3.2-cp310-abi3-manylinux_2_28_x86_64.whl CPython 3.10 abi3 Linux glibc 2.28+ x86-64 Details
ddxdb-0.3.2-cp310-abi3-manylinux_2_28_aarch64.whl CPython 3.10 abi3 Linux glibc 2.28+ ARM64 Details
ddxdb-0.3.2-cp310-abi3-macosx_11_0_arm64.whl CPython 3.10 abi3 macOS 11.0+ ARM64 Details
ddxdb-0.3.2-cp310-abi3-macosx_10_12_x86_64.whl CPython 3.10 abi3 macOS 10.12+ x86-64 Details

Total release size: 28.6 MB

Release files / ddxdb-0.3.2.tar.gz

Download URL ddxdb-0.3.2.tar.gz
Size 251.6 kB
Tags Source
SHA-256 checksum
How to use checksums
bb368122ff5c7b8f5bf215a485b2274f8be954e756a70a6fd6919a23a20edfd7
BLAKE2b-256 checksum
How to use checksums
2e4be342ae0e5956c586e60f7255e6e34f0adf618a4e0c8274696043ffaa7282
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 18, 2026.

Transparency log

Release files / ddxdb-0.3.2-cp310-abi3-win_amd64.whl

Download URL ddxdb-0.3.2-cp310-abi3-win_amd64.whl
Size 5.9 MB
Tags CPython 3.10 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
2a633c3846c90023a836124979ec3dca0d72ca2f75d7fb97d061c5278e81da4d
BLAKE2b-256 checksum
How to use checksums
25ddb527dd3bd70f32c11ea7ea8216ac19478938a4f40b2796aee0c683a8bc9c
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 18, 2026.

Transparency log

Release files / ddxdb-0.3.2-cp310-abi3-manylinux_2_28_x86_64.whl

Download URL ddxdb-0.3.2-cp310-abi3-manylinux_2_28_x86_64.whl
Size 5.9 MB
Tags CPython 3.10 Linux glibc 2.28+ x86-64 abi3
SHA-256 checksum
How to use checksums
914237c46df71b2934d3d0cbcf600dd6e0e4d6e3474ae9ddc69e7d06e99090ae
BLAKE2b-256 checksum
How to use checksums
9aa65cb6cf60e66a0992d5f5273bfd2abfa3fbd9a2da057050a395bd54f44b7a
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 18, 2026.

Transparency log

Release files / ddxdb-0.3.2-cp310-abi3-manylinux_2_28_aarch64.whl

Download URL ddxdb-0.3.2-cp310-abi3-manylinux_2_28_aarch64.whl
Size 5.5 MB
Tags CPython 3.10 Linux glibc 2.28+ ARM64 abi3
SHA-256 checksum
How to use checksums
343ca2c1b0e5c687556f0f89b3225617c891c0d341e049b3dfcde12270a3de2b
BLAKE2b-256 checksum
How to use checksums
e15909464e65db980fec77cb71351a8393cab4b1bab527c55bb91d243578dd30
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 18, 2026.

Transparency log

Release files / ddxdb-0.3.2-cp310-abi3-macosx_11_0_arm64.whl

Download URL ddxdb-0.3.2-cp310-abi3-macosx_11_0_arm64.whl
Size 5.4 MB
Tags CPython 3.10 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
f36569415ebd197268507abd9e74f11f27fb5887a9ddc7a3f3f5f65b1b98c26e
BLAKE2b-256 checksum
How to use checksums
78e1d937efb520d6c58e376d7aec44dbcb29636dfdad14d37872eb735b70c639
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 18, 2026.

Transparency log

Release files / ddxdb-0.3.2-cp310-abi3-macosx_10_12_x86_64.whl

Download URL ddxdb-0.3.2-cp310-abi3-macosx_10_12_x86_64.whl
Size 5.6 MB
Tags CPython 3.10 abi3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
bd100bb23f0e64a7a0ed5cfd817f9ddaae2d7102831fb34e101ad785829a8c90
BLAKE2b-256 checksum
How to use checksums
68ad6cd87e5494ed2a5bfbc86ae36af57239c33f88dc0587f80f268904cec9ba
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 18, 2026.

Transparency log

Security for ddxdb 0.3.2

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.

Full provenance

All 6 files in this release have been uploaded with provenance metadata.

Select from 6 files

Attestation for ddxdb-0.3.2.tar.gz

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 18, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page