From 04c4d5225bdc107e0965542ddb1005da64121f2c Mon Sep 17 00:00:00 2001 From: Alex Zaytsev Date: Sun, 16 Jul 2023 17:56:37 +0000 Subject: [PATCH] Fix incorrect parameter length for char types in MicrosoftDataSqlClientDriver (#3360) * Run tests for MicrosoftDataSqlClientDriver * Fix character parameter lengths for MicrosoftDataSqlClientDriver --- .github/workflows/NetCoreTests.yml | 4 ++++ appveyor.yml | 4 ++++ psake.ps1 | 13 +++++++++++++ .../TestDatabaseSetup.cs | 1 + .../Driver/MicrosoftDataSqlClientDriver.cs | 16 ++++++++++++++-- src/NHibernate/Driver/SqlClientDriver.cs | 4 ++-- teamcity.build | 11 +++++++++++ 7 files changed, 49 insertions(+), 4 deletions(-) diff --git a/.github/workflows/NetCoreTests.yml b/.github/workflows/NetCoreTests.yml index c88177b97e9..478eabf8f9a 100644 --- a/.github/workflows/NetCoreTests.yml +++ b/.github/workflows/NetCoreTests.yml @@ -12,6 +12,10 @@ jobs: CONNECTION_STRING: "Server=localhost;initial catalog=nhibernate;User Id=sa;Password=P@ssw0rd;packet size=4096;" DB_INIT: | docker run -e "ACCEPT_EULA=Y" -e "SA_PASSWORD=P@ssw0rd" -e "MSSQL_PID=Express" -p 1433:1433 -d --name sqlexpress mcr.microsoft.com/mssql/server:2019-latest; + - DB: SqlServer2008-MicrosoftDataSqlClientDriver + CONNECTION_STRING: "Server=localhost;initial catalog=nhibernate;User Id=sa;Password=P@ssw0rd;packet size=4096;" + DB_INIT: | + docker run -e "ACCEPT_EULA=Y" -e "SA_PASSWORD=P@ssw0rd" -e "MSSQL_PID=Express" -p 1433:1433 -d --name sqlexpress mcr.microsoft.com/mssql/server:2019-latest; - DB: PostgreSQL CONNECTION_STRING: "Host=localhost;Username=nhibernate;Password=nhibernate;Database=nhibernate;Enlist=true;" DB_INIT: | diff --git a/appveyor.yml b/appveyor.yml index a73e841f7e6..cf5da450722 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -4,6 +4,8 @@ environment: matrix: - DB: SqlServer2008 CONNECTION_STRING: Server=(local)\SQL2017;User ID=sa;Password=Password12!;initial catalog=nhibernate; + - DB: SqlServer2008-MicrosoftDataSqlClientDriver + CONNECTION_STRING: Server=(local)\SQL2017;User ID=sa;Password=Password12!;initial catalog=nhibernate; - DB: PostgreSQL CONNECTION_STRING: Host=localhost;Port=5432;Username=postgres;Password=Password12!;Database=nhibernate;Enlist=true; - DB: Firebird @@ -73,7 +75,9 @@ before_test: Start-Service 'postgresql-x64-10' } 'SqlServer2008' { Start-Service 'MSSQL$SQL2017' } + 'SqlServer2008-MicrosoftDataSqlClientDriver' { Start-Service 'MSSQL$SQL2017' } 'SqlServer2012' { Start-Service 'MSSQL$SQL2017' } + 'SqlServer2012-MicrosoftDataSqlClientDriver' { Start-Service 'MSSQL$SQL2017' } 'SQLite' { } } test_script: diff --git a/psake.ps1 b/psake.ps1 index 34fa3e2ea37..16f7a267f14 100644 --- a/psake.ps1 +++ b/psake.ps1 @@ -63,9 +63,22 @@ Task Set-Configuration { }; 'SqlServer2008' = @{ 'connection.connection_string' = 'Server=(local)\SQL2017;User ID=sa;Password=Password12!;initial catalog=nhibernate;' + 'connection.driver_class' = 'NHibernate.Driver.Sql2008ClientDriver'; + 'dialect' = 'NHibernate.Dialect.MsSql2008Dialect' }; 'SqlServer2012' = @{ 'connection.connection_string' = 'Server=(local)\SQL2017;User ID=sa;Password=Password12!;initial catalog=nhibernate;'; + 'connection.driver_class' = 'NHibernate.Driver.Sql2008ClientDriver'; + 'dialect' = 'NHibernate.Dialect.MsSql2012Dialect' + }; + 'SqlServer2008-MicrosoftDataSqlClientDriver' = @{ + 'connection.connection_string' = 'Server=(local)\SQL2017;User ID=sa;Password=Password12!;initial catalog=nhibernate;' + 'connection.driver_class' = 'NHibernate.Driver.MicrosoftDataSqlClientDriver'; + 'dialect' = 'NHibernate.Dialect.MsSql2008Dialect' + }; + 'SqlServer2012-MicrosoftDataSqlClientDriver' = @{ + 'connection.connection_string' = 'Server=(local)\SQL2017;User ID=sa;Password=Password12!;initial catalog=nhibernate;'; + 'connection.driver_class' = 'NHibernate.Driver.MicrosoftDataSqlClientDriver'; 'dialect' = 'NHibernate.Dialect.MsSql2012Dialect' }; 'Oracle' = @{ diff --git a/src/NHibernate.TestDatabaseSetup/TestDatabaseSetup.cs b/src/NHibernate.TestDatabaseSetup/TestDatabaseSetup.cs index deea09fb3a5..0856f339d02 100644 --- a/src/NHibernate.TestDatabaseSetup/TestDatabaseSetup.cs +++ b/src/NHibernate.TestDatabaseSetup/TestDatabaseSetup.cs @@ -23,6 +23,7 @@ public class DatabaseSetup { {"NHibernate.Driver.SqlClientDriver", SetupSqlServer}, {"NHibernate.Driver.Sql2008ClientDriver", SetupSqlServer}, + {"NHibernate.Driver.MicrosoftDataSqlClientDriver", SetupSqlServer}, {"NHibernate.Driver.FirebirdClientDriver", SetupFirebird}, {"NHibernate.Driver.NpgsqlDriver", SetupNpgsql}, {"NHibernate.Driver.OracleDataClientDriver", SetupOracle}, diff --git a/src/NHibernate/Driver/MicrosoftDataSqlClientDriver.cs b/src/NHibernate/Driver/MicrosoftDataSqlClientDriver.cs index 1c4ad3d9fc0..e2e12674e3d 100644 --- a/src/NHibernate/Driver/MicrosoftDataSqlClientDriver.cs +++ b/src/NHibernate/Driver/MicrosoftDataSqlClientDriver.cs @@ -112,7 +112,7 @@ protected override void InitializeParameter(DbParameter dbParam, string name, Sq case DbType.AnsiStringFixedLength: dbParam.Size = IsAnsiText(dbParam, sqlType) ? MsSql2000Dialect.MaxSizeForAnsiClob - : MsSql2000Dialect.MaxSizeForLengthLimitedAnsiString; + : IsChar(dbParam, sqlType) ? sqlType.Length : MsSql2000Dialect.MaxSizeForLengthLimitedAnsiString; break; case DbType.Binary: dbParam.Size = IsBlob(dbParam, sqlType) @@ -130,7 +130,7 @@ protected override void InitializeParameter(DbParameter dbParam, string name, Sq case DbType.StringFixedLength: dbParam.Size = IsText(dbParam, sqlType) ? MsSql2000Dialect.MaxSizeForClob - : MsSql2000Dialect.MaxSizeForLengthLimitedString; + : IsChar(dbParam, sqlType) ? sqlType.Length : MsSql2000Dialect.MaxSizeForLengthLimitedString; break; case DbType.DateTime2: dbParam.Size = MsSql2000Dialect.MaxDateTime2; @@ -199,6 +199,18 @@ protected static bool IsBlob(DbParameter dbParam, SqlType sqlType) return sqlType is BinaryBlobSqlType || DbType.Binary == dbParam.DbType && sqlType.LengthDefined && sqlType.Length > MsSql2000Dialect.MaxSizeForLengthLimitedBinary; } + + /// + /// Interprets if a parameter is a character (for the purposes of setting its default size) + /// + /// The parameter + /// The of the parameter + /// True, if the parameter should be interpreted as a character, otherwise False + protected static bool IsChar(DbParameter dbParam, SqlType sqlType) + { + return sqlType.LengthDefined && sqlType.Length == 1 && + (dbParam.DbType == DbType.StringFixedLength || dbParam.DbType == DbType.AnsiStringFixedLength); + } /// public override IResultSetsCommand GetResultSetsCommand(ISessionImplementor session) diff --git a/src/NHibernate/Driver/SqlClientDriver.cs b/src/NHibernate/Driver/SqlClientDriver.cs index 1002005395d..a3da3a4db73 100644 --- a/src/NHibernate/Driver/SqlClientDriver.cs +++ b/src/NHibernate/Driver/SqlClientDriver.cs @@ -295,8 +295,8 @@ protected static bool IsBlob(DbParameter dbParam, SqlType sqlType) /// True, if the parameter should be interpreted as a character, otherwise False protected static bool IsChar(DbParameter dbParam, SqlType sqlType) { - return (DbType.StringFixedLength == dbParam.DbType || DbType.AnsiStringFixedLength == dbParam.DbType) && - sqlType.LengthDefined && sqlType.Length == 1; + return sqlType.LengthDefined && sqlType.Length == 1 && + (dbParam.DbType == DbType.StringFixedLength || dbParam.DbType == DbType.AnsiStringFixedLength); } public override IResultSetsCommand GetResultSetsCommand(ISessionImplementor session) diff --git a/teamcity.build b/teamcity.build index 7e90e13e430..b8125f5dfe5 100644 --- a/teamcity.build +++ b/teamcity.build @@ -67,11 +67,22 @@ + + + + + + + + + + +