Skip to content

Commit 390c20e

Browse files
committed
Pin exact SQL service versions
1 parent 74e11ab commit 390c20e

9 files changed

Lines changed: 174 additions & 45 deletions

File tree

‎.github/workflows/ci.yml‎

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ jobs:
2020
uses: actions/checkout@v7
2121
with: &specification-checkout
2222
repository: OpenStatSpec/specification
23-
ref: fef0dc6f4b17ff7141dad3f49d0524c63efbfed5
23+
ref: e94ae8349d2b0dffe0c65e820b4b22b8c074b7b5
2424
path: openstatspec-specification
2525
- name: Checkout required SPSS engine
2626
uses: actions/checkout@v7
@@ -63,7 +63,7 @@ jobs:
6363
strategy:
6464
fail-fast: false
6565
matrix:
66-
postgres: ["17", "18"]
66+
postgres: ["17.10", "18.4"]
6767
services:
6868
postgres:
6969
image: postgres:${{ matrix.postgres }}
@@ -77,6 +77,7 @@ jobs:
7777
--health-interval 10s --health-timeout 5s --health-retries 5
7878
env:
7979
OPENSTATSPEC_POSTGRES_URL: postgresql+psycopg://openstatspec:openstatspec@localhost:5432/openstatspec
80+
OPENSTATSPEC_EXPECTED_POSTGRES_VERSION: ${{ matrix.postgres }}
8081
steps: &sql-test-steps
8182
- uses: actions/checkout@v7
8283
- name: Checkout OpenStatSpec specification fixtures
@@ -99,7 +100,7 @@ jobs:
99100
strategy:
100101
fail-fast: false
101102
matrix:
102-
mysql: ["8.4", "9.7"]
103+
mysql: ["8.4.11", "9.7.2"]
103104
services:
104105
mysql:
105106
image: mysql:${{ matrix.mysql }}
@@ -114,6 +115,7 @@ jobs:
114115
--health-interval 10s --health-timeout 5s --health-retries 10
115116
env:
116117
OPENSTATSPEC_MYSQL_URL: mysql+pymysql://openstatspec:openstatspec@localhost:3306/openstatspec
118+
OPENSTATSPEC_EXPECTED_MYSQL_VERSION: ${{ matrix.mysql }}
117119
steps: *sql-test-steps
118120

119121
mariadb-integration:
@@ -122,7 +124,7 @@ jobs:
122124
strategy:
123125
fail-fast: false
124126
matrix:
125-
mariadb: ["11.4", "11.8", "12.3"]
127+
mariadb: ["11.4.12", "11.8.8", "12.3.2"]
126128
services:
127129
mariadb:
128130
image: mariadb:${{ matrix.mariadb }}
@@ -137,6 +139,7 @@ jobs:
137139
--health-interval 10s --health-timeout 5s --health-retries 10
138140
env:
139141
OPENSTATSPEC_MARIADB_URL: mysql+pymysql://openstatspec:openstatspec@localhost:3306/openstatspec
142+
OPENSTATSPEC_EXPECTED_MARIADB_VERSION: ${{ matrix.mariadb }}
140143
steps: *sql-test-steps
141144

142145
dolt-integration:

‎.github/workflows/release.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ jobs:
4747
uses: actions/checkout@v7
4848
with:
4949
repository: OpenStatSpec/specification
50-
ref: fef0dc6f4b17ff7141dad3f49d0524c63efbfed5
50+
ref: e94ae8349d2b0dffe0c65e820b4b22b8c074b7b5
5151
path: openstatspec-specification
5252
- name: Checkout required SPSS engine
5353
uses: actions/checkout@v7

‎CHANGELOG.md‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,25 @@
22

33
All notable changes to this reference implementation are documented here.
44

5+
## Unreleased
6+
7+
### Changed
8+
9+
- SQL server support now distinguishes conservative family claims from exact
10+
CI evidence: PostgreSQL 17.x/18.x at 17.10/18.4, MySQL 8.4.x/9.7.x at
11+
8.4.11/9.7.2, and MariaDB 11.4.x/11.8.x/12.3.x at
12+
11.4.12/11.8.8/12.3.2. Each service job verifies the live normalized version.
13+
- Dolt remains independently pinned and service-tested at exact version 2.2.2.
14+
SQLite retains its core `>=3.24.0,<4.0.0` and optional workflow
15+
`>=3.35.0,<4.0.0` tiers. MSSQL remains unsupported and roadmap-only.
16+
17+
### Specification basis
18+
19+
- CI, release validation, and machine-readable capabilities use untagged
20+
OpenStatSpec specification `main` commit
21+
`e94ae8349d2b0dffe0c65e820b4b22b8c074b7b5`; the specification release value
22+
is null until that commit is tagged.
23+
524
## 0.2.0 — 2026-07-30
625

726
This release extends the reference adapter while keeping imported source

‎README.md‎

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,18 @@ derived datasets through a public catalog API. It uses a separate profile
5050
catalog and never presents SQL output as an imported source dataset.
5151
Workflow operations support SQLite only in this milestone and fail closed on
5252
PostgreSQL/MySQL/MariaDB; core import/export database support is unchanged.
53+
The core SQLite import/export profile accepts SQLite `>=3.24.0,<4.0.0`; the
54+
optional transformation workflow deliberately has the narrower
55+
`>=3.35.0,<4.0.0` runtime preflight. These independent tiers do not change the
56+
server-profile matrix. Microsoft SQL Server is not supported; its future
57+
dialect is scoped only in the specification's
58+
[MSSQL roadmap](https://github.com/OpenStatSpec/specification/blob/main/docs/mssql-dialect-roadmap.md).
5359

5460
See [the SQL transformation workflow](docs/sql-transformation-workflow.md) for
5561
Python and CLI examples, migration behavior, hashing, atomicity, and the exact
5662
implemented capability boundary.
5763

58-
## 0.2.0 support status
64+
## Current support status
5965

6066
The adapter requires `openstatspec-pyspssio==0.5.1.post2` as its sole SPSS
6167
engine. Its import module remains `pyspssio`; the exact source commit is recorded
@@ -64,7 +70,17 @@ SAV/ZSAV export for the semantics exposed by that engine. SQLite is the local
6470
reference path.
6571
PostgreSQL, MySQL, MariaDB, and Dolt are each covered by separate service-backed CI
6672
conformance checks. Dolt support is an independent core profile pinned to 2.2.2;
67-
other Dolt versions and unknown MySQL-wire products fail closed. Use these explicit SQLAlchemy URLs:
73+
other Dolt versions and unknown MySQL-wire products fail closed.
74+
75+
The supported family claims are broader than the deliberately exact CI
76+
evidence points: PostgreSQL 17.x/18.x is exercised at 17.10/18.4, MySQL
77+
8.4.x/9.7.x at 8.4.11/9.7.2, and MariaDB 11.4.x/11.8.x/12.3.x at
78+
11.4.12/11.8.8/12.3.2. Each service job checks the normalized live server
79+
version against its exact matrix entry before that run can count as evidence.
80+
Dolt remains a separate exact-version policy: its only claimed and CI-tested
81+
version is 2.2.2.
82+
83+
Use these explicit SQLAlchemy URLs:
6884

6985
- SQLite: `sqlite:///dataset.sqlite`
7086
- PostgreSQL: `postgresql+psycopg://user:password@host/database`

‎docs/release-readiness.md‎

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# 0.2.0 release readiness
1+
# Next release readiness
22

33
This page records the expected release contract, not a publication event.
44
Creating a version tag remains a separate maintainer action.
@@ -14,13 +14,13 @@ database contract.
1414

1515
## SQL profiles
1616

17-
| Profile | Connection URL | Verification |
18-
| --- | --- | --- |
19-
| SQLite | `sqlite:///dataset.sqlite` | Python 3.11–3.14 local reference jobs |
20-
| PostgreSQL | `postgresql+psycopg://…` | PostgreSQL 17 and 18 service jobs |
21-
| MySQL | `mysql+pymysql://…` | MySQL 8.4 and 9.7 service jobs |
22-
| MariaDB | `mysql+pymysql://…` | MariaDB 11.4, 11.8, and 12.3 service jobs |
23-
| Dolt | `mysql+pymysql://…` | Exact Dolt 2.2.2 service job |
17+
| Profile | Connection URL | Claimed versions | Exact CI evidence |
18+
| --- | --- | --- | --- |
19+
| SQLite | `sqlite:///dataset.sqlite` | `>=3.24.0,<4.0.0` | Active Python 3.11–3.14 runner version |
20+
| PostgreSQL | `postgresql+psycopg://…` | 17.x and 18.x | 17.10 and 18.4 |
21+
| MySQL | `mysql+pymysql://…` | 8.4.x and 9.7.x | 8.4.11 and 9.7.2 |
22+
| MariaDB | `mysql+pymysql://…` | 11.4.x, 11.8.x, and 12.3.x | 11.4.12, 11.8.8, and 12.3.2 |
23+
| Dolt | `mysql+pymysql://…` | Exact 2.2.2 | Exact 2.2.2 |
2424

2525
Separate service matrices test the shared MySQL/MariaDB profile contract while
2626
retaining distinct active-server identities and version claims. Dolt is an
@@ -29,6 +29,15 @@ independent core profile that fails closed unless the product version is exactly
2929
claim coverage for every server configuration. The machine-readable capability
3030
declaration reports both the theoretical profile boundaries and effective
3131
limits observed from the active connection.
32+
Every server service job compares the normalized live product version with its
33+
exact matrix entry, so a moved or mismatched image cannot substantiate the CI
34+
declaration. SQLite's optional Transformation Workflow retains its narrower
35+
`>=3.35.0,<4.0.0` live preflight alongside the core `>=3.24.0,<4.0.0` policy.
36+
Microsoft SQL Server remains unsupported and must not appear in runtime
37+
capabilities; future implementation requirements are documented in the
38+
specification's
39+
[MSSQL dialect roadmap](https://github.com/OpenStatSpec/specification/blob/main/docs/mssql-dialect-roadmap.md).
40+
3241

3342
## Export-loss policy
3443

@@ -53,14 +62,15 @@ machine-readable loss report with the export result.
5362
first and confirm that a clean environment can download it from PyPI. The
5463
main package has no fallback SPSS engine.
5564
2. Run `python -m pytest -m "not services"`.
56-
3. Confirm the GitHub Actions matrix is green for PostgreSQL 17/18, MySQL
57-
8.4/9.7, MariaDB 11.4/11.8/12.3, and exact Dolt 2.2.2.
65+
3. Confirm the GitHub Actions matrix is green for exact PostgreSQL 17.10/18.4,
66+
MySQL 8.4.11/9.7.2, MariaDB 11.4.12/11.8.8/12.3.2, and exact Dolt
67+
2.2.2 service evidence.
5868
4. Build with `python -m build` and install the generated wheel in a clean
5969
environment.
6070
5. Confirm `openstatspec capabilities` reflects the intended support boundary.
61-
6. Confirm the `v0.2.0` tag matches package version `0.2.0`, and that CI and
62-
release fixtures use specification release `v1.0.0-rc.1` at exact commit
63-
`fef0dc6f4b17ff7141dad3f49d0524c63efbfed5`.
71+
6. Confirm the release tag matches the package version and that CI, release
72+
fixtures, and capabilities use untagged specification `main` commit
73+
`e94ae8349d2b0dffe0c65e820b4b22b8c074b7b5` with a null release value.
6474
7. Review this document, the README, and CHANGELOG for accurate scope.
6575

6676
The tag-triggered release workflow repeats the non-service test suite, builds

‎docs/sav-profile.md‎

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,25 @@ unencrypted .sav and .zsav files, and writes both formats through the same imple
1515

1616
SQLite has a local reference fixture. PostgreSQL, MySQL, MariaDB, and Dolt have
1717
separate service-backed conformance checks in GitHub Actions that import,
18-
validate, and export the supported fixture. Dolt is an independent core profile
19-
pinned to exact server version 2.2.2 and detected over `mysql+pymysql` by active
20-
server identity; other Dolt versions and unknown MySQL-wire products fail closed.
21-
The core Dolt profile does not claim support for the separate Transformation
22-
Workflow. An import that exceeds a target's strict single-table column or row
23-
envelope fails before it creates a dataset.
18+
validate, and export the supported fixture. The family claims and exact CI
19+
points are PostgreSQL 17.x/18.x at 17.10/18.4, MySQL 8.4.x/9.7.x at
20+
8.4.11/9.7.2, and MariaDB 11.4.x/11.8.x/12.3.x at
21+
11.4.12/11.8.8/12.3.2. CI compares each live normalized server version with
22+
that exact evidence point.
23+
24+
Dolt is an independent core profile pinned to exact server version 2.2.2 and
25+
detected over `mysql+pymysql` by active server identity; other Dolt versions
26+
and unknown MySQL-wire products fail closed. The core Dolt profile does not
27+
claim support for the separate Transformation Workflow. An import that exceeds
28+
a target's strict single-table column or row envelope fails before it creates a
29+
dataset.
30+
31+
The core SQLite profile remains `>=3.24.0,<4.0.0`; only the optional
32+
Transformation Workflow requires `>=3.35.0,<4.0.0`. Microsoft SQL Server is
33+
not a supported profile. Its driver, SQL-difference, preflight, CI,
34+
conformance, security, and atomicity work is future scope in the
35+
specification's
36+
[MSSQL dialect roadmap](https://github.com/OpenStatSpec/specification/blob/main/docs/mssql-dialect-roadmap.md).
2437

2538
## Fidelity contract
2639

‎src/openstatspec/sql/capabilities.py‎

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@
1515
from .profiles import profile_for_url, validate_connection_url
1616
from ..core import UnsupportedOperationError
1717

18-
SPECIFICATION_COMMIT = "fef0dc6f4b17ff7141dad3f49d0524c63efbfed5"
19-
SPECIFICATION_RELEASE: str | None = "v1.0.0-rc.1"
18+
SPECIFICATION_COMMIT = "e94ae8349d2b0dffe0c65e820b4b22b8c074b7b5"
19+
SPECIFICATION_RELEASE: str | None = None
2020

2121
SERVER_POLICIES = {
2222
"sqlite": {
@@ -25,19 +25,19 @@
2525
},
2626
"mysql": {
2727
"claimed": ["MySQL 8.4.x", "MySQL 9.7.x"],
28-
"ci": ["MySQL 8.4.x", "MySQL 9.7.x"],
28+
"ci": ["MySQL 8.4.11", "MySQL 9.7.2"],
2929
},
3030
"dolt": {
3131
"claimed": ["Dolt 2.2.2"],
3232
"ci": ["Dolt 2.2.2"],
3333
},
3434
"mariadb": {
3535
"claimed": ["MariaDB 11.4.x", "MariaDB 11.8.x", "MariaDB 12.3.x"],
36-
"ci": ["MariaDB 11.4.x", "MariaDB 11.8.x", "MariaDB 12.3.x"],
36+
"ci": ["MariaDB 11.4.12", "MariaDB 11.8.8", "MariaDB 12.3.2"],
3737
},
3838
"postgresql": {
3939
"claimed": ["PostgreSQL 17.x", "PostgreSQL 18.x"],
40-
"ci": ["PostgreSQL 17.x", "PostgreSQL 18.x"],
40+
"ci": ["PostgreSQL 17.10", "PostgreSQL 18.4"],
4141
},
4242
}
4343

@@ -155,7 +155,7 @@ def active_connection(database_url: str) -> dict[str, Any]:
155155
"product": profile_name,
156156
"transport": "mysql" if dialect in {"mysql", "mariadb"} else dialect,
157157
"driver": engine.dialect.driver,
158-
"server_version": _normalized_version(raw_product_version),
158+
"server_version": _normalized_version(profile_name, raw_product_version),
159159
"raw_server_version": raw_product_version,
160160
"raw_wire_version": raw_wire_version,
161161
"raw_product_version": raw_product_version,
@@ -422,5 +422,8 @@ def _version_tuple(raw_version: str) -> tuple[int, ...]:
422422
return tuple(int(part) for part in match.groups(default="0"))
423423

424424

425-
def _normalized_version(raw_version: str) -> str:
426-
return ".".join(str(part) for part in _version_tuple(raw_version))
425+
def _normalized_version(profile: str, raw_version: str) -> str:
426+
"""Normalize a product version using that product's stable release width."""
427+
version = _version_tuple(raw_version)
428+
width = 2 if profile == "postgresql" else 3
429+
return ".".join(str(part) for part in version[:width])

‎tests/test_cli.py‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ def test_cli_import_inspect_validate_and_export_emit_json(tmp_path, capsys) -> N
3939
def test_capability_matrix_is_public_and_cli_matches_engine_boundary(capsys) -> None:
4040
matrix = openstatspec.capability_matrix()
4141
assert matrix["specification_status"] == "release_candidate"
42-
assert matrix["specification_release"] == "v1.0.0-rc.1"
43-
assert matrix["specification_commit"] == "fef0dc6f4b17ff7141dad3f49d0524c63efbfed5"
42+
assert matrix["specification_release"] is None
43+
assert matrix["specification_commit"] == "e94ae8349d2b0dffe0c65e820b4b22b8c074b7b5"
4444
assert matrix["directions"] == ["import", "export", "semantic_round_trip"]
4545
assert matrix["active_connection"] is None
4646
assert matrix["engine"]["package"] == "openstatspec-pyspssio"

0 commit comments

Comments
 (0)