Skip to content

Commit

Permalink
Merge branch 'CirrusRedOrg:master' into minreqoledbodbc
Browse files Browse the repository at this point in the history
  • Loading branch information
ChrisJollyAU committed Mar 12, 2024
2 parents 7077d0b + 17e8819 commit 5a61e01
Show file tree
Hide file tree
Showing 18 changed files with 307 additions and 156 deletions.
2 changes: 1 addition & 1 deletion Dependencies.targets
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project>
<PropertyGroup>
<EFCoreVersion>[8.0.2, 9.0.0)</EFCoreVersion>
<EFCoreVersion>[8.0.2,8.0.999]</EFCoreVersion>
</PropertyGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
Expand Down Expand Up @@ -277,7 +278,8 @@ methodType switch
QueryCompilationContext.QueryContextParameter);

var escapedPatternParameter =
_queryCompilationContext.RegisterRuntimeParameter(patternParameter.Name + "_rewritten", lambda);
_queryCompilationContext.RegisterRuntimeParameter(
$"{patternParameter.Name}_{methodType.ToString().ToLower(CultureInfo.InvariantCulture)}", lambda);

translation = _sqlExpressionFactory.Like(
translatedInstance,
Expand Down
2 changes: 1 addition & 1 deletion src/EFCore.Jet/Storage/Internal/JetDoubleTypeMapping.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ protected override string GenerateNonNullSqlLiteral(object value)
//-1.23456789 can have multiple 9s at the end
//Base uses format of G17
var doubleValue = Convert.ToDouble(value);
var literal = doubleValue.ToString("G", CultureInfo.InvariantCulture);
var literal = doubleValue.ToString("G15", CultureInfo.InvariantCulture);

return !literal.Contains('E')
&& !literal.Contains('e')
Expand Down
12 changes: 12 additions & 0 deletions src/EFCore.Jet/Storage/Internal/JetFloatTypeMapping.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Storage;
using System.Globalization;
using System;

namespace EntityFrameworkCore.Jet.Storage.Internal
{
Expand All @@ -25,5 +27,15 @@ protected override string ProcessStoreType(RelationalTypeMappingParameters param
{
return base.ProcessStoreType(parameters, storeTypeNameBase, storeTypeNameBase);
}

/// <summary>
/// Generates the SQL representation of a literal value.
/// </summary>
/// <param name="value">The literal value.</param>
/// <returns>
/// The generated string.
/// </returns>
protected override string GenerateNonNullSqlLiteral(object value)
=> Convert.ToSingle(value).ToString("G7", CultureInfo.InvariantCulture);
}
}
8 changes: 6 additions & 2 deletions src/EFCore.Jet/Storage/Internal/JetStringTypeMapping.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Data;
using System.Data.Common;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.ChangeTracking;
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.EntityFrameworkCore.Storage.Json;

Expand All @@ -18,6 +19,8 @@ public class JetStringTypeMapping : StringTypeMapping
private readonly bool _keepLineBreakCharacters;
private readonly int _maxSpecificSize;

private static readonly CaseInsensitiveValueComparer CaseInsensitiveValueComparer = new();

/// <summary>
/// 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.
Expand All @@ -28,10 +31,11 @@ public class JetStringTypeMapping : StringTypeMapping
int? size = null,
bool fixedLength = false,
StoreTypePostfix? storeTypePostfix = null,
bool keepLineBreakCharacters = false)
bool keepLineBreakCharacters = false,
bool useKeyComparison = false)
: this(
new RelationalTypeMappingParameters(
new CoreTypeMappingParameters(typeof(string), jsonValueReaderWriter: JsonStringReaderWriter.Instance),
new CoreTypeMappingParameters(typeof(string), comparer: useKeyComparison ? CaseInsensitiveValueComparer : null, keyComparer:useKeyComparison ? CaseInsensitiveValueComparer : null, jsonValueReaderWriter: JsonStringReaderWriter.Instance),
storeType ?? GetStoreName(fixedLength),
storeTypePostfix ?? StoreTypePostfix.Size,
(fixedLength
Expand Down
3 changes: 2 additions & 1 deletion src/EFCore.Jet/Storage/Internal/JetTypeMappingSource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,8 @@ protected override void ValidateMapping(CoreTypeMapping? mapping, IProperty? pro
? _fixedLengthUnicodeString.StoreTypeNameBase
: _variableLengthUnicodeString.StoreTypeNameBase,
size: size,
unicode: true);
unicode: true,
useKeyComparison: mappingInfo.IsKeyOrIndex);
}

if (clrType == typeof(byte[]))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1419,9 +1419,9 @@ public class ConvertToProviderTypesJetFixture : ConvertToProviderTypesFixtureBas
{
public override bool StrictEquality => true;

public override bool SupportsAnsi => true;
public override bool SupportsAnsi => false;

public override bool SupportsUnicodeToAnsiConversion => true;
public override bool SupportsUnicodeToAnsiConversion => false;

public override bool SupportsLargeStringComparisons => true;

Expand Down
130 changes: 128 additions & 2 deletions test/EFCore.Jet.FunctionalTests/CustomConvertersJetTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public class CustomConvertersJetTest : CustomConvertersTestBase<CustomConverters
public CustomConvertersJetTest(CustomConvertersJetFixture fixture)
: base(fixture)
{
Fixture.TestSqlLoggerFactory.Clear();
}

[ConditionalFact]
Expand Down Expand Up @@ -545,18 +546,143 @@ private static bool IsUnsignedInteger(Type type)
|| type == typeof(ushort)
|| type == typeof(char);

[ConditionalFact]
public override void Value_conversion_is_appropriately_used_for_join_condition()
{
base.Value_conversion_is_appropriately_used_for_join_condition();

AssertSql(
"""
@__blogId_0='1'

SELECT [b].[Url]
FROM [Blog] AS [b]
INNER JOIN [Post] AS [p] ON [b].[BlogId] = [p].[BlogId] AND [b].[IsVisible] = N'Y' AND [b].[BlogId] = @__blogId_0
WHERE [b].[IsVisible] = N'Y'
""");
}

[ConditionalFact]
public override void Value_conversion_is_appropriately_used_for_left_join_condition()
{
base.Value_conversion_is_appropriately_used_for_left_join_condition();

AssertSql(
"""
@__blogId_0='1'

SELECT [b].[Url]
FROM [Blog] AS [b]
LEFT JOIN [Post] AS [p] ON [b].[BlogId] = [p].[BlogId] AND [b].[IsVisible] = N'Y' AND [b].[BlogId] = @__blogId_0
WHERE [b].[IsVisible] = N'Y'
""");
}

[ConditionalFact]
public override void Where_bool_gets_converted_to_equality_when_value_conversion_is_used()
{
base.Where_bool_gets_converted_to_equality_when_value_conversion_is_used();

AssertSql(
"""
SELECT `b`.`BlogId`, `b`.`Discriminator`, `b`.`IndexerVisible`, `b`.`IsVisible`, `b`.`Url`, `b`.`RssUrl`
FROM `Blog` AS `b`
WHERE `b`.`IsVisible` = 'Y'
""");
}

[ConditionalFact]
public override void Where_negated_bool_gets_converted_to_equality_when_value_conversion_is_used()
{
base.Where_negated_bool_gets_converted_to_equality_when_value_conversion_is_used();

AssertSql(
"""
SELECT `b`.`BlogId`, `b`.`Discriminator`, `b`.`IndexerVisible`, `b`.`IsVisible`, `b`.`Url`, `b`.`RssUrl`
FROM `Blog` AS `b`
WHERE `b`.`IsVisible` = 'N'
""");
}

public override void Where_bool_gets_converted_to_equality_when_value_conversion_is_used_using_EFProperty()
{
base.Where_bool_gets_converted_to_equality_when_value_conversion_is_used_using_EFProperty();

AssertSql(
"""
SELECT `b`.`BlogId`, `b`.`Discriminator`, `b`.`IndexerVisible`, `b`.`IsVisible`, `b`.`Url`, `b`.`RssUrl`
FROM `Blog` AS `b`
WHERE `b`.`IsVisible` = 'Y'
""");
}

public override void Where_bool_gets_converted_to_equality_when_value_conversion_is_used_using_indexer()
{
base.Where_bool_gets_converted_to_equality_when_value_conversion_is_used_using_indexer();

AssertSql(
"""
SELECT `b`.`BlogId`, `b`.`Discriminator`, `b`.`IndexerVisible`, `b`.`IsVisible`, `b`.`Url`, `b`.`RssUrl`
FROM `Blog` AS `b`
WHERE `b`.`IndexerVisible` = 'Nay'
""");
}

public override void Object_to_string_conversion()
{
// Return values are not string
}

public override void Id_object_as_entity_key()
{
base.Id_object_as_entity_key();

AssertSql(
"""
SELECT `b`.`Id`, `b`.`Value`
FROM `Book` AS `b`
WHERE `b`.`Id` = 1
""");
}

public override void Infer_type_mapping_from_in_subquery_to_item()
{
base.Infer_type_mapping_from_in_subquery_to_item();

AssertSql(
"""
SELECT `b`.`Id`, `b`.`Enum16`, `b`.`Enum32`, `b`.`Enum64`, `b`.`Enum8`, `b`.`EnumS8`, `b`.`EnumU16`, `b`.`EnumU32`, `b`.`EnumU64`, `b`.`PartitionId`, `b`.`TestBoolean`, `b`.`TestByte`, `b`.`TestCharacter`, `b`.`TestDateOnly`, `b`.`TestDateTime`, `b`.`TestDateTimeOffset`, `b`.`TestDecimal`, `b`.`TestDouble`, `b`.`TestInt16`, `b`.`TestInt32`, `b`.`TestInt64`, `b`.`TestSignedByte`, `b`.`TestSingle`, `b`.`TestTimeOnly`, `b`.`TestTimeSpan`, `b`.`TestUnsignedInt16`, `b`.`TestUnsignedInt32`, `b`.`TestUnsignedInt64`
FROM `BuiltInDataTypes` AS `b`
WHERE 'Yeps' IN (
SELECT `b0`.`TestBoolean`
FROM `BuiltInDataTypes` AS `b0`
) AND `b`.`Id` = 13
""");
}

private void AssertSql(params string[] expected)
=> Fixture.TestSqlLoggerFactory.AssertBaseline(expected);

public override void Value_conversion_on_enum_collection_contains()
=> Assert.Contains(
CoreStrings.TranslationFailed("")[47..],
Assert.Throws<InvalidOperationException>(() => base.Value_conversion_on_enum_collection_contains()).Message);

public class CustomConvertersJetFixture : CustomConvertersFixtureBase
{
public override bool StrictEquality => true;

public override bool SupportsAnsi => true;
public override bool SupportsAnsi => false;

public override bool SupportsUnicodeToAnsiConversion => true;
public override bool SupportsUnicodeToAnsiConversion => false;

public override bool SupportsLargeStringComparisons => true;

protected override ITestStoreFactory TestStoreFactory => JetTestStoreFactory.Instance;

public TestSqlLoggerFactory TestSqlLoggerFactory
=> (TestSqlLoggerFactory)ListLoggerFactory;

public override bool SupportsBinaryKeys => true;

public override bool SupportsDecimalComparisons => true;
Expand Down
4 changes: 2 additions & 2 deletions test/EFCore.Jet.FunctionalTests/EverythingIsStringsJetTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -198,9 +198,9 @@ public class EverythingIsStringsJetFixture : BuiltInDataTypesFixtureBase
{
public override bool StrictEquality => true;

public override bool SupportsAnsi => true;
public override bool SupportsAnsi => false;

public override bool SupportsUnicodeToAnsiConversion => true;
public override bool SupportsUnicodeToAnsiConversion => false;

public override bool SupportsLargeStringComparisons => true;

Expand Down
8 changes: 5 additions & 3 deletions test/EFCore.Jet.FunctionalTests/ExecutionStrategyTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ private void Test_commit_failure(bool realFailure, Action<TestJetRetryingExecuti

var retryMessage = (TestEnvironment.DataAccessProviderType == DataAccessProviderType.OleDb
? typeof(OleDbException)
: typeof(OdbcException)).FullName + " : Bang!";;
: typeof(OdbcException)).FullName + " (0xFFFFFFFE): Bang!"; ;

if (realFailure)
{
Expand Down Expand Up @@ -220,8 +220,10 @@ public async Task Handles_commit_failure_async(bool realFailure)
await execute(new TestJetRetryingExecutionStrategy(context), context);
context.ChangeTracker.AcceptAllChanges();

var retryMessage =
"System.Data.OleDb.OleDbException : Bang!";
var retryMessage = (TestEnvironment.DataAccessProviderType == DataAccessProviderType.OleDb
? typeof(OleDbException)
: typeof(OdbcException)).FullName + " (0xFFFFFFFE): Bang!";

if (realFailure)
{
var logEntry = Fixture.TestSqlLoggerFactory.Log.Single(l => l.Id == CoreEventId.ExecutionStrategyRetrying);
Expand Down
10 changes: 10 additions & 0 deletions test/EFCore.Jet.FunctionalTests/GreenTests/ace_2010_odbc_x86.txt
Original file line number Diff line number Diff line change
Expand Up @@ -864,6 +864,7 @@ EntityFrameworkCore.Jet.FunctionalTests.CustomConvertersJetTest.Can_insert_and_r
EntityFrameworkCore.Jet.FunctionalTests.CustomConvertersJetTest.Can_insert_and_read_back_nullable_backed_data_types
EntityFrameworkCore.Jet.FunctionalTests.CustomConvertersJetTest.Can_insert_and_read_back_object_backed_data_types
EntityFrameworkCore.Jet.FunctionalTests.CustomConvertersJetTest.Can_insert_and_read_back_with_binary_key
EntityFrameworkCore.Jet.FunctionalTests.CustomConvertersJetTest.Can_insert_and_read_back_with_case_insensitive_string_key
EntityFrameworkCore.Jet.FunctionalTests.CustomConvertersJetTest.Can_insert_and_read_back_with_null_binary_foreign_key
EntityFrameworkCore.Jet.FunctionalTests.CustomConvertersJetTest.Can_insert_and_read_back_with_null_string_foreign_key
EntityFrameworkCore.Jet.FunctionalTests.CustomConvertersJetTest.Can_insert_and_read_back_with_string_key
Expand All @@ -878,6 +879,7 @@ EntityFrameworkCore.Jet.FunctionalTests.CustomConvertersJetTest.Can_query_custom
EntityFrameworkCore.Jet.FunctionalTests.CustomConvertersJetTest.Can_query_using_any_data_type
EntityFrameworkCore.Jet.FunctionalTests.CustomConvertersJetTest.Can_query_using_any_data_type_shadow
EntityFrameworkCore.Jet.FunctionalTests.CustomConvertersJetTest.Can_query_using_any_nullable_data_type
EntityFrameworkCore.Jet.FunctionalTests.CustomConvertersJetTest.Can_query_using_any_nullable_data_type_as_literal
EntityFrameworkCore.Jet.FunctionalTests.CustomConvertersJetTest.Can_query_with_null_parameters_using_any_nullable_data_type
EntityFrameworkCore.Jet.FunctionalTests.CustomConvertersJetTest.Can_read_back_bool_mapped_as_int_through_navigation
EntityFrameworkCore.Jet.FunctionalTests.CustomConvertersJetTest.Can_read_back_mapped_enum_from_collection_first_or_default
Expand All @@ -895,6 +897,7 @@ EntityFrameworkCore.Jet.FunctionalTests.CustomConvertersJetTest.Optional_datetim
EntityFrameworkCore.Jet.FunctionalTests.CustomConvertersJetTest.Optional_owned_with_converter_reading_non_nullable_column
EntityFrameworkCore.Jet.FunctionalTests.CustomConvertersJetTest.Select_bool_with_value_conversion_is_used
EntityFrameworkCore.Jet.FunctionalTests.CustomConvertersJetTest.Select_conditional_bool_with_value_conversion_is_used
EntityFrameworkCore.Jet.FunctionalTests.CustomConvertersJetTest.Value_conversion_on_enum_collection_contains
EntityFrameworkCore.Jet.FunctionalTests.CustomConvertersJetTest.Value_conversion_with_property_named_value
EntityFrameworkCore.Jet.FunctionalTests.CustomConvertersJetTest.Where_bool_gets_converted_to_equality_when_value_conversion_is_used
EntityFrameworkCore.Jet.FunctionalTests.CustomConvertersJetTest.Where_bool_gets_converted_to_equality_when_value_conversion_is_used_using_EFProperty
Expand Down Expand Up @@ -1274,6 +1277,7 @@ EntityFrameworkCore.Jet.FunctionalTests.EverythingIsStringsJetTest.Can_insert_an
EntityFrameworkCore.Jet.FunctionalTests.EverythingIsStringsJetTest.Can_insert_and_read_back_with_null_string_foreign_key
EntityFrameworkCore.Jet.FunctionalTests.EverythingIsStringsJetTest.Can_insert_and_read_back_with_string_key
EntityFrameworkCore.Jet.FunctionalTests.EverythingIsStringsJetTest.Can_insert_query_multiline_string
EntityFrameworkCore.Jet.FunctionalTests.EverythingIsStringsJetTest.Can_perform_query_with_ansi_strings_test
EntityFrameworkCore.Jet.FunctionalTests.EverythingIsStringsJetTest.Can_query_using_any_data_type
EntityFrameworkCore.Jet.FunctionalTests.EverythingIsStringsJetTest.Can_query_using_any_data_type_nullable_shadow
EntityFrameworkCore.Jet.FunctionalTests.EverythingIsStringsJetTest.Can_query_using_any_data_type_shadow
Expand Down Expand Up @@ -9909,6 +9913,8 @@ EntityFrameworkCore.Jet.FunctionalTests.Query.FromSqlSprocQueryJetTest.From_sql_
EntityFrameworkCore.Jet.FunctionalTests.Query.FromSqlSprocQueryJetTest.From_sql_queryable_with_multiple_stored_procedures_on_client(async: True)
EntityFrameworkCore.Jet.FunctionalTests.Query.FromSqlSprocQueryJetTest.From_sql_queryable_with_multiple_stored_procedures(async: False)
EntityFrameworkCore.Jet.FunctionalTests.Query.FromSqlSprocQueryJetTest.From_sql_queryable_with_multiple_stored_procedures(async: True)
EntityFrameworkCore.Jet.FunctionalTests.Query.FunkyDataQueryJetTest.String_Contains_and_StartsWith_with_same_parameter(async: False)
EntityFrameworkCore.Jet.FunctionalTests.Query.FunkyDataQueryJetTest.String_Contains_and_StartsWith_with_same_parameter(async: True)
EntityFrameworkCore.Jet.FunctionalTests.Query.FunkyDataQueryJetTest.String_contains_on_argument_with_wildcard_column_negated(isAsync: False)
EntityFrameworkCore.Jet.FunctionalTests.Query.FunkyDataQueryJetTest.String_contains_on_argument_with_wildcard_column_negated(isAsync: True)
EntityFrameworkCore.Jet.FunctionalTests.Query.FunkyDataQueryJetTest.String_contains_on_argument_with_wildcard_column(isAsync: False)
Expand Down Expand Up @@ -12661,6 +12667,8 @@ EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindMiscellaneousQueryJetTest
EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindMiscellaneousQueryJetTest.OrderByDescending_ThenByDescending(async: True)
EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindMiscellaneousQueryJetTest.OrderByDescending(async: False)
EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindMiscellaneousQueryJetTest.OrderByDescending(async: True)
EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindMiscellaneousQueryJetTest.Parameter_collection_Contains_with_projection_and_ordering(async: False)
EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindMiscellaneousQueryJetTest.Parameter_collection_Contains_with_projection_and_ordering(async: True)
EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindMiscellaneousQueryJetTest.Parameter_extraction_can_throw_exception_from_user_code_2(async: False)
EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindMiscellaneousQueryJetTest.Parameter_extraction_can_throw_exception_from_user_code_2(async: True)
EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindMiscellaneousQueryJetTest.Parameter_extraction_can_throw_exception_from_user_code(async: False)
Expand Down Expand Up @@ -13497,6 +13505,8 @@ EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindSelectQueryJetTest.Select
EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindSelectQueryJetTest.Select_short_constant(isAsync: True)
EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindSelectQueryJetTest.Select_with_complex_expression_that_can_be_funcletized(isAsync: False)
EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindSelectQueryJetTest.Select_with_complex_expression_that_can_be_funcletized(isAsync: True)
EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindSelectQueryJetTest.SelectMany_with_collection_being_correlated_subquery_which_references_non_mapped_properties_from_inner_and_outer_entity(isAsync: False)
EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindSelectQueryJetTest.SelectMany_with_collection_being_correlated_subquery_which_references_non_mapped_properties_from_inner_and_outer_entity(isAsync: True)
EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindSelectQueryJetTest.SelectMany_without_result_selector_collection_navigation_composed(isAsync: False)
EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindSelectQueryJetTest.SelectMany_without_result_selector_collection_navigation_composed(isAsync: True)
EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindSelectQueryJetTest.SelectMany_without_result_selector_naked_collection_navigation(isAsync: False)
Expand Down
Loading

0 comments on commit 5a61e01

Please sign in to comment.