-
Notifications
You must be signed in to change notification settings - Fork 874
Milestone
Description
Hi! I've faced an issue with Npgsql (v9.0.3) + Dapper (dynamic binding) when converting numeric to BigInteger (I'm using a custom TypeInfoResolverFactory, just like here: #448 (comment)).
It randomly fails on different queries with one the following errors:
There is not enough data left in the buffer.
System.InvalidCastException: Numeric value with non-zero fractional digits not supported by BigInteger
at Tzkt.Api.PgNumeric.Builder.ToBigInteger(Int16 weight, UInt16 sign, Span`1 digits)
at Tzkt.Api.BigIntegerNumericConverter.Read(PgReader reader)
System.ArgumentOutOfRangeException: Buffer requirement is larger than the remaining length of the value, make sure the value is always at least this size or use an upper bound requirement instead. (Parameter 'byteCount')
at Npgsql.ThrowHelper.ThrowArgumentOutOfRangeException(String paramName, String message)
at Npgsql.Internal.PgReader.<ShouldBuffer>g__ShouldBufferSlow|115_0(<>c__DisplayClass115_0&)
at Tzkt.Api.BigIntegerNumericConverter.Read(PgReader reader)
System.ArgumentOutOfRangeException: length ('-1') must be a non-negative value. (Parameter 'length')
Actual value was -1.
at System.ArgumentOutOfRangeException.ThrowNegative[T](T value, String paramName)
at System.Array.CopyImpl(Array sourceArray, Int32 sourceIndex, Array destinationArray, Int32 destinationIndex, Int32 length, Boolean reliable)
at Npgsql.Internal.NpgsqlReadBuffer.<Ensure>g__EnsureLong|55_0(NpgsqlReadBuffer buffer, Int32 count, Boolean async, Boolean readingNotifications)
at System.Runtime.CompilerServices.PoolingAsyncValueTaskMethodBuilder`1.StateMachineBox`1.System.Threading.Tasks.Sources.IValueTaskSource.GetResult(Int16 token)
at Npgsql.Internal.NpgsqlReadBuffer.Ensure(Int32 count)
at Tzkt.Api.BigIntegerNumericConverter.Read(PgReader reader)
System.IndexOutOfRangeException: Index was outside the bounds of the array.
at Tzkt.Api.BigIntegerNumericConverter.Read(PgReader reader) // in var digitCount = reader.ReadInt16();
Not sure if this is the reason, but I think the issue is caused by BigIntegerNumericConverter inheriting bufferRequirements = BufferRequirements.None; from PgStreamingConverter, that makes PgReader.GetBufferRequirementByteCount return 0, that makes PgReader.ShouldBuffer return false, that causes NpgsqlDataReader.GetValue to read from a possibly empty buffer.
As a quick workaround I've tried to patch the converter:
class PatchedBigIntegerNumericConverter : BigIntegerNumericConverter
{
public override bool CanConvert(DataFormat format, out BufferRequirements bufferRequirements)
{
bufferRequirements = BufferRequirements.Create(Size.CreateUpperBound(8192));
return format is DataFormat.Binary;
}
}and it seems to be working fine now.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels