Skip to content

v0.6.1

Choose a tag to compare

@github-actions github-actions released this 14 Oct 13:59
· 326 commits to main since this release
9fd28ad

Changelog

All notable changes to this project will be documented in this file.

[0.6.1] - 2026-10-14

πŸš€ Features

  • (46-02) Async query path end to end β€” AsyncEngine, AsyncSemolinaCursor, create_async_engine
  • (46-02) Complete the async cursor result surface and cover close ordering
  • (46-04) Add separate async engine registry with async-aware reset
  • (46-04) Add _Query.aexecute and export the async surface (ASYNC-02)
  • (47-01) Measure one DuckDB decimal metric end to end
  • (47-02) Widen the DuckDB probe to every field and name the disagreements
  • (47-02) Measure the downstream Decimal consumers instead of assuming them
  • (47-03) Probe Snowflake and Databricks result schemas from copied cassettes
  • (47-03) Add the Snowflake and Databricks rows, driver capability, and evidence limits
  • (48-01) DuckDB DECIMAL maps to decimal.Decimal; metrics annotate T | None
  • (48-01) Preserve the raw warehouse type in generated source (D-03)
  • (48-03) Apply the Decimal policy to Snowflake and Databricks (TYPE-03)
  • (48-03) Concrete types for every category-1 map gap (TYPE-05)
  • (48-03) Add the public semolina.JsonValue type alias (TYPE-06)
  • (48-03) Map VARIANT to the JsonValue union (TYPE-06)
  • (48-04) Promote probe_schema and ProbeResult into src/semolina/codegen/probe.py
  • (48-04) Arrow_type_to_python β€” the Arrow-to-annotation mapper (TYPE-07)
  • (48-05) Read a committed model's annotations without importing it
  • (48-05) Compare committed annotations against the probed result schema
  • (48-05) Wire semolina codegen --check --model with exit code 5
  • (49-01) .into(DTO) on the sync cursor with a structural schema pre-check
  • (49-02) Iter_into β€” check at the call, produce lazily
  • (49-05) Fetch_df and fetch_polars, guarded for what each actually imports
  • (49-06) Async into and iter_into on AsyncSemolinaCursor
  • (49-06) Async fetch_df / fetch_polars, and the four async guards
  • (49) Respect hand-authored coercions β€” gate the type check on validate=False
  • (50-02) Generate a typed Pydantic DTO from a query's probed result schema
  • (50-03) Per-class provenance and deferred annotations in generated DTOs
  • (50-06) Add the codegen-dto command and its exit-code epilog
  • (codegen-dto) Generate a DTO from a view, or from pyproject.toml
  • (codegen-dto) Add --check, so a committed DTO can be verified in CI
  • (config) Build, register and scope an engine in one call
  • Support model inheritance and abstract=True bases (52-06)

πŸ› Bug Fixes

  • (46) Let aclose() own the reader fetch_record_batch() hands out
  • (46) Stop async iteration cleanly on an already-drained stream
  • (46) Report a failed check-in as a ResourceWarning (WR-01)
  • (46) Guard the undocumented AsyncPool inner-pool access (WR-05)
  • (46) Clear both registries in a finally so reset() cannot strand them (WR-04)
  • (46) Bump duckdb to 1.5.5 for semantic_views 0.12.0, closing the ASYNC-06 gap
  • (47) WR-01 resolve the type-fidelity artifact through milestone archival
  • (47) WR-02 escape table cells so a pipe cannot misalign the circularity guard
  • (47) WR-03 refuse an empty field request instead of emitting a trailing comma
  • (48-01) Refuse DuckDB container types before stripping type parameters
  • (48-02) Render date, datetime and Decimal SQL literals (DBX-04)
  • (48) CR-01 render drift-report cells as Text so rich cannot parse them as markup
  • (48) CR-02 route every semantic_view() name through one shared SQL escaper
  • (48) CR-03 emit warehouse metadata as pre-quoted Python literals in generated models
  • (48) WR-01 compare the field role and the resolved column, not the annotation alone
  • (48) WR-02 guard fetch_record_batch by proxying its reader, not refusing the call
  • (48) WR-03 move probe setup inside the try that promises a fallback, not a crash
  • (48) WR-04 pair each probed schema with its own route and label unprobed rows
  • (48) WR-06 tell a duplicated result column apart from an absent one
  • (48) IN-01 resolve run-end-encoded columns through their value type
  • (48) IN-02 anchor the Snowflake cassette path on the test file, not the cwd
  • (49-07) Make [arrowmodel] extra compose semolina[pyarrow]
  • (49) Make [pandas] extra compose semolina[pyarrow]
  • (50-01) Derive a metric's result-column name from the dialect
  • (50-02) A provenance header can no longer name a backend that did not answer
  • (50-06) Unbreak just docs-build on the dto_codegen module docstring
  • (50) CR-01 validate the generated class name as a Python identifier
  • (50) Upper-case inside the quotes in SnowflakeDialect.metric_result_column_name
  • (50) Map a driver connection failure onto exit 4 in both codegen commands
  • (48) Annotate Databricks decimal and interval as the driver returns (GREEN)
  • (49) CR-01 accept every column key arrowmodel would, not just the first
  • (49) WR-01 refuse AliasChoices / AliasPath at the pre-check
  • (49) WR-02 refuse alias_generator by name, and document all three constructs
  • (49) WR-03 normalise a creation-time OSError in sync iter_into
  • (49) WR-04 close the three holes in the narrowed content fence
  • (49) WR-05 make the path fence runnable, and fatal, in CI
  • (49) IN-01 give the missing-column line its own sentence
  • (49) IN-02 treat a duplicated result column as unresolvable, as the converter does
  • (49) IN-04 list the arrowmodel and pydantic errors, and close the None-description hole
  • (49) IN-06 spell DEFAULT_BASE_REF as the full 40-character SHA
  • (codegen) Let a generated DTO be built from its field names
  • (engines) Drop the registry name only while it still points at this engine
  • (codegen) Refuse a leading-underscore field name with the way out
  • (scope-fence) Skip the base-ref premise check outside CI, fail it inside
  • (release) Compare the wheel's version to the tag as PEP 440, not as a string
  • (results) Make Row copyable, hashable and a real Mapping
  • (query) Compare OrderTerm and query by field identity, not by predicate
  • In_() owns its values, engines validate, no duplicate columns (52-03)
  • Cursor parity β€” safe close, one read per cursor, pyarrow guards (52-04)
  • Refuse a timestamp column into a date field on the fast path (52-05)
  • Keep a removed field removed down an inheritance chain (52-06)
  • (release) Grant the CI call the permissions ci.yml requests

🚜 Refactor

  • (47) IN-01 delete the unused collect_rows() aggregator
  • (48) WR-01 give FieldCheckRow a detail column for non-annotation drift
  • (50) WR-02 drop render_dtos' unreachable command parameter
  • (codegen) Derive the Arrow annotation from the runtime type

πŸ“š Documentation

  • (planning) Backlog todo β€” reduce register()/create_engine() redundancy
  • (planning) Refresh async todo with ADBC GIL-release findings
  • (planning) Async machinery belongs in adbc-poolhouse, not Semolina
  • (planning) Anyio posture for Semolina async layer
  • (planning) Async unblocked β€” adbc-poolhouse 1.5.0 ships the async stack
  • (planning) Backlog todo β€” arrowmodel typed-DTO integration + scrutiny
  • (planning) Research todo β€” warehouse type fidelity for field typing
  • (planning) Record untyped-fallback policy on type-fidelity todo
  • (planning) Untypeable-case taxonomy + VARIANT->JsonValue decision
  • (planning) Probe mechanics + timing model on type-fidelity todo
  • Start milestone v0.7 Async & Typed Results
  • Define milestone v0.7 requirements
  • Create milestone v0.7 roadmap (5 phases)
  • Tag 5 pending todos with resolves_phase after milestone v0.7 roadmap
  • Archive v0.5/v0.6 phase directories to milestones/v0.6-phases
  • (planning) Phase 46 context β€” async engine architecture decisions
  • (46) Research async query surface domain
  • (46) Add validation strategy
  • (46) Create phase plan β€” 7 plans, 5 waves, tracer-first async query surface
  • (46) Add pattern map
  • (46) Create phase plan
  • (46-01) Complete async packaging and Posture A lint plan
  • (46-02) Complete async engine and cursor plan
  • (46-03) Complete async cassette replay spike plan
  • (46-04) Complete async registry & query entry point plan
  • (46-06) Document async endpoints and async row streaming
  • (46-06) Document the async extra and the async engine surface
  • (46-06) Complete async documentation plan
  • (46-05) Complete cancellation proof and loop-matrix gate plan
  • (46-07) Record the phase gate result and close phase 46
  • (46) Correct the claim that a pre-cancelled aexecute proves check-in
  • (46) Tear the test fixture down with engine.dispose()
  • (46) Name the real adbc-poolhouse floor, 1.6.2
  • (46) Correct STATE.md β€” phase 46 is executed, not complete
  • (46) Plan 46-08 β€” gap closure for the unwritten cancellation docs
  • (46) Record gap-closure planning and correct stale STATE.md narrative
  • (46-08) Document timing out a slow query on the async path
  • (46-08) Document client disconnects and cancelling a stream mid-iteration
  • (46-08) Complete cancellation-docs gap-closure plan
  • (phase-46) Complete phase execution
  • (phase-46) Close resolved todos and evolve PROJECT.md
  • (phase-46) Correct plan count on the ROADMAP checkbox line
  • (47) Create phase plan
  • (47) Record planning completion and pattern map
  • (47-01) Complete type-fidelity probe tracer plan
  • (47-02) Complete named-disagreements plan
  • (47-03) Complete the Snowflake, Databricks, and driver-capability plan
  • (47-04) Explain warehouse type fidelity and why money is a Decimal
  • (47-04) Complete the type-mapping decision doc plan
  • (phase-47) Complete phase execution
  • (48) Create phase plan β€” 6 plans across 4 waves
  • (48) Create phase plan
  • (48-01) Complete type map tracer & renderer seams plan
  • (48-02) Complete databricks date/datetime/Decimal literals plan
  • (48-03) Complete type map implementation plan
  • (48-04) Complete probe promotion and arrow map plan
  • (48-05) Complete the codegen --check plan
  • (48-06) Replace the type-fidelity note Phase 48 falsified
  • (48-06) Document codegen --check and correct the VARIANT claim
  • (48-06) Complete documentation realignment and phase gate plan
  • (48) WR-05 correct exit code 2 in both places and document the new report rows
  • (49) Reword DTO-05 - pydantic is already a base dependency via adbc-poolhouse
  • (state) Record phase 49 context session
  • (49) Create phase plan β€” 7 plans, 4 waves
  • (49) Create phase plan
  • (49-01) Complete .into(DTO) tracer plan
  • (49-03) Complete polars measurement and A3 closure plan
  • (49-02) Complete iter_into plan
  • (49-04) Complete packaging contract plan
  • (49-05) Complete fetch_df and fetch_polars plan
  • (49-06) Record plan 06 state, roadmap progress and requirements
  • (49-07) Add the typed-results how-to with a worked BI example
  • (49-07) Point arrow-output, streaming and installation at the new surface
  • (49-07) Explain what the DTO schema check promises, retire two todos
  • (49-07) Record plan 07 state, roadmap progress and requirements
  • (49) Tick DTO-03/DTO-04 and persist human verification items as UAT
  • (roadmap) Bind Phase 50 codegen to the decimal annotation constraint
  • (50) Create phase plan
  • (50) Create phase plan
  • Checkpoint in-progress documentation rewrite
  • (50-01) Complete Databricks metric result-column fix plan
  • (50-02) Complete the DTO codegen tracer plan
  • (50-03) Complete the measured per-backend alias plan
  • (50-04) Complete the DTO-08 type-check proof plan
  • (50-04) Record the third DTO-08 decision in STATE
  • (50-05) Complete the refused-ExecuteSchema plan
  • (50-06) Complete the DTO codegen CLI plan
  • (50-07) Add the DTO codegen how-to page
  • (50-07) Bring three pages into agreement with the shipped CLI
  • (50-07) Complete the DTO codegen docs plan
  • (50-08) Set requirement statuses from measurement and route R-04
  • (50-08) Close phase 50 state and roadmap
  • (50) IN-01 state the --name identifier constraint
  • (50) Apply the Databricks consequence chain from live measurement
  • (50) Correct the Snowflake alias claim the live probe falsified
  • (50) Extract Phase 50 learnings
  • Settle R-04 β€” COUNT metrics keep | None, on a rationale that holds
  • (48) Record the Databricks type measurements and their consequences
  • (48) Driver v0.1.3 changes nothing β€” record it, and the route it exposed
  • Reword TYPE-03 β€” each backend's decimal follows its own driver
  • Document the two new codegen-dto routes
  • Correct the Databricks decimal claim, and the --view route's limits
  • Give every warehouse-synced tab-set a DuckDB tab, and fix the Snowflake ones
  • Explain AGG() vs MEASURE(), and route the landing page to Explanation
  • (web-api) Show the typed response, not just warn about dict(row)
  • Settle on Oxford -ize across source docstrings and tests
  • (49) WR-06 state what the Databricks extra actually installs
  • (49) WR-07 say that validate= is per-call, not per-field
  • (49) WR-08 correct the shared-stream rule against measurement
  • (49) IN-05 scope the no-Python-dictionaries claim to the default path
  • (49) IN-03 explain the enum refusal and the validate=True remedy
  • (49) IN-07 show aclosing for an async iter_into loop that may break
  • (49) Correct the fetchone() -> None claim in the drained-stream rule
  • (49) List TestDuplicateResultColumns in the test module's index
  • Fix seven claims the pages got wrong, measured against the code
  • Say how filter values reach the warehouse, and stop promising row.country
  • Rebalance the set, consolidate the how-to guides, teach register=
  • Correct the Snowflake codegen note and close the landing page's cursor
  • (planning) Add the 2026-09-06 codebase review and a draft v0.8 Hardening milestone
  • (planning) Fold the codebase-review fixes into v0.7 as Phases 51-57
  • (planning) Close Phase 51 with its summary and evidence
  • (planning) Record what PR #41 proved about the Phase 51 gates
  • (planning) Record the review finding and the artifact evidence in the Phase 51 summary
  • (planning) Add test suite review
  • (planning) Insert Phase 52.1 Test Suite Soundness
  • (planning) 52-03 complete; CORE-05, CORE-06, CORE-10 met
  • (planning) 52-04 complete; CORE-07, CORE-08, CORE-09, CORE-12 met
  • (planning) 52-05 complete; CORE-11 met
  • (planning) Phase 52 complete; CORE-04 met, 52-SUMMARY.md
  • (planning) Widen Phase 55 to --check accuracy, with alternatives (D9)
  • (planning) Add static-analysis libraries to the --check alternatives
  • (planning) Record the PR #43 review follow-up in 52-SUMMARY.md
  • Point repo and docs URLs at the s-layer org

πŸ§ͺ Testing

  • (46-01) Add the ASYNC-04 packaging test, CI no-anyio smoke, and floor amendments
  • (46-02) Prove the loop stays free and two queries run concurrently
  • (46-03) Add replay-only async engine fixtures and named cassettes
  • (46-03) Replay copied cassettes through the async path (D-16 spike)
  • (46-05) Enforce the asyncio/Trio loop matrix structurally (ASYNC-05)
  • (46-05) Prove cancellation reaches the driver and the pool recovers (ASYNC-06)
  • (46) Failing tests for the fetch_record_batch() pool-slot leak
  • (46) Failing tests for OSError escaping post-drain async iteration
  • (46) Cover aexecute's check-in arm with tests that can fail
  • (46) Failing test β€” aclose() leaks a pool slot silently (WR-01)
  • (46) Failing tests β€” private _pool access breaks bare (WR-05)
  • (46) Promote _sales_query to a shared conftest fixture
  • (46) Failing tests β€” reset() strands its registries when teardown raises (WR-04)
  • (47-01) Assert the DuckDB decimal canary by value
  • (47-01) Guard the committed artifact against staleness and circularity
  • (47-02) Assert each named disagreement on its exact Arrow type literal
  • (47-03) Check the replayed schemas against a raw Arrow read of the same cassettes
  • (48-01) Failing test β€” a list of DECIMAL must not annotate as decimal.Decimal
  • (48-01) Re-point Phase 47's canary, regenerate its artifact, arm the scope fence
  • (48-02) Add failing date/datetime/Decimal literal tests for DBX-04
  • (48-03) Add failing Decimal-policy tests for Snowflake and Databricks
  • (48-03) Add failing tests for the category-1 map gaps and Databricks interval
  • (48-03) Prove the annotation contract by measurement, not by inspection
  • (48-03) Add failing VARIANT -> JsonValue mapper and renderer tests
  • (48-04) Add failing circularity guard for the promoted probe
  • (48) CR-01 reproduce Rich markup mangling and crash in the drift report
  • (48) CR-02 reproduce unescaped catalogue names inside semantic_view() literals
  • (48) CR-02 assert on tokens outside string literals, not substring counts
  • (48) CR-03 reproduce catalogue metadata injecting Python into a generated model
  • (48) WR-01 reproduce a role change and a stale source= reporting as match
  • (48) WR-02 reproduce the unguarded fetch_record_batch route and exercise the fallback
  • (48) WR-03 reproduce probe setup escaping the fallback as an uncaught ValueError
  • (48) WR-04 reproduce the carried-forward route and the borrowed route on absent fields
  • (48) WR-06 reproduce a duplicated result column reporting as an absent one
  • (48) IN-01 reproduce run-end-encoded columns falling through to Any
  • (49-03) Measure polars for real and regenerate the type-fidelity artifact
  • (49-02) Pin the pre-check's full rule set on both sides of its boundary
  • (49-04) Assert the extras contract and lazy-import discipline
  • (49-05) Prove the dataframe returns live and every guard's install command
  • (49-06) Two-backend async DTO module, plus the async RESULT-01/02 groups
  • (50-01) Reproduce the Databricks metric candidate miss
  • (50-02) Pin D-02 β€” projection-only, and its param-free consequence
  • (50-03) Pin the measured per-backend alias on all six cells
  • (50-04) Prove the generated DTO passes stock strict, measured not asserted
  • (50-04) Prove .into(GeneratedDTO) types as list[GeneratedDTO]
  • (50-05) A refused ExecuteSchema still yields a working DTO
  • (50-05) A failed probe and an unbindable alias both raise
  • (50-06) Cover the codegen-dto CLI through CliRunner
  • (50) CR-01 reproduce the --name class-name injection
  • (50) Reproduce G-50-2 β€” Snowflake upper-cases inside the result-column quotes
  • (50) Reproduce the UAT-7 gap β€” a connection failure escapes as a raw traceback
  • (48) Pin Databricks decimal and interval to the measured value (RED)
  • (49) CR-01 lock in that populate_by_name adds a second column key
  • (49) WR-01 require the pre-check to refuse AliasChoices / AliasPath
  • (49) WR-02 require the pre-check to name alias_generator
  • (49) WR-03 require sync iter_into to normalise a creation-time OSError
  • (49) WR-04 point the scope fence at three bypasses it lets through
  • (49) WR-05 require the path fence to fail, not skip, when CI cannot run it
  • (49) IN-01 require the missing-column line to deny the column
  • (49) IN-02 pin a duplicated result column against the converter
  • (49) IN-04 require ALIAS-03 to hold on a None description too
  • (codegen) Pin that a generated DTO accepts its own field names
  • (engines) Pin that a replacement engine survives the scope exit
  • (codegen) Pin that a leading-underscore field name is refused
  • (scope-fence) Pin the base-ref premise check to the fence's own skip policy
  • (results) Pin the Row semantics a result object needs
  • (query) Pin OrderTerm and query equality to field identity
  • Delete tests/unit/test_scope_fence.py
  • Make the tests that could not fail able to fail (52.1-01)
  • Replace the tests that read the repository (52.1-02)
  • Delete tests of other code and replace mirror tests (52.1-03)
  • Suite hygiene and plain-language docstrings (52.1-04)
  • Test the builder through its public surface (52.1-05)
  • Pin in_(), empty-query engine calls and duplicate columns (52-03, red)
  • Pin cursor parity β€” close safety, one read per cursor, guards (52-04, red)
  • Pin timestamp-into-date as a strict xfail (52-05)
  • Pin model inheritance and abstract bases (52-06, red)
  • A field removed by a subclass must stay removed below it (52-06, red)

βš™οΈ Miscellaneous Tasks

  • (release) Create GitHub release with artifacts and changelog
  • (dependabot) Ignore duckdb bumps (version-locked to semantic_views)
  • (46-01) Bump adbc-poolhouse floor to 1.6.1 and declare the async extra
  • (46-01) Arm the TID251 Posture A lint gate over src/semolina
  • (46) Bump adbc-poolhouse floor to 1.6.2 to unblock ASYNC-06
  • (48) Mark phase complete - TYPE-05 Databricks interval accepted as tracked limitation
  • (49-01) Declare pyarrow/pandas/polars/arrowmodel extras and regenerate lock
  • (49-04) Prove DTO-05 against real clean venvs
  • (50) Close Phase 50 UAT in STATE, consume the handoff artifacts
  • (doc-writer) Refresh audit artifacts
  • (doc-writer) Refresh gap, editor and persona reports
  • Bump duckdb pin 1.5.3 -> 1.5.5
  • Regenerate the type-fidelity artifact for the current extension build
  • (release) Gate a tag on version agreement and a CI run against it
  • Run on pull requests, enforce a coverage floor, build docs, widen the matrix
  • (dev) Make just test run CI's suite, align the ruff pin, document maintenance
  • (release) 0.6.1