Skip to content

6.1.0: Errors while executing the query #3519

@Jakimar

Description

@Jakimar

Describe the bug

After upgrading from 6.0.1 to 6.1.0, some of my queries started to fail with an error.
If you roll back to 6.0.1 the error disappears

Sometimes the request hangs for a long time (I stopped waiting after 3 minutes) and sometimes I get one of the following errors:

1:
Specified argument was out of the range of valid values., System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values.
   at Microsoft.Data.SqlClient.TdsParserStateObject.TryReadByteArray(Span`1 buff, Int32 len, Int32& totalRead, Int32 startOffset, Boolean writeDataSizeToSnapshot)
   at Microsoft.Data.SqlClient.TdsParserStateObject.TryReadByteArray(Span`1 buff, Int32 len)
   at Microsoft.Data.SqlClient.TdsParser.TryReadSqlValueInternal(SqlBuffer value, Byte tdsType, Int32 length, TdsParserStateObject stateObj)
   at Microsoft.Data.SqlClient.TdsParser.TryReadSqlValue(SqlBuffer value, SqlMetaDataPriv md, Int32 length, TdsParserStateObject stateObj, SqlCommandColumnEncryptionSetting columnEncryptionOverride, String columnName, SqlCommand command)
   at Microsoft.Data.SqlClient.SqlDataReader.TryReadColumnInternal(Int32 i, Boolean readHeaderOnly, Boolean forStreaming)
   at Microsoft.Data.SqlClient.SqlDataReader.TryReadColumn(Int32 i, Boolean setTimeout, Boolean allowPartiallyReadColumn, Boolean forStreaming)
   at Microsoft.Data.SqlClient.SqlDataReader.ReadAsyncExecute(Task task, Object state)
   at Microsoft.Data.SqlClient.SqlDataReader.ContinueAsyncCall[T](Task task, SqlDataReaderBaseAsyncCallContext`1 context)
   at Microsoft.Data.SqlClient.SqlDataReader.SqlDataReaderBaseAsyncCallContext`1.ExecuteAsyncCallCallback(Task task, Object state)
   at System.Threading.Tasks.ContinuationResultTaskFromResultTask`2.InnerInvoke()
   at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)   
--- End of stack trace from previous location ---
   at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)   
   at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)

2:
Offset and length were out of bounds for the array or count is greater than the number of elements from index to the end of the source collection., System.ArgumentException: Offset and length were out of bounds for the array or count is greater than the number of elements from index to the end of the source collection.
   at System.Buffer.BlockCopy(Array src, Int32 srcOffset, Array dst, Int32 dstOffset, Int32 count)
   at Microsoft.Data.SqlClient.TdsParserStateObject.TryReadPlpBytes(Byte[]& buff, Int32 offset, Int32 len, Int32& totalBytesRead, Boolean canContinue, Boolean writeDataSizeToSnapshot, Boolean compatibilityMode)
   at Microsoft.Data.SqlClient.TdsParserStateObject.TryReadPlpBytes(Byte[]& buff, Int32 offset, Int32 len, Int32& totalBytesRead)
   at Microsoft.Data.SqlClient.TdsParserStateObject.TryReadStringWithEncoding(Int32 length, Encoding encoding, Boolean isPlp, String& value)
   at Microsoft.Data.SqlClient.TdsParser.TryReadSqlStringValue(SqlBuffer value, Byte type, Int32 length, Encoding encoding, Boolean isPlp, TdsParserStateObject stateObj)
   at Microsoft.Data.SqlClient.TdsParser.TryReadSqlValue(SqlBuffer value, SqlMetaDataPriv md, Int32 length, TdsParserStateObject stateObj, SqlCommandColumnEncryptionSetting columnEncryptionOverride, String columnName, SqlCommand command)
   at Microsoft.Data.SqlClient.SqlDataReader.TryReadColumnInternal(Int32 i, Boolean readHeaderOnly, Boolean forStreaming)
   at Microsoft.Data.SqlClient.SqlDataReader.TryReadColumn(Int32 i, Boolean setTimeout, Boolean allowPartiallyReadColumn, Boolean forStreaming)
   at Microsoft.Data.SqlClient.SqlDataReader.ReadAsyncExecute(Task task, Object state)
   at Microsoft.Data.SqlClient.SqlDataReader.ContinueAsyncCall[T](Task task, SqlDataReaderBaseAsyncCallContext`1 context)
   at Microsoft.Data.SqlClient.SqlDataReader.SqlDataReaderBaseAsyncCallContext`1.ExecuteAsyncCallCallback(Task task, Object state)
   at System.Threading.Tasks.ContinuationResultTaskFromResultTask`2.InnerInvoke()
   at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)       
--- End of stack trace from previous location ---
   at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)       
   at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)
--- End of stack trace from previous location ---


3:
Arithmetic operation resulted in an overflow., System.OverflowException: Arithmetic operation resulted in an overflow.
   at Microsoft.Data.SqlClient.TdsParserStateObject.TryReadPlpBytes(Byte[]& buff, Int32 offset, Int32 len, Int32& totalBytesRead, Boolean canContinue, Boolean writeDataSizeToSnapshot, Boolean compatibilityMode)
   at Microsoft.Data.SqlClient.TdsParserStateObject.TryReadPlpBytes(Byte[]& buff, Int32 offset, Int32 len, Int32& totalBytesRead)
   at Microsoft.Data.SqlClient.TdsParserStateObject.TryReadStringWithEncoding(Int32 length, Encoding encoding, Boolean isPlp, String& value)
   at Microsoft.Data.SqlClient.TdsParser.TryReadSqlStringValue(SqlBuffer value, Byte type, Int32 length, Encoding encoding, Boolean isPlp, TdsParserStateObject stateObj)
   at Microsoft.Data.SqlClient.TdsParser.TryReadSqlValue(SqlBuffer value, SqlMetaDataPriv md, Int32 length, TdsParserStateObject stateObj, SqlCommandColumnEncryptionSetting columnEncryptionOverride, String columnName, SqlCommand command)
   at Microsoft.Data.SqlClient.SqlDataReader.TryReadColumnInternal(Int32 i, Boolean readHeaderOnly, Boolean forStreaming)
   at Microsoft.Data.SqlClient.SqlDataReader.TryReadColumn(Int32 i, Boolean setTimeout, Boolean allowPartiallyReadColumn, Boolean forStreaming)
   at Microsoft.Data.SqlClient.SqlDataReader.ReadAsyncExecute(Task task, Object state)
   at Microsoft.Data.SqlClient.SqlDataReader.ContinueAsyncCall[T](Task task, SqlDataReaderBaseAsyncCallContext`1 context)
   at Microsoft.Data.SqlClient.SqlDataReader.SqlDataReaderBaseAsyncCallContext`1.ExecuteAsyncCallCallback(Task task, Object state)
   at System.Threading.Tasks.ContinuationResultTaskFromResultTask`2.InnerInvoke()
   at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)       
--- End of stack trace from previous location ---
   at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)       
   at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)

If you remove xml columns from the read query

Unexpected Unrecoverable Error., System.InvalidOperationException: Unexpected Unrecoverable Error.
   at Microsoft.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
   at Microsoft.Data.SqlClient.SqlDataReader.TryCloseInternal(Boolean closeReader)
   at Microsoft.Data.SqlClient.SqlDataReader.Close()
   at Microsoft.Data.SqlClient.SqlDataReader.Dispose(Boolean disposing)

To reproduce

I created a small project on which I now consistently receive errors:

// I was able to reproduce the error only when connecting to a remote server with a login and password
string connectionString = "Data Source=remote-server; Initial Catalog=test_db; User Id= test_user; Password=password;Encrypt=False";
        
var dbTester = new DatabaseTester(connectionString);
        
try
{
    Console.WriteLine("Creating table...");
    dbTester.CreateTable();
            
    Console.WriteLine("Filling table...");
    dbTester.FillTable();
            
    Console.WriteLine($"Table have {dbTester.GetRecordCount()} records");
    
    Console.WriteLine("Getting records GetDataAsync...");
   var data2 = await dbTester.GetDataAsync();
   Console.WriteLine("Getting records GetDataAsync(int, int)...");
    await dbTester.GetDataAsync(100, 1000);
    
    foreach (var row in data2)
    {
        Console.WriteLine(row.ToString());
    }

    for (int i = 0; i < 100; i++)
    {
        Console.WriteLine($"TEST RUN {i}");
        var data22 = await dbTester.GetDataAsync();
        await dbTester.GetDataAsync(100, 1000);
    }
}
catch (Exception ex)
{
    Console.WriteLine($"Error: {ex.Message}, {ex.ToString()}");
}
finally
{
     dbTester.DropTable();
}


using System.Data;
using System.Text;
using System.Xml;
using Microsoft.Data.SqlClient;

public class DatabaseTester
{
    private readonly string _connectionString;
    private const string TableName = "TestTable";

    public DatabaseTester(string connectionString)
    {
        _connectionString = connectionString;
    }
    
    public void CreateTable()
    {
        string createTableQuery = $@"
            IF OBJECT_ID('{TableName}', 'U') IS NOT NULL
                DROP TABLE {TableName};

            CREATE TABLE {TableName} (
                Id INT IDENTITY(1,1) PRIMARY KEY,
                Column1 VARCHAR(MAX),
                Column2 VARCHAR(MAX),
                Column3 VARCHAR(MAX),
                Column4 VARCHAR(MAX),
                Column5 VARCHAR(MAX),
                Column6 INT,
                Column7 DATETIME,
                Column8 DECIMAL(18,2),
                Column9 BIT,
                Column10 UNIQUEIDENTIFIER,
                Column11 XML,
                Column12 XML,
                Column13 BIGINT,
                Column14 SMALLINT,
                Column15 NVARCHAR(255)
            )";

        using (var connection = new SqlConnection(_connectionString))
        {
            connection.Open();
            using (var command = new SqlCommand(createTableQuery, connection))
            {
                command.ExecuteNonQuery();
            }
        }
    }
    
    public void FillTable()
    {
        using (var connection = new SqlConnection(_connectionString))
        {
            connection.Open();
            
            var random = new Random();
            var insertQuery = $@"
                INSERT INTO {TableName} (
                    Column1, Column2, Column3, Column4, Column5, 
                    Column6, Column7, Column8, Column9, Column10, 
                    Column11, Column12, Column13, Column14, Column15
                ) VALUES (
                    @Column1, @Column2, @Column3, @Column4, @Column5,
                    @Column6, @Column7, @Column8, @Column9, @Column10,
                    @Column11, @Column12, @Column13, @Column14, @Column15
                )";

            using (var command = new SqlCommand(insertQuery, connection))
            {
                command.Parameters.Add("@Column1", SqlDbType.VarChar, -1);
                command.Parameters.Add("@Column2", SqlDbType.VarChar, -1);
                command.Parameters.Add("@Column3", SqlDbType.VarChar, -1);
                command.Parameters.Add("@Column4", SqlDbType.VarChar, -1);
                command.Parameters.Add("@Column5", SqlDbType.VarChar, -1);
                command.Parameters.Add("@Column6", SqlDbType.Int);
                command.Parameters.Add("@Column7", SqlDbType.DateTime);
                command.Parameters.Add("@Column8", SqlDbType.Decimal);
                command.Parameters.Add("@Column9", SqlDbType.Bit);
                command.Parameters.Add("@Column10", SqlDbType.UniqueIdentifier);
                command.Parameters.Add("@Column11", SqlDbType.Xml);
                command.Parameters.Add("@Column12", SqlDbType.Xml);
                command.Parameters.Add("@Column13", SqlDbType.BigInt);
                command.Parameters.Add("@Column14", SqlDbType.SmallInt);
                command.Parameters.Add("@Column15", SqlDbType.NVarChar, 255);
                
                for (int i = 0; i < 5000; i++)
                {
                    command.Parameters["@Column1"].Value = GenerateRandomString(random, 1000);
                    command.Parameters["@Column2"].Value = GenerateRandomString(random, 1500);
                    command.Parameters["@Column3"].Value = GenerateRandomString(random, 2000);
                    command.Parameters["@Column4"].Value = GenerateRandomString(random, 500);
                    command.Parameters["@Column5"].Value = GenerateRandomString(random, 800);
                    command.Parameters["@Column6"].Value = random.Next(1, 1000000);
                    command.Parameters["@Column7"].Value = DateTime.Now.AddDays(-random.Next(1, 3650));
                    command.Parameters["@Column8"].Value = Math.Round((decimal)(random.NextDouble() * 10000), 2);
                    command.Parameters["@Column9"].Value = random.Next(0, 2) == 1;
                    command.Parameters["@Column10"].Value = Guid.NewGuid();
                    command.Parameters["@Column11"].Value = Random.Shared.Next(0, 3) == 2 ? GenerateRandomXml(random, 5) : DBNull.Value;
                    command.Parameters["@Column12"].Value = GenerateRandomXml(random, 3);
                    command.Parameters["@Column13"].Value = (long)random.Next(1, int.MaxValue) * 1000L;
                    command.Parameters["@Column14"].Value = (short)random.Next(1, 1000);
                    command.Parameters["@Column15"].Value = $"Record_{i}_{GenerateRandomString(random, 20)}";

                    command.ExecuteNonQuery();
                }
            }
        }
    }
    
    public async Task<List<TestTableRow>> GetDataAsync()
    {
        var result = new List<TestTableRow>();
        string selectQuery = $"SELECT * FROM {TableName} ORDER BY Id";
        
        using (var connection = new SqlConnection(_connectionString))
        {
            await connection.OpenAsync();
            using (var command = new SqlCommand(selectQuery, connection))
            {
                using (var reader = await command.ExecuteReaderAsync())
                {
                    while (await reader.ReadAsync())
                    {
                        var row = new TestTableRow
                        {
                            Id = reader.GetInt32("Id"),
                            Column1 = reader.IsDBNull("Column1") ? null : reader.GetString("Column1"),
                            Column2 = reader.IsDBNull("Column2") ? null : reader.GetString("Column2"),
                            Column3 = reader.IsDBNull("Column3") ? null : reader.GetString("Column3"),
                            Column4 = reader.IsDBNull("Column4") ? null : reader.GetString("Column4"),
                            Column5 = reader.IsDBNull("Column5") ? null : reader.GetString("Column5"),
                            Column6 = reader.IsDBNull("Column6") ? 0 : reader.GetInt32("Column6"),
                            Column7 = reader.IsDBNull("Column7") ? DateTime.MinValue : reader.GetDateTime("Column7"),
                            Column8 = reader.IsDBNull("Column8") ? 0 : reader.GetDecimal("Column8"),
                            Column9 = reader.IsDBNull("Column9") ? false : reader.GetBoolean("Column9"),
                            Column10 = reader.IsDBNull("Column10") ? Guid.Empty : reader.GetGuid("Column10"),
                            Column11 = reader.IsDBNull("Column11") ? null : reader.GetString("Column11"),
                            Column12 = reader.IsDBNull("Column12") ? null : reader.GetString("Column12"),
                            Column13 = reader.IsDBNull("Column13") ? 0 : reader.GetInt64("Column13"),
                            Column14 = reader.IsDBNull("Column14") ? (short)0 : reader.GetInt16("Column14"),
                            Column15 = reader.IsDBNull("Column15") ? null : reader.GetString("Column15")
                        };
                        
                        result.Add(row);
                    }
                }
            }
        }

        return result;
    }
    
    public async Task<List<TestTableRow>> GetDataAsync(int pageNumber, int pageSize)
    {
        var result = new List<TestTableRow>();
        int offset = (pageNumber - 1) * pageSize;
        
        string selectQuery = $@"
            SELECT * FROM {TableName}
            ORDER BY Id
            OFFSET {offset} ROWS
            FETCH NEXT {pageSize} ROWS ONLY";

        using (var connection = new SqlConnection(_connectionString))
        {
            await connection.OpenAsync();
            using (var command = new SqlCommand(selectQuery, connection))
            {
                using (var reader = await command.ExecuteReaderAsync())
                {
                    while (await reader.ReadAsync())
                    {
                        var row = new TestTableRow
                        {
                            Id = reader.GetInt32("Id"),
                            Column1 = reader.IsDBNull("Column1") ? null : reader.GetString("Column1"),
                            Column2 = reader.IsDBNull("Column2") ? null : reader.GetString("Column2"),
                            Column3 = reader.IsDBNull("Column3") ? null : reader.GetString("Column3"),
                            Column4 = reader.IsDBNull("Column4") ? null : reader.GetString("Column4"),
                            Column5 = reader.IsDBNull("Column5") ? null : reader.GetString("Column5"),
                            Column6 = reader.IsDBNull("Column6") ? 0 : reader.GetInt32("Column6"),
                            Column7 = reader.IsDBNull("Column7") ? DateTime.MinValue : reader.GetDateTime("Column7"),
                            Column8 = reader.IsDBNull("Column8") ? 0 : reader.GetDecimal("Column8"),
                            Column9 = reader.IsDBNull("Column9") ? false : reader.GetBoolean("Column9"),
                            Column10 = reader.IsDBNull("Column10") ? Guid.Empty : reader.GetGuid("Column10"), 
                            Column11 = reader.IsDBNull("Column11") ? null : reader.GetString("Column11"), 
                            Column12 = reader.IsDBNull("Column12") ? null : reader.GetString("Column12"),
                            Column13 = reader.IsDBNull("Column13") ? 0 : reader.GetInt64("Column13"),
                            Column14 = reader.IsDBNull("Column14") ? (short)0 : reader.GetInt16("Column14"),
                            Column15 = reader.IsDBNull("Column15") ? null : reader.GetString("Column15")
                        };
                        
                        result.Add(row);
                    }
                }
            }
        }

        return result;
    }

    public class TestTableRow
    {
        public int Id { get; set; }
        public string Column1 { get; set; }
        public string Column2 { get; set; }
        public string Column3 { get; set; }
        public string Column4 { get; set; }
        public string Column5 { get; set; }
        public int Column6 { get; set; }
        public DateTime Column7 { get; set; }
        public decimal Column8 { get; set; }
        public bool Column9 { get; set; }
        public Guid Column10 { get; set; }
        public string Column11 { get; set; } // XML
        public string Column12 { get; set; } // XML
        public long Column13 { get; set; }
        public short Column14 { get; set; }
        public string Column15 { get; set; }

        public override string ToString()
        {
            return $"Id: {Id}, Column15: {Column15}";
        }
    }
    
    public int GetRecordCount()
    {
        string countQuery = $"SELECT COUNT(*) FROM {TableName}";
        
        using (var connection = new SqlConnection(_connectionString))
        {
            connection.Open();
            using (var command = new SqlCommand(countQuery, connection))
            {
                return (int)command.ExecuteScalar();
            }
        }
    }
    
    public void DropTable()
    {
        string dropTableQuery = $"IF OBJECT_ID('{TableName}', 'U') IS NOT NULL DROP TABLE {TableName}";

        using (var connection = new SqlConnection(_connectionString))
        {
            connection.Open();
            using (var command = new SqlCommand(dropTableQuery, connection))
            {
                command.ExecuteNonQuery();
            }
        }
    }

    private DataTable CreateDataTable()
    {
        var dataTable = new DataTable();
        dataTable.Columns.Add("Column1", typeof(string));
        dataTable.Columns.Add("Column2", typeof(string));
        dataTable.Columns.Add("Column3", typeof(string));
        dataTable.Columns.Add("Column4", typeof(string));
        dataTable.Columns.Add("Column5", typeof(string));
        dataTable.Columns.Add("Column6", typeof(int));
        dataTable.Columns.Add("Column7", typeof(DateTime));
        dataTable.Columns.Add("Column8", typeof(decimal));
        dataTable.Columns.Add("Column9", typeof(bool));
        dataTable.Columns.Add("Column10", typeof(Guid));
        dataTable.Columns.Add("Column11", typeof(string));
        dataTable.Columns.Add("Column12", typeof(string));
        dataTable.Columns.Add("Column13", typeof(long));
        dataTable.Columns.Add("Column14", typeof(short));
        dataTable.Columns.Add("Column15", typeof(string));
        
        return dataTable;
    }

    private string GenerateRandomString(Random s, int length)
    {
        const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 ";
        var random = new Random();
        var stringBuilder = new StringBuilder(length);
        
        for (int i = 0; i < length; i++)
        {
            stringBuilder.Append(chars[random.Next(chars.Length)]);
        }
        
        return stringBuilder.ToString();
    }

    private string GenerateRandomXml(Random s, int nodeCount)
    {
        var random = new Random();
        nodeCount = random.Next(10, 25);
        var xml = new XmlDocument();
        var root = xml.CreateElement("root");
        xml.AppendChild(root);

        for (int i = 0; i < nodeCount; i++)
        {
            var element = xml.CreateElement($"element_{i}");
            element.InnerText = GenerateRandomString(random, 100);
            root.AppendChild(element);
        }

        return xml.OuterXml;
    }
}

Expected behavior

The query was completed without errors.

Further technical details

Microsoft.Data.SqlClient version: 6.1.0
.NET target: net 9.0
Operating system: Windows 10 Pro
SqlServer: Microsoft SQL Server 2019 (RTM-CU15) (KB5008996) - 15.0.4198.2 (X64)

Metadata

Metadata

Labels

P1Use to label relatively higher severity issues, or issues that impact a large number of customers.Potential RegressionHas not been confirmed as a regression, but it was working properly on a previous versionTriage Done ✔️Issues that are triaged by dev team and are in investigation.

Type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions