diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c93caa73..c84a8505 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -29,8 +29,8 @@ jobs: fail-fast: false matrix: dbVersion: - - 8.0.34-mysql - - 5.7.43-mysql + - 8.0.36-mysql + - 5.7.44-mysql - 11.2.2-mariadb - 11.1.3-mariadb - 11.0.4-mariadb diff --git a/Dependencies.targets b/Dependencies.targets index 33f6c76d..25c19dca 100644 --- a/Dependencies.targets +++ b/Dependencies.targets @@ -1,6 +1,6 @@ - [8.0.1,8.0.999] + [8.0.2,8.0.999] @@ -13,12 +13,12 @@ - + - - + + diff --git a/Directory.Build.props b/Directory.Build.props index f46a5770..5e57c684 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -2,6 +2,13 @@ + + Debug + debug + $(DefineConstants);EFCORE_DEBUG_BUILD + $(DefineConstants);MYSQLCONNECTOR_DEBUG_BUILD + + Pomelo.EntityFrameworkCore.MySql pomelo;mysql;mariadb;Entity Framework Core;entity-framework-core;ef;efcore;ef core;orm;sql diff --git a/NuGet.config b/NuGet.config index ca4722e3..57c30d15 100644 --- a/NuGet.config +++ b/NuGet.config @@ -5,10 +5,8 @@ - - - - + + diff --git a/src/EFCore.MySql.Json.Microsoft/EFCore.MySql.Json.Microsoft.csproj b/src/EFCore.MySql.Json.Microsoft/EFCore.MySql.Json.Microsoft.csproj index 4648e85c..a2b2b9ce 100644 --- a/src/EFCore.MySql.Json.Microsoft/EFCore.MySql.Json.Microsoft.csproj +++ b/src/EFCore.MySql.Json.Microsoft/EFCore.MySql.Json.Microsoft.csproj @@ -47,7 +47,7 @@ - $(LocalMySqlConnectorRepository)\artifacts\bin\MySqlConnector\debug_$(MySqlConnectorTargetFramework)\MySqlConnector.dll + $(LocalMySqlConnectorRepository)\artifacts\bin\MySqlConnector\$(LocalMySqlConnectorRepositoryConfiguration)_$(MySqlConnectorTargetFramework)\MySqlConnector.dll @@ -55,16 +55,16 @@ - $(LocalEFCoreRepository)\artifacts\bin\EFCore.Relational\Debug\$(EfCoreTargetFramework)\Microsoft.EntityFrameworkCore.dll + $(LocalEFCoreRepository)\artifacts\bin\EFCore.Relational\$(LocalEFCoreRepositoryConfiguration)\$(EfCoreTargetFramework)\Microsoft.EntityFrameworkCore.dll - $(LocalEFCoreRepository)\artifacts\bin\EFCore.Relational\Debug\$(EfCoreTargetFramework)\Microsoft.EntityFrameworkCore.Abstractions.dll + $(LocalEFCoreRepository)\artifacts\bin\EFCore.Relational\$(LocalEFCoreRepositoryConfiguration)\$(EfCoreTargetFramework)\Microsoft.EntityFrameworkCore.Abstractions.dll - $(LocalEFCoreRepository)\artifacts\bin\EFCore.Relational\Debug\$(EfCoreTargetFramework)\Microsoft.EntityFrameworkCore.Analyzers.dll + $(LocalEFCoreRepository)\artifacts\bin\EFCore.Relational\$(LocalEFCoreRepositoryConfiguration)\$(EfCoreTargetFramework)\Microsoft.EntityFrameworkCore.Analyzers.dll - $(LocalEFCoreRepository)\artifacts\bin\EFCore.Relational\Debug\$(EfCoreTargetFramework)\Microsoft.EntityFrameworkCore.Relational.dll + $(LocalEFCoreRepository)\artifacts\bin\EFCore.Relational\$(LocalEFCoreRepositoryConfiguration)\$(EfCoreTargetFramework)\Microsoft.EntityFrameworkCore.Relational.dll diff --git a/src/EFCore.MySql.Json.Newtonsoft/EFCore.MySql.Json.Newtonsoft.csproj b/src/EFCore.MySql.Json.Newtonsoft/EFCore.MySql.Json.Newtonsoft.csproj index 1d48f8bb..e7480c99 100644 --- a/src/EFCore.MySql.Json.Newtonsoft/EFCore.MySql.Json.Newtonsoft.csproj +++ b/src/EFCore.MySql.Json.Newtonsoft/EFCore.MySql.Json.Newtonsoft.csproj @@ -49,7 +49,7 @@ - $(LocalMySqlConnectorRepository)\artifacts\bin\MySqlConnector\debug_$(MySqlConnectorTargetFramework)\MySqlConnector.dll + $(LocalMySqlConnectorRepository)\artifacts\bin\MySqlConnector\$(LocalMySqlConnectorRepositoryConfiguration)_$(MySqlConnectorTargetFramework)\MySqlConnector.dll @@ -57,16 +57,16 @@ - $(LocalEFCoreRepository)\artifacts\bin\EFCore.Relational\Debug\$(EfCoreTargetFramework)\Microsoft.EntityFrameworkCore.dll + $(LocalEFCoreRepository)\artifacts\bin\EFCore.Relational\$(LocalEFCoreRepositoryConfiguration)\$(EfCoreTargetFramework)\Microsoft.EntityFrameworkCore.dll - $(LocalEFCoreRepository)\artifacts\bin\EFCore.Relational\Debug\$(EfCoreTargetFramework)\Microsoft.EntityFrameworkCore.Abstractions.dll + $(LocalEFCoreRepository)\artifacts\bin\EFCore.Relational\$(LocalEFCoreRepositoryConfiguration)\$(EfCoreTargetFramework)\Microsoft.EntityFrameworkCore.Abstractions.dll - $(LocalEFCoreRepository)\artifacts\bin\EFCore.Relational\Debug\$(EfCoreTargetFramework)\Microsoft.EntityFrameworkCore.Analyzers.dll + $(LocalEFCoreRepository)\artifacts\bin\EFCore.Relational\$(LocalEFCoreRepositoryConfiguration)\$(EfCoreTargetFramework)\Microsoft.EntityFrameworkCore.Analyzers.dll - $(LocalEFCoreRepository)\artifacts\bin\EFCore.Relational\Debug\$(EfCoreTargetFramework)\Microsoft.EntityFrameworkCore.Relational.dll + $(LocalEFCoreRepository)\artifacts\bin\EFCore.Relational\$(LocalEFCoreRepositoryConfiguration)\$(EfCoreTargetFramework)\Microsoft.EntityFrameworkCore.Relational.dll diff --git a/src/EFCore.MySql.NTS/EFCore.MySql.NTS.csproj b/src/EFCore.MySql.NTS/EFCore.MySql.NTS.csproj index 8b4629d5..46100a8d 100644 --- a/src/EFCore.MySql.NTS/EFCore.MySql.NTS.csproj +++ b/src/EFCore.MySql.NTS/EFCore.MySql.NTS.csproj @@ -49,7 +49,7 @@ - $(LocalMySqlConnectorRepository)\artifacts\bin\MySqlConnector\debug_$(MySqlConnectorTargetFramework)\MySqlConnector.dll + $(LocalMySqlConnectorRepository)\artifacts\bin\MySqlConnector\$(LocalMySqlConnectorRepositoryConfiguration)_$(MySqlConnectorTargetFramework)\MySqlConnector.dll @@ -57,16 +57,16 @@ - $(LocalEFCoreRepository)\artifacts\bin\EFCore.Relational\Debug\$(EfCoreTargetFramework)\Microsoft.EntityFrameworkCore.dll + $(LocalEFCoreRepository)\artifacts\bin\EFCore.Relational\$(LocalEFCoreRepositoryConfiguration)\$(EfCoreTargetFramework)\Microsoft.EntityFrameworkCore.dll - $(LocalEFCoreRepository)\artifacts\bin\EFCore.Relational\Debug\$(EfCoreTargetFramework)\Microsoft.EntityFrameworkCore.Abstractions.dll + $(LocalEFCoreRepository)\artifacts\bin\EFCore.Relational\$(LocalEFCoreRepositoryConfiguration)\$(EfCoreTargetFramework)\Microsoft.EntityFrameworkCore.Abstractions.dll - $(LocalEFCoreRepository)\artifacts\bin\EFCore.Relational\Debug\$(EfCoreTargetFramework)\Microsoft.EntityFrameworkCore.Analyzers.dll + $(LocalEFCoreRepository)\artifacts\bin\EFCore.Relational\$(LocalEFCoreRepositoryConfiguration)\$(EfCoreTargetFramework)\Microsoft.EntityFrameworkCore.Analyzers.dll - $(LocalEFCoreRepository)\artifacts\bin\EFCore.Relational\Debug\$(EfCoreTargetFramework)\Microsoft.EntityFrameworkCore.Relational.dll + $(LocalEFCoreRepository)\artifacts\bin\EFCore.Relational\$(LocalEFCoreRepositoryConfiguration)\$(EfCoreTargetFramework)\Microsoft.EntityFrameworkCore.Relational.dll diff --git a/src/EFCore.MySql/EFCore.MySql.csproj b/src/EFCore.MySql/EFCore.MySql.csproj index c1e081cd..5e36a026 100644 --- a/src/EFCore.MySql/EFCore.MySql.csproj +++ b/src/EFCore.MySql/EFCore.MySql.csproj @@ -30,16 +30,16 @@ - $(LocalEFCoreRepository)\artifacts\bin\EFCore.Relational\Debug\$(EfCoreTargetFramework)\Microsoft.EntityFrameworkCore.dll + $(LocalEFCoreRepository)\artifacts\bin\EFCore.Relational\$(LocalEFCoreRepositoryConfiguration)\$(EfCoreTargetFramework)\Microsoft.EntityFrameworkCore.dll - $(LocalEFCoreRepository)\artifacts\bin\EFCore.Relational\Debug\$(EfCoreTargetFramework)\Microsoft.EntityFrameworkCore.Abstractions.dll + $(LocalEFCoreRepository)\artifacts\bin\EFCore.Relational\$(LocalEFCoreRepositoryConfiguration)\$(EfCoreTargetFramework)\Microsoft.EntityFrameworkCore.Abstractions.dll - $(LocalEFCoreRepository)\artifacts\bin\EFCore.Relational\Debug\$(EfCoreTargetFramework)\Microsoft.EntityFrameworkCore.Analyzers.dll + $(LocalEFCoreRepository)\artifacts\bin\EFCore.Relational\$(LocalEFCoreRepositoryConfiguration)\$(EfCoreTargetFramework)\Microsoft.EntityFrameworkCore.Analyzers.dll - $(LocalEFCoreRepository)\artifacts\bin\EFCore.Relational\Debug\$(EfCoreTargetFramework)\Microsoft.EntityFrameworkCore.Relational.dll + $(LocalEFCoreRepository)\artifacts\bin\EFCore.Relational\$(LocalEFCoreRepositoryConfiguration)\$(EfCoreTargetFramework)\Microsoft.EntityFrameworkCore.Relational.dll @@ -55,7 +55,7 @@ - $(LocalMySqlConnectorRepository)\artifacts\bin\MySqlConnector\debug_$(MySqlConnectorTargetFramework)\MySqlConnector.dll + $(LocalMySqlConnectorRepository)\artifacts\bin\MySqlConnector\$(LocalMySqlConnectorRepositoryConfiguration)_$(MySqlConnectorTargetFramework)\MySqlConnector.dll diff --git a/src/EFCore.MySql/Infrastructure/MariaDbServerVersion.cs b/src/EFCore.MySql/Infrastructure/MariaDbServerVersion.cs index 6ab2e146..74946345 100644 --- a/src/EFCore.MySql/Infrastructure/MariaDbServerVersion.cs +++ b/src/EFCore.MySql/Infrastructure/MariaDbServerVersion.cs @@ -15,7 +15,7 @@ namespace Microsoft.EntityFrameworkCore public class MariaDbServerVersion : ServerVersion { public static readonly string MariaDbTypeIdentifier = nameof(ServerType.MariaDb).ToLowerInvariant(); - public static readonly ServerVersion LatestSupportedServerVersion = new MariaDbServerVersion(new Version(10, 9, 4)); + public static readonly ServerVersion LatestSupportedServerVersion = new MariaDbServerVersion(new Version(11, 3, 2)); public override ServerVersionSupport Supports { get; } @@ -90,7 +90,7 @@ internal MariaDbServerVersionSupport([NotNull] ServerVersion serverVersion) public override bool JsonValue => true; public override bool Values => ServerVersion.Version >= new Version(10, 3, 3); public override bool ValuesWithRows => false; - public override bool OffsetReferencesOuterQuery => false; + public override bool WhereSubqueryReferencesOuterQuery => false; public override bool JsonTableImplementationStable => false; public override bool JsonTableImplementationWithoutMariaDbBugs => false; diff --git a/src/EFCore.MySql/Infrastructure/MySqlServerVersion.cs b/src/EFCore.MySql/Infrastructure/MySqlServerVersion.cs index 9a6d7160..b64d70fe 100644 --- a/src/EFCore.MySql/Infrastructure/MySqlServerVersion.cs +++ b/src/EFCore.MySql/Infrastructure/MySqlServerVersion.cs @@ -15,7 +15,7 @@ namespace Microsoft.EntityFrameworkCore public class MySqlServerVersion : ServerVersion { public static readonly string MySqlTypeIdentifier = nameof(ServerType.MySql).ToLowerInvariant(); - public static readonly ServerVersion LatestSupportedServerVersion = new MySqlServerVersion(new Version(8, 0, 31)); + public static readonly ServerVersion LatestSupportedServerVersion = new MySqlServerVersion(new Version(8, 0, 36)); public override ServerVersionSupport Supports { get; } @@ -93,7 +93,7 @@ internal MySqlServerVersionSupport([NotNull] ServerVersion serverVersion) public override bool JsonValue => ServerVersion.Version >= new Version(8, 0, 21); public override bool Values => false; public override bool ValuesWithRows => ServerVersion.Version >= new Version(8, 0, 19); - public override bool OffsetReferencesOuterQuery => false; + public override bool WhereSubqueryReferencesOuterQuery => false; public override bool JsonTableImplementationStable => false; public override bool JsonTableImplementationWithoutMySqlBugs => false; // Other non-fatal bugs regarding JSON_TABLE. diff --git a/src/EFCore.MySql/Infrastructure/ServerVersionSupport.cs b/src/EFCore.MySql/Infrastructure/ServerVersionSupport.cs index 185fe097..64430907 100644 --- a/src/EFCore.MySql/Infrastructure/ServerVersionSupport.cs +++ b/src/EFCore.MySql/Infrastructure/ServerVersionSupport.cs @@ -93,7 +93,7 @@ public virtual bool PropertyOrVersion(string propertyNameOrServerVersion) public virtual bool JsonValue => false; public virtual bool Values => false; public virtual bool ValuesWithRows => false; - public virtual bool OffsetReferencesOuterQuery => false; + public virtual bool WhereSubqueryReferencesOuterQuery => false; public virtual bool JsonTableImplementationStable => JsonTable; public virtual bool JsonTableImplementationWithoutMySqlBugs => JsonTable; diff --git a/src/EFCore.MySql/Query/ExpressionTranslators/Internal/MySqlStringComparisonMethodTranslator.cs b/src/EFCore.MySql/Query/ExpressionTranslators/Internal/MySqlStringComparisonMethodTranslator.cs index f929557b..6adc92b1 100644 --- a/src/EFCore.MySql/Query/ExpressionTranslators/Internal/MySqlStringComparisonMethodTranslator.cs +++ b/src/EFCore.MySql/Query/ExpressionTranslators/Internal/MySqlStringComparisonMethodTranslator.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.Globalization; using System.Linq; using System.Linq.Expressions; using System.Reflection; @@ -538,7 +539,9 @@ protected virtual SqlExpression GetLikeExpressionUsingParameter(QueryCompilation QueryCompilationContext.QueryContextParameter); var escapedPatternParameter = - queryCompilationContext.RegisterRuntimeParameter(patternParameter.Name + "_rewritten", lambda); + queryCompilationContext.RegisterRuntimeParameter( + $"{patternParameter.Name}_{methodType.ToString().ToLower(CultureInfo.InvariantCulture)}", + lambda); return _sqlExpressionFactory.Like( targetTransform(target), diff --git a/src/EFCore.MySql/Query/ExpressionVisitors/Internal/MySqlQuerySqlGenerator.cs b/src/EFCore.MySql/Query/ExpressionVisitors/Internal/MySqlQuerySqlGenerator.cs index 404fd4bb..af025106 100644 --- a/src/EFCore.MySql/Query/ExpressionVisitors/Internal/MySqlQuerySqlGenerator.cs +++ b/src/EFCore.MySql/Query/ExpressionVisitors/Internal/MySqlQuerySqlGenerator.cs @@ -67,6 +67,9 @@ public class MySqlQuerySqlGenerator : QuerySqlGenerator private string _removeTableAliasOld; private string _removeTableAliasNew; + private static readonly bool _useOldBehavior32375 = + AppContext.TryGetSwitch("Microsoft.EntityFrameworkCore.Issue32375", out var enabled32375) && enabled32375; + /// /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. @@ -543,6 +546,11 @@ protected override void GenerateValues(ValuesExpression valuesExpression) return; } + if (!_useOldBehavior32375 && valuesExpression.RowValues.Count == 0) + { + throw new InvalidOperationException(RelationalStrings.EmptyCollectionNotSupportedAsInlineQueryRoot); + } + var rowValues = valuesExpression.RowValues; // diff --git a/test/EFCore.MySql.FunctionalTests/BulkUpdates/NorthwindBulkUpdatesMySqlTest.cs b/test/EFCore.MySql.FunctionalTests/BulkUpdates/NorthwindBulkUpdatesMySqlTest.cs index 8150b30a..ea3d1cb9 100644 --- a/test/EFCore.MySql.FunctionalTests/BulkUpdates/NorthwindBulkUpdatesMySqlTest.cs +++ b/test/EFCore.MySql.FunctionalTests/BulkUpdates/NorthwindBulkUpdatesMySqlTest.cs @@ -1032,7 +1032,7 @@ public override async Task Update_Where_set_property_plus_parameter(bool async) AssertExecuteUpdateSql( """ -@__value_0='Abc' (Size = 30) +@__value_0='Abc' (Size = 4000) UPDATE `Customers` AS `c` SET `c`.`ContactName` = CONCAT(COALESCE(`c`.`ContactName`, ''), @__value_0) diff --git a/test/EFCore.MySql.FunctionalTests/EFCore.MySql.FunctionalTests.csproj b/test/EFCore.MySql.FunctionalTests/EFCore.MySql.FunctionalTests.csproj index 3762cf72..efe3e927 100644 --- a/test/EFCore.MySql.FunctionalTests/EFCore.MySql.FunctionalTests.csproj +++ b/test/EFCore.MySql.FunctionalTests/EFCore.MySql.FunctionalTests.csproj @@ -7,7 +7,7 @@ true $(DefaultItemExcludes);*.trx - + false false @@ -47,28 +47,28 @@ - $(LocalEFCoreRepository)\artifacts\bin\EFCore.Relational.Tests\Debug\$(EfCoreTestTargetFramework)\Microsoft.EntityFrameworkCore.dll + $(LocalEFCoreRepository)\artifacts\bin\EFCore.Relational.Tests\$(LocalEFCoreRepositoryConfiguration)\$(EfCoreTestTargetFramework)\Microsoft.EntityFrameworkCore.dll - $(LocalEFCoreRepository)\artifacts\bin\EFCore.Relational.Tests\Debug\$(EfCoreTestTargetFramework)\Microsoft.EntityFrameworkCore.Abstractions.dll + $(LocalEFCoreRepository)\artifacts\bin\EFCore.Relational.Tests\$(LocalEFCoreRepositoryConfiguration)\$(EfCoreTestTargetFramework)\Microsoft.EntityFrameworkCore.Abstractions.dll - $(LocalEFCoreRepository)\artifacts\bin\EFCore.Relational.Tests\Debug\$(EfCoreTestTargetFramework)\Microsoft.EntityFrameworkCore.Analyzers.dll + $(LocalEFCoreRepository)\artifacts\bin\EFCore.Relational.Tests\$(LocalEFCoreRepositoryConfiguration)\$(EfCoreTestTargetFramework)\Microsoft.EntityFrameworkCore.Analyzers.dll - $(LocalEFCoreRepository)\artifacts\bin\EFCore.Relational.Tests\Debug\$(EfCoreTestTargetFramework)\Microsoft.EntityFrameworkCore.Proxies.dll + $(LocalEFCoreRepository)\artifacts\bin\EFCore.Relational.Tests\$(LocalEFCoreRepositoryConfiguration)\$(EfCoreTestTargetFramework)\Microsoft.EntityFrameworkCore.Proxies.dll - $(LocalEFCoreRepository)\artifacts\bin\EFCore.Relational.Tests\Debug\$(EfCoreTestTargetFramework)\Microsoft.EntityFrameworkCore.Relational.dll + $(LocalEFCoreRepository)\artifacts\bin\EFCore.Relational.Tests\$(LocalEFCoreRepositoryConfiguration)\$(EfCoreTestTargetFramework)\Microsoft.EntityFrameworkCore.Relational.dll - $(LocalEFCoreRepository)\artifacts\bin\EFCore.Relational.Tests\Debug\$(EfCoreTestTargetFramework)\Microsoft.EntityFrameworkCore.Relational.Specification.Tests.dll + $(LocalEFCoreRepository)\artifacts\bin\EFCore.Relational.Tests\$(LocalEFCoreRepositoryConfiguration)\$(EfCoreTestTargetFramework)\Microsoft.EntityFrameworkCore.Relational.Specification.Tests.dll - $(LocalEFCoreRepository)\artifacts\bin\EFCore.Relational.Tests\Debug\$(EfCoreTestTargetFramework)\Microsoft.EntityFrameworkCore.Specification.Tests.dll + $(LocalEFCoreRepository)\artifacts\bin\EFCore.Relational.Tests\$(LocalEFCoreRepositoryConfiguration)\$(EfCoreTestTargetFramework)\Microsoft.EntityFrameworkCore.Specification.Tests.dll - $(LocalEFCoreRepository)\artifacts\bin\EFCore.Design.Tests\Debug\$(EfCoreTestTargetFramework)\Microsoft.EntityFrameworkCore.Design.dll + $(LocalEFCoreRepository)\artifacts\bin\EFCore.Design.Tests\$(LocalEFCoreRepositoryConfiguration)\$(EfCoreTestTargetFramework)\Microsoft.EntityFrameworkCore.Design.dll @@ -79,7 +79,7 @@ - $(LocalMySqlConnectorRepository)\artifacts\bin\MySqlConnector\debug_$(MySqlConnectorTargetFramework)\MySqlConnector.dll + $(LocalMySqlConnectorRepository)\artifacts\bin\MySqlConnector\$(LocalMySqlConnectorRepositoryConfiguration)_$(MySqlConnectorTargetFramework)\MySqlConnector.dll diff --git a/test/EFCore.MySql.FunctionalTests/MigrationsInfrastructureMySqlTest.cs b/test/EFCore.MySql.FunctionalTests/MigrationsInfrastructureMySqlTest.cs index d6fb04be..6745b54b 100644 --- a/test/EFCore.MySql.FunctionalTests/MigrationsInfrastructureMySqlTest.cs +++ b/test/EFCore.MySql.FunctionalTests/MigrationsInfrastructureMySqlTest.cs @@ -55,7 +55,8 @@ public override void Can_generate_up_scripts() base.Can_generate_up_scripts(); Assert.Equal( - @"CREATE TABLE IF NOT EXISTS `__EFMigrationsHistory` ( +""" +CREATE TABLE IF NOT EXISTS `__EFMigrationsHistory` ( `MigrationId` varchar(150) CHARACTER SET utf8mb4 NOT NULL, `ProductVersion` varchar(32) CHARACTER SET utf8mb4 NOT NULL, CONSTRAINT `PK___EFMigrationsHistory` PRIMARY KEY (`MigrationId`) @@ -90,7 +91,15 @@ public override void Can_generate_up_scripts() COMMIT; -", +START TRANSACTION; + +INSERT INTO `__EFMigrationsHistory` (`MigrationId`, `ProductVersion`) +VALUES ('00000000000004_Migration4', '7.0.0-test'); + +COMMIT; + + +""", Sql, ignoreLineEndingDifferences: true); } @@ -137,7 +146,9 @@ public override void Can_generate_idempotent_up_scripts() { base.Can_generate_idempotent_up_scripts(); - Assert.Equal(@"CREATE TABLE IF NOT EXISTS `__EFMigrationsHistory` ( + Assert.Equal( +""" +CREATE TABLE IF NOT EXISTS `__EFMigrationsHistory` ( `MigrationId` varchar(150) CHARACTER SET utf8mb4 NOT NULL, `ProductVersion` varchar(32) CHARACTER SET utf8mb4 NOT NULL, CONSTRAINT `PK___EFMigrationsHistory` PRIMARY KEY (`MigrationId`) @@ -232,7 +243,27 @@ IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '00000 COMMIT; -", +START TRANSACTION; + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '00000000000004_Migration4') THEN + + INSERT INTO `__EFMigrationsHistory` (`MigrationId`, `ProductVersion`) + VALUES ('00000000000004_Migration4', '7.0.0-test'); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + +COMMIT; + + +""", Sql, ignoreLineEndingDifferences: true); } @@ -391,7 +422,8 @@ public override void Can_generate_up_scripts_noTransactions() base.Can_generate_up_scripts_noTransactions(); Assert.Equal( - @"CREATE TABLE IF NOT EXISTS `__EFMigrationsHistory` ( +""" +CREATE TABLE IF NOT EXISTS `__EFMigrationsHistory` ( `MigrationId` varchar(150) CHARACTER SET utf8mb4 NOT NULL, `ProductVersion` varchar(32) CHARACTER SET utf8mb4 NOT NULL, CONSTRAINT `PK___EFMigrationsHistory` PRIMARY KEY (`MigrationId`) @@ -414,7 +446,11 @@ public override void Can_generate_up_scripts_noTransactions() INSERT INTO `__EFMigrationsHistory` (`MigrationId`, `ProductVersion`) VALUES ('00000000000003_Migration3', '7.0.0-test'); -", +INSERT INTO `__EFMigrationsHistory` (`MigrationId`, `ProductVersion`) +VALUES ('00000000000004_Migration4', '7.0.0-test'); + + +""", Sql, ignoreLineEndingDifferences: true); } @@ -424,7 +460,8 @@ public override void Can_generate_idempotent_up_scripts_noTransactions() base.Can_generate_idempotent_up_scripts_noTransactions(); Assert.Equal( - @"CREATE TABLE IF NOT EXISTS `__EFMigrationsHistory` ( +""" +CREATE TABLE IF NOT EXISTS `__EFMigrationsHistory` ( `MigrationId` varchar(150) CHARACTER SET utf8mb4 NOT NULL, `ProductVersion` varchar(32) CHARACTER SET utf8mb4 NOT NULL, CONSTRAINT `PK___EFMigrationsHistory` PRIMARY KEY (`MigrationId`) @@ -507,7 +544,23 @@ IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '00000 CALL MigrationsScript(); DROP PROCEDURE MigrationsScript; -", +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '00000000000004_Migration4') THEN + + INSERT INTO `__EFMigrationsHistory` (`MigrationId`, `ProductVersion`) + VALUES ('00000000000004_Migration4', '7.0.0-test'); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +""", Sql, ignoreLineEndingDifferences: true); } diff --git a/test/EFCore.MySql.FunctionalTests/Query/FunkyDataQueryMySqlTest.cs b/test/EFCore.MySql.FunctionalTests/Query/FunkyDataQueryMySqlTest.cs index 970054c1..e8726567 100644 --- a/test/EFCore.MySql.FunctionalTests/Query/FunkyDataQueryMySqlTest.cs +++ b/test/EFCore.MySql.FunctionalTests/Query/FunkyDataQueryMySqlTest.cs @@ -175,6 +175,21 @@ WHERE FALSE """); } + public override async Task String_Contains_and_StartsWith_with_same_parameter(bool async) + { + await base.String_Contains_and_StartsWith_with_same_parameter(async); + + AssertSql( +""" +@__s_0_contains='%B%' (Size = 4000) +@__s_0_startswith='B%' (Size = 4000) + +SELECT `f`.`Id`, `f`.`FirstName`, `f`.`LastName`, `f`.`NullableBool` +FROM `FunkyCustomers` AS `f` +WHERE (`f`.`FirstName` LIKE @__s_0_contains) OR (`f`.`LastName` LIKE @__s_0_startswith) +"""); + } + protected override void ClearLog() => Fixture.TestSqlLoggerFactory.Clear(); diff --git a/test/EFCore.MySql.FunctionalTests/Query/NorthwindAggregateOperatorsQueryMySqlTest.cs b/test/EFCore.MySql.FunctionalTests/Query/NorthwindAggregateOperatorsQueryMySqlTest.cs index 47b6e521..581460ab 100644 --- a/test/EFCore.MySql.FunctionalTests/Query/NorthwindAggregateOperatorsQueryMySqlTest.cs +++ b/test/EFCore.MySql.FunctionalTests/Query/NorthwindAggregateOperatorsQueryMySqlTest.cs @@ -64,6 +64,26 @@ await Assert.ThrowsAsync( AssertSql(); } + public override async Task Contains_inside_Average_without_GroupBy(bool async) + { + var cities = new[] { "London", "Berlin" }; + + await AssertAverage( + async, + ss => ss.Set(), + selector: c => cities.Contains(c.City) ? 1.0 : 0.0, + asserter: (e, a) => Assert.Equal(e, a, 0.00001)); // expected: 0.076923076923076927, MySQL actual: 0.076920000000000002 + + AssertSql( +""" +SELECT AVG(CASE + WHEN `c`.`City` IN ('London', 'Berlin') THEN 1.0 + ELSE 0.0 +END) +FROM `Customers` AS `c` +"""); + } + protected override bool CanExecuteQueryString => true; diff --git a/test/EFCore.MySql.FunctionalTests/Query/NorthwindFunctionsQueryMySqlTest.cs b/test/EFCore.MySql.FunctionalTests/Query/NorthwindFunctionsQueryMySqlTest.cs index ff8e5def..6bf1e579 100644 --- a/test/EFCore.MySql.FunctionalTests/Query/NorthwindFunctionsQueryMySqlTest.cs +++ b/test/EFCore.MySql.FunctionalTests/Query/NorthwindFunctionsQueryMySqlTest.cs @@ -530,11 +530,11 @@ public override async Task String_Contains_parameter_with_whitespace(bool async) AssertSql( """ -@__pattern_0_rewritten='% %' (Size = 30) +@__pattern_0_contains='% %' (Size = 30) SELECT `c`.`CustomerID`, `c`.`Address`, `c`.`City`, `c`.`CompanyName`, `c`.`ContactName`, `c`.`ContactTitle`, `c`.`Country`, `c`.`Fax`, `c`.`Phone`, `c`.`PostalCode`, `c`.`Region` FROM `Customers` AS `c` -WHERE `c`.`ContactName` LIKE @__pattern_0_rewritten +WHERE `c`.`ContactName` LIKE @__pattern_0_contains """); } @@ -1808,11 +1808,11 @@ public override async Task String_StartsWith_Parameter(bool async) AssertSql( """ -@__pattern_0_rewritten='M%' (Size = 30) +@__pattern_0_startswith='M%' (Size = 30) SELECT `c`.`CustomerID`, `c`.`Address`, `c`.`City`, `c`.`CompanyName`, `c`.`ContactName`, `c`.`ContactTitle`, `c`.`Country`, `c`.`Fax`, `c`.`Phone`, `c`.`PostalCode`, `c`.`Region` FROM `Customers` AS `c` -WHERE `c`.`ContactName` LIKE @__pattern_0_rewritten +WHERE `c`.`ContactName` LIKE @__pattern_0_startswith """); } @@ -1822,11 +1822,11 @@ public override async Task String_EndsWith_Parameter(bool async) AssertSql( """ -@__pattern_0_rewritten='%b' (Size = 30) +@__pattern_0_endswith='%b' (Size = 30) SELECT `c`.`CustomerID`, `c`.`Address`, `c`.`City`, `c`.`CompanyName`, `c`.`ContactName`, `c`.`ContactTitle`, `c`.`Country`, `c`.`Fax`, `c`.`Phone`, `c`.`PostalCode`, `c`.`Region` FROM `Customers` AS `c` -WHERE `c`.`ContactName` LIKE @__pattern_0_rewritten +WHERE `c`.`ContactName` LIKE @__pattern_0_endswith """); } diff --git a/test/EFCore.MySql.FunctionalTests/Query/NorthwindGroupByQueryMySqlTest.cs b/test/EFCore.MySql.FunctionalTests/Query/NorthwindGroupByQueryMySqlTest.cs index 637ae56e..05ad158c 100644 --- a/test/EFCore.MySql.FunctionalTests/Query/NorthwindGroupByQueryMySqlTest.cs +++ b/test/EFCore.MySql.FunctionalTests/Query/NorthwindGroupByQueryMySqlTest.cs @@ -3,7 +3,6 @@ using Microsoft.EntityFrameworkCore.TestUtilities; using Pomelo.EntityFrameworkCore.MySql.Infrastructure; using Pomelo.EntityFrameworkCore.MySql.Tests.TestUtilities.Attributes; -using Xunit; using Xunit.Abstractions; namespace Pomelo.EntityFrameworkCore.MySql.FunctionalTests.Query diff --git a/test/EFCore.MySql.FunctionalTests/Query/NorthwindMiscellaneousQueryMySqlTest.cs b/test/EFCore.MySql.FunctionalTests/Query/NorthwindMiscellaneousQueryMySqlTest.cs index bf037e68..7a0fa35c 100644 --- a/test/EFCore.MySql.FunctionalTests/Query/NorthwindMiscellaneousQueryMySqlTest.cs +++ b/test/EFCore.MySql.FunctionalTests/Query/NorthwindMiscellaneousQueryMySqlTest.cs @@ -473,6 +473,44 @@ public override Task DefaultIfEmpty_Sum_over_collection_navigation(bool async) return base.DefaultIfEmpty_Sum_over_collection_navigation(async); } + public override async Task Parameter_collection_Contains_with_projection_and_ordering(bool async) + { +#if EFCORE_DEBUG_BUILD + // GroupBy debug assert. Issue #26104. + Assert.StartsWith( + "Missing alias in the list", + (await Assert.ThrowsAsync( + () => base.Parameter_collection_Contains_with_projection_and_ordering(async))).Message); +#else + await base.Parameter_collection_Contains_with_projection_and_ordering(async); + + AssertSql( +""" +SELECT `o`.`Quantity` AS `Key`, ( + SELECT MAX(`o3`.`OrderDate`) + FROM `Order Details` AS `o2` + INNER JOIN `Orders` AS `o3` ON `o2`.`OrderID` = `o3`.`OrderID` + WHERE `o2`.`OrderID` IN (10248, 10249) AND (`o`.`Quantity` = `o2`.`Quantity`)) AS `MaxTimestamp` +FROM `Order Details` AS `o` +WHERE `o`.`OrderID` IN (10248, 10249) +GROUP BY `o`.`Quantity` +ORDER BY ( + SELECT MAX(`o3`.`OrderDate`) + FROM `Order Details` AS `o2` + INNER JOIN `Orders` AS `o3` ON `o2`.`OrderID` = `o3`.`OrderID` + WHERE `o2`.`OrderID` IN (10248, 10249) AND (`o`.`Quantity` = `o2`.`Quantity`)) +"""); +#endif + } + + [SupportedServerVersionCondition(nameof(ServerVersionSupport.WhereSubqueryReferencesOuterQuery))] + public override async Task Subquery_with_navigation_inside_inline_collection(bool async) + { + await base.Subquery_with_navigation_inside_inline_collection(async); + + AssertSql(""); + } + private void AssertSql(params string[] expected) => Fixture.TestSqlLoggerFactory.AssertBaseline(expected); diff --git a/test/EFCore.MySql.FunctionalTests/Query/NorthwindQueryFiltersQueryMySqlTest.cs b/test/EFCore.MySql.FunctionalTests/Query/NorthwindQueryFiltersQueryMySqlTest.cs index fcc5eff9..5c0c8e84 100644 --- a/test/EFCore.MySql.FunctionalTests/Query/NorthwindQueryFiltersQueryMySqlTest.cs +++ b/test/EFCore.MySql.FunctionalTests/Query/NorthwindQueryFiltersQueryMySqlTest.cs @@ -1,4 +1,4 @@ -using System.Threading.Tasks; +using System.Threading.Tasks; using Microsoft.EntityFrameworkCore.Query; using Xunit.Abstractions; @@ -22,11 +22,11 @@ public override async Task Count_query(bool async) AssertSql( """ -@__ef_filter__TenantPrefix_0_rewritten='B%' (Size = 40) +@__ef_filter__TenantPrefix_0_startswith='B%' (Size = 40) SELECT COUNT(*) FROM `Customers` AS `c` -WHERE `c`.`CompanyName` LIKE @__ef_filter__TenantPrefix_0_rewritten +WHERE `c`.`CompanyName` LIKE @__ef_filter__TenantPrefix_0_startswith """); } diff --git a/test/EFCore.MySql.FunctionalTests/Query/PrimitiveCollectionsQueryMySqlTest.cs b/test/EFCore.MySql.FunctionalTests/Query/PrimitiveCollectionsQueryMySqlTest.cs index ccfec481..2d4283bb 100644 --- a/test/EFCore.MySql.FunctionalTests/Query/PrimitiveCollectionsQueryMySqlTest.cs +++ b/test/EFCore.MySql.FunctionalTests/Query/PrimitiveCollectionsQueryMySqlTest.cs @@ -61,10 +61,12 @@ public override async Task Inline_collection_of_nullable_ints_Contains_null(bool """); } - public override Task Inline_collection_Count_with_zero_values(bool async) - => AssertTranslationFailedWithDetails( - () => base.Inline_collection_Count_with_zero_values(async), - RelationalStrings.EmptyCollectionNotSupportedAsInlineQueryRoot); + public override async Task Inline_collection_Count_with_zero_values(bool async) + { + await base.Inline_collection_Count_with_zero_values(async); + + AssertSql(); + } public override async Task Inline_collection_Count_with_one_value(bool async) { @@ -148,10 +150,17 @@ SELECT COUNT(*) } } - public override Task Inline_collection_Contains_with_zero_values(bool async) - => AssertTranslationFailedWithDetails( - () => base.Inline_collection_Contains_with_zero_values(async), - RelationalStrings.EmptyCollectionNotSupportedAsInlineQueryRoot); + public override async Task Inline_collection_Contains_with_zero_values(bool async) + { + await base.Inline_collection_Contains_with_zero_values(async); + + AssertSql( +""" +SELECT `p`.`Id`, `p`.`Bool`, `p`.`Bools`, `p`.`DateTime`, `p`.`DateTimes`, `p`.`Enum`, `p`.`Enums`, `p`.`Int`, `p`.`Ints`, `p`.`NullableInt`, `p`.`NullableInts`, `p`.`NullableString`, `p`.`NullableStrings`, `p`.`String`, `p`.`Strings` +FROM `PrimitiveCollectionsEntity` AS `p` +WHERE FALSE +"""); + } public override async Task Inline_collection_Contains_with_one_value(bool async) { @@ -262,9 +271,9 @@ FROM JSON_TABLE('[2,999]', '$[*]' COLUMNS ( """); } - public override async Task Parameter_collection_of_ints_Contains(bool async) + public override async Task Parameter_collection_of_ints_Contains_int(bool async) { - await base.Parameter_collection_of_ints_Contains(async); + await base.Parameter_collection_of_ints_Contains_int(async); if (MySqlTestHelpers.HasPrimitiveCollectionsSupport(Fixture)) { @@ -283,18 +292,24 @@ FROM JSON_TABLE('[10,999]', '$[*]' COLUMNS ( } else { - AssertSql( + AssertSql( """ SELECT `p`.`Id`, `p`.`Bool`, `p`.`Bools`, `p`.`DateTime`, `p`.`DateTimes`, `p`.`Enum`, `p`.`Enums`, `p`.`Int`, `p`.`Ints`, `p`.`NullableInt`, `p`.`NullableInts`, `p`.`NullableString`, `p`.`NullableStrings`, `p`.`String`, `p`.`Strings` FROM `PrimitiveCollectionsEntity` AS `p` WHERE `p`.`Int` IN (10, 999) +""", + // + """ +SELECT `p`.`Id`, `p`.`Bool`, `p`.`Bools`, `p`.`DateTime`, `p`.`DateTimes`, `p`.`Enum`, `p`.`Enums`, `p`.`Int`, `p`.`Ints`, `p`.`NullableInt`, `p`.`NullableInts`, `p`.`NullableString`, `p`.`NullableStrings`, `p`.`String`, `p`.`Strings` +FROM `PrimitiveCollectionsEntity` AS `p` +WHERE `p`.`Int` NOT IN (10, 999) """); } } - public override async Task Parameter_collection_of_nullable_ints_Contains_int(bool async) + public override async Task Parameter_collection_of_ints_Contains_nullable_int(bool async) { - await base.Parameter_collection_of_nullable_ints_Contains_int(async); + await base.Parameter_collection_of_ints_Contains_nullable_int(async); if (MySqlTestHelpers.HasPrimitiveCollectionsSupport(Fixture)) { @@ -303,28 +318,34 @@ public override async Task Parameter_collection_of_nullable_ints_Contains_int(bo SELECT `p`.`Id`, `p`.`Bool`, `p`.`Bools`, `p`.`DateTime`, `p`.`DateTimes`, `p`.`Enum`, `p`.`Enums`, `p`.`Int`, `p`.`Ints`, `p`.`NullableInt`, `p`.`NullableInts`, `p`.`NullableString`, `p`.`NullableStrings`, `p`.`String`, `p`.`Strings` FROM `PrimitiveCollectionsEntity` AS `p` WHERE `p`.`Int` IN ( - SELECT `n`.`value` + SELECT `i`.`value` FROM JSON_TABLE('[10,999]', '$[*]' COLUMNS ( `key` FOR ORDINALITY, `value` int PATH '$[0]' - )) AS `n` + )) AS `i` ) """); } else { - AssertSql( + AssertSql( """ SELECT `p`.`Id`, `p`.`Bool`, `p`.`Bools`, `p`.`DateTime`, `p`.`DateTimes`, `p`.`Enum`, `p`.`Enums`, `p`.`Int`, `p`.`Ints`, `p`.`NullableInt`, `p`.`NullableInts`, `p`.`NullableString`, `p`.`NullableStrings`, `p`.`String`, `p`.`Strings` FROM `PrimitiveCollectionsEntity` AS `p` -WHERE `p`.`Int` IN (10, 999) +WHERE `p`.`NullableInt` IN (10, 999) +""", + // + """ +SELECT `p`.`Id`, `p`.`Bool`, `p`.`Bools`, `p`.`DateTime`, `p`.`DateTimes`, `p`.`Enum`, `p`.`Enums`, `p`.`Int`, `p`.`Ints`, `p`.`NullableInt`, `p`.`NullableInts`, `p`.`NullableString`, `p`.`NullableStrings`, `p`.`String`, `p`.`Strings` +FROM `PrimitiveCollectionsEntity` AS `p` +WHERE `p`.`NullableInt` NOT IN (10, 999) OR (`p`.`NullableInt` IS NULL) """); } } - public override async Task Parameter_collection_of_nullable_ints_Contains_nullable_int(bool async) + public override async Task Parameter_collection_of_nullable_ints_Contains_int(bool async) { - await base.Parameter_collection_of_nullable_ints_Contains_nullable_int(async); + await base.Parameter_collection_of_nullable_ints_Contains_int(async); if (MySqlTestHelpers.HasPrimitiveCollectionsSupport(Fixture)) { @@ -332,29 +353,35 @@ public override async Task Parameter_collection_of_nullable_ints_Contains_nullab """ SELECT `p`.`Id`, `p`.`Bool`, `p`.`Bools`, `p`.`DateTime`, `p`.`DateTimes`, `p`.`Enum`, `p`.`Enums`, `p`.`Int`, `p`.`Ints`, `p`.`NullableInt`, `p`.`NullableInts`, `p`.`NullableString`, `p`.`NullableStrings`, `p`.`String`, `p`.`Strings` FROM `PrimitiveCollectionsEntity` AS `p` -WHERE EXISTS ( - SELECT 1 - FROM JSON_TABLE('[null,999]', '$[*]' COLUMNS ( +WHERE `p`.`Int` IN ( + SELECT `n`.`value` + FROM JSON_TABLE('[10,999]', '$[*]' COLUMNS ( `key` FOR ORDINALITY, `value` int PATH '$[0]' )) AS `n` - WHERE (`n`.`value` = `p`.`NullableInt`) OR (`n`.`value` IS NULL AND (`p`.`NullableInt` IS NULL))) +) """); } else { - AssertSql( + AssertSql( """ SELECT `p`.`Id`, `p`.`Bool`, `p`.`Bools`, `p`.`DateTime`, `p`.`DateTimes`, `p`.`Enum`, `p`.`Enums`, `p`.`Int`, `p`.`Ints`, `p`.`NullableInt`, `p`.`NullableInts`, `p`.`NullableString`, `p`.`NullableStrings`, `p`.`String`, `p`.`Strings` FROM `PrimitiveCollectionsEntity` AS `p` -WHERE `p`.`NullableInt` IS NULL OR (`p`.`NullableInt` = 999) +WHERE `p`.`Int` IN (10, 999) +""", + // + """ +SELECT `p`.`Id`, `p`.`Bool`, `p`.`Bools`, `p`.`DateTime`, `p`.`DateTimes`, `p`.`Enum`, `p`.`Enums`, `p`.`Int`, `p`.`Ints`, `p`.`NullableInt`, `p`.`NullableInts`, `p`.`NullableString`, `p`.`NullableStrings`, `p`.`String`, `p`.`Strings` +FROM `PrimitiveCollectionsEntity` AS `p` +WHERE `p`.`Int` NOT IN (10, 999) """); } } - public override async Task Parameter_collection_of_strings_Contains_nullable_string(bool async) + public override async Task Parameter_collection_of_nullable_ints_Contains_nullable_int(bool async) { - await base.Parameter_collection_of_strings_Contains_nullable_string(async); + await base.Parameter_collection_of_nullable_ints_Contains_nullable_int(async); if (MySqlTestHelpers.HasPrimitiveCollectionsSupport(Fixture)) { @@ -364,27 +391,33 @@ public override async Task Parameter_collection_of_strings_Contains_nullable_str FROM `PrimitiveCollectionsEntity` AS `p` WHERE EXISTS ( SELECT 1 - FROM JSON_TABLE('["999",null]', '$[*]' COLUMNS ( + FROM JSON_TABLE('[null,999]', '$[*]' COLUMNS ( `key` FOR ORDINALITY, - `value` longtext PATH '$[0]' - )) AS `s` - WHERE (`s`.`value` = `p`.`NullableString`) OR (`s`.`value` IS NULL AND (`p`.`NullableString` IS NULL))) + `value` int PATH '$[0]' + )) AS `n` + WHERE (`n`.`value` = `p`.`NullableInt`) OR (`n`.`value` IS NULL AND (`p`.`NullableInt` IS NULL))) """); } else { - AssertSql( + AssertSql( """ SELECT `p`.`Id`, `p`.`Bool`, `p`.`Bools`, `p`.`DateTime`, `p`.`DateTimes`, `p`.`Enum`, `p`.`Enums`, `p`.`Int`, `p`.`Ints`, `p`.`NullableInt`, `p`.`NullableInts`, `p`.`NullableString`, `p`.`NullableStrings`, `p`.`String`, `p`.`Strings` FROM `PrimitiveCollectionsEntity` AS `p` -WHERE `p`.`NullableString` IS NULL OR (`p`.`NullableString` = '999') +WHERE `p`.`NullableInt` IS NULL OR (`p`.`NullableInt` = 999) +""", + // + """ +SELECT `p`.`Id`, `p`.`Bool`, `p`.`Bools`, `p`.`DateTime`, `p`.`DateTimes`, `p`.`Enum`, `p`.`Enums`, `p`.`Int`, `p`.`Ints`, `p`.`NullableInt`, `p`.`NullableInts`, `p`.`NullableString`, `p`.`NullableStrings`, `p`.`String`, `p`.`Strings` +FROM `PrimitiveCollectionsEntity` AS `p` +WHERE `p`.`NullableInt` IS NOT NULL AND (`p`.`NullableInt` <> 999) """); } } - public override async Task Parameter_collection_of_strings_Contains_non_nullable_string(bool async) + public override async Task Parameter_collection_of_strings_Contains_nullable_string(bool async) { - await base.Parameter_collection_of_strings_Contains_non_nullable_string(async); + await base.Parameter_collection_of_strings_Contains_nullable_string(async); if (MySqlTestHelpers.HasPrimitiveCollectionsSupport(Fixture)) { @@ -392,22 +425,28 @@ public override async Task Parameter_collection_of_strings_Contains_non_nullable """ SELECT `p`.`Id`, `p`.`Bool`, `p`.`Bools`, `p`.`DateTime`, `p`.`DateTimes`, `p`.`Enum`, `p`.`Enums`, `p`.`Int`, `p`.`Ints`, `p`.`NullableInt`, `p`.`NullableInts`, `p`.`NullableString`, `p`.`NullableStrings`, `p`.`String`, `p`.`Strings` FROM `PrimitiveCollectionsEntity` AS `p` -WHERE `p`.`String` IN ( - SELECT `s`.`value` - FROM JSON_TABLE('["10","999"]', '$[*]' COLUMNS ( +WHERE EXISTS ( + SELECT 1 + FROM JSON_TABLE('["999",null]', '$[*]' COLUMNS ( `key` FOR ORDINALITY, `value` longtext PATH '$[0]' )) AS `s` -) + WHERE (`s`.`value` = `p`.`NullableString`) OR (`s`.`value` IS NULL AND (`p`.`NullableString` IS NULL))) """); } else { - AssertSql( + AssertSql( """ SELECT `p`.`Id`, `p`.`Bool`, `p`.`Bools`, `p`.`DateTime`, `p`.`DateTimes`, `p`.`Enum`, `p`.`Enums`, `p`.`Int`, `p`.`Ints`, `p`.`NullableInt`, `p`.`NullableInts`, `p`.`NullableString`, `p`.`NullableStrings`, `p`.`String`, `p`.`Strings` FROM `PrimitiveCollectionsEntity` AS `p` -WHERE `p`.`String` IN ('10', '999') +WHERE `p`.`NullableString` IN ('10', '999') +""", + // + """ +SELECT `p`.`Id`, `p`.`Bool`, `p`.`Bools`, `p`.`DateTime`, `p`.`DateTimes`, `p`.`Enum`, `p`.`Enums`, `p`.`Int`, `p`.`Ints`, `p`.`NullableInt`, `p`.`NullableInts`, `p`.`NullableString`, `p`.`NullableStrings`, `p`.`String`, `p`.`Strings` +FROM `PrimitiveCollectionsEntity` AS `p` +WHERE `p`.`NullableString` NOT IN ('10', '999') OR (`p`.`NullableString` IS NULL) """); } } @@ -794,7 +833,7 @@ public override async Task Non_nullable_reference_column_collection_index_equals } } - [SupportedServerVersionCondition(nameof(ServerVersionSupport.OffsetReferencesOuterQuery))] + [SupportedServerVersionCondition(nameof(ServerVersionSupport.WhereSubqueryReferencesOuterQuery))] public override async Task Inline_collection_index_Column(bool async) { await base.Inline_collection_index_Column(async); @@ -1688,6 +1727,72 @@ END IN ('one', 'two', 'three') """); } + public override async Task Inline_collection_Contains_with_EF_Constant(bool async) + { + await base.Inline_collection_Contains_with_EF_Constant(async); + + AssertSql( +""" +SELECT `p`.`Id`, `p`.`Bool`, `p`.`Bools`, `p`.`DateTime`, `p`.`DateTimes`, `p`.`Enum`, `p`.`Enums`, `p`.`Int`, `p`.`Ints`, `p`.`NullableInt`, `p`.`NullableInts`, `p`.`NullableString`, `p`.`NullableStrings`, `p`.`String`, `p`.`Strings` +FROM `PrimitiveCollectionsEntity` AS `p` +WHERE `p`.`Id` IN (2, 999, 1000) +"""); + } + + public override async Task Parameter_collection_of_strings_Contains_string(bool async) + { + await base.Parameter_collection_of_strings_Contains_string(async); + + AssertSql( +""" +SELECT `p`.`Id`, `p`.`Bool`, `p`.`Bools`, `p`.`DateTime`, `p`.`DateTimes`, `p`.`Enum`, `p`.`Enums`, `p`.`Int`, `p`.`Ints`, `p`.`NullableInt`, `p`.`NullableInts`, `p`.`NullableString`, `p`.`NullableStrings`, `p`.`String`, `p`.`Strings` +FROM `PrimitiveCollectionsEntity` AS `p` +WHERE `p`.`String` IN ('10', '999') +""", + // + """ +SELECT `p`.`Id`, `p`.`Bool`, `p`.`Bools`, `p`.`DateTime`, `p`.`DateTimes`, `p`.`Enum`, `p`.`Enums`, `p`.`Int`, `p`.`Ints`, `p`.`NullableInt`, `p`.`NullableInts`, `p`.`NullableString`, `p`.`NullableStrings`, `p`.`String`, `p`.`Strings` +FROM `PrimitiveCollectionsEntity` AS `p` +WHERE `p`.`String` NOT IN ('10', '999') +"""); + } + + public override async Task Parameter_collection_of_nullable_strings_Contains_string(bool async) + { + await base.Parameter_collection_of_nullable_strings_Contains_string(async); + + AssertSql( +""" +SELECT `p`.`Id`, `p`.`Bool`, `p`.`Bools`, `p`.`DateTime`, `p`.`DateTimes`, `p`.`Enum`, `p`.`Enums`, `p`.`Int`, `p`.`Ints`, `p`.`NullableInt`, `p`.`NullableInts`, `p`.`NullableString`, `p`.`NullableStrings`, `p`.`String`, `p`.`Strings` +FROM `PrimitiveCollectionsEntity` AS `p` +WHERE `p`.`String` = '10' +""", + // + """ +SELECT `p`.`Id`, `p`.`Bool`, `p`.`Bools`, `p`.`DateTime`, `p`.`DateTimes`, `p`.`Enum`, `p`.`Enums`, `p`.`Int`, `p`.`Ints`, `p`.`NullableInt`, `p`.`NullableInts`, `p`.`NullableString`, `p`.`NullableStrings`, `p`.`String`, `p`.`Strings` +FROM `PrimitiveCollectionsEntity` AS `p` +WHERE `p`.`String` <> '10' +"""); + } + + public override async Task Parameter_collection_of_nullable_strings_Contains_nullable_string(bool async) + { + await base.Parameter_collection_of_nullable_strings_Contains_nullable_string(async); + + AssertSql( +""" +SELECT `p`.`Id`, `p`.`Bool`, `p`.`Bools`, `p`.`DateTime`, `p`.`DateTimes`, `p`.`Enum`, `p`.`Enums`, `p`.`Int`, `p`.`Ints`, `p`.`NullableInt`, `p`.`NullableInts`, `p`.`NullableString`, `p`.`NullableStrings`, `p`.`String`, `p`.`Strings` +FROM `PrimitiveCollectionsEntity` AS `p` +WHERE `p`.`NullableString` IS NULL OR (`p`.`NullableString` = '999') +""", + // + """ +SELECT `p`.`Id`, `p`.`Bool`, `p`.`Bools`, `p`.`DateTime`, `p`.`DateTimes`, `p`.`Enum`, `p`.`Enums`, `p`.`Int`, `p`.`Ints`, `p`.`NullableInt`, `p`.`NullableInts`, `p`.`NullableString`, `p`.`NullableStrings`, `p`.`String`, `p`.`Strings` +FROM `PrimitiveCollectionsEntity` AS `p` +WHERE `p`.`NullableString` IS NOT NULL AND (`p`.`NullableString` <> '999') +"""); + } + [ConditionalFact] public virtual void Check_all_tests_overridden() => TestHelpers.AssertAllMethodsOverridden(GetType()); diff --git a/test/EFCore.MySql.FunctionalTests/Query/TPCGearsOfWarQueryMySqlTest.cs b/test/EFCore.MySql.FunctionalTests/Query/TPCGearsOfWarQueryMySqlTest.cs index 878e31a3..035735c3 100644 --- a/test/EFCore.MySql.FunctionalTests/Query/TPCGearsOfWarQueryMySqlTest.cs +++ b/test/EFCore.MySql.FunctionalTests/Query/TPCGearsOfWarQueryMySqlTest.cs @@ -3077,9 +3077,9 @@ public override async Task Non_unicode_string_literals_is_used_for_non_unicode_c """); } - public override async Task Non_unicode_string_literals_is_used_for_non_unicode_column_with_concat(bool async) + public override async Task Unicode_string_literals_is_used_for_non_unicode_column_with_concat(bool async) { - await base.Non_unicode_string_literals_is_used_for_non_unicode_column_with_concat(async); + await base.Unicode_string_literals_is_used_for_non_unicode_column_with_concat(async); AssertSql( """ diff --git a/test/EFCore.MySql.IntegrationTests/EFCore.MySql.IntegrationTests.csproj b/test/EFCore.MySql.IntegrationTests/EFCore.MySql.IntegrationTests.csproj index 469bc392..69c0c2ef 100644 --- a/test/EFCore.MySql.IntegrationTests/EFCore.MySql.IntegrationTests.csproj +++ b/test/EFCore.MySql.IntegrationTests/EFCore.MySql.IntegrationTests.csproj @@ -51,28 +51,28 @@ - $(LocalEFCoreRepository)\artifacts\bin\EFCore.Design.Tests\Debug\$(EfCoreTestTargetFramework)\Microsoft.EntityFrameworkCore.dll + $(LocalEFCoreRepository)\artifacts\bin\EFCore.Design.Tests\$(LocalEFCoreRepositoryConfiguration)\$(EfCoreTestTargetFramework)\Microsoft.EntityFrameworkCore.dll - $(LocalEFCoreRepository)\artifacts\bin\EFCore.Design.Tests\Debug\$(EfCoreTestTargetFramework)\Microsoft.EntityFrameworkCore.Abstractions.dll + $(LocalEFCoreRepository)\artifacts\bin\EFCore.Design.Tests\$(LocalEFCoreRepositoryConfiguration)\$(EfCoreTestTargetFramework)\Microsoft.EntityFrameworkCore.Abstractions.dll - $(LocalEFCoreRepository)\artifacts\bin\EFCore.Design.Tests\Debug\$(EfCoreTestTargetFramework)\Microsoft.EntityFrameworkCore.Analyzers.dll + $(LocalEFCoreRepository)\artifacts\bin\EFCore.Design.Tests\$(LocalEFCoreRepositoryConfiguration)\$(EfCoreTestTargetFramework)\Microsoft.EntityFrameworkCore.Analyzers.dll - $(LocalEFCoreRepository)\artifacts\bin\EFCore.Design.Tests\Debug\$(EfCoreTestTargetFramework)\Microsoft.EntityFrameworkCore.Design.dll + $(LocalEFCoreRepository)\artifacts\bin\EFCore.Design.Tests\$(LocalEFCoreRepositoryConfiguration)\$(EfCoreTestTargetFramework)\Microsoft.EntityFrameworkCore.Design.dll - $(LocalEFCoreRepository)\artifacts\bin\EFCore.Design.Tests\Debug\$(EfCoreTestTargetFramework)\Microsoft.EntityFrameworkCore.Relational.dll + $(LocalEFCoreRepository)\artifacts\bin\EFCore.Design.Tests\$(LocalEFCoreRepositoryConfiguration)\$(EfCoreTestTargetFramework)\Microsoft.EntityFrameworkCore.Relational.dll - $(LocalEFCoreRepository)\artifacts\bin\EFCore.Relational.Tests\Debug\$(EfCoreTestTargetFramework)\Microsoft.EntityFrameworkCore.Specification.Tests.dll + $(LocalEFCoreRepository)\artifacts\bin\EFCore.Relational.Tests\$(LocalEFCoreRepositoryConfiguration)\$(EfCoreTestTargetFramework)\Microsoft.EntityFrameworkCore.Specification.Tests.dll - $(LocalMySqlConnectorRepository)\artifacts\bin\MySqlConnector\debug_$(MySqlConnectorTargetFramework)\MySqlConnector.dll + $(LocalMySqlConnectorRepository)\artifacts\bin\MySqlConnector\$(LocalMySqlConnectorRepositoryConfiguration)_$(MySqlConnectorTargetFramework)\MySqlConnector.dll diff --git a/test/EFCore.MySql.Tests/EFCore.MySql.Tests.csproj b/test/EFCore.MySql.Tests/EFCore.MySql.Tests.csproj index 6b9b211d..9975ac10 100644 --- a/test/EFCore.MySql.Tests/EFCore.MySql.Tests.csproj +++ b/test/EFCore.MySql.Tests/EFCore.MySql.Tests.csproj @@ -46,37 +46,37 @@ - $(LocalEFCoreRepository)\artifacts\bin\EFCore.Relational.Tests\Debug\$(EfCoreTestTargetFramework)\Microsoft.EntityFrameworkCore.dll + $(LocalEFCoreRepository)\artifacts\bin\EFCore.Relational.Tests\$(LocalEFCoreRepositoryConfiguration)\$(EfCoreTestTargetFramework)\Microsoft.EntityFrameworkCore.dll - $(LocalEFCoreRepository)\artifacts\bin\EFCore.Relational.Tests\Debug\$(EfCoreTestTargetFramework)\Microsoft.EntityFrameworkCore.Abstractions.dll + $(LocalEFCoreRepository)\artifacts\bin\EFCore.Relational.Tests\$(LocalEFCoreRepositoryConfiguration)\$(EfCoreTestTargetFramework)\Microsoft.EntityFrameworkCore.Abstractions.dll - $(LocalEFCoreRepository)\artifacts\bin\EFCore.Relational.Tests\Debug\$(EfCoreTestTargetFramework)\Microsoft.EntityFrameworkCore.Analyzers.dll + $(LocalEFCoreRepository)\artifacts\bin\EFCore.Relational.Tests\$(LocalEFCoreRepositoryConfiguration)\$(EfCoreTestTargetFramework)\Microsoft.EntityFrameworkCore.Analyzers.dll - $(LocalEFCoreRepository)\artifacts\bin\EFCore.Design.Tests\Debug\$(EfCoreTestTargetFramework)\Microsoft.EntityFrameworkCore.Design.dll + $(LocalEFCoreRepository)\artifacts\bin\EFCore.Design.Tests\$(LocalEFCoreRepositoryConfiguration)\$(EfCoreTestTargetFramework)\Microsoft.EntityFrameworkCore.Design.dll - $(LocalEFCoreRepository)\artifacts\bin\EFCore.Relational.Tests\Debug\$(EfCoreTestTargetFramework)\Microsoft.EntityFrameworkCore.Proxies.dll + $(LocalEFCoreRepository)\artifacts\bin\EFCore.Relational.Tests\$(LocalEFCoreRepositoryConfiguration)\$(EfCoreTestTargetFramework)\Microsoft.EntityFrameworkCore.Proxies.dll - $(LocalEFCoreRepository)\artifacts\bin\EFCore.Relational.Tests\Debug\$(EfCoreTestTargetFramework)\Microsoft.EntityFrameworkCore.Relational.dll + $(LocalEFCoreRepository)\artifacts\bin\EFCore.Relational.Tests\$(LocalEFCoreRepositoryConfiguration)\$(EfCoreTestTargetFramework)\Microsoft.EntityFrameworkCore.Relational.dll - $(LocalEFCoreRepository)\artifacts\bin\EFCore.Relational.Tests\Debug\$(EfCoreTestTargetFramework)\Microsoft.EntityFrameworkCore.Relational.Specification.Tests.dll + $(LocalEFCoreRepository)\artifacts\bin\EFCore.Relational.Tests\$(LocalEFCoreRepositoryConfiguration)\$(EfCoreTestTargetFramework)\Microsoft.EntityFrameworkCore.Relational.Specification.Tests.dll - $(LocalEFCoreRepository)\artifacts\bin\EFCore.Relational.Tests\Debug\$(EfCoreTestTargetFramework)\Microsoft.EntityFrameworkCore.Specification.Tests.dll + $(LocalEFCoreRepository)\artifacts\bin\EFCore.Relational.Tests\$(LocalEFCoreRepositoryConfiguration)\$(EfCoreTestTargetFramework)\Microsoft.EntityFrameworkCore.Specification.Tests.dll - $(LocalMySqlConnectorRepository)\artifacts\bin\MySqlConnector\debug_$(MySqlConnectorTargetFramework)\MySqlConnector.dll + $(LocalMySqlConnectorRepository)\artifacts\bin\MySqlConnector\$(LocalMySqlConnectorRepositoryConfiguration)_$(MySqlConnectorTargetFramework)\MySqlConnector.dll - $(LocalMySqlConnectorRepository)\artifacts\bin\MySqlConnector.DependencyInjection\debug_$(MySqlConnectorDependencyInjectionTargetFramework)\MySqlConnector.DependencyInjection.dll + $(LocalMySqlConnectorRepository)\artifacts\bin\MySqlConnector.DependencyInjection\$(LocalMySqlConnectorRepositoryConfiguration)_$(MySqlConnectorDependencyInjectionTargetFramework)\MySqlConnector.DependencyInjection.dll