Skip to content

chore: Release v1.0.0.dev10 - #28

Merged
vistart merged 13 commits into
mainfrom
release/v1.0.0.dev10
Apr 12, 2026
Merged

vistart merged 13 commits into
mainfrom
release/v1.0.0.dev10

Conversation

@vistart

@vistart vistart commented Apr 12, 2026 •

Copy link
Copy Markdown
Contributor

Description

This PR merges the release/v1.0.0.dev10 branch into main, delivering PostgreSQL backend enhancements including row-level locking, comprehensive PostgreSQL function support, and constraint support protocol.

Release/Hotfix Details

  • Target Version: v1.0.0.dev10
  • Type: Development Release
  • Key Changes:
  • New Features
  • Bug Fixes
  • Breaking Changes
  • Security Fixes

Included Changes

New Features

Bug Fixes

Other Updates

  • feat(examples): add exp6 and FastAPI examples for connection management
  • fix(examples): add Windows event loop compatibility for async PostgreSQL
  • fix(tests): resolve asyncio.set_event_loop_policy assertion error on Python 3.8
  • docs: add DDL, BackendGroup docs and worker isolation examples
  • docs: add test verification conclusions for parallel workers (zh_CN + en_US)
  • docs: update parallel_workers test results for macOS Tahoe 26 arm64
  • chore: bump version to 1.0.0.dev10

Related Issues/PRs

Breaking Change

  • Yes
  • No

Applicable rhosocial-activerecord Version Range: >=1.0.0.dev10

Testing

  • All CI checks passed on the source branch (e.g., release/v1.0.0.dev10 or hotfix/ar-XXX).
  • Specific tests for this hotfix have been run and passed.

Test Plan: Full test suite execution on release branch

Checklist

  • My changes follow the project's version control guidelines (especially for release and hotfix procedures).
  • I have updated the CHANGELOG.md using towncrier build (for releases).
  • All necessary documentation (e.g., release notes, migration guides) has been prepared or updated.
  • I have confirmed all CI checks have passed on the target branch after merging (post-merge verification).

Additional Notes

This is a development release (dev10) containing PostgreSQL backend improvements. The changelog will be built using towncrier after CI verification.

vistart and others added 12 commits April 8, 2026 22:05
…ort (#23)

* feat(postgres): add row-level lock enhancement and advisory lock support

Row-level lock enhancement:
- FOR SHARE: Shared lock, allows reads but blocks updates (PG 9.0+)
- FOR NO KEY UPDATE: Weaker exclusive lock (PG 9.0+)
- FOR KEY SHARE: Weakest shared lock (PG 9.3+)
- Add LockStrength enum in core query_parts
- Extend ForUpdateClause to support different lock strengths
- Add capability detection methods in PostgreSQLDialect

Advisory lock support:
- Session-level locks: pg_advisory_lock, pg_advisory_lock_shared
- Transaction-level locks: pg_advisory_xact_lock, pg_advisory_xact_lock_shared
- Non-blocking try variants: pg_try_advisory_lock, pg_try_advisory_lock_shared
- Unlock functions: pg_advisory_unlock, pg_advisory_unlock_all
- Context manager support for automatic lock release
- Support for both single-key and two-key variants

Implementation:
- Add PostgreSQLAdvisoryLockSupport protocol
- Add AdvisoryLockMixin for backend methods
- Add expression classes in core advisory module
- Implement format_for_update_clause with lock strength
- Add version-aware capability detection

Tests:
- test_row_level_locks.py: Row-level lock strength tests
- test_advisory_lock.py: Advisory lock functionality tests
- Both sync and async versions covered

Official Documentation:
- Row-level locks: https://www.postgresql.org/docs/current/explicit-locking.html
- Advisory locks: https://www.postgresql.org/docs/current/functions-admin.html#FUNCTIONS-ADVISORY-LOCKS

* refactor(postgres): migrate advisory lock and lock strength to extension package

- Move advisory lock expressions from core to postgres/expression/advisory/
- Define LockStrength enum and PostgresForUpdateClause in postgres/expression/
- PostgresForUpdateClause.to_sql() handles PostgreSQL-specific lock strengths
- Update import paths in backend, mixin, and protocol files
- Reorganize test directory: move activerecord_test/ to activerecord_postgres_test/
- Add postgres_dialect fixture to backend conftest.py
- Add .claude/tmp/ to .gitignore

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

* ci: update dependency sources to Git branches

- rhosocial-activerecord: git+https@release/v1.0.0.dev23
- rhosocial-activerecord-testsuite: git+https@release/v1.0.0.dev10

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

* chore: add changelog fragment for PR #23

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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* refactor: migrate functions from types to functions modules

Split responsibilities between types and functions modules for text search and XML:

**Text Search**
- Create: functions/text_search.py with SQL generation functions
- Moved functions (14 total):
  - to_tsvector, to_tsquery, plainto_tsquery, phraseto_tsquery, websearch_to_tsquery
  - ts_matches, ts_matches_expr, ts_rank, ts_rank_cd, ts_headline
  - tsvector_concat, tsvector_strip, tsvector_setweight, tsvector_length
- Retained in types/text_search.py: PostgresTsVector, PostgresTsQuery, and related classes

**XML**
- Create: functions/xml.py with SQL generation functions
- Moved functions (4 total): xmlparse, xpath_query, xpath_exists, xml_is_well_formed
- Retained in types/xml.py: PostgresXML class

**Module Updates**
- functions/__init__.py: Export all new text search and XML functions
- types/__init__.py: Remove function exports, keep only type exports
- backend/__init__.py: Update imports to use functions.text_search
- test_xml_types.py: Update to import functions from functions.xml

**Benefits**
- Clear separation of concerns: types for data structures, functions for SQL generators
- Better module organization following single responsibility principle
- Easier maintenance and discoverability of SQL generation utilities

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

* chore: add changelog fragment for PR #24

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat(postgres): add math enhanced functions with proper naming

- round_ (round is Python builtin)
- pow, power (POWER alias)
- sqrt, mod, ceil, floor, trunc
- max_, min_ (GREATEST/LEAST for scalar, MAX/MIN for aggregate)
- avg (AVG aggregate)

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

* chore: add changelog fragment for PR #25

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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
… network, UUID, hstore, range) (#26)

* feat(postgres): add array, network, UUID functions and fix range constructors

New function modules:
- array.py: 17 array functions (array_agg, array_append, etc.)
- network.py: 15 network functions (inet_client_addr, inet_merge, etc.)
- uuid.py: 7 UUID functions (uuid_generate_v1, uuid_generate_v4, etc.)

Fix range constructors to use sentinel pattern for bounds parameter:
- int4range, int8range, numrange, tsrange, tstzrange, daterange
- Omit bounds when using default inclusive '[]', include when explicitly specified

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

* feat(postgres): add comprehensive hstore function support

Add PostgreSQL hstore extension functions including:
- Constructors: hstore_from_record, hstore_from_key_value
- Key/Value extraction: akeys, skeys, avals, svals, each
- Conversion: hstore_to_array, hstore_to_matrix, hstore_to_json,
  hstore_to_jsonb, hstore_to_json_loose, hstore_to_jsonb_loose
- Existence: hstore_exist, hstore_defined
- Delete: hstore_delete, hstore_delete_keys, hstore_delete_pairs
- Record: hstore_populate_record
- Operators: hstore_get_value, hstore_get_values, hstore_concat,
  hstore_key_exists, hstore_all_keys_exist, hstore_any_key_exists,
  hstore_contains, hstore_contained_by, hstore_subtract_*,
  hstore_to_array_operator, hstore_to_matrix_operator,
  hstore_record_update
- Subscript: hstore_subscript_get, hstore_subscript_set

Note: Generic function names (exist, delete, defined, slice,
populate_record, record_update) are prefixed with hstore_ to
avoid confusion with unrelated functionality.

* refactor(postgres): rename hstore extraction functions with hstore_ prefix

Rename generic function names to avoid confusion:
- akeys → hstore_akeys
- skeys → hstore_skeys
- avals → hstore_avals
- svals → hstore_svals
- each → hstore_each

All hstore functions now consistently use the hstore_ prefix.

* chore: add changelog fragment for PR #26

* test(postgres): add hstore function tests for full coverage

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat(postgres): add constraint DDL support with EXCLUDE and NOT VALID

Add PostgreSQL-specific constraint DDL formatting directly in
PostgresDialect (not via mixin override, due to Python C3 MRO
placing SQLDialectBase before mixins):

- EXCLUDE constraint support with USING, elements, WHERE, DEFERRABLE
- NOT VALID suffix for skipping validation of existing rows
- format_add_table_constraint_action overrides base class for PG extensions
- PostgresConstraintMixin retained as organizational placeholder

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

* feat(backend): add PostgreSQL constraint support protocol

- Add PostgresConstraintSupport protocol for PostgreSQL-proprietary
  constraint features (NOT VALID, EXCLUDE constraints)
- Implement supports_constraint_enforced() returning False
  (PostgreSQL uses NOT VALID instead of ENFORCED/NOT ENFORCED)
- Add supports_constraint_novalidate() and supports_exclude_constraint()
  to PostgresConstraintMixin

* chore: add changelog fragment for PR #27

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
- Add DDL documentation covering PostgreSQL-specific DDL operations
- Add BackendGroup documentation for connection management
- Add worker_isolation examples demonstrating connection sharing anti-pattern
- Fix schema to include order_number column
…Python 3.8

Instantiate WindowsSelectorEventLoopPolicy before passing to
set_event_loop_policy() to avoid assertion failure when the
policy argument is not an AbstractEventLoopPolicy instance.
- Add WindowsSelectorEventLoopPolicy setup for Windows async workers
- Add Windows test results to README.md
- Fixes Psycopg ProactorEventLoop compatibility error on Windows
… en_US)

Add comprehensive Section 9 with:
- Test environment details (macOS Tahoe 26, Windows 11)
- Test results for exp1-exp5
- Platform-specific notes for Windows event loop
- Cross-platform conclusions
Add detailed experimental data from Python 3.8.10 environment:
- macOS arm64 shows stable 1.0x speedup with sync multiprocess
- Async exp2 triggered deadlock (SQLSTATE 40P01) due to small dataset
- Updated test environment details with exact version numbers
- Added notes on PostgreSQL deadlock behavior in concurrent testing
- Add exp6_backend_group_pool.py to compare BackendGroup vs BackendPool
- Add chapter_10_fastapi/ with complete FastAPI async example
- Update parallel_workers.md (zh_CN + en_US) with exp6 results
- Document BackendPool as recommended approach for PostgreSQL
- Document connection pooling best practices for FastAPI

Key findings from exp6:
- BackendPool (20/20 success) outperforms BackendGroup for thread safety
- PostgreSQL (threadsafety=2) supports connection pooling
- BackendPool is recommended for FastAPI + PostgreSQL
- Connection pooling provides efficient connection reuse
@codecov

codecov Bot commented Apr 12, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 69.55307% with 218 lines in your changes missing coverage. Please review.
✅ Project coverage is 72.51%. Comparing base (55be2ea) to head (8ad08b8).
⚠️ Report is 13 commits behind head on main.

Files with missing lines Patch % Lines
...iverecord/backend/impl/postgres/functions/range.py 29.87% 33 Missing and 21 partials ⚠️
...cial/activerecord/backend/impl/postgres/dialect.py 26.08% 50 Missing and 1 partial ⚠️
...ord/backend/impl/postgres/functions/text_search.py 26.66% 44 Missing ⚠️
...record/backend/impl/postgres/expression/locking.py 66.66% 8 Missing and 7 partials ⚠️
.../backend/impl/postgres/mixins/dml/advisory_lock.py 68.42% 8 Missing and 4 partials ⚠️
...ord/backend/impl/postgres/backend/async_backend.py 75.60% 7 Missing and 3 partials ⚠️
...iverecord/backend/impl/postgres/functions/array.py 85.41% 4 Missing and 3 partials ⚠️
...activerecord/backend/impl/postgres/backend/sync.py 85.00% 3 Missing and 3 partials ⚠️
...erecord/backend/impl/postgres/functions/network.py 90.00% 2 Missing and 2 partials ⚠️
...tiverecord/backend/impl/postgres/functions/uuid.py 81.81% 2 Missing and 2 partials ⚠️
... and 6 more
Additional details and impacted files
@@            Coverage Diff             @@
##             main      #28      +/-   ##
==========================================
+ Coverage   72.45%   72.51%   +0.05%     
==========================================
  Files         113      128      +15     
  Lines        6632     7261     +629     
  Branches     1103     1194      +91     
==========================================
+ Hits         4805     5265     +460     
- Misses       1445     1565     +120     
- Partials      382      431      +49     
Flag Coverage Δ
postgres-18 72.51% <69.55%> (+0.05%) ⬆️
python-3.14 72.51% <69.55%> (+0.05%) ⬆️
unittests 72.51% <69.55%> (+0.05%) ⬆️

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

☔ View full report in Codecov by Sentry.
📢 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 self-assigned this Apr 12, 2026
@sonarqubecloud

Copy link
Copy Markdown

@vistart
vistart merged commit e8c0dcf into main Apr 12, 2026
23 of 24 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