Skip to content

Additional work on temporal constraints#3746

Merged
roji merged 1 commit intonpgsql:mainfrom
roji:TemporalAgain
Feb 22, 2026
Merged

Additional work on temporal constraints#3746
roji merged 1 commit intonpgsql:mainfrom
roji:TemporalAgain

Conversation

@roji
Copy link
Copy Markdown
Member

@roji roji commented Feb 22, 2026

Fix lack of NpgsqlRange comparer

Closes #3739
Part of #2097

Fix lack of NpgsqlRange comparer

Closes npgsql#3739
Part of npgsql#2097
Copilot AI review requested due to automatic review settings February 22, 2026 12:09
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request addresses issue #3739 by implementing support for using NpgsqlRange<T> types in composite keys, which is essential for PostgreSQL 18's new WITHOUT OVERLAPS and PERIOD temporal constraint features.

The core problem was that NpgsqlRange<T> doesn't implement IComparable (ranges are only partially ordered), causing EF Core's model validation to fail when using range types in keys or foreign keys. The solution introduces:

  1. NpgsqlRangeCurrentValueComparer: A custom comparer that provides an arbitrary but stable total ordering for range values, used internally by EF Core's update pipeline
  2. NpgsqlPeriodForeignKeyPostprocessor: A query postprocessor that rewrites join predicates for PERIOD foreign keys from equality (=) to range containment (@>)
  3. Integration points in model conventions to automatically apply the comparer to range key/FK properties
  4. Comprehensive functional tests demonstrating the temporal constraint features

Changes:

  • Added custom comparer for NpgsqlRange to enable use in keys and foreign keys
  • Implemented query postprocessor to handle PERIOD foreign key semantics with range containment
  • Added comprehensive functional tests for temporal constraints including WITHOUT OVERLAPS and PERIOD features
  • Removed obsolete workaround comments from unit tests

Reviewed changes

Copilot reviewed 9 out of 10 changed files in this pull request and generated no comments.

Show a summary per file
File Description
src/EFCore.PG/ChangeTracking/Internal/NpgsqlRangeCurrentValueComparer.cs New comparer providing total ordering for NpgsqlRange values used in keys/FKs
src/EFCore.PG/Metadata/Conventions/NpgsqlPostgresModelFinalizingConvention.cs Sets range comparer during model finalization for key/FK properties
src/EFCore.PG/Metadata/Conventions/NpgsqlRuntimeModelConvention.cs Applies range comparer to runtime model properties; modernizes to primary constructor
src/EFCore.PG/Query/Internal/NpgsqlPeriodForeignKeyPostprocessor.cs New postprocessor rewriting PERIOD FK joins from equality to containment
src/EFCore.PG/Query/Internal/NpgsqlQueryTranslationPostprocessor.cs Integrates PERIOD FK postprocessor; modernizes to primary constructor
src/EFCore.PG/Properties/NpgsqlStrings.resx Adds error message for unsupported tracking with PERIOD FKs
src/EFCore.PG/Properties/NpgsqlStrings.Designer.cs Generated code for new error message
test/EFCore.PG.FunctionalTests/TemporalConstraintTest.cs Comprehensive functional tests covering INSERT, query, UPDATE, DELETE, and error scenarios for temporal constraints
test/EFCore.PG.Tests/Infrastructure/NpgsqlModelValidatorTest.cs Removes obsolete workaround comments now that range types work in keys
test/EFCore.PG.FunctionalTests/SpatialNpgsqlFixture.cs Minor whitespace improvement for readability
Files not reviewed (1)
  • src/EFCore.PG/Properties/NpgsqlStrings.Designer.cs: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@roji roji merged commit 86c777b into npgsql:main Feb 22, 2026
14 checks passed
@roji roji deleted the TemporalAgain branch February 22, 2026 12:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Can't Use NpgsqlRange in Composite Key

2 participants