NETProvider icon indicating copy to clipboard operation
NETProvider copied to clipboard

DbDataReader.GetIntXX throws "Unable to cast object of type 'System.Numerics.BigInteger' to type 'System.IConvertible'"

Open hazzik opened this issue 3 years ago • 0 comments

When upgrading from Firebird3 to Firebird4 I've found that in certain scenarios the DbDataReader's GetByte, GetInt16, GetInt32, GetInt64 throw "Unable to cast object of type 'System.Numerics.BigInteger' to type 'System.IConvertible'" when resulting column type is INT128.

The reason being that, in our case, the definition of SUMs return type has changed from

Result typeReturns a result of the same numeric data type as the input expression.

To:

The result type of SUM depends on the input type:

input type result type
FLOAT, DOUBLE PRECISION DOUBLE PRECISION
SMALLINT, INTEGER BIGINT
BIGINT, INT128 INT128
DECIMAL/NUMERIC(p, n) with p < 10 DECIMAL/NUMERIC(18, n)
DECIMAL/NUMERIC(p, n) with p >= 10 DECIMAL/NUMERIC(38, n)

Expected behavior: exception should be thrown only when value is too big to fit into the requested type.

The culprit is Convert.ToXXX in this (and similar) code block:

https://github.com/FirebirdSQL/NETProvider/blob/ebd58c427de8fcdc3c5b08541a450dc09831e023/src/FirebirdSql.Data.FirebirdClient/Common/DbValue.cs#L200-L203

Code to reproduce:

var cmd = connection.CreateCommand();
cmd.CommandText = "select sum(cast(1 as bigint)) from RDB$DATABASE";
var r = cmd.ExecuteReader();
r.Read();
var v = r.GetInt64(0);

Full stack trace:

System.InvalidCastException : Unable to cast object of type 'System.Numerics.BigInteger' to type 'System.IConvertible'.
   at System.Convert.ToInt64(Object value, IFormatProvider provider)
   at FirebirdSql.Data.Common.DbValue.GetInt64()
   at FirebirdSql.Data.FirebirdClient.FbDataReader.GetInt64(Int32 i)

hazzik avatar Sep 27 '22 11:09 hazzik