Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Move conversion context to connector#6587

Open
NinoFloris wants to merge 13 commits into
npgsql:mainnpgsql/npgsql:mainfrom
NinoFloris:connector-conversion-contextNinoFloris/npgsql:connector-conversion-contextCopy head branch name to clipboard
Open

Move conversion context to connector#6587
NinoFloris wants to merge 13 commits into
npgsql:mainnpgsql/npgsql:mainfrom
NinoFloris:connector-conversion-contextNinoFloris/npgsql:connector-conversion-contextCopy head branch name to clipboard

Conversation

@NinoFloris

Copy link
Copy Markdown
Member

And update mid session changes via ParameterStatus. Closes #5146

Copilot AI review requested due to automatic review settings May 22, 2026 21:18
@NinoFloris
NinoFloris requested review from Brar, roji and vonzshik as code owners May 22, 2026 21:18

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR moves conversion/session state (text encoding, time zone, and other ParameterStatus-driven values) from PgSerializerOptions to a per-connector PgConversionContext, and threads that context through binding/reading/writing so Npgsql can react to mid-session state changes (notably client_encoding and TimeZone).

Changes:

  • Introduces per-connection NpgsqlConnector.ConversionContext, rotates it on relevant ParameterStatus updates, and updates reader/writer/binding call sites to use it.
  • Adjusts type binding (PgConcreteTypeInfo) to distinguish invariant vs context-dependent descriptors and re-resolve buffer requirements at runtime when needed.
  • Updates NodaTime legacy timestamp-tz converters to resolve time zone at read-time from the connection context instead of capturing it at type-mapping creation time.

Reviewed changes

Copilot reviewed 27 out of 27 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
test/Npgsql.Tests/WriteStateTests.cs Updates parameter binding calls to pass an explicit conversion context in tests.
test/Npgsql.Benchmarks/WriteParameter.cs Uses connector conversion context for benchmark parameter binding.
src/Npgsql/Replication/PgOutput/ReplicationValue.cs Uses connector conversion context when resolving field types and conversion contexts.
src/Npgsql/NpgsqlParameterCollection.cs Threads conversion context into validation-time parameter binding.
src/Npgsql/NpgsqlParameter`.cs Passes conversion context into typed parameter binding.
src/Npgsql/NpgsqlParameter.cs Updates Bind/typed binding hooks to accept conversion context and flow it into concrete binding.
src/Npgsql/NpgsqlNestedDataReader.cs Passes connector conversion context into field binding for nested reads.
src/Npgsql/NpgsqlDataSource.cs Stops constructing serializer options with per-connector encoding/timezone; options become context-agnostic.
src/Npgsql/NpgsqlDataReader.cs Threads connector conversion context into row description conversion-context resolution.
src/Npgsql/NpgsqlCommand.cs Passes connector conversion context into parameter processing.
src/Npgsql/NpgsqlBinaryImporter.cs Passes connector conversion context into binary import parameter binding.
src/Npgsql/NpgsqlBinaryExporter.cs Passes connector conversion context into binary export field binding.
src/Npgsql/Internal/PgWriter.cs Captures conversion context per Init and uses cached encoder when available to reduce allocations.
src/Npgsql/Internal/PgTypeInfo.cs Probes descriptors with empty context, caches invariance flags, and re-resolves requirements when non-invariant.
src/Npgsql/Internal/PgSerializerOptions.cs Removes TimeZone provider and shared ConversionContext from serializer options.
src/Npgsql/Internal/PgReader.cs Sources conversion context from connector (or buffer fallback when connector-less).
src/Npgsql/Internal/PgConverter.cs Extends PgConversionContext to carry encoder/timezone; documents invariance via ConverterDescriptor.
src/Npgsql/Internal/NpgsqlWriteBuffer.cs Sources encoding from connector dynamically and uses connector encoder; adds fallback conversion context for connector-less buffers.
src/Npgsql/Internal/NpgsqlReadBuffer.cs Sources encoding from connector dynamically; adds fallback conversion context for connector-less buffers.
src/Npgsql/Internal/NpgsqlConnector.FrontendMessages.cs Binds parameters using connector conversion context when writing Bind messages.
src/Npgsql/Internal/NpgsqlConnector.cs Adds per-connector conversion context and encoder cache; rotates them on TimeZone/client_encoding ParameterStatus changes.
src/Npgsql/Internal/Converters/RecordConverter.cs Binds fields using the runtime reader conversion context.
src/Npgsql/Internal/Converters/CompositeConverter.cs Resolves composite field read requirements using runtime conversion context.
src/Npgsql/Internal/Composites/Metadata/CompositeFieldInfo.cs Re-resolves requirements for non-invariant composite fields using runtime conversion context; adjusts fast-path assumptions.
src/Npgsql/BackendMessages/RowDescriptionMessage.cs Threads conversion context into field binding/conversion-context resolution and field-type lookup.
src/Npgsql.NodaTime/Internal/NodaTimeTypeInfoResolverFactory.cs Stops capturing time zone at mapping creation; defers to runtime context.
src/Npgsql.NodaTime/Internal/LegacyConverters.cs Resolves session time zone at read-time from PgConversionContext and preserves the localtime error behavior.

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

Comment thread src/Npgsql/BackendMessages/RowDescriptionMessage.cs
Comment thread src/Npgsql/NpgsqlDataReader.cs
Comment thread src/Npgsql/Internal/NpgsqlConnector.cs

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 28 out of 28 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (1)

src/Npgsql/BackendMessages/RowDescriptionMessage.cs:360

  • FieldDescription.GetInfoAndBind can return a cached _objectConversionContext that was built against a prior PgConversionContext when called with type==typeof(object) and DataFormat != Text. Since PgConversionContext instances are rotated on ParameterStatus updates (client_encoding/TimeZone), this can serve stale BufferRequirement data. Consider routing any access to the object-typed cache through GetObjectConversionContext(conversionContext) (at least when type is null or typeof(object)), rather than using _objectConversionContext directly.
        if (result is { IsDefault: false, TypeInfo.Type: var typeToConvert } && typeToConvert == type)
            return;

        var objectInfo = DataFormat is DataFormat.Text && type is not null ? GetObjectConversionContext(conversionContext) : _objectConversionContext;
        if (objectInfo.TypeInfo is not null && (typeof(object) == type || objectInfo.TypeInfo.Type == type))
        {
            result = objectInfo;
            return;

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 28 out of 28 changed files in this pull request and generated 4 comments.

Comment thread src/Npgsql/BackendMessages/RowDescriptionMessage.cs Outdated
Comment thread src/Npgsql/NpgsqlDataReader.cs Outdated
Comment thread src/Npgsql.NodaTime/Internal/LegacyConverters.cs
Comment thread src/Npgsql/Replication/PgOutput/ReplicationValue.cs

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 28 out of 28 changed files in this pull request and generated 2 comments.

Comment thread src/Npgsql/BackendMessages/RowDescriptionMessage.cs Outdated
Comment thread src/Npgsql/NpgsqlDataReader.cs Outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 28 out of 28 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (1)

src/Npgsql/BackendMessages/RowDescriptionMessage.cs:366

  • FieldDescription.GetInfoAndBind can return a cached _objectConversionContext that was resolved against an older PgConversionContext: when type != null and DataFormat != Text, objectInfo is taken directly from _objectConversionContext (line 362) and returned for object/matching types without checking SourceContext. After a client_encoding/TimeZone rotation, this can reuse stale BufferRequirement/binding. Consider ensuring that any returned objectInfo was resolved against the supplied conversionContext (e.g., call GetObjectConversionContext(conversionContext) whenever type != null, or explicitly check ReferenceEquals(objectInfo.SourceContext, conversionContext) before using _objectConversionContext).
        var objectInfo = DataFormat is DataFormat.Text && type is not null ? GetObjectConversionContext(conversionContext) : _objectConversionContext;
        if (objectInfo.TypeInfo is not null && (typeof(object) == type || objectInfo.TypeInfo.Type == type))
        {
            result = objectInfo;
            return;

Comment thread src/Npgsql/NpgsqlDataReader.cs Outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 28 out of 28 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (1)

src/Npgsql/NpgsqlParameter.cs:756

  • Bind is idempotent via _isBound, but it doesn’t validate that the cached _binding was produced against the same PgConversionContext instance passed in. After a mid-session client_encoding/TimeZone rotation the connector replaces ConversionContext, and reusing a binding computed under the old context can yield an incorrect size (e.g. string byte count differs between UTF-8 and WIN1252), which can corrupt the bind message/protocol framing. Consider storing the source PgConversionContext on the parameter binding (similar to ReadConversionContext.SourceContext) and forcing DisposeBindingState()/rebind when it differs (or when relevant fields changed).
    /// Bind the current value to the type info, truncate (if applicable), take its size, and do any final validation before writing.
    internal void Bind(PgConversionContext conversionContext, out DataFormat format, out Size size, DataFormat? requiredFormat = null)
    {
        if (TypeInfo is null || ConcreteTypeInfo is null)
            ThrowHelper.ThrowInvalidOperationException($"Missing type info, {nameof(ResolveTypeInfo)} needs to be called before {nameof(Bind)}.");

        // Invalidate a cached binding whose format no longer matches what the caller requires —
        // the type info may still support the required format, just not the format the cached
        // binding chose. Re-running Bind with the new preference can produce a satisfying binding.
        if (_isBound && requiredFormat is not null && _binding.DataFormat != requiredFormat.GetValueOrDefault())
        {
            DisposeBindingState();

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 28 out of 28 changed files in this pull request and generated 1 comment.

Comment thread src/Npgsql/Internal/NpgsqlConnector.cs Outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 28 out of 28 changed files in this pull request and generated 2 comments.

Comment thread src/Npgsql/Internal/NpgsqlConnector.cs
Comment thread src/Npgsql/Internal/NpgsqlConnector.cs

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 34 out of 34 changed files in this pull request and generated 1 comment.

Comment thread src/Npgsql/Internal/NpgsqlWriteBuffer.cs

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 34 out of 34 changed files in this pull request and generated 1 comment.

Comment thread src/Npgsql/Internal/Composites/Metadata/CompositeFieldInfo.cs Outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 34 out of 34 changed files in this pull request and generated 2 comments.

Comment thread src/Npgsql.NodaTime/Internal/LegacyConverters.cs
Comment thread src/Npgsql/Internal/NpgsqlConnector.cs

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 34 out of 34 changed files in this pull request and generated 1 comment.

Comment thread src/Npgsql/Internal/NpgsqlConnector.cs

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 34 out of 34 changed files in this pull request and generated 1 comment.

Comment thread src/Npgsql/NpgsqlNestedDataReader.cs

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 34 out of 34 changed files in this pull request and generated no new comments.

@NinoFloris
NinoFloris force-pushed the connector-conversion-context branch from 45457c9 to e3ff456 Compare May 23, 2026 15:53
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.

React better to connection state changes at runtime (e.g. client_encoding)

2 participants

Morty Proxy This is a proxified and sanitized view of the page, visit original site.