Changelog¶
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[Unreleased]¶
1.0.1 - 2026-07-11¶
Fixed¶
Clarify
_is_positive_finitereturn typing for stricter mypy
Changed¶
Strengthen core and dialect test oracles (exact SQL / expression semantics)
Docs and examples navigation polish (getting started, troubleshooting, upgrade guide, examples hub)
1.0.0 - 2026-07-10¶
Added¶
Stable 1.0 Application + Plugin APIs frozen; classifiers
Production/StableOpt-in
emit_type_checksonCompiler/compile(): extractstype_checkIR (TypeSpec) from supported scalar annotations, honoring Field /Strict()/model_configstrictness andOptional→allow_noneTypeSpec/type_spec()helper; dialect plugins translatetype_check(PostgreSQL reference matrix; SQLite / MySQL / MSSQL partial support)Application API
clear_model_cache()for the process-wide Phase-1 IR cachedocs/IR_CONTRACT.md— frozen Plugin API v1 IR schemascripts/check_versions.py— core/plugin lockstep + extras pin checksAll-or-nothing PyPI publish via Trusted Publishing (OIDC)
Plugin wheel install + conformance smoke in CI; mypy on dialect packages
examples/runnable scripts; Makefile (install/test/docs/dist)Root
SECURITY.md,CODE_OF_CONDUCT.md,RELEASING.md; GitHub issue templatesDocs: Application vs Plugin autodoc pages; pattern footgun in getting started; how-to guides (ORM/
column_map, markers); Support & compatibility page
Changed¶
Core and dialect packages versioned
1.0.0in lockstep; pinssqlrules>=1,<2/ extrassqlrules-*>=1,<2Phase-1 IR cache keyed by
(model, emit_type_checks)so type-check IR does not collide with default compilesStrict()metadata is no longer turned into a fake IR operatorBuiltin translator registry built once per process; module
compile()reuses shared defaultCompilerinstancesmax_digits/decimal_placesand unknown Field metadata keys rejected at extract (no invented operators)Elevated pattern/ReDoS guidance in SECURITY and dialect READMEs
Core sdist no longer bundles
/packagesannotated-typesupper-bounded (>=0.6,<1)README mental-model anti-example, install honesty (PyPI vs source), prefer
where; CONTRIBUTING focused on contributors; release steps in RELEASING.md
Docs¶
Whole-model type matrix documented as intentional 1.0 contract
Registry mutation after
Compilerinit documented as unsupportedPrefer
register_constraintin Plugin docsDiátaxis-oriented navigation; one H1 per page for sidebar hygiene
0.4.0 - 2026-07-10¶
Added¶
ConstraintMarkerprotocol and shared markers insqlrules.markers:JsonContains,JsonHasKey,ArrayContains,ArrayOverlap,RangeContains,RangeOverlap,FullTextMatchPatternSpecIR value forpattern(preservesignore_casefromre.Patternflags);pattern_text()helper for pluginslist/dictannotations for marker-driven fields (portable constraints on containers still raise)Expanded dialect plugins:
sqlrules-postgresql—~/~*, JSONB, ARRAY, range operatorssqlrules-sqlite—register_regexp(), flag-aware REGEXP, JSON helperssqlrules-mysql— REGEXP, JSON,fulltext_matchsqlrules-mssql— JSON helpers,LENoverrides for length constraints
Conformance helpers accept optional
model/table/fieldfor non-patternoperators
Changed¶
Package version bumped to 0.4.0
Official plugin packages depend on
sqlrules>=0.4,<0.5
0.3.0 - 2026-07-10¶
Added¶
Versioned plugin API:
SQLRulesPlugin,PLUGIN_API_VERSION("1"), andPluginErrorCompiler(plugins=..., on_conflict=..., dialect=...)for explicit plugin registration (no auto-discovery)Expanded registry API:
register_constraint, conflict policies (raise/replace/ignore),copy(),operators(), and__contains__InvalidTranslatorErrorraised for non-callable or wrong-arity translators at registration timeDiagnostic.code(e.g.unsupported_constrainton warn/ignore skips)Optional
CompilationContext.dialecthint (never auto-detected)Plugin conformance helpers in
sqlrules.conformanceOfficial starter dialect packages:
sqlrules-postgresql(pattern→~)sqlrules-sqlite(pattern→REGEXP)
Changed¶
Package version bumped to 0.3.0
0.2.0 - 2026-07-10¶
Added¶
Two-phase compilation:
Compiler.compile_model()(static IR) andCompiler.bind()(column resolve + translate)In-process metadata cache for Phase-1
ModelIR(default on; disable withcache=False)Structured diagnostics: public
Diagnosticviacompiler.diagnosticsfor skipped constraints underon_unsupported="warn"/"ignore"Type support for
UUIDandtime(range comparisons fortime; Literal/Enum forUUID)First-class
patternconstraint IR (no portable core translator; register a custom translator or use a future dialect plugin)IR types:
ModelIR,FieldIR,DiagnosticLocal benchmark suite:
python -m benchmarks.bench_compile
Changed¶
Unsupported-constraint error messages no longer hard-code a release version
CompilationContextcarries an optional diagnostics collectorUnconstrained
UUID/timefields are skipped (no longer type-rejected);timedeltaand containers still always raiseValidation-only metadata flags (
strip_whitespace,allow_inf_nan, …) are ignored when extracting constraintspatternvalues fromre.Patternare normalized to strings in IRInvalid
column_mapentries raise instead of falling through to table columns
Fixed¶
Reject
multiple_ofondate/datetime/time(previously emitted nonsensical modulo SQL)Module-level
sqlrules.compile(..., on_unsupported="warn")now attributes warnings to the caller, notcompiler.pycompile_modelclears stale diagnostics from prior binds
0.1.0 - 2026-07-10¶
Added¶
Public API:
compile(),where(),flatten(), andCompilerConstraint support:
gt,ge,lt,le,multiple_of,min_length,max_length,Literal, andEnumEquivalent Pydantic forms:
Interval,conint/constr,Len, andStringConstraints(supported attributes only)Fail-fast handling for unsupported metadata (
pattern, validators, decimal precision) and unsupported types (containers, UUID, time, timedelta)Field alias resolution when binding SQLAlchemy columns (
alias,validation_alias, andserialization_aliasstring forms)Unsupported-constraint policies:
raise(default),warn, andignorefor unknown operators (unsupported types always raise)Exception hierarchy rooted at
SQLRulesErrorColumn resolution for SQLAlchemy
Tableobjects, ORM attributes, and explicitcolumn_mapDocumentation for the compiler, translators, errors, types, and roadmap
Fixed¶
Column resolution no longer treats non-column
Tableattributes (such asnameoris_selectable) as columns, which previously produced invalid SQL or Pythonboolvalues in the rules dictAnnotated[T, ...] | None/Optional[Annotated[T, ...]]now unwraps nested metadata correctlyString
validation_alias/serialization_aliasparticipate in column bindingmultiple_ofvalues<= 0are rejectedLength constraints on non-
strfields and numeric constraints onstr/boolfields are rejected
Changed¶
Alias candidates are preferred over the Python field name when binding columns
Unconstrained fields are skipped and no longer require a matching column
Packaging URLs point at
eddiethedean/sqlrulesDocs clarify that
on_unsupporteddoes not soften unsupported types; plugin / two-phase compile designs are marked as future