X Tutup
Skip to content

Breaking change in 8.0: NpgsqlDataReader.GetValue with CommandBehavior.SequentialAccess #5439

@kae

Description

@kae

Steps to reproduce

using System;
using System.Threading.Tasks;

namespace pgTest;

public class Program {
	private const string ConnStr = "Server=pg;Port=5432;Database=temp;User id=admin;Password=admin";
	private static readonly Npgsql.NpgsqlDataSource ds = new Npgsql.NpgsqlDataSourceBuilder(ConnStr).Build();

	public static async Task Main() {
		try {
			Console.WriteLine($"Started");
			using var conn = await ds.OpenConnectionAsync();
			Console.WriteLine($"Connected");
			using var tx = await conn.BeginTransactionAsync();

			using var cmd = conn.CreateCommand();
			cmd.CommandTimeout = 1;
			cmd.Transaction = tx;
			cmd.CommandText = """select v.i, jsonb_build_object(), current_timestamp + make_interval(0, 0, 0, 0, 0, 0, v.i), null::jsonb, '{"value": 42}'::jsonb from generate_series(1, 1000) as v(i)""";
			var rdr = await cmd.ExecuteReaderAsync(System.Data.CommandBehavior.SingleResult | System.Data.CommandBehavior.SequentialAccess);
			while (await rdr.ReadAsync()) {
				var v1 = rdr[0];
				var v2 = rdr[1];
				//_ = rdr[2]; // uncomment line for successful execution
				var v3 = rdr[3];
				var v4 = rdr[4];
			}
			await rdr.DisposeAsync();
			await cmd.DisposeAsync();

			await tx.CommitAsync();
			await conn.DisposeAsync();
		}
		catch (Exception e) {
			Console.WriteLine(e);
		}
	}
}

The issue

With pre-8.0 versions program executes successfuly.
With 8.0 gets error

System.InvalidCastException: Unknown wire format version: 55
   at Npgsql.Internal.Converters.VersionPrefixedTextConverter.ReadVersion(Boolean async, Byte expectedVersion, PgReader reader, Size textConverterReadRequirement, CancellationToken cancellationToken)
   at Npgsql.Internal.Converters.VersionPrefixedTextConverter`1.Read(Boolean async, PgReader reader, CancellationToken cancellationToken)
   at Npgsql.Internal.Converters.VersionPrefixedTextConverter`1.Read(PgReader reader)
   at Npgsql.Internal.PgStreamingConverter`1.ReadAsObject(Boolean async, PgReader reader, CancellationToken cancellationToken)
   at Npgsql.Internal.PgConverter.ReadAsObject(PgReader reader)
   at Npgsql.NpgsqlDataReader.GetValue(Int32 ordinal)
   at Npgsql.NpgsqlDataReader.get_Item(Int32 ordinal)
   at pgTest.Program.Main() in C:\Users\kae\Dump\dnx\pgTest\Program.cs:line 27

Surprisingly, lowering count in generate_series may cause execution without error (in my case with 100)

Access to reader fields without skipping index also remove error.

This behavior cause issues with Dapper, when results of execution contain columns that doesn't map with model to deserialize.

Npgsql version: 8.0.0
PostgreSQL version: 16.0
Operating system: Windows

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions

    X Tutup