Skip to content

chore: Release v1.0.0.dev15 - #45

Merged
vistart merged 22 commits into
mainfrom
release/v1.0.0.dev15
Jun 15, 2026
Merged

vistart merged 22 commits into
mainfrom
release/v1.0.0.dev15

Conversation

@vistart

@vistart vistart commented Jun 15, 2026 •

Copy link
Copy Markdown
Contributor

Description

This PR merges the release/v1.0.0.dev15 branch into main, publishing the v1.0.0.dev15 development release of python-activerecord-postgres.

Release Details

  • Target Version: v1.0.0.dev15
  • Type: Development Release
  • Key Changes:
    • New Features
    • Bug Fixes
    • Refactors
    • Tests
    • CI/Chore Updates

New Features

Fixes

  • Fill all PostgreSQL index and DDL feature coverage gaps (fix: fill all PostgreSQL index and DDL feature coverage gaps #39)
  • Declare JSONB expression formatter protocol (bd2a129)
  • Remove redundant Postgres-specific expression subclasses (e7f67ae)
  • Replace deleted PostgresSQLSyntaxSupport ref in CLI info (9f51a4c)
  • Remove rhosocial-activerecord from requirements.txt (df84e80)
  • Security fixes: remove dead _quote_identifier, fix _format_partition_value injection (ac59b8b)
  • Test indentation fix and format_identifier security tests (57732d8)
  • Adapter inheritance fix: BaseSQLTypeAdapter for proper Optional type handling (98a7839)
  • Register PostgresJSONBAdapter for JsonUser JSON fields (6b50ecc)
  • Preserve exception chain and add credential warning (f65c710)

Refactors

CI/Chore

  • Bump version to 1.0.0.dev15
  • Add Python 3.15 experimental tests for PostgreSQL
  • Switch testsuite dependency from GitHub to PyPI (v1.0.0.dev15)
  • Loosen pytest dependency constraints
  • Upgrade actions/checkout from v4 to v6
  • Add .gitattributes to enforce LF line endings

Tests

  • Add backend type integration coverage (e5d6887)
  • Align Postgres coverage with testsuite contract (af21612)
  • Add bulk operations schema and provider (70b05ce)
  • Add Pydantic native validation coverage (34799ba)
  • Improve CLI and backend initialization coverage (b8ed54f)
  • Add bridge for unicode/emoji/injection round-trip tests (c2721f8)
  • Update PostgreSQL benchmarks and testsuite dependency (db87330)

Documentation

  • Add documentation for partition, PGQ, COLLATE, datetime interval, SQL/XML, index enhancements (cd8710e)

Related PRs

Breaking Change

  • Yes
  • No

Testing

  • All CI checks passed on the source branch

Checklist

  • My changes follow the project's version control guidelines
  • I have updated the CHANGELOG.md using towncrier build
  • All necessary documentation has been prepared or updated
  • I have confirmed all CI checks have passed on the target branch after merging

Additional Notes

This is a development release (dev15) continuing the v1.0.0 pre-release series for the PostgreSQL backend.

vistart and others added 21 commits May 30, 2026 12:00
* fix: fill all PostgreSQL index feature coverage gaps

- Add PostgresDropIndexExpression with CONCURRENTLY support (PG18+)
- Add PostgresAlterIndexExpression with all 8 ALTER INDEX action types
- Add PostgresIndexMixin protocol method overrides (7 methods)
- Add format_drop/alter_index_statement to PostgresIndexMixin
- Add format_add/drop_index_action UnsupportedFeatureError stubs in dialect
- Register 3 new expression/dialect pairs in protocol conformance tests
- Add 21 new test cases covering all CREATE INDEX options, ALTER INDEX
  error paths, DROP INDEX CONCURRENTLY, and WHERE expression protocol

* fix: complete remaining DDL feature gaps in trigger and index mixins

- Add supports_trigger/supports_create_trigger/supports_drop_trigger
  to PostgresTriggerMixin (previously only in dialect.py)
- Add supports_create_index/supports_drop_index/supports_unique_index/
  supports_index_if_not_exists/supports_index_if_exists to PostgresIndexMixin
- Add explicit fulltext method overrides returning False/UnsupportedFeatureError
- Fix supports_index_if_not_exists version gate in dialect.py (PG 9.5+)
- Add corresponding unit tests for all new methods (16 new tests)
- All 489 related tests pass without regression

* fix: add missing table feature methods to PostgresTableMixin

- Add supports_if_not_exists_table (PG 9.5+), supports_if_exists_table,
  supports_temporary_table, supports_table_partitioning (PG 10+),
  supports_table_tablespace to PostgresTableMixin
- Add version gates to dialect.py for if_not_exists_table and
  table_partitioning to match mixin
- Add 8 test cases for all table feature detection methods
- 425 related tests pass without regression

* test: add 10 missing extension protocol-mixin pairs to conformance tests

- Add 10 unpaired extension protocols to POSTGRES_PROTOCOL_MIXIN_PAIRS
  for forward/reverse coverage verification
- All 517 related tests pass without regression

* chore: add changelog fragment for PR #39

* test: achieve 100% coverage on 5 target files

- Add pragma: no cover to protocol ellipsis bodies and TYPE_CHECKING blocks
  (matching core project convention with per-line markers)
- Add direct mixin tests for PostgresIndexMixin, PostgresTableMixin,
  and PostgresTriggerMixin (not through PostgresDialect overrides)
- Add expression column, INCLUDE error paths, and unsupported ALTER INDEX
  action tests for index mixin
- Add trigger WITH condition expression test
- Add trigger with no-level (FOR EACH omitted) test
- All 5 files now at 100% statement and branch coverage
…cstrings, fix lint

- Remove PostgresCreateIndexExpression, PostgresDropIndexExpression,
  PostgresForUpdateClause — use generic expressions with dialect_options
- Add comprehensive docstrings to all format_* methods in PG mixins
- Fix ruff D413 (blank line after docstring sections) + E501 (line length)
- Update tests to use generic expressions + dialect_options
- Remove obsolete protocol conformance entries
Register the relation provider, bridge shared relation tests, and map JSON derived-field extraction to PostgreSQL JSONPath capability without parsing user path parameters.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Extend PostgreSQL backend integration tests for specialized data types and XML behavior so backend-specific coverage tracks implemented capabilities.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Allow development environments to resolve pytest and pytest plugin versions without package-level pins.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Ensure the PostgreSQL JSONB enhanced protocol declares the public
formatter implemented by its mixin so protocol conformance checks pass.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* feat(postgres): add expression-level COLLATE support

Add PostgreSQL collation validation and dialect formatting so COLLATE
expressions remain schema-aware and safe for query composition.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* refactor(postgres): validate COLLATE names via dialect hook

Return the PostgreSQL collation SQL representation from validate_collation_name
so COLLATE formatting validates backend-specific names in one place.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* style(postgres): type COLLATE validation hook parameter

Annotate validate_collation_name with CollationName so the PostgreSQL dialect
hook documents the structured collation argument it receives.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* refactor(postgres): accept collation expression in validation

Adapt COLLATE validation to consume the full CollateExpression while preserving PostgreSQL schema-qualified collation handling.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* chore: add changelog fragment for PR #40

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
* feat(postgres): use core SQL/XML XMLPARSE expression

Wire PostgreSQL XMLPARSE support through the core SQL/XML expression
protocol and remove the old PostgreSQL-specific function factory.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* feat(postgres): add SQL/XML standard expression support

Enable PostgreSQL SQL/XML capabilities through core expression protocols,
keep PostgreSQL-specific XPath helpers separate, and add self-contained
examples that exercise expression-generated SQL.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* chore: add changelog fragment for PR #41

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
…es (#42)

* feat(postgres): add datetime interval expression formatting

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* test(postgres): add datetime interval EXPLAIN examples

Cover temporal expression queries against indexed datetime filters while allowing PostgreSQL planner cost choices between eligible datetime indexes.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* chore: add changelog fragment for PR #42

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
- Add Python 3.15.0-beta.2 classifier to pyproject.toml
- Add experimental test job for Python 3.15 (standard and free-threaded)
- Jobs use continue-on-error: true to allow failures
- Test with PostgreSQL 18
The core package is installed via CI workflow from git, not PyPI.
requirements.txt should only contain backend-specific dependencies.
* feat(postgres): add pg_partman partition support

Add PostgreSQL partition and pg_partman support with dialect,
expression, protocol, mixin, provider, and test updates.

Also apply ruff formatting/lint cleanup across the current change set
and add low-risk backend signature annotations.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix(test): align partition tests with public protocol API

Update partition value security tests to exercise the public
format_partition_value expression path instead of the removed
_format_partition_value helper.

Declare supports_table_partitioning in PostgresTableSupport so the
protocol conformance reverse coverage matches PostgresTableMixin.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix(postgres): avoid table and partition protocol overlap

Remove supports_table_partitioning from PostgresTableMixin so the
partition capability remains owned by PartitionSupport and
PostgresPartitionMixin. This keeps PostgreSQL protocol interfaces
non-overlapping while preserving dialect support through the partition
mixin.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* refactor(postgres): separate table and partition capabilities

Move PostgreSQL implementations of generic PartitionSupport capability
methods into PostgresPartitionMixin and ensure that mixin takes
precedence over the generic PartitionMixin in the dialect MRO.

Keep PostgresTableMixin focused on table capabilities only, and move
partition feature detection coverage from table tests into DDL protocol
and partition mixin tests. Explicitly include PartitionSupport in the
protocol conformance checks to document the inheritance boundary.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* refactor(postgres): expressionize partition operation helpers

Disable the Python 3.15 experimental workflow job until the beta
toolchain stabilizes.

Move pg_partman part_config cleanup into a dedicated expression and
formatter, then update partition operation tests to use expression
helpers for DDL and pg_partman operations instead of hand-built SQL.
Validation queries remain raw SQL because they inspect PostgreSQL
runtime metadata and routing behavior directly.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat(postgres): align partition capability mapping

Add PostgreSQL partition metadata query expression and align generic partition capability methods with PostgreSQL declarative partitioning.

Update provider and tests to use Expression-Dialect generated SQL for partition metadata, truncate, and drop paths.

Also update PR template links to repository-local .claude rule documents.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test(partition): add production time partition operation scenarios

Add production-style PostgreSQL time partition scenarios covering microsecond boundaries, future partition preparation, continuous partition pruning, index usage, metadata changes, and cold archival via DETACH PARTITION.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix(ddl): generate DEFAULT partition clauses correctly

Fix PostgreSQL DEFAULT partition DDL by omitting FOR VALUES for DEFAULT RANGE and LIST partitions.

Also add expression and real backend coverage for DEFAULT partition maintenance and pg_partman configuration maintenance.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test(query): add eager loading and split sync/async relation with bridge files

- Add 5 eager loading test bridge files (one-to-one import)
- Split test_relations_with.py into sync/async bridge files
- Remove old combined test_relations_with.py bridge
- Remove partition.interfaces dependency from provider registry
- Fix async_blog_fixtures to import AsyncUser from async_models for fixture parity

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat(provider): implement setup_profile_fixtures for Postgres sync/async

- Add setup_profile_fixtures() and setup_async_profile_fixtures() to Postgres QueryProvider
- Create profiles.sql schema with FK reference to users table
- Add bridge files for eager_loading_scenarios_sync/async tests

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* refactor(dialect): split mixins into directory-based modules

* fix(ci): remove bridge file referencing non-existent testsuite module

test_eager_loading_scenarios.py imported
rhosocial.activerecord.testsuite.feature.query.test_eager_loading_scenarios
which does not exist in the testsuite's release/v1.0.0.dev15 branch.
This caused ModuleNotFoundError during test collection on all
Python/PostgreSQL versions in CI.

The async and sync variants
(test_eager_loading_scenarios_async.py,
test_eager_loading_scenarios_sync.py) already exist and work correctly.

* fix(test): import Profile from version-specific module, not base models

setup_profile_fixtures() imported Profile from the base models module,
but User is selected from a version-specific module (e.g. models_py312)
via _select_model_class(). The profile relation on the selected User
class resolves to the version-specific Profile class, which had no
backend configured, causing 'No backend configured' errors in all
eager loading tests using with_('profile').

Fix: add Profile to the module-level version-conditional imports
using the same _select_model_class() pattern as User, Order, etc.

* fix(test): allow TEXT[]/INTEGER[] in column definition and fix detach concurrently assertion

- Override format_column_definition in PostgresTableMixin to permit
  PostgreSQL array types (e.g. TEXT[], INTEGER[]) that contain brackets
- Fix test_detach_concurrently_pg14 assertion: PR refactoring moved
  CONCURRENTLY from adjacent to DETACH to a separate token after the
  partition name

* fix(protocol): declare format_column_definition in PostgresTableSupport

The method was added to PostgresTableMixin but not declared in
the matching protocol, causing protocol conformance test failure.

* feat(partition): complete partitioning support with named expressions, attach improvements, and comprehensive docstrings

- Add ATTACH CONCURRENTLY support (PG 14+) to PostgresAttachPartitionExpression
- Add ATTACH DEFAULT partition support via partition_values={'default': True}
- Refactor format_partition_metadata_query to use dynamic schema filtering
- Complete pg_partman create_parent with all 7 optional parameters
- Add named expression functions for partition auto-management (create_next_monthly_partition,
  create_range_partition_for_month, create_range_partition_for_quarter,
  create_range_partitions_for_interval) via rhosocial-activerecord resolver
- Add english docstrings (Args/Returns/Raises) to all partition classes and methods
- Add tests: ATTACH CONCURRENTLY, ATTACH DEFAULT, multi-column partition keys,
  expression boundary values, DETACH FINALIZE, pg_partman optional params,
  metadata query schema filtering, concurrent_attach capability
- Verify on real PostgreSQL 18, 14, 11, 10, 9: all 150+ unit + 27 integration tests pass

* chore: add changelog fragment for PR #43

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
)

* feat(postgres): add PGQ support with property graph query scenarios

- Fix version regex to handle beta versions (e.g. 19beta1)
- Add PostgresPropertyGraphQueryMixin for PGQ support
- Add format tests for PGQ expressions
- Add scenario tests for real PGQ queries against PG19
- Update dialect and mixins init

* test(postgres): add 19 PGQ format tests for 100% expression coverage

Cover all expression edge cases and variants:
- anonymous vertex, invalid variable name (ValueError)
- undirected edge (NONE), table-only edge, variable-only edge
- empty MATCH path, anonymous vertex in MATCH
- GraphTableExpression alias, GraphColumn without alias
- CREATE IF NOT EXISTS, CREATE without edge tables
- VertexTable/EdgeTable with alias
- TablePropertiesClause ALL COLUMNS / NONE
- ALTER DROP VERTEX TABLES
- UnsupportedFeatureError for all TablePropertiesClause variants

Total: 33 -> 52 format tests, all passing.

* ci(postgres): add standalone Python 3.14 / PostgreSQL 19beta1 test job

PG 19 has no extensions yet, so it gets its own job without
postgres-exts service. Uses postgres:19beta1 official image.
Main test matrix (PG 9-18) unchanged.

* ci(postgres): add --scenario-parallel to PGQ test job

* fix(postgres): handle PG beta version strings without dot separator in async version parsing

* test(postgres): normalize LSN assertion to handle PG19 zero-padding

* test(postgres): fix async PGQ fixture graph name mismatch

* test(postgres): add version-aware LSN assertion for PG19 zero-padded format

* chore: add changelog fragment for PR #44
…ure pairs

Replace QL/DDL/DML grouping with 21 individual protocol+mixin pairs
following base dialect system conventions (CTE, Window, Returning, etc.)

- Delete old ql_support/ddl_support/dml_support/pg_features files
- Create per-feature protocol+mixin pairs in protocols/ and mixins/
- Update __init__.py, dialect.py MRO, and test protocol references
- Add view protocol+mixin for view-related supports_* methods
- Move index/constraint/trigger/multirange methods to existing mixins
- All 435 tests pass
…fo.py

cli/info.py still imported the deleted PostgresSQLSyntaxSupport protocol,
causing ImportError in CI. Replace with new per-feature protocols.
- Add bridge files: test_descriptor_compat, test_descriptors_async, test_validator
feature/fix branches can now be triggered manually via workflow_dispatch;
release/main/maint branches retain both automatic and manual triggers.
@vistart vistart self-assigned this Jun 15, 2026
@sonarqubecloud

Copy link
Copy Markdown

@codecov

codecov Bot commented Jun 15, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 85.49383% with 141 lines in your changes missing coverage. Please review.
✅ Project coverage is 71.66%. Comparing base (bbe15f4) to head (23bf4b9).

Files with missing lines Patch % Lines
...cord/backend/impl/postgres/mixins/ddl/partition.py 85.31% 11 Missing and 10 partials ⚠️
...ctiverecord/backend/impl/postgres/protocols/xml.py 25.00% 0 Missing and 12 partials ⚠️
...record/backend/impl/postgres/protocols/features.py 26.66% 0 Missing and 11 partials ⚠️
.../activerecord/backend/impl/postgres/mixins/view.py 52.63% 9 Missing ⚠️
...ckend/impl/postgres/mixins/types/jsonb_enhanced.py 52.94% 4 Missing and 4 partials ⚠️
...tiverecord/backend/impl/postgres/protocols/view.py 33.33% 0 Missing and 8 partials ⚠️
...d/backend/impl/postgres/protocols/set_operation.py 40.00% 0 Missing and 6 partials ⚠️
...activerecord/backend/impl/postgres/mixins/table.py 82.75% 4 Missing and 1 partial ⚠️
...d/impl/postgres/protocols/extensions/pg_partman.py 50.00% 4 Missing and 1 partial ⚠️
...cial/activerecord/backend/impl/postgres/dialect.py 90.47% 3 Missing and 1 partial ⚠️
... and 27 more
Additional details and impacted files
@@            Coverage Diff             @@
##             main      #45      +/-   ##
==========================================
+ Coverage   69.29%   71.66%   +2.37%     
==========================================
  Files         231      274      +43     
  Lines       10088    10687     +599     
  Branches     1593     1743     +150     
==========================================
+ Hits         6990     7659     +669     
+ Misses       2569     2438     -131     
- Partials      529      590      +61     
Flag Coverage Δ
postgres-18 71.66% <85.49%> (+2.37%) ⬆️
python-3.14 71.66% <85.49%> (+2.37%) ⬆️
unittests 71.66% <85.49%> (+2.37%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@vistart
vistart merged commit 39b2169 into main Jun 15, 2026
30 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant