Skip to content

Commit a426cfb

Browse files
committed
refactor!: reduce sql-transform to an unimplemented interface
Nuke the SQLTransform implementation entirely. What remains is the class, its method signatures, defaults and return types -- every body raises NotImplementedError naming itself. Deleted: the fit pipeline (_compose, _rewrite, _schema, _sql, _state, _transformer_ref) and their tests. With them went the last uses of datafusion, sqlglot and numpy, so those drop out of the package's dependencies -- it now needs only pyarrow and pydantic, the two types its signatures mention. Also deleted scripts/gen_datafusion_catalogue.py: datafusion is no longer installed anywhere in the workspace, so the generator could not run at all. Moved, not deleted: tests/test_serving_scenarios.py -> packages/confit/tests/. It is the three-way parity gate (confit == DuckDB == handcrafted twin) and never touched sql_transform; leaving it behind would have orphaned it in an empty package. The replacement tests assert shape, not behaviour: each method still exists with its exact parameter list, the properties are still properties, and every one raises. They fail if a method is dropped or renamed, and -- the failure mode a stub package invites -- if one quietly starts returning something. confit is untouched: 258 passed + 1 xfailed, cargo 168. Gate: pytest 270 passed + 1 xfailed, pre-commit clean, uv sync --locked clean.
1 parent 08574de commit a426cfb

21 files changed

Lines changed: 149 additions & 1590 deletions

README.md

Lines changed: 48 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,13 @@ This repository is a workspace of two packages:
1010
| package | what it is |
1111
|---|---|
1212
| [`packages/confit`](packages/confit) | **Confit** — the serving engine. SQL plus static tables frozen at fit time are partially evaluated, once, into a native function. Serves bit-exact with DuckDB or refuses at build time. Usable on its own. |
13-
| [`packages/sql-transform`](packages/sql-transform) | The authoring layer: `SQLTransform` — fit window-aggregate state from training data, then serve through Confit. |
13+
| [`packages/sql-transform`](packages/sql-transform) | The authoring surface: `SQLTransform`. **Not implemented** — signatures only, being rebuilt on Confit. |
1414

15-
> **sql-transform was reset.** The DataFusion-differentiated native engine, the
16-
> Python codegen backend, and the batch `transform()` path were removed; the
17-
> package is being rebuilt on Confit. Confit itself is unaffected.
15+
> **sql-transform is a stub.** Its implementation was deliberately removed --
16+
> the DataFusion engine, the codegen backend, the batch `transform()` path and
17+
> the fit pipeline are all gone. What remains is the interface, raising
18+
> `NotImplementedError`, as the contract for a rebuild on Confit.
19+
> **Confit itself is complete and unaffected.**
1820
1921
## Installation
2022

@@ -45,80 +47,67 @@ uv run pytest -q && cargo test --release
4547

4648
## Quick Start
4749

50+
Confit, the serving engine, works today:
51+
4852
```python
4953
import pyarrow as pa
50-
from sql_transform import SQLTransform
51-
52-
data = pa.table({
53-
"feature1": [1.0, 2.0, 3.0, 4.0, 5.0],
54-
"feature2": [10, 20, 30, 40, 50],
55-
})
56-
57-
# The input table is always referenced as __THIS__.
58-
sql = """
59-
SELECT
60-
feature1 / MEAN(feature1) OVER () AS feature1_norm,
61-
feature2 / SUM(feature2) OVER () AS feature2_share
62-
FROM __THIS__
63-
"""
64-
65-
t = SQLTransform(sql)
66-
t.fit(data)
67-
68-
# Serving: dict or Pydantic model in, typed model out.
69-
one = t.infer({"feature1": 2.0, "feature2": 20})
70-
print(one.feature1_norm)
71-
many = t.infer_batch([{"feature1": 2.0, "feature2": 20}])
54+
from pydantic import BaseModel
55+
from confit import DuckDBInferFn
56+
57+
class Row(BaseModel):
58+
age: float
59+
60+
fn = DuckDBInferFn(
61+
"SELECT (age - 30.0) / 10.0 AS age_z FROM __THIS__",
62+
row_tables={"__THIS__": Row},
63+
static_tables={},
64+
shape="map",
65+
)
66+
fn.infer_rows([Row(age=40.0)]) # row objects in, row objects out
67+
fn.infer_arrow(pa.table({"age": [40.0]})) # pa.Table in, pa.Table out
7268
```
7369

74-
Per-group statistics use `OVER (PARTITION BY ...)` — the group means/counts are
75-
frozen at `fit` and looked up per row at inference:
76-
77-
```python
78-
sql = "SELECT target / MEAN(target) OVER (PARTITION BY city) AS enc FROM __THIS__"
79-
```
70+
`sql_transform.SQLTransform` is the intended authoring layer on top of it --
71+
write SQL with window aggregates, `fit()` to freeze them, then serve. It is
72+
currently **not implemented**; see [packages/sql-transform](packages/sql-transform).
8073

8174
## Architecture
8275

83-
Two phases, one rewritten query:
76+
The intended two-phase shape, of which **only the second phase exists today**:
8477

8578
```
8679
SQL over __THIS__
8780
8881
89-
fit(train) ── DataFusion runs the SQL, freezes each window aggregate (e.g.
90-
│ MEAN(age)) into a typed __STATE__ table, and rewrites the SQL
91-
│ to reference __STATE__ + the raw row __THIS__ instead of
92-
│ recomputing aggregates.
82+
fit(train) ── freeze each window aggregate (e.g. MEAN(age)) into a typed
83+
│ __STATE__ table and rewrite the SQL to reference it instead
84+
│ of recomputing. [NOT IMPLEMENTED]
9385
9486
│ rewritten SQL + frozen state
9587
96-
Confit ── partially evaluates the pair into a native function:
97-
binding-time analysis collapses every static lookup into a
98-
prepare-time probe, so nothing general remains at call time.
88+
Confit ── partially evaluates the pair into a native function: binding-time
89+
│ analysis collapses every static lookup into a prepare-time probe,
90+
│ so nothing general remains at call time. [WORKS]
9991
10092
infer(row) / infer_batch(rows)
10193
```
10294

103-
`fit` pays for a real query engine once; serving pays only for straight-line
104-
native code over the frozen state. Confit's contract carries through: the fitted
105-
SQL either serves bit-exact with DuckDB, or `fit()` raises and names the
106-
construct it will not serve — see
107-
[Confit's known limitations](docs/known-limitations.md).
108-
109-
## What it supports
110-
111-
- **Window aggregates**, computed once at `fit` and frozen: whole-table `OVER ()`
112-
and per-group `OVER (PARTITION BY ...)` (`MEAN`, `SUM`, `COUNT`, `STDDEV`, …).
113-
- **Everything Confit serves** at inference — the expression surface, joins to
114-
static tables, and the row-shape contract are documented in
115-
[`packages/confit`](packages/confit) and
116-
[docs/known-limitations.md](docs/known-limitations.md).
117-
- **Typed I/O**: Pydantic models for the input row and output, validated when the
118-
transform is fitted and again at call time.
119-
120-
Not currently supported, pending the rebuild: batch `transform()`, sklearn
121-
transformer references, and composing one `SQLTransform` into another.
95+
Confit's contract: SQL plus frozen tables either specialize into a function
96+
bit-exact with DuckDB, or construction raises and names the construct it will
97+
not serve — see [Confit's known limitations](docs/known-limitations.md).
98+
99+
## What Confit supports
100+
101+
The expression surface, joins to static tables, the row-shape contract
102+
(`map`/`filter`/`many`) and the Arrow boundary are documented in
103+
[`packages/confit`](packages/confit) and
104+
[docs/known-limitations.md](docs/known-limitations.md): **550 of 678** statements
105+
mined from DuckDB's own test suite replay bit-exact, with the remainder clean,
106+
named build-time rejections.
107+
108+
The authoring layer on top — window-aggregate `fit`, typed I/O, sklearn
109+
transformer references, and composing one transform into another — is what the
110+
rebuild has to supply.
122111

123112
## Reports
124113

File renamed without changes.

packages/sql-transform/README.md

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,29 @@
11
# sql-transform
22

3-
SQL feature transforms, fitted once and served by [Confit](../confit).
3+
The authoring surface for SQL feature transforms — **not implemented**.
44

55
```python
66
from sql_transform import SQLTransform
77

8-
t = SQLTransform("SELECT (age - avg(age) OVER ()) AS age_c FROM __THIS__")
9-
t.fit(train_table)
10-
t.infer({"age": 40})
8+
t = SQLTransform(sql) # NotImplementedError
119
```
1210

13-
`fit()` runs the SQL over training data to freeze each window aggregate into a
14-
static table, rewrites the SQL into plain-column form, and hands the pair to
15-
Confit, which partially evaluates them into a native serving function.
11+
Every method raises `NotImplementedError`. The signatures, defaults and return
12+
types are all that remain, and they are the contract a rebuild has to satisfy:
1613

17-
**This package was reset.** The DataFusion-differentiated native engine, the
18-
Python codegen backend, and the batch `transform()` path have been removed; what
19-
remains is the fit-and-serve path built on Confit. Composing one transform into
20-
another (`t"... {other}(col) ..."`) is kept as a surface but refuses by name
21-
until it is rebuilt.
14+
| method | intended behaviour |
15+
|---|---|
16+
| `SQLTransform(sql)` | accept SQL (or a t-string) over `__THIS__` |
17+
| `from_file(path)` | same, read from a file |
18+
| `fit(table, this_model=None)` | freeze window-aggregate state into static tables, rewrite the SQL to reference them, specialize via Confit; returns self |
19+
| `infer(row)` / `infer_batch(rows)` | serve rows through the specialized function |
20+
| `backend` / `boundary` | report which engine and boundary the fitted function uses |
21+
22+
The serving half already exists and is unaffected: [Confit](../confit) takes SQL
23+
plus frozen static tables and partially evaluates them into a native function,
24+
bit-exact with DuckDB or refusing at build time. What was removed here is the
25+
fit half, the DataFusion batch engine, the codegen backend, and transform
26+
composition.
27+
28+
Tests in this package assert only that the surface exists and refuses honestly —
29+
they fail if a method is dropped, renamed, or quietly starts returning something.
Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,16 @@
11
[project]
22
name = "sql-transform"
33
version = "0.1.0"
4-
description = "SQL feature transforms, fitted once and served by Confit"
4+
description = "SQL feature transforms — authoring surface, being rebuilt on Confit"
55
readme = "README.md"
66
requires-python = ">=3.14"
7+
# Only what the surface itself references. The fit-time engine (datafusion,
8+
# sqlglot, numpy) went with the implementation; add back what the rebuild needs.
79
dependencies = [
8-
"confit",
9-
"datafusion>=46.0.0",
10-
"numpy>=2.0",
1110
"pyarrow>=19.0",
1211
"pydantic>=2.0,<3.0",
13-
"sqlglot>=30.12.0",
1412
]
1513

16-
[tool.uv.sources]
17-
confit = { workspace = true }
18-
19-
# Pure Python: the native engine is confit's. This package fits state and
20-
# hands the pair to it.
2114
[build-system]
2215
requires = ["hatchling"]
2316
build-backend = "hatchling.build"
@@ -27,7 +20,4 @@ packages = ["sql_transform"]
2720

2821
[tool.pytest.ini_options]
2922
python_files = ["*_test.py", "test_*.py"]
30-
# The repo-root `benchmarks` package carries the shared serving-scenario
31-
# parity fixtures used by these tests.
32-
pythonpath = ["../.."]
33-
testpaths = ["tests", "sql_transform"]
23+
testpaths = ["sql_transform"]

packages/sql-transform/sql_transform/__init__.py

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,11 @@
1-
"""SQLTransform — SQL feature transforms, fitted once and served by Confit.
1+
"""SQLTransform — the authoring surface, awaiting reimplementation.
22
3-
Author the transform as SQL, `fit()` it against training data to freeze the
4-
window-aggregate state into static tables, then serve it row-at-a-time:
3+
Every method raises `NotImplementedError`. The signatures are the contract a
4+
rebuild has to satisfy; the previous implementation (a DataFusion batch engine,
5+
a codegen backend, and transform composition) was deleted deliberately.
56
6-
t = SQLTransform("SELECT (age - avg(age) OVER ()) AS age_c FROM __THIS__")
7-
t.fit(train_table)
8-
t.infer({"age": 40})
9-
10-
`fit()` hands the rewritten SQL and the frozen tables to Confit
11-
(`packages/confit`), which partially evaluates the pair into a native
12-
function. Confit's contract carries through: the fitted SQL either serves
13-
bit-exact with DuckDB, or `fit()` raises and names the construct it will not
14-
serve.
7+
The serving half already exists and is unaffected: confit takes SQL plus static
8+
tables frozen at fit time and partially evaluates them into a native function.
159
"""
1610

1711
from __future__ import annotations

packages/sql-transform/sql_transform/_compose.py

Lines changed: 0 additions & 102 deletions
This file was deleted.

packages/sql-transform/sql_transform/_compose_test.py

Lines changed: 0 additions & 49 deletions
This file was deleted.

0 commit comments

Comments
 (0)