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.1

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.1
File Size Uploaded Provenance
ddxdb-0.3.1.tar.gz 243.7 kB With provenance Details

Built distributions (wheels)

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

Total release size: 28.4 MB

Release files / ddxdb-0.3.1.tar.gz

Download URL ddxdb-0.3.1.tar.gz
Size 243.7 kB
Tags Source
SHA-256 checksum
How to use checksums
0b802b49988c2c5f0b533d2158783f35974872c8f31f64c8d605b1954aad3915
BLAKE2b-256 checksum
How to use checksums
922f38fcdedeca223b36c5405488a6b22d761ed54a9f075b0269ef613ec59ad3
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.1-cp310-abi3-win_amd64.whl

Download URL ddxdb-0.3.1-cp310-abi3-win_amd64.whl
Size 5.8 MB
Tags CPython 3.10 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
9bbe1be1c0e9c7ce0fb58db2a29546d4b5d3f7618f51b63086798997a8c0212d
BLAKE2b-256 checksum
How to use checksums
0fc54decabefdf58229f11c6af3039107f0ab81539d29028e5ab218dfb40e78b
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.1-cp310-abi3-manylinux_2_28_x86_64.whl

Download URL ddxdb-0.3.1-cp310-abi3-manylinux_2_28_x86_64.whl
Size 5.8 MB
Tags CPython 3.10 Linux glibc 2.28+ x86-64 abi3
SHA-256 checksum
How to use checksums
5dcc6729267f550afc4ad2e355fcf6137b9e8a9d0a4cdd99ca01a894a3d05c7d
BLAKE2b-256 checksum
How to use checksums
ae8ccb411aeafa24c6cba9b87d8117fd6fd52813b2b10fe348fc916600a0b620
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.1-cp310-abi3-manylinux_2_28_aarch64.whl

Download URL ddxdb-0.3.1-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
973a3b7ae06aafa13c788c1fa413864bd76d0257a52e45f52aab7d1a1c666f2f
BLAKE2b-256 checksum
How to use checksums
a795fc23238cd938d75425f625d4c5b53e3bd13c63a86bcfebdf33b071c0e7a7
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.1-cp310-abi3-macosx_11_0_arm64.whl

Download URL ddxdb-0.3.1-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
747c94804b845ce7f6199f32db698dafcdb09732c4b2772b523d8348b8284490
BLAKE2b-256 checksum
How to use checksums
1461d5ab8a7cd943d592bb9897faf72cebcc9fa2cbf5508ed692f7a585fcca09
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.1-cp310-abi3-macosx_10_12_x86_64.whl

Download URL ddxdb-0.3.1-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
2ef6e491cbf813bc6e2b1473133bb23a3e391ebf5fd9c6899c0e068b2e30bb8c
BLAKE2b-256 checksum
How to use checksums
9b5add7e123933700207ab18d39cec8a6248353a75833a5f5957124a1cdfb718
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.1

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.1.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