From 59cfb1f71ce4832b8f815a6189138d5564de48ab Mon Sep 17 00:00:00 2001 From: Jiri Cincura Date: Wed, 8 Jan 2025 14:13:21 +0100 Subject: [PATCH 01/32] Use Convert.ToHexString. --- .../FbDataReaderTests.cs | 2 +- src/FirebirdSql.Data.FirebirdClient/Common/Extensions.cs | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/FirebirdSql.Data.FirebirdClient.Tests/FbDataReaderTests.cs b/src/FirebirdSql.Data.FirebirdClient.Tests/FbDataReaderTests.cs index 1aa2e50e6..c87c804bc 100644 --- a/src/FirebirdSql.Data.FirebirdClient.Tests/FbDataReaderTests.cs +++ b/src/FirebirdSql.Data.FirebirdClient.Tests/FbDataReaderTests.cs @@ -313,7 +313,7 @@ public async Task ReadBinaryTest() { bytes[i] = (byte)random.Next(byte.MinValue, byte.MaxValue); } - var binaryString = $"x'{BitConverter.ToString(bytes).Replace("-", string.Empty)}'"; + var binaryString = $"x'{Convert.ToHexString(bytes)}'"; await using (var command = new FbCommand($"select {binaryString} from TEST", Connection, transaction)) { diff --git a/src/FirebirdSql.Data.FirebirdClient/Common/Extensions.cs b/src/FirebirdSql.Data.FirebirdClient/Common/Extensions.cs index b3d5d4327..39bcbd91b 100644 --- a/src/FirebirdSql.Data.FirebirdClient/Common/Extensions.cs +++ b/src/FirebirdSql.Data.FirebirdClient/Common/Extensions.cs @@ -48,7 +48,11 @@ public static IntPtr ReadIntPtr(this BinaryReader self) public static string ToHexString(this byte[] b) { +#if NET5_0_OR_GREATER + return Convert.ToHexString(b); +#else return BitConverter.ToString(b).Replace("-", string.Empty); +#endif } public static IEnumerable> Split(this T[] array, int size) From 8ddc5b124459b99a56fd6247ad1be455a8a10ac4 Mon Sep 17 00:00:00 2001 From: Jiri Cincura Date: Thu, 6 Feb 2025 10:13:17 +0100 Subject: [PATCH 02/32] EF Core 9 support. --- .github/workflows/ci.yml | 4 +- .../EntityFramework.Firebird.Tests.csproj | 4 +- ...rebirdSql.Data.FirebirdClient.Tests.csproj | 2 +- .../ComplianceFbTest.cs | 158 ++++++++++++ ...meworkCore.Firebird.FunctionalTests.csproj | 6 +- .../MigrationsFbTest.cs | 51 ++++ ...cs => AdHocAdvancedMappingsQueryFbTest.cs} | 2 +- .../Query/AdHocComplexTypeQueryFbTest.cs | 27 ++ .../Query/AdHocManyToManyQueryFbTest.cs | 27 ++ ...st.cs => AdHocMiscellaneousQueryFbTest.cs} | 21 +- .../Query/AdHocNavigationsQueryFbTest.cs | 56 +++++ .../Query/AdHocQueryFiltersQueryFbTest.cs | 35 +++ .../Query/AdHocQuerySplittingQueryFbTest.cs | 72 ++++++ .../Query/ComplexNavigationsQueryFbTest.cs | 24 +- ...ComplexNavigationsSharedTypeQueryFbTest.cs | 21 ++ .../Query/CompositeKeysQueryFbTest.cs | 3 - .../Query/CompositeKeysSplitQueryFbTest.cs | 2 - .../Query/Ef6GroupByFbTest.cs | 4 +- .../Query/FromSqlQueryFbTest.cs | 7 + .../Query/FunkyDataQueryFbTest.cs | 5 +- .../Query/GearsOfWarQueryFbTest.cs | 7 + ...onSharedPrimitiveCollectionsQueryFbTest.cs | 44 +++- .../NorthwindAggregateOperatorsQueryFbTest.cs | 18 +- .../Query/NorthwindDbFunctionsQueryFbTest.cs | 5 +- .../Query/NorthwindFunctionsQueryFbTest.cs | 12 +- .../Query/NorthwindGroupByQueryFbTest.cs | 2 +- .../Query/NorthwindIncludeQueryFbTest.cs | 9 +- .../Query/NorthwindJoinQueryFbTest.cs | 2 - .../NorthwindKeylessEntitiesQueryFbTest.cs | 7 +- .../NorthwindMiscellaneousQueryFbTest.cs | 2 - .../Query/NorthwindNavigationsQueryFbTest.cs | 8 +- .../Query/NorthwindQueryFbFixture.cs | 5 +- .../Query/NorthwindSelectQueryFbTest.cs | 7 + .../NorthwindSetOperationsQueryFbTest.cs | 16 +- .../Query/NorthwindWhereQueryFbTest.cs | 7 - .../Query/NullSemanticsQueryFbTest.cs | 15 ++ .../Query/OperatorsQueryFbTest.cs | 15 +- .../Query/OwnedQueryFbTest.cs | 4 - .../Query/PrimitiveCollectionsQueryFbTest.cs | 235 +++++++++++++++++- .../Query/SqlExecutorFbTest.cs | 5 +- .../Query/SqlQueryFbTest.cs | 7 + .../Query/TPCGearsOfWarQueryFbFixture.cs | 8 - .../Query/TPCGearsOfWarQueryFbTest.cs | 11 +- .../Query/TPTGearsOfWarQueryFbTest.cs | 11 +- .../Query/ToSqlQueryFbTest.cs | 6 +- .../Query/UdfDbFunctionFbTests.cs | 27 +- .../FbPrecompiledQueryTestHelpers.cs | 37 +++ .../TestUtilities/FbTestStore.cs | 54 ++-- .../UpdatesFbTest.cs | 4 +- ....EntityFrameworkCore.Firebird.Tests.csproj | 2 +- .../Internal/FbHistoryRepository.cs | 149 ++++++++++- .../Internal/FbMigrationDatabaseLock.cs | 39 +++ .../Internal/FbDateOnlyMethodTranslator.cs | 4 +- .../Internal/FbMathTranslator.cs | 31 +-- .../Internal/FbObjectToStringTranslator.cs | 49 +++- .../Internal/FbTimeOnlyMethodTranslator.cs | 54 ++++ .../Query/Internal/FbQuerySqlGenerator.cs | 10 +- .../FbSqlTranslatingExpressionVisitor.cs | 27 ++ .../Storage/Internal/FbDatabaseCreator.cs | 18 ++ .../Storage/Internal/FbDateTimeTypeMapping.cs | 4 +- .../Storage/Internal/FbTimeOnlyTypeMapping.cs | 2 +- .../Storage/Internal/FbTimeSpanTypeMapping.cs | 2 +- .../Internal/FbValueGeneratorSelector.cs | 32 ++- src/Perf/Perf.csproj | 2 +- src/Scratchpad/Scratchpad.csproj | 2 +- src/Versions.props | 6 +- tests.ps1 | 3 +- 67 files changed, 1322 insertions(+), 235 deletions(-) create mode 100644 src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/ComplianceFbTest.cs rename src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/{ManyToManyHeterogeneousQueryFbTest.cs => AdHocAdvancedMappingsQueryFbTest.cs} (91%) create mode 100644 src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/AdHocComplexTypeQueryFbTest.cs create mode 100644 src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/AdHocManyToManyQueryFbTest.cs rename src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/{SimpleQueryFbTest.cs => AdHocMiscellaneousQueryFbTest.cs} (83%) create mode 100644 src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/AdHocNavigationsQueryFbTest.cs create mode 100644 src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/AdHocQueryFiltersQueryFbTest.cs create mode 100644 src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/AdHocQuerySplittingQueryFbTest.cs create mode 100644 src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/TestUtilities/FbPrecompiledQueryTestHelpers.cs create mode 100644 src/FirebirdSql.EntityFrameworkCore.Firebird/Migrations/Internal/FbMigrationDatabaseLock.cs create mode 100644 src/FirebirdSql.EntityFrameworkCore.Firebird/Query/ExpressionTranslators/Internal/FbTimeOnlyMethodTranslator.cs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9213627ec..7b47e6567 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,10 +19,10 @@ jobs: - name: Checkout uses: actions/checkout@v4 - - name: .NET 8.0 + - name: .NET 9.0 uses: actions/setup-dotnet@v4 with: - dotnet-version: 8.0.x + dotnet-version: 9.0.x - name: Build run: | diff --git a/src/EntityFramework.Firebird.Tests/EntityFramework.Firebird.Tests.csproj b/src/EntityFramework.Firebird.Tests/EntityFramework.Firebird.Tests.csproj index 52fbd1394..c3eb7d657 100644 --- a/src/EntityFramework.Firebird.Tests/EntityFramework.Firebird.Tests.csproj +++ b/src/EntityFramework.Firebird.Tests/EntityFramework.Firebird.Tests.csproj @@ -1,6 +1,6 @@  - net8.0 + net9.0 false false true @@ -16,7 +16,7 @@ - + diff --git a/src/FirebirdSql.Data.FirebirdClient.Tests/FirebirdSql.Data.FirebirdClient.Tests.csproj b/src/FirebirdSql.Data.FirebirdClient.Tests/FirebirdSql.Data.FirebirdClient.Tests.csproj index 1e902480b..1fe8ead88 100644 --- a/src/FirebirdSql.Data.FirebirdClient.Tests/FirebirdSql.Data.FirebirdClient.Tests.csproj +++ b/src/FirebirdSql.Data.FirebirdClient.Tests/FirebirdSql.Data.FirebirdClient.Tests.csproj @@ -1,6 +1,6 @@  - net8.0 + net9.0 false false true diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/ComplianceFbTest.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/ComplianceFbTest.cs new file mode 100644 index 000000000..1f2493f63 --- /dev/null +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/ComplianceFbTest.cs @@ -0,0 +1,158 @@ +/* + * The contents of this file are subject to the Initial + * Developer's Public License Version 1.0 (the "License"); + * you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * https://github.com/FirebirdSQL/NETProvider/raw/master/license.txt. + * + * Software distributed under the License is distributed on + * an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either + * express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * All Rights Reserved. + */ + +//$Authors = Jiri Cincura (jiri@cincura.net) + +using System; +using System.Collections.Generic; +using System.Reflection; + +namespace FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests; + +public class ComplianceFbTest : Microsoft.EntityFrameworkCore.RelationalComplianceTestBase +{ + protected override ICollection IgnoredTestBases { get; } = + [ + typeof(Microsoft.EntityFrameworkCore.ApiConsistencyTestBase<>), + typeof(Microsoft.EntityFrameworkCore.BadDataJsonDeserializationTestBase), + typeof(Microsoft.EntityFrameworkCore.BuiltInDataTypesTestBase<>), + typeof(Microsoft.EntityFrameworkCore.ComplexTypesTrackingTestBase<>), + typeof(Microsoft.EntityFrameworkCore.CompositeKeyEndToEndTestBase<>), + typeof(Microsoft.EntityFrameworkCore.ConcurrencyDetectorDisabledTestBase<>), + typeof(Microsoft.EntityFrameworkCore.ConcurrencyDetectorEnabledTestBase<>), + typeof(Microsoft.EntityFrameworkCore.ConcurrencyDetectorTestBase<>), + typeof(Microsoft.EntityFrameworkCore.ConferencePlannerTestBase<>), + typeof(Microsoft.EntityFrameworkCore.ConvertToProviderTypesTestBase<>), + typeof(Microsoft.EntityFrameworkCore.CustomConvertersTestBase<>), + typeof(Microsoft.EntityFrameworkCore.DataAnnotationTestBase<>), + typeof(Microsoft.EntityFrameworkCore.DataBindingTestBase<>), + typeof(Microsoft.EntityFrameworkCore.EntityFrameworkServiceCollectionExtensionsTestBase), + typeof(Microsoft.EntityFrameworkCore.FieldMappingTestBase<>), + typeof(Microsoft.EntityFrameworkCore.FieldsOnlyLoadTestBase<>), + typeof(Microsoft.EntityFrameworkCore.FindTestBase<>), + typeof(Microsoft.EntityFrameworkCore.GraphUpdatesTestBase<>), + typeof(Microsoft.EntityFrameworkCore.ProxyGraphUpdatesTestBase<>), + typeof(Microsoft.EntityFrameworkCore.InterceptionTestBase), + typeof(Microsoft.EntityFrameworkCore.JsonTypesTestBase), + typeof(Microsoft.EntityFrameworkCore.KeysWithConvertersTestBase<>), + typeof(Microsoft.EntityFrameworkCore.LazyLoadProxyTestBase<>), + typeof(Microsoft.EntityFrameworkCore.LoadTestBase<>), + typeof(Microsoft.EntityFrameworkCore.LoggingTestBase), + typeof(Microsoft.EntityFrameworkCore.ManyToManyFieldsLoadTestBase<>), + typeof(Microsoft.EntityFrameworkCore.ManyToManyLoadTestBase<>), + typeof(Microsoft.EntityFrameworkCore.ManyToManyTrackingTestBase<>), + typeof(Microsoft.EntityFrameworkCore.MaterializationInterceptionTestBase<>), + typeof(Microsoft.EntityFrameworkCore.ModelBuilding101TestBase), + typeof(Microsoft.EntityFrameworkCore.MonsterFixupTestBase<>), + typeof(Microsoft.EntityFrameworkCore.MusicStoreTestBase<>), + typeof(Microsoft.EntityFrameworkCore.NotificationEntitiesTestBase<>), + typeof(Microsoft.EntityFrameworkCore.OptimisticConcurrencyTestBase<,>), + typeof(Microsoft.EntityFrameworkCore.OverzealousInitializationTestBase<>), + typeof(Microsoft.EntityFrameworkCore.PropertyValuesTestBase<>), + typeof(Microsoft.EntityFrameworkCore.QueryExpressionInterceptionTestBase), + typeof(Microsoft.EntityFrameworkCore.AdHocManyToManyQueryTestBase), + typeof(Microsoft.EntityFrameworkCore.SaveChangesInterceptionTestBase), + typeof(Microsoft.EntityFrameworkCore.SeedingTestBase), + typeof(Microsoft.EntityFrameworkCore.SerializationTestBase<>), + typeof(Microsoft.EntityFrameworkCore.SingletonInterceptorsTestBase<>), + typeof(Microsoft.EntityFrameworkCore.SpatialTestBase<>), + typeof(Microsoft.EntityFrameworkCore.StoreGeneratedFixupTestBase<>), + typeof(Microsoft.EntityFrameworkCore.StoreGeneratedTestBase<>), + typeof(Microsoft.EntityFrameworkCore.ValueConvertersEndToEndTestBase<>), + typeof(Microsoft.EntityFrameworkCore.WithConstructorsTestBase<>), + typeof(Microsoft.EntityFrameworkCore.CommandInterceptionTestBase), + typeof(Microsoft.EntityFrameworkCore.ConcurrencyDetectorDisabledRelationalTestBase<>), + typeof(Microsoft.EntityFrameworkCore.ConcurrencyDetectorEnabledRelationalTestBase<>), + typeof(Microsoft.EntityFrameworkCore.ConnectionInterceptionTestBase), + typeof(Microsoft.EntityFrameworkCore.DataAnnotationRelationalTestBase<>), + typeof(Microsoft.EntityFrameworkCore.DesignTimeTestBase<>), + typeof(Microsoft.EntityFrameworkCore.EntitySplittingTestBase), + typeof(Microsoft.EntityFrameworkCore.JsonTypesRelationalTestBase), + typeof(Microsoft.EntityFrameworkCore.LoggingRelationalTestBase<,>), + typeof(Microsoft.EntityFrameworkCore.ManyToManyTrackingRelationalTestBase<>), + typeof(Microsoft.EntityFrameworkCore.ModelBuilding101RelationalTestBase), + typeof(Microsoft.EntityFrameworkCore.OptimisticConcurrencyRelationalTestBase<,>), + typeof(Microsoft.EntityFrameworkCore.RelationalServiceCollectionExtensionsTestBase), + typeof(Microsoft.EntityFrameworkCore.StoreGeneratedFixupRelationalTestBase<>), + typeof(Microsoft.EntityFrameworkCore.TableSplittingTestBase), + typeof(Microsoft.EntityFrameworkCore.TPTTableSplittingTestBase), + typeof(Microsoft.EntityFrameworkCore.TransactionInterceptionTestBase), + typeof(Microsoft.EntityFrameworkCore.TransactionTestBase<>), + typeof(Microsoft.EntityFrameworkCore.TwoDatabasesTestBase), + + typeof(Microsoft.EntityFrameworkCore.ModelBuilding.ModelBuilderTest.ComplexTypeTestBase), + typeof(Microsoft.EntityFrameworkCore.ModelBuilding.ModelBuilderTest.ModelBuilderTestBase), + typeof(Microsoft.EntityFrameworkCore.ModelBuilding.ModelBuilderTest.InheritanceTestBase), + typeof(Microsoft.EntityFrameworkCore.ModelBuilding.ModelBuilderTest.ManyToManyTestBase), + typeof(Microsoft.EntityFrameworkCore.ModelBuilding.ModelBuilderTest.ManyToOneTestBase), + typeof(Microsoft.EntityFrameworkCore.ModelBuilding.ModelBuilderTest.NonRelationshipTestBase), + typeof(Microsoft.EntityFrameworkCore.ModelBuilding.ModelBuilderTest.OneToManyTestBase), + typeof(Microsoft.EntityFrameworkCore.ModelBuilding.ModelBuilderTest.OneToOneTestBase), + typeof(Microsoft.EntityFrameworkCore.ModelBuilding.ModelBuilderTest.OwnedTypesTestBase), + typeof(Microsoft.EntityFrameworkCore.ModelBuilding.RelationalModelBuilderTest.RelationalNonRelationshipTestBase), + typeof(Microsoft.EntityFrameworkCore.ModelBuilding.RelationalModelBuilderTest.RelationalComplexTypeTestBase), + typeof(Microsoft.EntityFrameworkCore.ModelBuilding.RelationalModelBuilderTest.RelationalInheritanceTestBase), + typeof(Microsoft.EntityFrameworkCore.ModelBuilding.RelationalModelBuilderTest.RelationalOneToManyTestBase), + typeof(Microsoft.EntityFrameworkCore.ModelBuilding.RelationalModelBuilderTest.RelationalManyToOneTestBase), + typeof(Microsoft.EntityFrameworkCore.ModelBuilding.RelationalModelBuilderTest.RelationalOneToOneTestBase), + typeof(Microsoft.EntityFrameworkCore.ModelBuilding.RelationalModelBuilderTest.RelationalManyToManyTestBase), + typeof(Microsoft.EntityFrameworkCore.ModelBuilding.RelationalModelBuilderTest.RelationalOwnedTypesTestBase), + + typeof(Microsoft.EntityFrameworkCore.BulkUpdates.BulkUpdatesTestBase<>), + typeof(Microsoft.EntityFrameworkCore.BulkUpdates.ComplexTypeBulkUpdatesTestBase<>), + typeof(Microsoft.EntityFrameworkCore.BulkUpdates.FiltersInheritanceBulkUpdatesTestBase<>), + typeof(Microsoft.EntityFrameworkCore.BulkUpdates.InheritanceBulkUpdatesTestBase<>), + typeof(Microsoft.EntityFrameworkCore.BulkUpdates.NonSharedModelBulkUpdatesTestBase), + typeof(Microsoft.EntityFrameworkCore.BulkUpdates.NorthwindBulkUpdatesTestBase<>), + typeof(Microsoft.EntityFrameworkCore.BulkUpdates.ComplexTypeBulkUpdatesRelationalTestBase<>), + typeof(Microsoft.EntityFrameworkCore.BulkUpdates.FiltersInheritanceBulkUpdatesRelationalTestBase<>), + typeof(Microsoft.EntityFrameworkCore.BulkUpdates.InheritanceBulkUpdatesRelationalTestBase<>), + typeof(Microsoft.EntityFrameworkCore.BulkUpdates.NonSharedModelBulkUpdatesRelationalTestBase), + typeof(Microsoft.EntityFrameworkCore.BulkUpdates.NorthwindBulkUpdatesRelationalTestBase<>), + typeof(Microsoft.EntityFrameworkCore.BulkUpdates.TPCFiltersInheritanceBulkUpdatesTestBase<>), + typeof(Microsoft.EntityFrameworkCore.BulkUpdates.TPCInheritanceBulkUpdatesTestBase<>), + typeof(Microsoft.EntityFrameworkCore.BulkUpdates.TPHInheritanceBulkUpdatesTestBase<>), + typeof(Microsoft.EntityFrameworkCore.BulkUpdates.TPTFiltersInheritanceBulkUpdatesTestBase<>), + typeof(Microsoft.EntityFrameworkCore.BulkUpdates.TPTInheritanceBulkUpdatesTestBase<>), + + typeof(Microsoft.EntityFrameworkCore.Update.JsonUpdateTestBase<>), + typeof(Microsoft.EntityFrameworkCore.Update.NonSharedModelUpdatesTestBase), + typeof(Microsoft.EntityFrameworkCore.Update.StoredProcedureUpdateTestBase), + typeof(Microsoft.EntityFrameworkCore.Update.StoreValueGenerationTestBase<>), + typeof(Microsoft.EntityFrameworkCore.Update.UpdateSqlGeneratorTestBase), + + typeof(Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase), + typeof(Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelRelationalTestBase), + + typeof(Microsoft.EntityFrameworkCore.Migrations.MigrationsInfrastructureTestBase<>), + typeof(Microsoft.EntityFrameworkCore.Migrations.MigrationsSqlGeneratorTestBase), + + // JSON not supported on FB + typeof(Microsoft.EntityFrameworkCore.Query.JsonQueryTestBase<>), + typeof(Microsoft.EntityFrameworkCore.Query.JsonQueryRelationalTestBase<>), + typeof(Microsoft.EntityFrameworkCore.Query.AdHocJsonQueryTestBase), + + // Spatial not supported on FB + typeof(Microsoft.EntityFrameworkCore.Query.SpatialQueryTestBase<>), + typeof(Microsoft.EntityFrameworkCore.Query.SpatialQueryRelationalTestBase<>), + + // Uses some JSON + typeof(Microsoft.EntityFrameworkCore.Query.AdHocPrecompiledQueryRelationalTestBase), + typeof(Microsoft.EntityFrameworkCore.Query.PrecompiledQueryRelationalTestBase), + typeof(Microsoft.EntityFrameworkCore.Query.PrecompiledSqlPregenerationQueryRelationalTestBase), + ]; + + protected override Assembly TargetAssembly { get; } = typeof(ComplianceFbTest).Assembly; +} diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.csproj b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.csproj index df649fe46..10f830844 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.csproj +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.csproj @@ -1,6 +1,6 @@  - net8.0 + net9.0 false false true @@ -13,8 +13,8 @@ - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/MigrationsFbTest.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/MigrationsFbTest.cs index dc0c08b49..0b2be24b1 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/MigrationsFbTest.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/MigrationsFbTest.cs @@ -356,6 +356,57 @@ public MigrationsFbTest(MigrationsFbFixture fixture) [Fact(Skip = SkipReason)] public override Task Add_required_primitve_collection_with_custom_default_value_sql_to_existing_table() => Task.CompletedTask; + [Fact(Skip = SkipReason)] + public override Task Add_required_primitive_collection_with_custom_default_value_sql_to_existing_table() => Task.CompletedTask; + + [Fact(Skip = SkipReason)] + public override Task Add_json_columns_to_existing_table() => base.Add_json_columns_to_existing_table(); + + [Fact(Skip = SkipReason)] + public override Task Add_required_primitive_collection_to_existing_table() => base.Add_required_primitive_collection_to_existing_table(); + + [Fact(Skip = SkipReason)] + public override Task Add_required_primitive_collection_with_custom_converter_and_custom_default_value_to_existing_table() => base.Add_required_primitive_collection_with_custom_converter_and_custom_default_value_to_existing_table(); + + [Fact(Skip = SkipReason)] + public override Task Add_required_primitive_collection_with_custom_converter_to_existing_table() => base.Add_required_primitive_collection_with_custom_converter_to_existing_table(); + + [Fact(Skip = SkipReason)] + public override Task Add_required_primitive_collection_with_custom_default_value_to_existing_table() => base.Add_required_primitive_collection_with_custom_default_value_to_existing_table(); + + [Fact(Skip = SkipReason)] + public override Task Add_required_primitve_collection_with_custom_converter_to_existing_table() => base.Add_required_primitve_collection_with_custom_converter_to_existing_table(); + + [Fact(Skip = SkipReason)] + public override Task Convert_json_entities_to_regular_owned() => base.Convert_json_entities_to_regular_owned(); + + [Fact(Skip = SkipReason)] + public override Task Convert_regular_owned_entities_to_json() => base.Convert_regular_owned_entities_to_json(); + + [Fact(Skip = SkipReason)] + public override Task Convert_string_column_to_a_json_column_containing_collection() => base.Convert_string_column_to_a_json_column_containing_collection(); + + [Fact(Skip = SkipReason)] + public override Task Convert_string_column_to_a_json_column_containing_reference() => base.Convert_string_column_to_a_json_column_containing_reference(); + + [Fact(Skip = SkipReason)] + public override Task Convert_string_column_to_a_json_column_containing_required_reference() => base.Convert_string_column_to_a_json_column_containing_required_reference(); + + [Fact(Skip = SkipReason)] + public override Task Create_table_with_json_column() => base.Create_table_with_json_column(); + + [Fact(Skip = SkipReason)] + public override Task Create_table_with_json_column_explicit_json_column_names() => base.Create_table_with_json_column_explicit_json_column_names(); + + [Fact(Skip = SkipReason)] + public override Task Drop_json_columns_from_existing_table() => base.Drop_json_columns_from_existing_table(); + + [Fact(Skip = SkipReason)] + public override Task Rename_json_column() => base.Rename_json_column(); + + [Fact(Skip = SkipReason)] + public override Task Rename_table_with_json_column() => base.Rename_table_with_json_column(); + public class MigrationsFbFixture : MigrationsFixtureBase { protected override string StoreName => nameof(MigrationsFbTest); diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/ManyToManyHeterogeneousQueryFbTest.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/AdHocAdvancedMappingsQueryFbTest.cs similarity index 91% rename from src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/ManyToManyHeterogeneousQueryFbTest.cs rename to src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/AdHocAdvancedMappingsQueryFbTest.cs index 910e239cf..f18e24d8a 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/ManyToManyHeterogeneousQueryFbTest.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/AdHocAdvancedMappingsQueryFbTest.cs @@ -21,7 +21,7 @@ namespace FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.Query; -public class ManyToManyHeterogeneousQueryFbTest : ManyToManyHeterogeneousQueryRelationalTestBase +public class AdHocAdvancedMappingsQueryFbTest : AdHocAdvancedMappingsQueryRelationalTestBase { protected override ITestStoreFactory TestStoreFactory => FbTestStoreFactory.Instance; } diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/AdHocComplexTypeQueryFbTest.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/AdHocComplexTypeQueryFbTest.cs new file mode 100644 index 000000000..e8a58d4a4 --- /dev/null +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/AdHocComplexTypeQueryFbTest.cs @@ -0,0 +1,27 @@ +/* + * The contents of this file are subject to the Initial + * Developer's Public License Version 1.0 (the "License"); + * you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * https://github.com/FirebirdSQL/NETProvider/raw/master/license.txt. + * + * Software distributed under the License is distributed on + * an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either + * express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * All Rights Reserved. + */ + +//$Authors = Jiri Cincura (jiri@cincura.net) + +using FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.TestUtilities; +using Microsoft.EntityFrameworkCore.Query; +using Microsoft.EntityFrameworkCore.TestUtilities; + +namespace FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.Query; + +public class AdHocComplexTypeQueryFbTest : AdHocComplexTypeQueryTestBase +{ + protected override ITestStoreFactory TestStoreFactory => FbTestStoreFactory.Instance; +} diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/AdHocManyToManyQueryFbTest.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/AdHocManyToManyQueryFbTest.cs new file mode 100644 index 000000000..d091978f5 --- /dev/null +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/AdHocManyToManyQueryFbTest.cs @@ -0,0 +1,27 @@ +/* + * The contents of this file are subject to the Initial + * Developer's Public License Version 1.0 (the "License"); + * you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * https://github.com/FirebirdSQL/NETProvider/raw/master/license.txt. + * + * Software distributed under the License is distributed on + * an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either + * express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * All Rights Reserved. + */ + +//$Authors = Jiri Cincura (jiri@cincura.net) + +using FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.TestUtilities; +using Microsoft.EntityFrameworkCore.Query; +using Microsoft.EntityFrameworkCore.TestUtilities; + +namespace FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.Query; + +public class AdHocManyToManyQueryFbTest : AdHocManyToManyQueryRelationalTestBase +{ + protected override ITestStoreFactory TestStoreFactory => FbTestStoreFactory.Instance; +} diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/SimpleQueryFbTest.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/AdHocMiscellaneousQueryFbTest.cs similarity index 83% rename from src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/SimpleQueryFbTest.cs rename to src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/AdHocMiscellaneousQueryFbTest.cs index 06c511f52..1acdeedb5 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/SimpleQueryFbTest.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/AdHocMiscellaneousQueryFbTest.cs @@ -26,7 +26,7 @@ namespace FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.Query; -public class SimpleQueryFbTest : SimpleQueryRelationalTestBase +public class AdHocMiscellaneousQueryFbTest : AdHocMiscellaneousQueryRelationalTestBase { protected override ITestStoreFactory TestStoreFactory => FbTestStoreFactory.Instance; @@ -44,13 +44,6 @@ public override Task Multiple_different_entity_type_from_different_namespaces(bo return base.Multiple_different_entity_type_from_different_namespaces(async); } - [HasDataInTheSameTransactionAsDDLTheory] - [MemberData(nameof(IsAsyncData))] - public override Task Multiple_nested_reference_navigations(bool async) - { - return base.Multiple_nested_reference_navigations(async); - } - [HasDataInTheSameTransactionAsDDLTheory] [MemberData(nameof(IsAsyncData))] public override Task Comparing_byte_column_to_enum_in_vb_creating_double_cast(bool async) @@ -78,4 +71,16 @@ public override Task Null_check_removal_in_ternary_maintain_appropriate_cast(boo { return base.Null_check_removal_in_ternary_maintain_appropriate_cast(async); } + + [NotSupportedOnFirebirdFact] + public override Task Operators_combine_nullability_of_entity_shapers() + { + return base.Operators_combine_nullability_of_entity_shapers(); + } + + protected override async Task Seed2951(Context2951 context) + { + await context.Database.ExecuteSqlRawAsync("""CREATE TABLE "ZeroKey" ("Id" INT)"""); + await context.Database.ExecuteSqlRawAsync("""INSERT INTO "ZeroKey" VALUES (NULL)"""); + } } diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/AdHocNavigationsQueryFbTest.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/AdHocNavigationsQueryFbTest.cs new file mode 100644 index 000000000..6ceedbf87 --- /dev/null +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/AdHocNavigationsQueryFbTest.cs @@ -0,0 +1,56 @@ +/* + * The contents of this file are subject to the Initial + * Developer's Public License Version 1.0 (the "License"); + * you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * https://github.com/FirebirdSQL/NETProvider/raw/master/license.txt. + * + * Software distributed under the License is distributed on + * an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either + * express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * All Rights Reserved. + */ + +//$Authors = Jiri Cincura (jiri@cincura.net) + +using System.Linq; +using System.Threading.Tasks; +using FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.Helpers; +using FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.TestUtilities; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Query; +using Microsoft.EntityFrameworkCore.TestUtilities; +using Xunit; + +namespace FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.Query; + +public class AdHocNavigationsQueryFbTest : AdHocNavigationsQueryRelationalTestBase +{ + protected override ITestStoreFactory TestStoreFactory => FbTestStoreFactory.Instance; + + [NotSupportedOnFirebirdFact] + public override Task Let_multiple_references_with_reference_to_outer() + { + return base.Let_multiple_references_with_reference_to_outer(); + } + + [NotSupportedOnFirebirdFact] + public override Task Projection_with_multiple_includes_and_subquery_with_set_operation() + { + return base.Projection_with_multiple_includes_and_subquery_with_set_operation(); + } + + [NotSupportedOnFirebirdFact] + public override Task SelectMany_and_collection_in_projection_in_FirstOrDefault() + { + return base.SelectMany_and_collection_in_projection_in_FirstOrDefault(); + } + + [NotSupportedOnFirebirdFact] + public override Task Correlated_collection_correctly_associates_entities_with_byte_array_keys() + { + return base.Correlated_collection_correctly_associates_entities_with_byte_array_keys(); + } +} diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/AdHocQueryFiltersQueryFbTest.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/AdHocQueryFiltersQueryFbTest.cs new file mode 100644 index 000000000..24a64585c --- /dev/null +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/AdHocQueryFiltersQueryFbTest.cs @@ -0,0 +1,35 @@ +/* + * The contents of this file are subject to the Initial + * Developer's Public License Version 1.0 (the "License"); + * you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * https://github.com/FirebirdSQL/NETProvider/raw/master/license.txt. + * + * Software distributed under the License is distributed on + * an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either + * express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * All Rights Reserved. + */ + +//$Authors = Jiri Cincura (jiri@cincura.net) + +using System.Threading.Tasks; +using FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.TestUtilities; +using Microsoft.EntityFrameworkCore.Query; +using Microsoft.EntityFrameworkCore.TestUtilities; +using Xunit; + +namespace FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.Query; + +public class AdHocQueryFiltersQueryFbTest : AdHocQueryFiltersQueryRelationalTestBase +{ + protected override ITestStoreFactory TestStoreFactory => FbTestStoreFactory.Instance; + + [Fact(Skip = "PK name collision and not easy way to override model.")] + public override Task Self_reference_in_query_filter_works() + { + return base.Self_reference_in_query_filter_works(); + } +} diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/AdHocQuerySplittingQueryFbTest.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/AdHocQuerySplittingQueryFbTest.cs new file mode 100644 index 000000000..c08ae53aa --- /dev/null +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/AdHocQuerySplittingQueryFbTest.cs @@ -0,0 +1,72 @@ +/* + * The contents of this file are subject to the Initial + * Developer's Public License Version 1.0 (the "License"); + * you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * https://github.com/FirebirdSQL/NETProvider/raw/master/license.txt. + * + * Software distributed under the License is distributed on + * an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either + * express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * All Rights Reserved. + */ + +//$Authors = Jiri Cincura (jiri@cincura.net) + +using System.Reflection; +using System.Threading.Tasks; +using FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.TestUtilities; +using FirebirdSql.EntityFrameworkCore.Firebird.Infrastructure; +using FirebirdSql.EntityFrameworkCore.Firebird.Infrastructure.Internal; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Query; +using Microsoft.EntityFrameworkCore.TestUtilities; +using Xunit; + +namespace FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.Query; + +public class AdHocQuerySplittingQueryFbTest : AdHocQuerySplittingQueryTestBase +{ + protected override ITestStoreFactory TestStoreFactory => FbTestStoreFactory.Instance; + + static readonly FieldInfo _querySplittingBehaviorFieldInfo = typeof(RelationalOptionsExtension).GetField("_querySplittingBehavior", BindingFlags.NonPublic | BindingFlags.Instance); + + protected override DbContextOptionsBuilder SetQuerySplittingBehavior(DbContextOptionsBuilder optionsBuilder, QuerySplittingBehavior splittingBehavior) + { + new FbDbContextOptionsBuilder(optionsBuilder).UseQuerySplittingBehavior(splittingBehavior); + return optionsBuilder; + } + + protected override DbContextOptionsBuilder ClearQuerySplittingBehavior(DbContextOptionsBuilder optionsBuilder) + { +#pragma warning disable EF1001 + var extension = optionsBuilder.Options.FindExtension(); + if (extension == null) + { + extension = new FbOptionsExtension(); + } + else + { + _querySplittingBehaviorFieldInfo.SetValue(extension, null); + } + ((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(extension); + return optionsBuilder; +#pragma warning restore EF1001 + } + + [Fact(Skip = "Not supported because of current test initialization setup.")] + public override Task Can_query_with_nav_collection_in_projection_with_split_query_in_parallel_async() + { + return base.Can_query_with_nav_collection_in_projection_with_split_query_in_parallel_async(); + } + + [Fact(Skip = "Not supported because of current test initialization setup.")] + public override Task Can_query_with_nav_collection_in_projection_with_split_query_in_parallel_sync() + { + return base.Can_query_with_nav_collection_in_projection_with_split_query_in_parallel_sync(); + } +} + diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/ComplexNavigationsQueryFbTest.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/ComplexNavigationsQueryFbTest.cs index 5b0edb499..8f4b3ed9d 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/ComplexNavigationsQueryFbTest.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/ComplexNavigationsQueryFbTest.cs @@ -18,13 +18,12 @@ using System; using System.Threading.Tasks; using FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.Helpers; -using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Query; using Xunit; namespace FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.Query; -public class ComplexNavigationsQueryFbTest : ComplexNavigationsQueryTestBase +public class ComplexNavigationsQueryFbTest : ComplexNavigationsQueryRelationalTestBase { public ComplexNavigationsQueryFbTest(ComplexNavigationsQueryFbFixture fixture) : base(fixture) @@ -772,6 +771,27 @@ public override Task Nested_SelectMany_correlated_with_join_table_correctly_tran return base.Nested_SelectMany_correlated_with_join_table_correctly_translated_to_apply(async); } + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Correlated_projection_with_first(bool async) + { + return base.Correlated_projection_with_first(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Multiple_select_many_in_projection(bool async) + { + return base.Multiple_select_many_in_projection(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Single_select_many_in_projection_with_take(bool async) + { + return base.Single_select_many_in_projection_with_take(async); + } + [Theory] [MemberData(nameof(IsAsyncData))] public override Task GroupJoin_client_method_in_OrderBy(bool async) diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/ComplexNavigationsSharedTypeQueryFbTest.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/ComplexNavigationsSharedTypeQueryFbTest.cs index 2d69e9631..d7dabbcca 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/ComplexNavigationsSharedTypeQueryFbTest.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/ComplexNavigationsSharedTypeQueryFbTest.cs @@ -79,6 +79,27 @@ public override Task Prune_does_not_throw_null_ref(bool async) return base.Prune_does_not_throw_null_ref(async); } + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Correlated_projection_with_first(bool async) + { + return base.Correlated_projection_with_first(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Multiple_select_many_in_projection(bool async) + { + return base.Multiple_select_many_in_projection(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Single_select_many_in_projection_with_take(bool async) + { + return base.Single_select_many_in_projection_with_take(async); + } + [Theory] [MemberData(nameof(IsAsyncData))] public override Task Project_shadow_properties10(bool async) diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/CompositeKeysQueryFbTest.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/CompositeKeysQueryFbTest.cs index c4b8eed66..1caa4123c 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/CompositeKeysQueryFbTest.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/CompositeKeysQueryFbTest.cs @@ -24,7 +24,4 @@ public class CompositeKeysQueryFbTest : CompositeKeysQueryRelationalTestBase false; - } diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/CompositeKeysSplitQueryFbTest.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/CompositeKeysSplitQueryFbTest.cs index 82d9dfbd6..725f0826d 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/CompositeKeysSplitQueryFbTest.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/CompositeKeysSplitQueryFbTest.cs @@ -24,6 +24,4 @@ public class CompositeKeysSplitQueryFbTest : CompositeKeysSplitQueryRelationalTe public CompositeKeysSplitQueryFbTest(CompositeKeysQueryFbFixture fixture) : base(fixture) { } - - protected override bool CanExecuteQueryString => false; } diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/Ef6GroupByFbTest.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/Ef6GroupByFbTest.cs index 8735d6788..d0e8b5b9e 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/Ef6GroupByFbTest.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/Ef6GroupByFbTest.cs @@ -45,10 +45,12 @@ public override Task Average_Grouped_from_LINQ_101(bool async) return base.Average_Grouped_from_LINQ_101(async); } - public class Ef6GroupByFbFixture : Ef6GroupByFixtureBase + public class Ef6GroupByFbFixture : Ef6GroupByFixtureBase, ITestSqlLoggerFactory { protected override ITestStoreFactory TestStoreFactory => FbTestStoreFactory.Instance; + public TestSqlLoggerFactory TestSqlLoggerFactory => (TestSqlLoggerFactory)ListLoggerFactory; + protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext context) { base.OnModelCreating(modelBuilder, context); diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/FromSqlQueryFbTest.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/FromSqlQueryFbTest.cs index 3c1770985..0644961ef 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/FromSqlQueryFbTest.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/FromSqlQueryFbTest.cs @@ -157,6 +157,13 @@ public override Task Multiple_occurrences_of_FromSql_with_db_parameter_adds_para return base.Multiple_occurrences_of_FromSql_with_db_parameter_adds_parameter_only_once(async); } + [Theory(Skip = "Firebird matches the casing exactly. Frankly the test is weird.")] + [MemberData(nameof(IsAsyncData))] + public override Task FromSqlRaw_queryable_simple_different_cased_columns_and_not_enough_columns_throws(bool async) + { + return base.FromSqlRaw_queryable_simple_different_cased_columns_and_not_enough_columns_throws(async); + } + protected override DbParameter CreateDbParameter(string name, object value) => new FbParameter { ParameterName = name, Value = value }; } diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/FunkyDataQueryFbTest.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/FunkyDataQueryFbTest.cs index da2911974..1a778cf07 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/FunkyDataQueryFbTest.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/FunkyDataQueryFbTest.cs @@ -15,7 +15,6 @@ //$Authors = Jiri Cincura (jiri@cincura.net) -using System.Linq; using System.Threading.Tasks; using FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.Helpers; using FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.TestUtilities; @@ -39,10 +38,12 @@ public override Task String_contains_on_argument_with_wildcard_column(bool async return base.String_contains_on_argument_with_wildcard_column(async); } - public class FunkyDataQueryFbFixture : FunkyDataQueryFixtureBase + public class FunkyDataQueryFbFixture : FunkyDataQueryFixtureBase, ITestSqlLoggerFactory { protected override ITestStoreFactory TestStoreFactory => FbTestStoreFactory.Instance; + public TestSqlLoggerFactory TestSqlLoggerFactory => (TestSqlLoggerFactory)ListLoggerFactory; + protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext context) { base.OnModelCreating(modelBuilder, context); diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/GearsOfWarQueryFbTest.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/GearsOfWarQueryFbTest.cs index 3ae01245b..f6d64548d 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/GearsOfWarQueryFbTest.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/GearsOfWarQueryFbTest.cs @@ -411,6 +411,13 @@ public override Task DateTimeOffset_to_unix_time_seconds(bool async) return base.DateTimeOffset_to_unix_time_seconds(async); } + [NotSupportedByProviderTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Non_string_concat_uses_appropriate_type_mapping(bool async) + { + return base.Non_string_concat_uses_appropriate_type_mapping(async); + } + [Theory(Skip = "NETProvider#1008")] [MemberData(nameof(IsAsyncData))] public override Task Where_TimeOnly_IsBetween(bool async) diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NonSharedPrimitiveCollectionsQueryFbTest.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NonSharedPrimitiveCollectionsQueryFbTest.cs index 42e0b1e56..b197da91b 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NonSharedPrimitiveCollectionsQueryFbTest.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NonSharedPrimitiveCollectionsQueryFbTest.cs @@ -18,6 +18,8 @@ using System.Threading.Tasks; using FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.Helpers; using FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.TestUtilities; +using FirebirdSql.EntityFrameworkCore.Firebird.Infrastructure; +using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Query; using Microsoft.EntityFrameworkCore.TestUtilities; @@ -25,6 +27,18 @@ namespace FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.Query; public class NonSharedPrimitiveCollectionsQueryFbTest : NonSharedPrimitiveCollectionsQueryRelationalTestBase { + protected override DbContextOptionsBuilder SetTranslateParameterizedCollectionsToConstants(DbContextOptionsBuilder optionsBuilder) + { + new FbDbContextOptionsBuilder(optionsBuilder).TranslateParameterizedCollectionsToConstants(); + return optionsBuilder; + } + + protected override DbContextOptionsBuilder SetTranslateParameterizedCollectionsToParameters(DbContextOptionsBuilder optionsBuilder) + { + new FbDbContextOptionsBuilder(optionsBuilder).TranslateParameterizedCollectionsToParameters(); + return optionsBuilder; + } + [NotSupportedOnFirebirdFact] public override Task Array_of_string() { @@ -145,12 +159,6 @@ public override Task Array_of_enum() return base.Array_of_enum(); } - [NotSupportedOnFirebirdFact] - public override Task Array_of_array_is_not_supported() - { - return base.Array_of_array_is_not_supported(); - } - [NotSupportedOnFirebirdFact] public override Task Multidimensional_array_is_not_supported() { @@ -187,5 +195,29 @@ public override Task Column_collection_inside_json_owned_entity() return base.Column_collection_inside_json_owned_entity(); } + [NotSupportedOnFirebirdFact] + public override Task Parameter_collection_Count_with_column_predicate_with_default_constants() + { + return base.Parameter_collection_Count_with_column_predicate_with_default_constants(); + } + + [NotSupportedOnFirebirdFact] + public override Task Parameter_collection_Count_with_column_predicate_with_default_constants_EF_Parameter() + { + return base.Parameter_collection_Count_with_column_predicate_with_default_constants_EF_Parameter(); + } + + [NotSupportedOnFirebirdFact] + public override Task Parameter_collection_Count_with_column_predicate_with_default_parameters() + { + return base.Parameter_collection_Count_with_column_predicate_with_default_parameters(); + } + + [NotSupportedOnFirebirdFact] + public override Task Parameter_collection_Count_with_column_predicate_with_default_parameters_EF_Constant() + { + return base.Parameter_collection_Count_with_column_predicate_with_default_parameters_EF_Constant(); + } + protected override ITestStoreFactory TestStoreFactory => FbTestStoreFactory.Instance; } diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindAggregateOperatorsQueryFbTest.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindAggregateOperatorsQueryFbTest.cs index 778d544bf..8cd9f61a0 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindAggregateOperatorsQueryFbTest.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindAggregateOperatorsQueryFbTest.cs @@ -30,8 +30,6 @@ public NorthwindAggregateOperatorsQueryFbTest(NorthwindQueryFbFixture false; - [NotSupportedOnFirebirdTheory] [MemberData(nameof(IsAsyncData))] public override Task Multiple_collection_navigation_with_FirstOrDefault_chained(bool async) @@ -73,29 +71,29 @@ public override Task Contains_with_local_tuple_array_closure(bool async) [Theory(Skip = "Different math on Firebird.")] [MemberData(nameof(IsAsyncData))] - public override Task Average_over_max_subquery_is_client_eval(bool async) + public override Task Sum_with_division_on_decimal(bool async) { - return base.Average_over_max_subquery_is_client_eval(async); + return base.Sum_with_division_on_decimal(async); } [Theory(Skip = "Different math on Firebird.")] [MemberData(nameof(IsAsyncData))] - public override Task Average_over_nested_subquery_is_client_eval(bool async) + public override Task Contains_inside_Average_without_GroupBy(bool async) { - return base.Average_over_nested_subquery_is_client_eval(async); + return base.Contains_inside_Average_without_GroupBy(async); } [Theory(Skip = "Different math on Firebird.")] [MemberData(nameof(IsAsyncData))] - public override Task Sum_with_division_on_decimal(bool async) + public override Task Average_over_max_subquery(bool async) { - return base.Sum_with_division_on_decimal(async); + return base.Average_over_max_subquery(async); } [Theory(Skip = "Different math on Firebird.")] [MemberData(nameof(IsAsyncData))] - public override Task Contains_inside_Average_without_GroupBy(bool async) + public override Task Average_over_nested_subquery(bool async) { - return base.Contains_inside_Average_without_GroupBy(async); + return base.Average_over_nested_subquery(async); } } diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindDbFunctionsQueryFbTest.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindDbFunctionsQueryFbTest.cs index 3ff08a17d..edc655c36 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindDbFunctionsQueryFbTest.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindDbFunctionsQueryFbTest.cs @@ -22,12 +22,15 @@ namespace FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.Query; -public class NorthwindDbFunctionsQueryFbTest : NorthwindDbFunctionsQueryTestBase> +public class NorthwindDbFunctionsQueryFbTest : NorthwindDbFunctionsQueryRelationalTestBase> { public NorthwindDbFunctionsQueryFbTest(NorthwindQueryFbFixture fixture) : base(fixture) { } + protected override string CaseInsensitiveCollation => "UNICODE_CI"; + protected override string CaseSensitiveCollation => "UNICODE"; + public override Task Like_literal(bool async) { // fix wrong assumptions on collate diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindFunctionsQueryFbTest.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindFunctionsQueryFbTest.cs index 13eb38b40..eb9cdec0b 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindFunctionsQueryFbTest.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindFunctionsQueryFbTest.cs @@ -15,9 +15,12 @@ //$Authors = Jiri Cincura (jiri@cincura.net) +using System; +using System.Linq; using System.Threading.Tasks; using FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.Helpers; using Microsoft.EntityFrameworkCore.Query; +using Microsoft.EntityFrameworkCore.TestModels.Northwind; using Microsoft.EntityFrameworkCore.TestUtilities; using Xunit; @@ -29,8 +32,6 @@ public NorthwindFunctionsQueryFbTest(NorthwindQueryFbFixture false; - [NotSupportedOnFirebirdTheory] [MemberData(nameof(IsAsyncData))] public override Task Convert_ToBoolean(bool async) @@ -136,6 +137,13 @@ public override Task Where_mathf_radians(bool async) return base.Where_mathf_radians(async); } + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task String_Join_non_aggregate(bool async) + { + return AssertTranslationFailed(() => base.String_Join_non_aggregate(async)); + } + [NotSupportedByProviderTheory] [MemberData(nameof(IsAsyncData))] public override Task Regex_IsMatch_MethodCall(bool async) diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindGroupByQueryFbTest.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindGroupByQueryFbTest.cs index dbbdc0a75..9cbb7e6e1 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindGroupByQueryFbTest.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindGroupByQueryFbTest.cs @@ -25,7 +25,7 @@ namespace FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.Query; -public class NorthwindGroupByQueryFbTest : NorthwindGroupByQueryTestBase> +public class NorthwindGroupByQueryFbTest : NorthwindGroupByQueryRelationalTestBase> { public NorthwindGroupByQueryFbTest(NorthwindQueryFbFixture fixture) : base(fixture) diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindIncludeQueryFbTest.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindIncludeQueryFbTest.cs index 40c659ef4..87c8b0264 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindIncludeQueryFbTest.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindIncludeQueryFbTest.cs @@ -24,7 +24,7 @@ namespace FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.Query; -public class NorthwindIncludeQueryFbTest : NorthwindIncludeQueryTestBase> +public class NorthwindIncludeQueryFbTest : NorthwindIncludeQueryRelationalTestBase> { public NorthwindIncludeQueryFbTest(NorthwindQueryFbFixture fixture) : base(fixture) @@ -58,13 +58,6 @@ public override Task Include_collection_with_cross_apply_with_filter(bool async) return base.Include_collection_with_cross_apply_with_filter(async); } - [Theory] - [MemberData(nameof(IsAsyncData))] - public override Task Include_collection_with_last_no_orderby(bool async) - { - return Assert.ThrowsAsync(() => base.Include_collection_with_last_no_orderby(async)); - } - [Theory(Skip = "Different ordering on Firebird.")] [MemberData(nameof(IsAsyncData))] public override Task Include_collection_OrderBy_list_contains(bool async) diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindJoinQueryFbTest.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindJoinQueryFbTest.cs index f6fd3ffae..072b8caec 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindJoinQueryFbTest.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindJoinQueryFbTest.cs @@ -29,8 +29,6 @@ public NorthwindJoinQueryFbTest(NorthwindQueryFbFixture fix : base(fixture) { } - protected override bool CanExecuteQueryString => false; - [NotSupportedOnFirebirdTheory] [MemberData(nameof(IsAsyncData))] public override Task GroupJoin_as_final_operator(bool async) diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindKeylessEntitiesQueryFbTest.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindKeylessEntitiesQueryFbTest.cs index cae3409d5..cc5ce7978 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindKeylessEntitiesQueryFbTest.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindKeylessEntitiesQueryFbTest.cs @@ -30,8 +30,6 @@ public NorthwindKeylessEntitiesQueryFbTest(NorthwindQueryFbFixture false; - [DoesNotHaveTheDataTheory] [MemberData(nameof(IsAsyncData))] public override Task KeylessEntity_by_database_view(bool async) @@ -50,10 +48,7 @@ public override Task Entity_mapped_to_view_on_right_side_of_join(bool async) [MemberData(nameof(IsAsyncData))] public override async Task KeylessEntity_with_nav_defining_query(bool async) { - Assert.Equal( - "0", - (await Assert.ThrowsAsync( - () => base.KeylessEntity_with_nav_defining_query(async))).Actual); + await Assert.ThrowsAsync(() => base.KeylessEntity_with_nav_defining_query(async)); } [Theory] diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindMiscellaneousQueryFbTest.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindMiscellaneousQueryFbTest.cs index 9a48b8376..eae538742 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindMiscellaneousQueryFbTest.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindMiscellaneousQueryFbTest.cs @@ -31,8 +31,6 @@ public NorthwindMiscellaneousQueryFbTest(NorthwindQueryFbFixture false; - [Theory] [MemberData(nameof(IsAsyncData))] public override Task Select_DTO_constructor_distinct_with_collection_projection_translated_to_server_with_binding_after_client_eval(bool async) diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindNavigationsQueryFbTest.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindNavigationsQueryFbTest.cs index cda754b77..19dbf5243 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindNavigationsQueryFbTest.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindNavigationsQueryFbTest.cs @@ -15,20 +15,14 @@ //$Authors = Jiri Cincura (jiri@cincura.net) -using System.Threading.Tasks; using Microsoft.EntityFrameworkCore.Query; using Microsoft.EntityFrameworkCore.TestUtilities; namespace FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.Query; -public class NorthwindNavigationsQueryFbTest : NorthwindNavigationsQueryTestBase> +public class NorthwindNavigationsQueryFbTest : NorthwindNavigationsQueryRelationalTestBase> { public NorthwindNavigationsQueryFbTest(NorthwindQueryFbFixture fixture) : base(fixture) { } - - public override Task Where_subquery_on_navigation_client_eval(bool async) - { - return AssertTranslationFailed(() => base.Where_subquery_on_navigation_client_eval(async)); - } } diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindQueryFbFixture.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindQueryFbFixture.cs index d6c6e7212..2d2413997 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindQueryFbFixture.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindQueryFbFixture.cs @@ -16,19 +16,16 @@ //$Authors = Jiri Cincura (jiri@cincura.net) using System; -using FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.Helpers; using FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.TestModels.Northwind; using FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.TestUtilities; -using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Query; -using Microsoft.EntityFrameworkCore.TestModels.Northwind; using Microsoft.EntityFrameworkCore.TestUtilities; namespace FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.Query; public class NorthwindQueryFbFixture : NorthwindQueryRelationalFixture - where TModelCustomizer : IModelCustomizer, new() + where TModelCustomizer : ITestModelCustomizer, new() { protected override ITestStoreFactory TestStoreFactory => FbTestStoreFactory.Instance; protected override Type ContextType => typeof(NorthwindFbContext); diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindSelectQueryFbTest.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindSelectQueryFbTest.cs index ccfb89ed9..a3dcdf99e 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindSelectQueryFbTest.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindSelectQueryFbTest.cs @@ -206,6 +206,13 @@ public override Task Reverse_in_SelectMany_with_Take(bool async) return base.Reverse_in_SelectMany_with_Take(async); } + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Set_operation_in_pending_collection(bool async) + { + return base.Set_operation_in_pending_collection(async); + } + [Theory] [MemberData(nameof(IsAsyncData))] public override async Task Correlated_collection_after_distinct_with_complex_projection_not_containing_original_identifier(bool async) diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindSetOperationsQueryFbTest.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindSetOperationsQueryFbTest.cs index ecf161e9f..1c81f0cf2 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindSetOperationsQueryFbTest.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindSetOperationsQueryFbTest.cs @@ -30,8 +30,6 @@ public NorthwindSetOperationsQueryFbTest(NorthwindQueryFbFixture false; - [NotSupportedOnFirebirdTheory] [MemberData(nameof(IsAsyncData))] public override Task Union_Select_scalar(bool async) @@ -102,6 +100,20 @@ public override Task Union_Intersect(bool async) return base.Union_Intersect(async); } + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Except_on_distinct(bool async) + { + return base.Except_on_distinct(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Intersect_on_distinct(bool async) + { + return base.Intersect_on_distinct(async); + } + [Theory] [MemberData(nameof(IsAsyncData))] public override Task Client_eval_Union_FirstOrDefault(bool async) diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindWhereQueryFbTest.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindWhereQueryFbTest.cs index 9b30b4475..0632ea821 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindWhereQueryFbTest.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindWhereQueryFbTest.cs @@ -86,13 +86,6 @@ public override Task Where_datetimeoffset_utcnow(bool async) return base.Where_datetimeoffset_utcnow(async); } - [Theory] - [MemberData(nameof(IsAsyncData))] - public override Task Where_bitwise_xor(bool async) - { - return AssertTranslationFailed(() => base.Where_bitwise_xor(async)); - } - [Theory] [MemberData(nameof(IsAsyncData))] public override Task Where_compare_constructed_equal(bool async) diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NullSemanticsQueryFbTest.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NullSemanticsQueryFbTest.cs index 42ab65d89..b945434f2 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NullSemanticsQueryFbTest.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NullSemanticsQueryFbTest.cs @@ -20,6 +20,7 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Query; using Microsoft.EntityFrameworkCore.TestModels.NullSemanticsModel; +using Xunit; namespace FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.Query; @@ -40,4 +41,18 @@ protected override NullSemanticsContext CreateContext(bool useRelationalNulls = context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking; return context; } + + [Theory(Skip = "efcore#34906")] + [MemberData(nameof(IsAsyncData))] + public override Task CaseOpWhen_predicate(bool async) + { + return base.CaseOpWhen_predicate(async); + } + + [Theory(Skip = "efcore#34906")] + [MemberData(nameof(IsAsyncData))] + public override Task CaseOpWhen_projection(bool async) + { + return base.CaseOpWhen_projection(async); + } } diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/OperatorsQueryFbTest.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/OperatorsQueryFbTest.cs index 72a4473e5..626db284e 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/OperatorsQueryFbTest.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/OperatorsQueryFbTest.cs @@ -36,18 +36,7 @@ public override Task Concat_and_json_scalar(bool async) return base.Concat_and_json_scalar(async); } - protected override ContextFactory Initialize(Action onModelCreating = null, Action onConfiguring = null, Action addServices = null, Action seed = null, Func shouldLogCategory = null, Func createTestStore = null, bool usePooling = true) - { - return base.Initialize( - modelBuilder => - { - ModelHelpers.SetStringLengths(modelBuilder); - onModelCreating?.Invoke(modelBuilder); - }, - onConfiguring, addServices, seed, shouldLogCategory, createTestStore, usePooling); - } - - protected override Task> InitializeAsync(Action onModelCreating = null, Action onConfiguring = null, Action addServices = null, Action seed = null, Func shouldLogCategory = null, Func createTestStore = null, bool usePooling = true) + protected override Task> InitializeAsync(Action onModelCreating = null, Action onConfiguring = null, Func addServices = null, Action configureConventions = null, Func seed = null, Func shouldLogCategory = null, Func> createTestStore = null, bool usePooling = true, bool useServiceProvider = true) { return base.InitializeAsync( modelBuilder => @@ -55,7 +44,7 @@ protected override Task> InitializeAsync(Acti ModelHelpers.SetStringLengths(modelBuilder); onModelCreating?.Invoke(modelBuilder); }, - onConfiguring, addServices, seed, shouldLogCategory, createTestStore, usePooling); + onConfiguring, addServices, configureConventions, seed, shouldLogCategory, createTestStore, usePooling, useServiceProvider); } protected override ITestStoreFactory TestStoreFactory => FbTestStoreFactory.Instance; diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/OwnedQueryFbTest.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/OwnedQueryFbTest.cs index 834e3a234..8806524a3 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/OwnedQueryFbTest.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/OwnedQueryFbTest.cs @@ -270,10 +270,6 @@ public OwnedQueryFbTest(OwnedQueryFbFixture fixture) [MemberData(nameof(IsAsyncData))] public override Task Can_join_on_indexer_property_on_query(bool isAsync) => base.Can_join_on_indexer_property_on_query(isAsync); - [DoesNotHaveTheDataTheory] - [MemberData(nameof(IsAsyncData))] - public override Task Can_OrderBy_owened_indexer_properties_converted(bool isAsync) => base.Can_OrderBy_owened_indexer_properties_converted(isAsync); - [DoesNotHaveTheDataTheory] [MemberData(nameof(IsAsyncData))] public override Task Where_collection_navigation_ToList_Count_member(bool isAsync) => base.Where_collection_navigation_ToList_Count_member(isAsync); diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/PrimitiveCollectionsQueryFbTest.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/PrimitiveCollectionsQueryFbTest.cs index 8b800517d..5d098f6a9 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/PrimitiveCollectionsQueryFbTest.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/PrimitiveCollectionsQueryFbTest.cs @@ -196,6 +196,13 @@ public override Task Column_collection_Count_method(bool async) return base.Column_collection_Count_method(async); } + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Column_collection_Count_with_predicate(bool async) + { + return base.Column_collection_Count_with_predicate(async); + } + [NotSupportedOnFirebirdTheory] [MemberData(nameof(IsAsyncData))] public override Task Column_collection_Length(bool async) @@ -469,13 +476,239 @@ public override Task Nested_contains_with_arrays_and_no_inferred_type_mapping(bo return base.Nested_contains_with_arrays_and_no_inferred_type_mapping(async); } + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Column_collection_Contains_over_subquery(bool async) + { + return base.Column_collection_Contains_over_subquery(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Column_collection_First(bool async) + { + return base.Column_collection_First(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Column_collection_FirstOrDefault(bool async) + { + return base.Column_collection_FirstOrDefault(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Column_collection_SelectMany(bool async) + { + return base.Column_collection_SelectMany(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Column_collection_SelectMany_with_filter(bool async) + { + return base.Column_collection_SelectMany_with_filter(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Column_collection_SelectMany_with_Select_to_anonymous_type(bool async) + { + return base.Column_collection_SelectMany_with_Select_to_anonymous_type(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Column_collection_Single(bool async) + { + return base.Column_collection_Single(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Column_collection_SingleOrDefault(bool async) + { + return base.Column_collection_SingleOrDefault(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Column_collection_Where_Count(bool async) + { + return base.Column_collection_Where_Count(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Column_collection_Where_ElementAt(bool async) + { + return base.Column_collection_Where_ElementAt(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Column_collection_Where_Skip(bool async) + { + return base.Column_collection_Where_Skip(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Column_collection_Where_Skip_Take(bool async) + { + return base.Column_collection_Where_Skip_Take(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Column_collection_Where_Take(bool async) + { + return base.Column_collection_Where_Take(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Column_collection_Where_Union(bool async) + { + return base.Column_collection_Where_Union(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Inline_collection_Count_with_column_predicate_with_EF_Parameter(bool async) + { + return base.Inline_collection_Count_with_column_predicate_with_EF_Parameter(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Inline_collection_List_Max_with_three_values(bool async) + { + return base.Inline_collection_List_Max_with_three_values(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Inline_collection_List_Max_with_two_values(bool async) + { + return base.Inline_collection_List_Max_with_two_values(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Inline_collection_List_Min_with_two_values(bool async) + { + return base.Inline_collection_List_Min_with_two_values(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Inline_collection_List_value_index_Column(bool async) + { + return base.Inline_collection_List_value_index_Column(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Inline_collection_Max_with_three_values(bool async) + { + return base.Inline_collection_Max_with_three_values(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Inline_collection_Max_with_two_values(bool async) + { + return base.Inline_collection_Max_with_two_values(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Inline_collection_Min_with_three_values(bool async) + { + return base.Inline_collection_Min_with_three_values(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Inline_collection_Min_with_two_values(bool async) + { + return base.Inline_collection_Min_with_two_values(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Inline_collection_of_nullable_value_type_Max(bool async) + { + return base.Inline_collection_of_nullable_value_type_Max(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Inline_collection_of_nullable_value_type_Min(bool async) + { + return base.Inline_collection_of_nullable_value_type_Min(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Inline_collection_of_nullable_value_type_with_null_Max(bool async) + { + return base.Inline_collection_of_nullable_value_type_with_null_Max(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Inline_collection_of_nullable_value_type_with_null_Min(bool async) + { + return base.Inline_collection_of_nullable_value_type_with_null_Min(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Inline_collection_value_index_Column(bool async) + { + return base.Inline_collection_value_index_Column(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Inline_collection_with_single_parameter_element_Count(bool async) + { + return base.Inline_collection_with_single_parameter_element_Count(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Parameter_collection_Count_with_column_predicate_with_EF_Constant(bool async) + { + return base.Parameter_collection_Count_with_column_predicate_with_EF_Constant(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Parameter_collection_Where_with_EF_Constant_Where_Any(bool async) + { + return base.Parameter_collection_Where_with_EF_Constant_Where_Any(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Project_inline_collection_with_Union(bool async) + { + return base.Project_inline_collection_with_Union(async); + } + PrimitiveCollectionsContext CreateContext() { return Fixture.CreateContext(); } - public class PrimitiveCollectionsQueryFbFixture : PrimitiveCollectionsQueryFixtureBase + public class PrimitiveCollectionsQueryFbFixture : PrimitiveCollectionsQueryFixtureBase, ITestSqlLoggerFactory { protected override ITestStoreFactory TestStoreFactory => FbTestStoreFactory.Instance; + + public TestSqlLoggerFactory TestSqlLoggerFactory => (TestSqlLoggerFactory)ListLoggerFactory; } } diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/SqlExecutorFbTest.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/SqlExecutorFbTest.cs index d852e8c1b..53b19e377 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/SqlExecutorFbTest.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/SqlExecutorFbTest.cs @@ -21,14 +21,13 @@ using FirebirdSql.Data.FirebirdClient; using FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.Helpers; using Microsoft.EntityFrameworkCore.Query; -using Microsoft.EntityFrameworkCore.TestUtilities; using Xunit; namespace FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.Query; -public class SqlExecutorFbTest : SqlExecutorTestBase> +public class SqlExecutorFbTest : SqlExecutorTestBase> { - public SqlExecutorFbTest(NorthwindQueryFbFixture fixture) + public SqlExecutorFbTest(NorthwindQueryFbFixture fixture) : base(fixture) { } diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/SqlQueryFbTest.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/SqlQueryFbTest.cs index b5f827a2f..52d10ed26 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/SqlQueryFbTest.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/SqlQueryFbTest.cs @@ -143,6 +143,13 @@ public override Task SqlQuery_queryable_multiple_composed_with_parameters_and_cl return base.SqlQuery_queryable_multiple_composed_with_parameters_and_closure_parameters_interpolated(async); } + [Theory(Skip = "Firebird matches the casing exactly. Frankly the test is weird.")] + [MemberData(nameof(IsAsyncData))] + public override Task SqlQueryRaw_queryable_simple_different_cased_columns_and_not_enough_columns_throws(bool async) + { + return base.SqlQueryRaw_queryable_simple_different_cased_columns_and_not_enough_columns_throws(async); + } + protected override DbParameter CreateDbParameter(string name, object value) => new FbParameter { ParameterName = name, Value = value }; } diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/TPCGearsOfWarQueryFbFixture.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/TPCGearsOfWarQueryFbFixture.cs index fe4c60fbc..fea02aad8 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/TPCGearsOfWarQueryFbFixture.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/TPCGearsOfWarQueryFbFixture.cs @@ -34,13 +34,5 @@ protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext con ModelHelpers.SetStringLengths(modelBuilder); modelBuilder.Entity().Property(g => g.Location).HasColumnType("varchar(100)"); - - // No support yet for DateOnly/TimeOnly (#24507) - modelBuilder.Entity( - b => - { - b.Ignore(m => m.Date); - b.Ignore(m => m.Time); - }); } } diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/TPCGearsOfWarQueryFbTest.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/TPCGearsOfWarQueryFbTest.cs index ef788f503..dd1231de1 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/TPCGearsOfWarQueryFbTest.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/TPCGearsOfWarQueryFbTest.cs @@ -36,7 +36,7 @@ public override Task ToString_boolean_property_non_nullable(bool async) { return AssertQuery( async, - ss => ss.Set().Select(w => w.IsAutomatic.ToString()), elementAsserter: (lhs, rhs) => { Assert.True(lhs.Equals(rhs, System.StringComparison.OrdinalIgnoreCase)); }); + ss => ss.Set().Select(w => w.IsAutomatic.ToString())); } [Theory] @@ -45,7 +45,7 @@ public override Task ToString_boolean_property_nullable(bool async) { return AssertQuery( async, - ss => ss.Set().Select(lh => lh.Eradicated.ToString()), elementAsserter: (lhs, rhs) => { Assert.True(lhs.Equals(rhs, System.StringComparison.OrdinalIgnoreCase)); }); + ss => ss.Set().Select(lh => lh.Eradicated.ToString())); } [Theory(Skip = "Different implicit ordering on Firebird.")] @@ -384,6 +384,13 @@ public override Task Where_datetimeoffset_year_component(bool async) return base.Where_datetimeoffset_year_component(async); } + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Non_string_concat_uses_appropriate_type_mapping(bool async) + { + return base.Non_string_concat_uses_appropriate_type_mapping(async); + } + [NotSupportedByProviderTheory] [MemberData(nameof(IsAsyncData))] public override Task Where_TimeOnly_Add_TimeSpan(bool async) diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/TPTGearsOfWarQueryFbTest.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/TPTGearsOfWarQueryFbTest.cs index 62886174e..d0c129d2c 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/TPTGearsOfWarQueryFbTest.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/TPTGearsOfWarQueryFbTest.cs @@ -36,7 +36,7 @@ public override Task ToString_boolean_property_non_nullable(bool async) { return AssertQuery( async, - ss => ss.Set().Select(w => w.IsAutomatic.ToString()), elementAsserter: (lhs, rhs) => { Assert.True(lhs.Equals(rhs, System.StringComparison.OrdinalIgnoreCase)); }); + ss => ss.Set().Select(w => w.IsAutomatic.ToString())); } [Theory] @@ -45,7 +45,7 @@ public override Task ToString_boolean_property_nullable(bool async) { return AssertQuery( async, - ss => ss.Set().Select(lh => lh.Eradicated.ToString()), elementAsserter: (lhs, rhs) => { Assert.True(lhs.Equals(rhs, System.StringComparison.OrdinalIgnoreCase)); }); + ss => ss.Set().Select(lh => lh.Eradicated.ToString())); } [Theory(Skip = "Different implicit ordering on Firebird.")] @@ -349,6 +349,13 @@ public override Task Subquery_inside_Take_argument(bool async) return base.Subquery_inside_Take_argument(async); } + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Non_string_concat_uses_appropriate_type_mapping(bool async) + { + return base.Non_string_concat_uses_appropriate_type_mapping(async); + } + [NotSupportedByProviderTheory] [MemberData(nameof(IsAsyncData))] public override Task DateTimeOffset_to_unix_time_milliseconds(bool async) diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/ToSqlQueryFbTest.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/ToSqlQueryFbTest.cs index a11b0fde5..6867be489 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/ToSqlQueryFbTest.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/ToSqlQueryFbTest.cs @@ -32,16 +32,16 @@ public class ToSqlQueryFbTest : ToSqlQueryTestBase public override async Task Entity_type_with_navigation_mapped_to_SqlQuery(bool async) { var contextFactory = await InitializeAsync( - seed: c => + seed: async c => { var author = new Author { Name = "Toast", Posts = { new Post { Title = "Sausages of the world!" } } }; c.Add(author); - c.SaveChanges(); + await c.SaveChangesAsync(); var postStat = new PostStat { Count = 10, Author = author }; author.PostStat = postStat; c.Add(postStat); - c.SaveChanges(); + await c.SaveChangesAsync(); }); using var context = contextFactory.CreateContext(); diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/UdfDbFunctionFbTests.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/UdfDbFunctionFbTests.cs index fc05c2bf5..937a842d2 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/UdfDbFunctionFbTests.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/UdfDbFunctionFbTests.cs @@ -16,6 +16,7 @@ //$Authors = Jiri Cincura (jiri@cincura.net) using System; +using System.Threading.Tasks; using FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.Helpers; using FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.TestUtilities; using Microsoft.EntityFrameworkCore; @@ -222,11 +223,11 @@ public class Fb : UdfFixtureBase protected override ITestStoreFactory TestStoreFactory => FbTestStoreFactory.Instance; protected override Type ContextType { get; } = typeof(FbUDFSqlContext); - protected override void Seed(DbContext context) + protected override async Task SeedAsync(DbContext context) { - base.Seed(context); + await base.SeedAsync(context); - context.Database.ExecuteSqlRaw( + await context.Database.ExecuteSqlRawAsync( @"create function ""CustomerOrderCount"" (customerId int) returns int as @@ -234,7 +235,7 @@ returns int return (select count(""Id"") from ""Orders"" where ""CustomerId"" = :customerId); end"); - context.Database.ExecuteSqlRaw( + await context.Database.ExecuteSqlRawAsync( @"create function ""StarValue"" (starCount int, val varchar(1000)) returns varchar(1000) as @@ -242,7 +243,7 @@ returns varchar(1000) return rpad('', :starCount, '*') || :val; end"); - context.Database.ExecuteSqlRaw( + await context.Database.ExecuteSqlRawAsync( @"create function ""DollarValue"" (starCount int, val varchar(1000)) returns varchar(1000) as @@ -250,7 +251,7 @@ returns varchar(1000) return rpad('', :starCount, '$') || :val; end"); - context.Database.ExecuteSqlRaw( + await context.Database.ExecuteSqlRawAsync( @"create function ""GetReportingPeriodStartDate"" (period int) returns timestamp as @@ -258,7 +259,7 @@ returns timestamp return cast('1998-01-01' as timestamp); end"); - context.Database.ExecuteSqlRaw( + await context.Database.ExecuteSqlRawAsync( @"create function ""GetCustWithMostOrdersAfterDate"" (searchDate Date) returns int as @@ -270,7 +271,7 @@ group by ""CustomerId"" order by count(""Id"") desc); end"); - context.Database.ExecuteSqlRaw( + await context.Database.ExecuteSqlRawAsync( @"create function ""IsTopCustomer"" (customerId int) returns boolean as @@ -281,7 +282,7 @@ returns boolean return false; end"); - context.Database.ExecuteSqlRaw( + await context.Database.ExecuteSqlRawAsync( @"create function ""IdentityString"" (customerName varchar(1000)) returns varchar(1000) as @@ -289,7 +290,7 @@ returns varchar(1000) return :customerName; end"); - context.Database.ExecuteSqlRaw( + await context.Database.ExecuteSqlRawAsync( @"create function ""IsDate"" (val varchar(1000)) returns boolean as @@ -307,7 +308,7 @@ returns boolean return true; end"); - context.Database.ExecuteSqlRaw( + await context.Database.ExecuteSqlRawAsync( @"create procedure ""GetTopTwoSellingProducts"" returns ( @@ -326,7 +327,7 @@ order by ""TotalSold"" desc end end"); - context.Database.ExecuteSqlRaw( + await context.Database.ExecuteSqlRawAsync( @"create procedure ""GetOrdersWithMultipleProducts""(customerId int) returns ( @@ -348,7 +349,7 @@ having count(""ProductId"") > 1 end end"); - context.SaveChanges(); + await context.SaveChangesAsync(); } } } diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/TestUtilities/FbPrecompiledQueryTestHelpers.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/TestUtilities/FbPrecompiledQueryTestHelpers.cs new file mode 100644 index 000000000..023076cf2 --- /dev/null +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/TestUtilities/FbPrecompiledQueryTestHelpers.cs @@ -0,0 +1,37 @@ +/* + * The contents of this file are subject to the Initial + * Developer's Public License Version 1.0 (the "License"); + * you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * https://github.com/FirebirdSQL/NETProvider/raw/master/license.txt. + * + * Software distributed under the License is distributed on + * an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either + * express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * All Rights Reserved. + */ + +//$Authors = Jiri Cincura (jiri@cincura.net) + +using System.Collections.Generic; +using System.Reflection; +using FirebirdSql.EntityFrameworkCore.Firebird.Infrastructure.Internal; +using Microsoft.CodeAnalysis; +using Microsoft.EntityFrameworkCore.TestUtilities; + +namespace FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.TestUtilities; + +public class FbPrecompiledQueryTestHelpers : PrecompiledQueryTestHelpers +{ + public static readonly FbPrecompiledQueryTestHelpers Instance = new(); + + protected override IEnumerable BuildProviderMetadataReferences() + { +#pragma warning disable EF1001 + yield return MetadataReference.CreateFromFile(typeof(FbOptionsExtension).Assembly.Location); +#pragma warning restore EF1001 + yield return MetadataReference.CreateFromFile(Assembly.GetExecutingAssembly().Location); + } +} diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/TestUtilities/FbTestStore.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/TestUtilities/FbTestStore.cs index b11c93c56..144862c74 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/TestUtilities/FbTestStore.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/TestUtilities/FbTestStore.cs @@ -33,20 +33,8 @@ public static FbTestStore GetOrCreate(string name) => new FbTestStore(name, shared: true); public FbTestStore(string name, bool shared) - : base(name, shared) - { - var csb = new FbConnectionStringBuilder - { - Database = $"EFCore_{name}.fdb", - DataSource = "localhost", - UserID = "sysdba", - Password = "masterkey", - Pooling = false, - Charset = "utf8" - }; - ConnectionString = csb.ToString(); - Connection = new FbConnection(ConnectionString); - } + : base(name, shared, CreateConnection(name, shared)) + { } protected override string OpenDelimiter => "\""; protected override string CloseDelimiter => "\""; @@ -54,23 +42,28 @@ public FbTestStore(string name, bool shared) public Version ServerVersion { get; private set; } public bool ServerLessThan4() => ServerVersion < new Version(4, 0, 0, 0); - protected override void Initialize(Func createContext, Action seed, Action clean) + protected override async Task InitializeAsync(Func createContext, Func seed, Func clean) { - using (var context = createContext()) + // create database explicitly to specify Page Size and Forced Writes + await FbConnection.CreateDatabaseAsync(ConnectionString, pageSize: 16384, forcedWrites: false, overwrite: true); + await using (var context = createContext()) { - // create database explicitly to specify Page Size and Forced Writes - FbConnection.CreateDatabase(ConnectionString, pageSize: 16384, forcedWrites: false, overwrite: true); try { - context.Database.EnsureCreated(); + await context.Database.EnsureCreatedAsync(); } catch (FbException ex) when (ServerLessThan4() && ex.Message.EndsWith("Name longer than database column size", StringComparison.Ordinal)) { return; } - clean?.Invoke(context); - Clean(context); - seed?.Invoke(context); + if (clean != null) + { + await clean(context); + } + if (seed != null) + { + await seed(context); + } } } @@ -97,7 +90,7 @@ public override async Task OpenConnectionAsync() await base.OpenConnectionAsync(); if (FbServerProperties.ParseServerVersion(Connection.ServerVersion) >= new Version(4, 0, 0, 0)) { - using (var cmd = Connection.CreateCommand()) + await using (var cmd = Connection.CreateCommand()) { cmd.CommandText = "set bind of decfloat to legacy"; await cmd.ExecuteNonQueryAsync(); @@ -113,6 +106,17 @@ public override DbContextOptionsBuilder AddProviderOptions(DbContextOptionsBuild => builder.UseFirebird(Connection, x => x.UseQuerySplittingBehavior(QuerySplittingBehavior.SingleQuery)); - public override void Clean(DbContext context) - { } + static FbConnection CreateConnection(string name, bool shared) + { + var csb = new FbConnectionStringBuilder + { + Database = $"EFCore_{name}.fdb", + DataSource = "localhost", + UserID = "sysdba", + Password = "masterkey", + Pooling = false, + Charset = "utf8" + }; + return new FbConnection(csb.ToString()); + } } diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/UpdatesFbTest.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/UpdatesFbTest.cs index 3ede018ee..1b5909bcb 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/UpdatesFbTest.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/UpdatesFbTest.cs @@ -17,12 +17,14 @@ using System; using System.Linq; +using System.Threading.Tasks; using FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.Helpers; using FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.TestUtilities; using FirebirdSql.EntityFrameworkCore.Firebird.Metadata; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.TestModels.UpdatesModel; using Microsoft.EntityFrameworkCore.TestUtilities; +using Microsoft.EntityFrameworkCore.Update; using Xunit; namespace FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests; @@ -55,7 +57,7 @@ public override void Identifiers_are_generated_correctly() } [Fact(Skip = "Uses type of filtered index that is not supported on Firebird.")] - public override void Swap_filtered_unique_index_values() => base.Swap_filtered_unique_index_values(); + public override Task Swap_filtered_unique_index_values() => base.Swap_filtered_unique_index_values(); public class UpdatesFbFixture : UpdatesRelationalFixture { diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.Tests/FirebirdSql.EntityFrameworkCore.Firebird.Tests.csproj b/src/FirebirdSql.EntityFrameworkCore.Firebird.Tests/FirebirdSql.EntityFrameworkCore.Firebird.Tests.csproj index 851bf975e..f126570bf 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.Tests/FirebirdSql.EntityFrameworkCore.Firebird.Tests.csproj +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.Tests/FirebirdSql.EntityFrameworkCore.Firebird.Tests.csproj @@ -1,6 +1,6 @@  - net8.0 + net9.0 false false true diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird/Migrations/Internal/FbHistoryRepository.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird/Migrations/Internal/FbHistoryRepository.cs index fc675b8b4..2ccc66ee7 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird/Migrations/Internal/FbHistoryRepository.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird/Migrations/Internal/FbHistoryRepository.cs @@ -16,42 +16,167 @@ //$Authors = Jiri Cincura (jiri@cincura.net), Jean Ressouche, Rafael Almeida (ralms@ralms.net) using System; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage; namespace FirebirdSql.EntityFrameworkCore.Firebird.Migrations.Internal; -public class FbHistoryRepository : HistoryRepository +public class FbHistoryRepository(HistoryRepositoryDependencies dependencies) : HistoryRepository(dependencies) { - public FbHistoryRepository(HistoryRepositoryDependencies dependencies) - : base(dependencies) - { } + static readonly TimeSpan RetryDelay = TimeSpan.FromSeconds(1); protected override string ExistsSql { get { var escapedTableName = Dependencies.TypeMappingSource.GetMapping(typeof(string)).GenerateSqlLiteral(TableName); - return $@"SELECT COUNT(*) FROM rdb$relations WHERE COALESCE(rdb$system_flag, 0) = 0 AND rdb$view_blr IS NULL AND rdb$relation_name = {escapedTableName}"; + return $""" + SELECT COUNT(*) FROM rdb$relations WHERE COALESCE(rdb$system_flag, 0) = 0 AND rdb$view_blr IS NULL AND rdb$relation_name = {escapedTableName} + """; } } - protected override bool InterpretExistsResult(object value) => Convert.ToInt64(value) != 0; + protected override bool InterpretExistsResult(object value) + => Convert.ToInt64(value) != 0; - public override string GetCreateIfNotExistsScript() => GetCreateScript(); + public override string GetCreateIfNotExistsScript() + { + var script = GetCreateScript(); + return BuildIfTableNotExistsBlock(script).CommandText; + } - public override string GetBeginIfExistsScript(string migrationId) + protected virtual string LockTableName { get; } = "__EFMigrationsLock"; + + public override LockReleaseBehavior LockReleaseBehavior + => LockReleaseBehavior.Explicit; + + public override IMigrationsDatabaseLock AcquireDatabaseLock() { - throw new NotSupportedException("Generating idempotent scripts is currently not supported."); + Dependencies.MigrationsLogger.AcquiringMigrationLock(); + + CreateLockTableCommand().ExecuteNonQuery(CreateRelationalCommandParameters()); + + var retryDelay = RetryDelay; + while (true) + { + var dbLock = CreateMigrationDatabaseLock(); + var insertCount = CreateInsertLockCommand(DateTime.UtcNow) + .ExecuteScalar(CreateRelationalCommandParameters()); + if ((int)insertCount == 1) + { + return dbLock; + } + + Thread.Sleep(retryDelay); + if (retryDelay < TimeSpan.FromMinutes(1)) + { + retryDelay = retryDelay.Add(retryDelay); + } + } } - public override string GetBeginIfNotExistsScript(string migrationId) + public override async Task AcquireDatabaseLockAsync(CancellationToken cancellationToken = default) { - throw new NotSupportedException("Generating idempotent scripts is currently not supported."); + Dependencies.MigrationsLogger.AcquiringMigrationLock(); + + await CreateLockTableCommand().ExecuteNonQueryAsync(CreateRelationalCommandParameters(), cancellationToken).ConfigureAwait(false); + + var retryDelay = RetryDelay; + while (true) + { + var dbLock = CreateMigrationDatabaseLock(); + var insertCount = await CreateInsertLockCommand(DateTime.UtcNow) + .ExecuteScalarAsync(CreateRelationalCommandParameters(), cancellationToken) + .ConfigureAwait(false); + if ((int)insertCount == 1) + { + return dbLock; + } + + await Task.Delay(RetryDelay, cancellationToken).ConfigureAwait(true); + if (retryDelay < TimeSpan.FromMinutes(1)) + { + retryDelay = retryDelay.Add(retryDelay); + } + } } + public override string GetBeginIfExistsScript(string migrationId) + => throw new NotSupportedException("Generating idempotent scripts is currently not supported."); + + public override string GetBeginIfNotExistsScript(string migrationId) + => throw new NotSupportedException("Generating idempotent scripts is currently not supported."); + public override string GetEndIfScript() + => throw new NotSupportedException("Generating idempotent scripts is currently not supported."); + + IRelationalCommand CreateLockTableCommand() + { + return BuildIfTableNotExistsBlock($""" + CREATE TABLE "{LockTableName}" ( + "Id" INT NOT NULL CONSTRAINT "PK_{LockTableName}" PRIMARY KEY, + "Timestamp" TIMESTAMP NOT NULL + ) + """); + } + + IRelationalCommand CreateInsertLockCommand(DateTime timestamp) + { + var timestampLiteral = Dependencies.TypeMappingSource.GetMapping(typeof(DateTime)).GenerateSqlLiteral(timestamp); + return Dependencies.RawSqlCommandBuilder.Build($""" + EXECUTE BLOCK + RETURNS (ROWS_AFFECTED INT) + AS + BEGIN + ROWS_AFFECTED = 1; + BEGIN + INSERT INTO "{LockTableName}" ("Id", "Timestamp") VALUES (1, {timestampLiteral}); + WHEN SQLSTATE '23000' DO + BEGIN + ROWS_AFFECTED = 0; + END + END + SUSPEND; + END + """); + } + + IRelationalCommand CreateDeleteLockCommand() + { + return Dependencies.RawSqlCommandBuilder.Build($""" + DELETE FROM "{LockTableName}" WHERE "Id" = 1 + """); + } + + FbMigrationDatabaseLock CreateMigrationDatabaseLock() + => new(CreateDeleteLockCommand(), CreateRelationalCommandParameters(), this); + + RelationalCommandParameterObject CreateRelationalCommandParameters() + => new( + Dependencies.Connection, + null, + null, + Dependencies.CurrentContext.Context, + Dependencies.CommandLogger, CommandSource.Migrations); + + IRelationalCommand BuildIfTableNotExistsBlock(string statement) { - throw new NotSupportedException("Generating idempotent scripts is currently not supported."); + var statementLiteral = Dependencies.TypeMappingSource.GetMapping(typeof(string)).GenerateSqlLiteral(statement); + return Dependencies.RawSqlCommandBuilder.Build($""" + EXECUTE BLOCK + AS + BEGIN + BEGIN + EXECUTE STATEMENT + {statementLiteral}; + WHEN SQLSTATE '42S01' DO + BEGIN + END + END + END + """); } } diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird/Migrations/Internal/FbMigrationDatabaseLock.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird/Migrations/Internal/FbMigrationDatabaseLock.cs new file mode 100644 index 000000000..cb85c830c --- /dev/null +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird/Migrations/Internal/FbMigrationDatabaseLock.cs @@ -0,0 +1,39 @@ +/* + * The contents of this file are subject to the Initial + * Developer's Public License Version 1.0 (the "License"); + * you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * https://github.com/FirebirdSQL/NETProvider/raw/master/license.txt. + * + * Software distributed under the License is distributed on + * an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either + * express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * All Rights Reserved. + */ + +//$Authors = Jiri Cincura (jiri@cincura.net) + +using System.Threading; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage; + +namespace FirebirdSql.EntityFrameworkCore.Firebird.Migrations.Internal; + +public class FbMigrationDatabaseLock( + IRelationalCommand releaseLockCommand, + RelationalCommandParameterObject relationalCommandParameters, + IHistoryRepository historyRepository, + CancellationToken cancellationToken = default) + : IMigrationsDatabaseLock +{ + public virtual IHistoryRepository HistoryRepository => historyRepository; + + public void Dispose() + => releaseLockCommand.ExecuteScalar(relationalCommandParameters); + + public async ValueTask DisposeAsync() + => await releaseLockCommand.ExecuteScalarAsync(relationalCommandParameters, cancellationToken).ConfigureAwait(false); +} diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird/Query/ExpressionTranslators/Internal/FbDateOnlyMethodTranslator.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird/Query/ExpressionTranslators/Internal/FbDateOnlyMethodTranslator.cs index 05dd34f40..8557a6f21 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird/Query/ExpressionTranslators/Internal/FbDateOnlyMethodTranslator.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird/Query/ExpressionTranslators/Internal/FbDateOnlyMethodTranslator.cs @@ -25,7 +25,7 @@ namespace FirebirdSql.EntityFrameworkCore.Firebird.Query.ExpressionTranslators.Internal; -public class SqlServerDateOnlyMethodTranslator : IMethodCallTranslator +public class FbDateOnlyMethodTranslator : IMethodCallTranslator { readonly Dictionary _methodInfoDatePartMapping = new() { @@ -36,7 +36,7 @@ public class SqlServerDateOnlyMethodTranslator : IMethodCallTranslator readonly ISqlExpressionFactory _sqlExpressionFactory; - public SqlServerDateOnlyMethodTranslator(ISqlExpressionFactory sqlExpressionFactory) + public FbDateOnlyMethodTranslator(ISqlExpressionFactory sqlExpressionFactory) { _sqlExpressionFactory = sqlExpressionFactory; } diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird/Query/ExpressionTranslators/Internal/FbMathTranslator.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird/Query/ExpressionTranslators/Internal/FbMathTranslator.cs index 263248f50..63b8ff9b6 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird/Query/ExpressionTranslators/Internal/FbMathTranslator.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird/Query/ExpressionTranslators/Internal/FbMathTranslator.cs @@ -52,7 +52,6 @@ public class FbMathTranslator : IMethodCallTranslator { typeof(Math).GetRuntimeMethod(nameof(Math.Log10), new[] { typeof(double) }), "LOG10" }, { typeof(Math).GetRuntimeMethod(nameof(Math.Log), new[] { typeof(double) }), "LN" }, - { typeof(Math).GetRuntimeMethod(nameof(Math.Log), new[] { typeof(double), typeof(double) }), "LOG" }, { typeof(Math).GetRuntimeMethod(nameof(Math.Sqrt), new[] { typeof(double) }), "SQRT" }, @@ -77,30 +76,6 @@ public class FbMathTranslator : IMethodCallTranslator { typeof(Math).GetRuntimeMethod(nameof(Math.Sign), new[] { typeof(double) }), "SIGN" }, { typeof(Math).GetRuntimeMethod(nameof(Math.Sign), new[] { typeof(decimal) }), "SIGN" }, { typeof(Math).GetRuntimeMethod(nameof(Math.Sign), new[] { typeof(short) }), "SIGN" }, - - { typeof(Math).GetRuntimeMethod(nameof(Math.Max), new[] { typeof(float), typeof(float) }), "MAXVALUE" }, - { typeof(Math).GetRuntimeMethod(nameof(Math.Max), new[] { typeof(sbyte), typeof(sbyte) }), "MAXVALUE" }, - { typeof(Math).GetRuntimeMethod(nameof(Math.Max), new[] { typeof(ulong), typeof(ulong) }), "MAXVALUE" }, - { typeof(Math).GetRuntimeMethod(nameof(Math.Max), new[] { typeof(uint), typeof(uint) }), "MAXVALUE" }, - { typeof(Math).GetRuntimeMethod(nameof(Math.Max), new[] { typeof(long), typeof(long) }), "MAXVALUE" }, - { typeof(Math).GetRuntimeMethod(nameof(Math.Max), new[] { typeof(ushort), typeof(ushort) }), "MAXVALUE" }, - { typeof(Math).GetRuntimeMethod(nameof(Math.Max), new[] { typeof(short), typeof(short) }), "MAXVALUE" }, - { typeof(Math).GetRuntimeMethod(nameof(Math.Max), new[] { typeof(double), typeof(double) }), "MAXVALUE" }, - { typeof(Math).GetRuntimeMethod(nameof(Math.Max), new[] { typeof(decimal), typeof(decimal) }), "MAXVALUE" }, - { typeof(Math).GetRuntimeMethod(nameof(Math.Max), new[] { typeof(byte), typeof(byte) }), "MAXVALUE" }, - { typeof(Math).GetRuntimeMethod(nameof(Math.Max), new[] { typeof(int), typeof(int) }), "MAXVALUE" }, - - { typeof(Math).GetRuntimeMethod(nameof(Math.Min), new[] { typeof(float), typeof(float) }), "MINVALUE" }, - { typeof(Math).GetRuntimeMethod(nameof(Math.Min), new[] { typeof(sbyte), typeof(sbyte) }), "MINVALUE" }, - { typeof(Math).GetRuntimeMethod(nameof(Math.Min), new[] { typeof(ulong), typeof(ulong) }), "MINVALUE" }, - { typeof(Math).GetRuntimeMethod(nameof(Math.Min), new[] { typeof(uint), typeof(uint) }), "MINVALUE" }, - { typeof(Math).GetRuntimeMethod(nameof(Math.Min), new[] { typeof(long), typeof(long) }), "MINVALUE" }, - { typeof(Math).GetRuntimeMethod(nameof(Math.Min), new[] { typeof(ushort), typeof(ushort) }), "MINVALUE" }, - { typeof(Math).GetRuntimeMethod(nameof(Math.Min), new[] { typeof(short), typeof(short) }), "MINVALUE" }, - { typeof(Math).GetRuntimeMethod(nameof(Math.Min), new[] { typeof(double), typeof(double) }), "MINVALUE" }, - { typeof(Math).GetRuntimeMethod(nameof(Math.Min), new[] { typeof(decimal), typeof(decimal) }), "MINVALUE" }, - { typeof(Math).GetRuntimeMethod(nameof(Math.Min), new[] { typeof(byte), typeof(byte) }), "MINVALUE" }, - { typeof(Math).GetRuntimeMethod(nameof(Math.Min), new[] { typeof(int), typeof(int) }), "MINVALUE" }, }; static readonly HashSet TruncateMethodInfos = new HashSet @@ -117,6 +92,8 @@ public class FbMathTranslator : IMethodCallTranslator typeof(Math).GetRuntimeMethod(nameof(Math.Round), new[] { typeof(double), typeof(int) }) }; + static readonly MethodInfo LogNewBaseMethod = typeof(Math).GetRuntimeMethod(nameof(Math.Log), new[] { typeof(double), typeof(double) }); + readonly FbSqlExpressionFactory _fbSqlExpressionFactory; public FbMathTranslator(FbSqlExpressionFactory fbSqlExpressionFactory) @@ -154,6 +131,10 @@ public SqlExpression Translate(SqlExpression instance, MethodInfo method, IReadO nullability, method.ReturnType)); } + if (LogNewBaseMethod == method) + { + return _fbSqlExpressionFactory.Function("LOG", arguments.Reverse(), true, arguments.Select(_ => true), method.ReturnType); + } return null; } } diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird/Query/ExpressionTranslators/Internal/FbObjectToStringTranslator.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird/Query/ExpressionTranslators/Internal/FbObjectToStringTranslator.cs index 835f923fd..0c7e2b24e 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird/Query/ExpressionTranslators/Internal/FbObjectToStringTranslator.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird/Query/ExpressionTranslators/Internal/FbObjectToStringTranslator.cs @@ -33,7 +33,6 @@ public class FbObjectToStringTranslator : IMethodCallTranslator typeof(int), typeof(long), typeof(DateTime), - typeof(bool), typeof(byte), typeof(byte[]), typeof(double), @@ -59,18 +58,54 @@ public FbObjectToStringTranslator(FbSqlExpressionFactory fbSqlExpressionFactory) public SqlExpression Translate(SqlExpression instance, MethodInfo method, IReadOnlyList arguments, IDiagnosticsLogger logger) { - if (method.Name == nameof(ToString) && method.GetParameters().Length == 0) + if (instance == null || method.Name != nameof(ToString) || arguments.Count != 0) { - var type = instance.Type.UnwrapNullableType(); - if (SupportedTypes.Contains(type)) + return null; + } + + if (instance.TypeMapping?.ClrType == typeof(string)) + { + return instance; + } + + if (SupportedTypes.Contains(instance.Type)) + { + return _fbSqlExpressionFactory.Convert(instance, typeof(string)); + } + else if (instance.Type == typeof(Guid)) + { + return _fbSqlExpressionFactory.Function("UUID_TO_CHAR", new[] { instance }, true, new[] { true }, typeof(string)); + } + else if (instance.Type == typeof(bool)) + { + if (instance is not ColumnExpression { IsNullable: false }) { - return _fbSqlExpressionFactory.Convert(instance, typeof(string)); + return _fbSqlExpressionFactory.Case( + instance, + new[] + { + new CaseWhenClause( + _fbSqlExpressionFactory.Constant(false), + _fbSqlExpressionFactory.Constant(false.ToString())), + new CaseWhenClause( + _fbSqlExpressionFactory.Constant(true), + _fbSqlExpressionFactory.Constant(true.ToString())) + }, + _fbSqlExpressionFactory.Constant(string.Empty)); } - else if (type == typeof(Guid)) + else { - return _fbSqlExpressionFactory.Function("UUID_TO_CHAR", new[] { instance }, true, new[] { true }, typeof(string)); + return _fbSqlExpressionFactory.Case( + new[] + { + new CaseWhenClause( + instance, + _fbSqlExpressionFactory.Constant(true.ToString())) + }, + _fbSqlExpressionFactory.Constant(false.ToString())); } } + return null; } } diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird/Query/ExpressionTranslators/Internal/FbTimeOnlyMethodTranslator.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird/Query/ExpressionTranslators/Internal/FbTimeOnlyMethodTranslator.cs new file mode 100644 index 000000000..16946d9e3 --- /dev/null +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird/Query/ExpressionTranslators/Internal/FbTimeOnlyMethodTranslator.cs @@ -0,0 +1,54 @@ +/* + * The contents of this file are subject to the Initial + * Developer's Public License Version 1.0 (the "License"); + * you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * https://github.com/FirebirdSQL/NETProvider/raw/master/license.txt. + * + * Software distributed under the License is distributed on + * an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either + * express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * All Rights Reserved. + */ + +//$Authors = Jiri Cincura (jiri@cincura.net) + +using System; +using System.Collections.Generic; +using System.Reflection; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Diagnostics; +using Microsoft.EntityFrameworkCore.Query; +using Microsoft.EntityFrameworkCore.Query.SqlExpressions; + +namespace FirebirdSql.EntityFrameworkCore.Firebird.Query.ExpressionTranslators.Internal; + +public class FbTimeOnlyMethodTranslator : IMethodCallTranslator +{ + static readonly MethodInfo FromDateTime = typeof(TimeOnly).GetRuntimeMethod(nameof(TimeOnly.FromDateTime), [typeof(DateTime)]); + static readonly MethodInfo FromTimeSpan = typeof(TimeOnly).GetRuntimeMethod(nameof(TimeOnly.FromTimeSpan), [typeof(TimeSpan)]); + + readonly ISqlExpressionFactory _sqlExpressionFactory; + + public FbTimeOnlyMethodTranslator(ISqlExpressionFactory sqlExpressionFactory) + { + _sqlExpressionFactory = sqlExpressionFactory; + } + + public virtual SqlExpression Translate(SqlExpression instance, MethodInfo method, IReadOnlyList arguments, IDiagnosticsLogger logger) + { + if (method.DeclaringType != typeof(TimeOnly)) + { + return null; + } + + if ((method == FromDateTime || method == FromTimeSpan) && instance is null && arguments.Count == 1) + { + return _sqlExpressionFactory.Convert(arguments[0], typeof(TimeOnly)); + } + + return null; + } +} diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird/Query/Internal/FbQuerySqlGenerator.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird/Query/Internal/FbQuerySqlGenerator.cs index 64a79623f..17fb2ff67 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird/Query/Internal/FbQuerySqlGenerator.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird/Query/Internal/FbQuerySqlGenerator.cs @@ -201,11 +201,7 @@ protected override Expression VisitSqlConstant(SqlConstantExpression sqlConstant protected override void GenerateEmptyProjection(SelectExpression selectExpression) { - base.GenerateEmptyProjection(selectExpression); - if (selectExpression.Alias != null) - { - Sql.Append(" AS empty"); - } + Sql.Append("1 AS dummy"); } protected override void GenerateTop(SelectExpression selectExpression) @@ -312,7 +308,7 @@ protected override Expression VisitOrdering(OrderingExpression orderingExpressio protected override Expression VisitTableValuedFunction(TableValuedFunctionExpression tableValuedFunctionExpression) { - Sql.Append(Dependencies.SqlGenerationHelper.DelimitIdentifier(tableValuedFunctionExpression.StoreFunction.Name)); + Sql.Append(Dependencies.SqlGenerationHelper.DelimitIdentifier(tableValuedFunctionExpression.Name)); if (tableValuedFunctionExpression.Arguments.Any()) { Sql.Append("("); @@ -333,7 +329,7 @@ protected override Expression VisitExtension(Expression extensionExpression) }; } - public virtual Expression VisitSpacedFunction(FbSpacedFunctionExpression spacedFunctionExpression) + protected virtual Expression VisitSpacedFunction(FbSpacedFunctionExpression spacedFunctionExpression) { Sql.Append(spacedFunctionExpression.Name); Sql.Append("("); diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird/Query/Internal/FbSqlTranslatingExpressionVisitor.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird/Query/Internal/FbSqlTranslatingExpressionVisitor.cs index e8a0754bb..b1f81d540 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird/Query/Internal/FbSqlTranslatingExpressionVisitor.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird/Query/Internal/FbSqlTranslatingExpressionVisitor.cs @@ -15,6 +15,9 @@ //$Authors = Jiri Cincura (jiri@cincura.net) +using System; +using System.Collections.Generic; +using System.Linq; using System.Linq.Expressions; using Microsoft.EntityFrameworkCore.Query; using Microsoft.EntityFrameworkCore.Query.SqlExpressions; @@ -39,4 +42,28 @@ protected override Expression VisitUnary(UnaryExpression unaryExpression) } return base.VisitUnary(unaryExpression); } + + public override SqlExpression GenerateGreatest(IReadOnlyList expressions, Type resultType) + { + var resultTypeMapping = ExpressionExtensions.InferTypeMapping(expressions); + return Dependencies.SqlExpressionFactory.Function( + "MAXVALUE", + expressions, + nullable: true, + Enumerable.Repeat(true, expressions.Count), + resultType, + resultTypeMapping); + } + + public override SqlExpression GenerateLeast(IReadOnlyList expressions, Type resultType) + { + var resultTypeMapping = ExpressionExtensions.InferTypeMapping(expressions); + return Dependencies.SqlExpressionFactory.Function( + "MINVALUE", + expressions, + nullable: true, + Enumerable.Repeat(true, expressions.Count), + resultType, + resultTypeMapping); + } } diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird/Storage/Internal/FbDatabaseCreator.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird/Storage/Internal/FbDatabaseCreator.cs index 5c233f90d..c44bf21f9 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird/Storage/Internal/FbDatabaseCreator.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird/Storage/Internal/FbDatabaseCreator.cs @@ -22,6 +22,7 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage; namespace FirebirdSql.EntityFrameworkCore.Firebird.Storage.Internal; @@ -163,4 +164,21 @@ IRelationalCommand CreateAlterCollationCommand(string collation) BEGIN execute statement 'alter character set ' || (select coalesce(trim(rdb$character_set_name), 'NONE') from rdb$database) || ' set default collation {collation}'; END"); + + public override void CreateTables() + { + // we need to execute commands separately to avoid issues with inserts and transactions after creating a table + foreach (var command in GetCreateTablesCommands()) + { + Dependencies.MigrationCommandExecutor.ExecuteNonQuery([command], Dependencies.Connection, new MigrationExecutionState(), commitTransaction: true); + } + } + public override async Task CreateTablesAsync(CancellationToken cancellationToken = default) + { + // we need to execute commands separately to avoid issues with inserts and transactions after creating a table + foreach (var command in GetCreateTablesCommands()) + { + await Dependencies.MigrationCommandExecutor.ExecuteNonQueryAsync([command], Dependencies.Connection, new MigrationExecutionState(), commitTransaction: true, cancellationToken: cancellationToken); + } + } } diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird/Storage/Internal/FbDateTimeTypeMapping.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird/Storage/Internal/FbDateTimeTypeMapping.cs index 86dad167b..b9dc140d9 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird/Storage/Internal/FbDateTimeTypeMapping.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird/Storage/Internal/FbDateTimeTypeMapping.cs @@ -48,11 +48,11 @@ protected override string GenerateNonNullSqlLiteral(object value) switch (_fbDbType) { case FbDbType.TimeStamp: - return $"CAST('{value:yyyy-MM-dd HH:mm:ss.ffff}' AS TIMESTAMP)"; + return $"CAST('{value:yyyy-MM-dd HH\\:mm\\:ss.ffff}' AS TIMESTAMP)"; case FbDbType.Date: return $"CAST('{value:yyyy-MM-dd}' AS DATE)"; case FbDbType.Time: - return $"CAST('{value:HH:mm:ss.ffff}' AS TIME)"; + return $"CAST('{value:HH\\:mm\\:ss.ffff}' AS TIME)"; default: throw new ArgumentOutOfRangeException(nameof(_fbDbType), $"{nameof(_fbDbType)}={_fbDbType}"); } diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird/Storage/Internal/FbTimeOnlyTypeMapping.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird/Storage/Internal/FbTimeOnlyTypeMapping.cs index ee72312ac..d9d4138a0 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird/Storage/Internal/FbTimeOnlyTypeMapping.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird/Storage/Internal/FbTimeOnlyTypeMapping.cs @@ -31,7 +31,7 @@ protected FbTimeOnlyTypeMapping(RelationalTypeMappingParameters parameters) protected override string GenerateNonNullSqlLiteral(object value) { - return $"CAST('{value:HH:mm:ss.ffff}' AS TIME)"; + return $"CAST('{value:HH\\:mm\\:ss.ffff}' AS TIME)"; } protected override RelationalTypeMapping Clone(RelationalTypeMappingParameters parameters) diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird/Storage/Internal/FbTimeSpanTypeMapping.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird/Storage/Internal/FbTimeSpanTypeMapping.cs index 35c4a459d..0dac60aff 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird/Storage/Internal/FbTimeSpanTypeMapping.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird/Storage/Internal/FbTimeSpanTypeMapping.cs @@ -48,7 +48,7 @@ protected override string GenerateNonNullSqlLiteral(object value) switch (_fbDbType) { case FbDbType.Time: - return $"CAST('{value:hh\\:mm\\:ss\\.ffff}' AS TIME)"; + return $"CAST('{value:hh\\:mm\\:ss.ffff}' AS TIME)"; default: throw new ArgumentOutOfRangeException(nameof(_fbDbType), $"{nameof(_fbDbType)}={_fbDbType}"); } diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird/ValueGeneration/Internal/FbValueGeneratorSelector.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird/ValueGeneration/Internal/FbValueGeneratorSelector.cs index dd01a34dc..4e01ee43b 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird/ValueGeneration/Internal/FbValueGeneratorSelector.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird/ValueGeneration/Internal/FbValueGeneratorSelector.cs @@ -44,17 +44,30 @@ public FbValueGeneratorSelector(ValueGeneratorSelectorDependencies dependencies, public new virtual IFbValueGeneratorCache Cache => (IFbValueGeneratorCache)base.Cache; + [Obsolete("Use TrySelect and throw if needed when the generator is not found.")] public override ValueGenerator Select(IProperty property, ITypeBase entityType) + { + if (TrySelect(property, entityType, out var generator)) + { + return generator; + } + + throw new ArgumentException( + CoreStrings.InvalidValueGeneratorFactoryProperty( + nameof(FbSequenceValueGeneratorFactory), property.Name, property.DeclaringType.DisplayName())); + } + + public override bool TrySelect(IProperty property, ITypeBase entityType, out ValueGenerator valueGenerator) { if (property.GetValueGeneratorFactory() != null || property.GetValueGenerationStrategy() != FbValueGenerationStrategy.HiLo) { - return base.Select(property, entityType); + return base.TrySelect(property, entityType, out valueGenerator); } var propertyType = property.ClrType.UnwrapNullableType().UnwrapEnumType(); - var generator = _sequenceFactory.TryCreate( + valueGenerator = _sequenceFactory.TryCreate( property, propertyType, Cache.GetOrAddSequenceState(property, _connection), @@ -62,16 +75,16 @@ public override ValueGenerator Select(IProperty property, ITypeBase entityType) _rawSqlCommandBuilder, _commandLogger); - if (generator != null) + if (valueGenerator != null) { - return generator; + return true; } var converter = property.GetTypeMapping().Converter; if (converter != null && converter.ProviderClrType != propertyType) { - generator = _sequenceFactory.TryCreate( + valueGenerator = _sequenceFactory.TryCreate( property, converter.ProviderClrType, Cache.GetOrAddSequenceState(property, _connection), @@ -79,15 +92,14 @@ public override ValueGenerator Select(IProperty property, ITypeBase entityType) _rawSqlCommandBuilder, _commandLogger); - if (generator != null) + if (valueGenerator != null) { - return generator.WithConverter(converter); + valueGenerator = valueGenerator.WithConverter(converter); + return true; } } - throw new ArgumentException( - CoreStrings.InvalidValueGeneratorFactoryProperty( - nameof(FbSequenceValueGeneratorFactory), property.Name, property.DeclaringType.DisplayName())); + return false; } protected override ValueGenerator FindForType(IProperty property, ITypeBase entityType, Type clrType) diff --git a/src/Perf/Perf.csproj b/src/Perf/Perf.csproj index 3896df311..f47a017c6 100644 --- a/src/Perf/Perf.csproj +++ b/src/Perf/Perf.csproj @@ -1,7 +1,7 @@  Exe - net8.0 + net9.0 true diff --git a/src/Scratchpad/Scratchpad.csproj b/src/Scratchpad/Scratchpad.csproj index 08b17c2d5..e6caecba1 100644 --- a/src/Scratchpad/Scratchpad.csproj +++ b/src/Scratchpad/Scratchpad.csproj @@ -1,7 +1,7 @@  Exe - net8.0 + net9.0 true true ..\FirebirdSql.Data.TestsBase\FirebirdSql.Data.TestsBase.snk diff --git a/src/Versions.props b/src/Versions.props index 1c0346839..613410130 100644 --- a/src/Versions.props +++ b/src/Versions.props @@ -5,9 +5,9 @@ - 11.0.0 - 10.1.0 - 8.0.4 + 12.0.0 + 10.3.2 + 9.0.1 diff --git a/tests.ps1 b/tests.ps1 index b293410ca..49940f135 100644 --- a/tests.ps1 +++ b/tests.ps1 @@ -6,7 +6,6 @@ param( $ErrorActionPreference = 'Stop' $ProgressPreference = 'SilentlyContinue' # Faster downloads with Invoke-RestMethod -- https://stackoverflow.com/a/43477248/33244 - $baseDir = Split-Path -Parent $PSCommandPath . "$baseDir\include.ps1" @@ -29,7 +28,7 @@ $FirebirdConfiguration = @{ } } -$frameworkVersion = 'net8.0' +$frameworkVersion = 'net9.0' $testsBaseDir = "$baseDir\src\FirebirdSql.Data.FirebirdClient.Tests" $testsProviderDir = "$testsBaseDir\bin\$Configuration\$frameworkVersion" From 4230c1e2985ad91442145f743f0c9033cfdfbe5e Mon Sep 17 00:00:00 2001 From: Jiri Cincura Date: Thu, 6 Feb 2025 10:18:56 +0100 Subject: [PATCH 03/32] Fix new test --- .../Query/PrimitiveCollectionsQueryFbTest.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/PrimitiveCollectionsQueryFbTest.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/PrimitiveCollectionsQueryFbTest.cs index 5d098f6a9..2ba0a856e 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/PrimitiveCollectionsQueryFbTest.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/PrimitiveCollectionsQueryFbTest.cs @@ -700,6 +700,13 @@ public override Task Project_inline_collection_with_Union(bool async) return base.Project_inline_collection_with_Union(async); } + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Parameter_collection_ImmutableArray_of_ints_Contains_int(bool async) + { + return base.Parameter_collection_ImmutableArray_of_ints_Contains_int(async); + } + PrimitiveCollectionsContext CreateContext() { return Fixture.CreateContext(); From 2bcd1dcdd06826cb8ce7f38e6505f70dd9a065e2 Mon Sep 17 00:00:00 2001 From: Jiri Cincura Date: Thu, 3 Apr 2025 15:00:36 +0200 Subject: [PATCH 04/32] Fix names. --- .../FbCommandTests.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/FirebirdSql.Data.FirebirdClient.Tests/FbCommandTests.cs b/src/FirebirdSql.Data.FirebirdClient.Tests/FbCommandTests.cs index 639c746ea..876a2d9ad 100644 --- a/src/FirebirdSql.Data.FirebirdClient.Tests/FbCommandTests.cs +++ b/src/FirebirdSql.Data.FirebirdClient.Tests/FbCommandTests.cs @@ -647,7 +647,7 @@ public async Task GetCommandExplainedPlanNoPlanTest() } [Test] - public async Task ReadsTimeWithProperPrecision() + public async Task ReadsTimeWithProperPrecisionTest() { await using (var cmd = Connection.CreateCommand()) { @@ -658,7 +658,7 @@ public async Task ReadsTimeWithProperPrecision() } [Test] - public async Task PassesTimeSpanWithProperPrecision() + public async Task PassesTimeSpanWithProperPrecisionTest() { var ts = TimeSpan.FromTicks(14321000); await using (var cmd = Connection.CreateCommand()) @@ -671,7 +671,7 @@ public async Task PassesTimeSpanWithProperPrecision() } [Test] - public async Task ReadsDateTimeWithProperPrecision() + public async Task ReadsDateTimeWithProperPrecisionTest() { await using (var cmd = Connection.CreateCommand()) { @@ -682,7 +682,7 @@ public async Task ReadsDateTimeWithProperPrecision() } [Test] - public async Task PassesDateTimeWithProperPrecision() + public async Task PassesDateTimeWithProperPrecisionTest() { var dt = new DateTime(635583639614321000); await using (var cmd = Connection.CreateCommand()) @@ -695,7 +695,7 @@ public async Task PassesDateTimeWithProperPrecision() } [Test] - public async Task ExecuteNonQueryReturnsMinusOneOnNonInsertUpdateDelete() + public async Task ExecuteNonQueryReturnsMinusOneOnNonInsertUpdateDeleteTest() { await using (var cmd = Connection.CreateCommand()) { From f7a721a339a5b893cdec44cbc3284c118a9df6a1 Mon Sep 17 00:00:00 2001 From: Jiri Cincura Date: Thu, 3 Apr 2025 15:00:44 +0200 Subject: [PATCH 05/32] Bump version. --- src/Versions.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Versions.props b/src/Versions.props index 613410130..c05a921ef 100644 --- a/src/Versions.props +++ b/src/Versions.props @@ -1,7 +1,7 @@ - 10.3.2 + 10.3.3 From adcbe2436e47378693447b2cda34e3fb2da69a1f Mon Sep 17 00:00:00 2001 From: Jiri Cincura Date: Thu, 3 Apr 2025 16:57:38 +0200 Subject: [PATCH 06/32] Fix reading/writing characters with high/low surrogate pairs. (#1213) --- .../FbCommandTests.cs | 34 +++++++++++++++++++ .../Client/Managed/Version10/GdsStatement.cs | 12 +++---- .../Common/DbField.cs | 2 +- .../Common/DbValue.cs | 8 ++--- .../Common/Extensions.cs | 22 ++++++++++++ 5 files changed, 67 insertions(+), 11 deletions(-) diff --git a/src/FirebirdSql.Data.FirebirdClient.Tests/FbCommandTests.cs b/src/FirebirdSql.Data.FirebirdClient.Tests/FbCommandTests.cs index 876a2d9ad..74810d125 100644 --- a/src/FirebirdSql.Data.FirebirdClient.Tests/FbCommandTests.cs +++ b/src/FirebirdSql.Data.FirebirdClient.Tests/FbCommandTests.cs @@ -694,6 +694,40 @@ public async Task PassesDateTimeWithProperPrecisionTest() } } + [Test] + public async Task HighLowSurrogatePassingTest() + { + await using (var cmd = Connection.CreateCommand()) + { + const string Value = "😊"; + cmd.CommandText = "select cast(@value1 as varchar(1) character set utf8), cast(@value2 as char(1) character set utf8) from rdb$database"; + cmd.Parameters.Add("value1", Value); + cmd.Parameters.Add("value2", Value); + await using (var reader = await cmd.ExecuteReaderAsync()) + { + await reader.ReadAsync(); + Assert.AreEqual(Value, reader[0]); + Assert.AreEqual(Value, reader[1]); + } + } + } + + [Test] + public async Task HighLowSurrogateReadingTest() + { + await using (var cmd = Connection.CreateCommand()) + { + const string Value = "😊"; + cmd.CommandText = "select cast(x'F09F988A' as varchar(1) character set utf8), cast(x'F09F988A' as char(1) character set utf8) from rdb$database"; + await using (var reader = await cmd.ExecuteReaderAsync()) + { + await reader.ReadAsync(); + Assert.AreEqual(Value, reader[0]); + Assert.AreEqual(Value, reader[1]); + } + } + } + [Test] public async Task ExecuteNonQueryReturnsMinusOneOnNonInsertUpdateDeleteTest() { diff --git a/src/FirebirdSql.Data.FirebirdClient/Client/Managed/Version10/GdsStatement.cs b/src/FirebirdSql.Data.FirebirdClient/Client/Managed/Version10/GdsStatement.cs index f920c2706..484a7afd7 100644 --- a/src/FirebirdSql.Data.FirebirdClient/Client/Managed/Version10/GdsStatement.cs +++ b/src/FirebirdSql.Data.FirebirdClient/Client/Managed/Version10/GdsStatement.cs @@ -1246,7 +1246,7 @@ protected void WriteRawParameter(IXdrWriter xdr, DbField field) else { var svalue = field.DbValue.GetString(); - if ((field.Length % field.Charset.BytesPerCharacter) == 0 && svalue.Length > field.CharCount) + if ((field.Length % field.Charset.BytesPerCharacter) == 0 && svalue.RuneCount() > field.CharCount) { throw IscException.ForErrorCodes(new[] { IscCodes.isc_arith_except, IscCodes.isc_string_truncation }); } @@ -1271,7 +1271,7 @@ protected void WriteRawParameter(IXdrWriter xdr, DbField field) else { var svalue = field.DbValue.GetString(); - if ((field.Length % field.Charset.BytesPerCharacter) == 0 && svalue.Length > field.CharCount) + if ((field.Length % field.Charset.BytesPerCharacter) == 0 && svalue.RuneCount() > field.CharCount) { throw IscException.ForErrorCodes(new[] { IscCodes.isc_arith_except, IscCodes.isc_string_truncation }); } @@ -1394,7 +1394,7 @@ protected async ValueTask WriteRawParameterAsync(IXdrWriter xdr, DbField field, else { var svalue = await field.DbValue.GetStringAsync(cancellationToken).ConfigureAwait(false); - if ((field.Length % field.Charset.BytesPerCharacter) == 0 && svalue.Length > field.CharCount) + if ((field.Length % field.Charset.BytesPerCharacter) == 0 && svalue.RuneCount() > field.CharCount) { throw IscException.ForErrorCodes(new[] { IscCodes.isc_arith_except, IscCodes.isc_string_truncation }); } @@ -1419,7 +1419,7 @@ protected async ValueTask WriteRawParameterAsync(IXdrWriter xdr, DbField field, else { var svalue = await field.DbValue.GetStringAsync(cancellationToken).ConfigureAwait(false); - if ((field.Length % field.Charset.BytesPerCharacter) == 0 && svalue.Length > field.CharCount) + if ((field.Length % field.Charset.BytesPerCharacter) == 0 && svalue.RuneCount() > field.CharCount) { throw IscException.ForErrorCodes(new[] { IscCodes.isc_arith_except, IscCodes.isc_string_truncation }); } @@ -1533,7 +1533,7 @@ protected object ReadRawValue(IXdrReader xdr, DbField field) { var s = xdr.ReadString(innerCharset, field.Length); if ((field.Length % field.Charset.BytesPerCharacter) == 0 && - s.Length > field.CharCount) + s.RuneCount() > field.CharCount) { return s.Substring(0, field.CharCount); } @@ -1630,7 +1630,7 @@ protected async ValueTask ReadRawValueAsync(IXdrReader xdr, DbField fiel { var s = await xdr.ReadStringAsync(innerCharset, field.Length, cancellationToken).ConfigureAwait(false); if ((field.Length % field.Charset.BytesPerCharacter) == 0 && - s.Length > field.CharCount) + s.RuneCount() > field.CharCount) { return s.Substring(0, field.CharCount); } diff --git a/src/FirebirdSql.Data.FirebirdClient/Common/DbField.cs b/src/FirebirdSql.Data.FirebirdClient/Common/DbField.cs index 924991656..0b9e4a913 100644 --- a/src/FirebirdSql.Data.FirebirdClient/Common/DbField.cs +++ b/src/FirebirdSql.Data.FirebirdClient/Common/DbField.cs @@ -326,7 +326,7 @@ public void SetValue(byte[] buffer) var s = Charset.GetString(buffer, 0, buffer.Length); if ((Length % Charset.BytesPerCharacter) == 0 && - s.Length > CharCount) + s.RuneCount() > CharCount) { s = s.Substring(0, CharCount); } diff --git a/src/FirebirdSql.Data.FirebirdClient/Common/DbValue.cs b/src/FirebirdSql.Data.FirebirdClient/Common/DbValue.cs index b0656d3e2..62d990e08 100644 --- a/src/FirebirdSql.Data.FirebirdClient/Common/DbValue.cs +++ b/src/FirebirdSql.Data.FirebirdClient/Common/DbValue.cs @@ -427,7 +427,7 @@ public byte[] GetBytes() else { var svalue = GetString(); - if ((Field.Length % Field.Charset.BytesPerCharacter) == 0 && svalue.Length > Field.CharCount) + if ((Field.Length % Field.Charset.BytesPerCharacter) == 0 && svalue.RuneCount() > Field.CharCount) { throw IscException.ForErrorCodes(new[] { IscCodes.isc_arith_except, IscCodes.isc_string_truncation }); } @@ -463,7 +463,7 @@ public byte[] GetBytes() else { var svalue = GetString(); - if ((Field.Length % Field.Charset.BytesPerCharacter) == 0 && svalue.Length > Field.CharCount) + if ((Field.Length % Field.Charset.BytesPerCharacter) == 0 && svalue.RuneCount() > Field.CharCount) { throw IscException.ForErrorCodes(new[] { IscCodes.isc_arith_except, IscCodes.isc_string_truncation }); } @@ -642,7 +642,7 @@ public async ValueTask GetBytesAsync(CancellationToken cancellationToken else { var svalue = await GetStringAsync(cancellationToken).ConfigureAwait(false); - if ((Field.Length % Field.Charset.BytesPerCharacter) == 0 && svalue.Length > Field.CharCount) + if ((Field.Length % Field.Charset.BytesPerCharacter) == 0 && svalue.RuneCount() > Field.CharCount) { throw IscException.ForErrorCodes(new[] { IscCodes.isc_arith_except, IscCodes.isc_string_truncation }); } @@ -678,7 +678,7 @@ public async ValueTask GetBytesAsync(CancellationToken cancellationToken else { var svalue = await GetStringAsync(cancellationToken).ConfigureAwait(false); - if ((Field.Length % Field.Charset.BytesPerCharacter) == 0 && svalue.Length > Field.CharCount) + if ((Field.Length % Field.Charset.BytesPerCharacter) == 0 && svalue.RuneCount() > Field.CharCount) { throw IscException.ForErrorCodes(new[] { IscCodes.isc_arith_except, IscCodes.isc_string_truncation }); } diff --git a/src/FirebirdSql.Data.FirebirdClient/Common/Extensions.cs b/src/FirebirdSql.Data.FirebirdClient/Common/Extensions.cs index 39bcbd91b..5aa76e336 100644 --- a/src/FirebirdSql.Data.FirebirdClient/Common/Extensions.cs +++ b/src/FirebirdSql.Data.FirebirdClient/Common/Extensions.cs @@ -66,4 +66,26 @@ public static IEnumerable> Split(this T[] array, int size) #if NETSTANDARD2_0 public static HashSet ToHashSet(this IEnumerable source) => new HashSet(source); #endif + + public static int RuneCount(this string s) + { + if (s == null) + throw new ArgumentNullException(nameof(s)); + +#if NETSTANDARD2_0 || NETSTANDARD2_1 || NET48 + var cnt = 0; + for (var i = 0; i < s.Length; i++) + { + if (char.IsHighSurrogate(s[i]) && i + 1 < s.Length && char.IsLowSurrogate(s[i + 1])) + { + i++; + } + cnt++; + } + return cnt; + +#else + return s.EnumerateRunes().Count(); +#endif + } } From bd0db8823eef2551243e97c64424dd8c69ebca50 Mon Sep 17 00:00:00 2001 From: Jiri Cincura Date: Sun, 13 Apr 2025 16:02:22 +0200 Subject: [PATCH 07/32] Fix reading/writing characters with high/low surrogate pairs. Part 2. (#1213) --- .../FbCommandTests.cs | 8 ++--- .../Client/Managed/Version10/GdsStatement.cs | 19 +++++++----- .../Common/DbField.cs | 6 ++-- .../Common/DbValue.cs | 9 +++--- .../Common/Extensions.cs | 29 ++++++++++++------- 5 files changed, 42 insertions(+), 29 deletions(-) diff --git a/src/FirebirdSql.Data.FirebirdClient.Tests/FbCommandTests.cs b/src/FirebirdSql.Data.FirebirdClient.Tests/FbCommandTests.cs index 74810d125..44ba7c151 100644 --- a/src/FirebirdSql.Data.FirebirdClient.Tests/FbCommandTests.cs +++ b/src/FirebirdSql.Data.FirebirdClient.Tests/FbCommandTests.cs @@ -699,8 +699,8 @@ public async Task HighLowSurrogatePassingTest() { await using (var cmd = Connection.CreateCommand()) { - const string Value = "😊"; - cmd.CommandText = "select cast(@value1 as varchar(1) character set utf8), cast(@value2 as char(1) character set utf8) from rdb$database"; + const string Value = "😊!"; + cmd.CommandText = "select cast(@value1 as varchar(2) character set utf8), cast(@value2 as char(2) character set utf8) from rdb$database"; cmd.Parameters.Add("value1", Value); cmd.Parameters.Add("value2", Value); await using (var reader = await cmd.ExecuteReaderAsync()) @@ -717,8 +717,8 @@ public async Task HighLowSurrogateReadingTest() { await using (var cmd = Connection.CreateCommand()) { - const string Value = "😊"; - cmd.CommandText = "select cast(x'F09F988A' as varchar(1) character set utf8), cast(x'F09F988A' as char(1) character set utf8) from rdb$database"; + const string Value = "😊!"; + cmd.CommandText = "select cast(x'F09F988A21' as varchar(2) character set utf8), cast(x'F09F988A21' as char(2) character set utf8) from rdb$database"; await using (var reader = await cmd.ExecuteReaderAsync()) { await reader.ReadAsync(); diff --git a/src/FirebirdSql.Data.FirebirdClient/Client/Managed/Version10/GdsStatement.cs b/src/FirebirdSql.Data.FirebirdClient/Client/Managed/Version10/GdsStatement.cs index 484a7afd7..f6d33d155 100644 --- a/src/FirebirdSql.Data.FirebirdClient/Client/Managed/Version10/GdsStatement.cs +++ b/src/FirebirdSql.Data.FirebirdClient/Client/Managed/Version10/GdsStatement.cs @@ -19,6 +19,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; +using System.Linq; using System.Threading; using System.Threading.Tasks; using FirebirdSql.Data.Common; @@ -1246,7 +1247,7 @@ protected void WriteRawParameter(IXdrWriter xdr, DbField field) else { var svalue = field.DbValue.GetString(); - if ((field.Length % field.Charset.BytesPerCharacter) == 0 && svalue.RuneCount() > field.CharCount) + if ((field.Length % field.Charset.BytesPerCharacter) == 0 && svalue.EnumerateRunesEx().Count() > field.CharCount) { throw IscException.ForErrorCodes(new[] { IscCodes.isc_arith_except, IscCodes.isc_string_truncation }); } @@ -1271,7 +1272,7 @@ protected void WriteRawParameter(IXdrWriter xdr, DbField field) else { var svalue = field.DbValue.GetString(); - if ((field.Length % field.Charset.BytesPerCharacter) == 0 && svalue.RuneCount() > field.CharCount) + if ((field.Length % field.Charset.BytesPerCharacter) == 0 && svalue.EnumerateRunesEx().Count() > field.CharCount) { throw IscException.ForErrorCodes(new[] { IscCodes.isc_arith_except, IscCodes.isc_string_truncation }); } @@ -1394,7 +1395,7 @@ protected async ValueTask WriteRawParameterAsync(IXdrWriter xdr, DbField field, else { var svalue = await field.DbValue.GetStringAsync(cancellationToken).ConfigureAwait(false); - if ((field.Length % field.Charset.BytesPerCharacter) == 0 && svalue.RuneCount() > field.CharCount) + if ((field.Length % field.Charset.BytesPerCharacter) == 0 && svalue.EnumerateRunesEx().Count() > field.CharCount) { throw IscException.ForErrorCodes(new[] { IscCodes.isc_arith_except, IscCodes.isc_string_truncation }); } @@ -1419,7 +1420,7 @@ protected async ValueTask WriteRawParameterAsync(IXdrWriter xdr, DbField field, else { var svalue = await field.DbValue.GetStringAsync(cancellationToken).ConfigureAwait(false); - if ((field.Length % field.Charset.BytesPerCharacter) == 0 && svalue.RuneCount() > field.CharCount) + if ((field.Length % field.Charset.BytesPerCharacter) == 0 && svalue.EnumerateRunesEx().Count() > field.CharCount) { throw IscException.ForErrorCodes(new[] { IscCodes.isc_arith_except, IscCodes.isc_string_truncation }); } @@ -1532,10 +1533,11 @@ protected object ReadRawValue(IXdrReader xdr, DbField field) else { var s = xdr.ReadString(innerCharset, field.Length); + var runes = s.EnumerateRunesEx().ToList(); if ((field.Length % field.Charset.BytesPerCharacter) == 0 && - s.RuneCount() > field.CharCount) + runes.Count > field.CharCount) { - return s.Substring(0, field.CharCount); + return new string([.. runes.Take(field.CharCount).SelectMany(x => x)]); } else { @@ -1629,10 +1631,11 @@ protected async ValueTask ReadRawValueAsync(IXdrReader xdr, DbField fiel else { var s = await xdr.ReadStringAsync(innerCharset, field.Length, cancellationToken).ConfigureAwait(false); + var runes = s.EnumerateRunesEx().ToList(); if ((field.Length % field.Charset.BytesPerCharacter) == 0 && - s.RuneCount() > field.CharCount) + runes.Count > field.CharCount) { - return s.Substring(0, field.CharCount); + return new string([.. runes.Take(field.CharCount).SelectMany(x => x)]); } else { diff --git a/src/FirebirdSql.Data.FirebirdClient/Common/DbField.cs b/src/FirebirdSql.Data.FirebirdClient/Common/DbField.cs index 0b9e4a913..4e0a435af 100644 --- a/src/FirebirdSql.Data.FirebirdClient/Common/DbField.cs +++ b/src/FirebirdSql.Data.FirebirdClient/Common/DbField.cs @@ -16,6 +16,7 @@ //$Authors = Carlos Guzman Alvarez, Jiri Cincura (jiri@cincura.net) using System; +using System.Linq; using System.Numerics; using FirebirdSql.Data.Types; @@ -325,10 +326,11 @@ public void SetValue(byte[] buffer) { var s = Charset.GetString(buffer, 0, buffer.Length); + var runes = s.EnumerateRunesEx().ToList(); if ((Length % Charset.BytesPerCharacter) == 0 && - s.RuneCount() > CharCount) + runes.Count > CharCount) { - s = s.Substring(0, CharCount); + s = new string([.. runes.Take(CharCount).SelectMany(x => x)]); } DbValue.SetValue(s); diff --git a/src/FirebirdSql.Data.FirebirdClient/Common/DbValue.cs b/src/FirebirdSql.Data.FirebirdClient/Common/DbValue.cs index 62d990e08..4e2d2e7f2 100644 --- a/src/FirebirdSql.Data.FirebirdClient/Common/DbValue.cs +++ b/src/FirebirdSql.Data.FirebirdClient/Common/DbValue.cs @@ -17,6 +17,7 @@ using System; using System.Globalization; +using System.Linq; using System.Numerics; using System.Threading; using System.Threading.Tasks; @@ -427,7 +428,7 @@ public byte[] GetBytes() else { var svalue = GetString(); - if ((Field.Length % Field.Charset.BytesPerCharacter) == 0 && svalue.RuneCount() > Field.CharCount) + if ((Field.Length % Field.Charset.BytesPerCharacter) == 0 && svalue.EnumerateRunesEx().Count() > Field.CharCount) { throw IscException.ForErrorCodes(new[] { IscCodes.isc_arith_except, IscCodes.isc_string_truncation }); } @@ -463,7 +464,7 @@ public byte[] GetBytes() else { var svalue = GetString(); - if ((Field.Length % Field.Charset.BytesPerCharacter) == 0 && svalue.RuneCount() > Field.CharCount) + if ((Field.Length % Field.Charset.BytesPerCharacter) == 0 && svalue.EnumerateRunesEx().Count() > Field.CharCount) { throw IscException.ForErrorCodes(new[] { IscCodes.isc_arith_except, IscCodes.isc_string_truncation }); } @@ -642,7 +643,7 @@ public async ValueTask GetBytesAsync(CancellationToken cancellationToken else { var svalue = await GetStringAsync(cancellationToken).ConfigureAwait(false); - if ((Field.Length % Field.Charset.BytesPerCharacter) == 0 && svalue.RuneCount() > Field.CharCount) + if ((Field.Length % Field.Charset.BytesPerCharacter) == 0 && svalue.EnumerateRunesEx().Count() > Field.CharCount) { throw IscException.ForErrorCodes(new[] { IscCodes.isc_arith_except, IscCodes.isc_string_truncation }); } @@ -678,7 +679,7 @@ public async ValueTask GetBytesAsync(CancellationToken cancellationToken else { var svalue = await GetStringAsync(cancellationToken).ConfigureAwait(false); - if ((Field.Length % Field.Charset.BytesPerCharacter) == 0 && svalue.RuneCount() > Field.CharCount) + if ((Field.Length % Field.Charset.BytesPerCharacter) == 0 && svalue.EnumerateRunesEx().Count() > Field.CharCount) { throw IscException.ForErrorCodes(new[] { IscCodes.isc_arith_except, IscCodes.isc_string_truncation }); } diff --git a/src/FirebirdSql.Data.FirebirdClient/Common/Extensions.cs b/src/FirebirdSql.Data.FirebirdClient/Common/Extensions.cs index 5aa76e336..48e2c75fa 100644 --- a/src/FirebirdSql.Data.FirebirdClient/Common/Extensions.cs +++ b/src/FirebirdSql.Data.FirebirdClient/Common/Extensions.cs @@ -67,25 +67,32 @@ public static IEnumerable> Split(this T[] array, int size) public static HashSet ToHashSet(this IEnumerable source) => new HashSet(source); #endif - public static int RuneCount(this string s) + public static IEnumerable EnumerateRunesEx(this string s) { if (s == null) throw new ArgumentNullException(nameof(s)); #if NETSTANDARD2_0 || NETSTANDARD2_1 || NET48 - var cnt = 0; for (var i = 0; i < s.Length; i++) - { - if (char.IsHighSurrogate(s[i]) && i + 1 < s.Length && char.IsLowSurrogate(s[i + 1])) - { - i++; - } - cnt++; - } - return cnt; + { + if (char.IsHighSurrogate(s[i]) && i + 1 < s.Length && char.IsLowSurrogate(s[i + 1])) + { + yield return new[] { s[i], s[i + 1] }; + i++; + } + else + { + yield return new[] { s[i] }; + } + } #else - return s.EnumerateRunes().Count(); + return s.EnumerateRunes().Select(r => + { + var result = new char[r.Utf16SequenceLength]; + r.EncodeToUtf16(result); + return result; + }); #endif } } From ac0fc7987cd028a875e6399eefb8d4f7b3df0e13 Mon Sep 17 00:00:00 2001 From: Mark Rotteveel Date: Wed, 23 Apr 2025 09:30:49 +0200 Subject: [PATCH 08/32] #1221 Add missing error messages and refresh error messages (#133) Source: Firebird 5.0.2.1613-0 --- .../Common/IscErrorMessages.cs | 1450 ++++++++++++++++- 1 file changed, 1433 insertions(+), 17 deletions(-) diff --git a/src/FirebirdSql.Data.FirebirdClient/Common/IscErrorMessages.cs b/src/FirebirdSql.Data.FirebirdClient/Common/IscErrorMessages.cs index ad90db0c3..a3ad97a9e 100644 --- a/src/FirebirdSql.Data.FirebirdClient/Common/IscErrorMessages.cs +++ b/src/FirebirdSql.Data.FirebirdClient/Common/IscErrorMessages.cs @@ -23,6 +23,7 @@ internal static class IscErrorMessages { static Dictionary _messages = new Dictionary() { + {335544320, ""}, {335544321, "arithmetic exception, numeric overflow, or string truncation"}, /* arith_except */ {335544322, "invalid database key"}, /* bad_dbkey */ {335544323, "file {0} is not a valid database"}, /* bad_db_format */ @@ -215,8 +216,7 @@ internal static class IscErrorMessages {335544510, "lock time-out on wait transaction"}, /* lock_timeout */ {335544511, "procedure {0} is not defined"}, /* prcnotdef */ {335544512, "Input parameter mismatch for procedure {0}"}, /* prcmismat */ - {335544513, @"Database {0}: WAL subsystem bug for pid {1} -{2}"}, /* wal_bugcheck */ + {335544513, "Database {0}: WAL subsystem bug for pid {1}\n{2}"}, /* wal_bugcheck */ {335544514, "Could not expand the WAL segment for database {0}"}, /* wal_cant_expand */ {335544515, "status code {0} unknown"}, /* codnotdef */ {335544516, "exception {0} not defined"}, /* xcpnotdef */ @@ -340,9 +340,9 @@ internal static class IscErrorMessages {335544634, "Token unknown - line {0}, column {1}"}, /* dsql_token_unk_err */ {335544635, "there is no alias or table named {0} at this scope level"}, /* dsql_no_relation_alias */ {335544636, "there is no index {0} for table {1}"}, /* indexname */ - {335544637, "table {0} is not referenced in plan"}, /* no_stream_plan */ - {335544638, "table {0} is referenced more than once in plan; use aliases to distinguish"}, /* stream_twice */ - {335544639, "table {0} is referenced in the plan but not the from list"}, /* stream_not_found */ + {335544637, "table or procedure {0} is not referenced in plan"}, /* no_stream_plan */ + {335544638, "table or procedure {0} is referenced more than once in plan; use aliases to distinguish"}, /* stream_twice */ + {335544639, "table or procedure {0} is referenced in the plan but not the from list"}, /* stream_not_found */ {335544640, "Invalid use of CHARACTER SET or COLLATE"}, /* collation_requires_text */ {335544641, "Specified domain or source column {0} does not exist"}, /* dsql_domain_not_found */ {335544642, "index {0} cannot be used in the specified plan"}, /* index_unused */ @@ -362,7 +362,7 @@ internal static class IscErrorMessages {335544656, "variable {0} conflicts with parameter in same procedure"}, /* dsql_var_conflict */ {335544657, "Array/BLOB/DATE data types not allowed in arithmetic"}, /* dsql_no_blob_array */ {335544658, "{0} is not a valid base table of the specified view"}, /* dsql_base_table */ - {335544659, "table {0} is referenced twice in view; use an alias to distinguish"}, /* duplicate_base_table */ + {335544659, "table or procedure {0} is referenced twice in view; use an alias to distinguish"}, /* duplicate_base_table */ {335544660, "view {0} has more than one base table; use aliases to distinguish"}, /* view_alias */ {335544661, "cannot add index, index root page is full."}, /* index_root_page_full */ {335544662, "BLOB SUB_TYPE {0} is not defined"}, /* dsql_blob_type_unknown */ @@ -546,8 +546,8 @@ internal static class IscErrorMessages {335544840, "cannot update"}, /* no_update */ {335544841, "Cursor is already open"}, /* cursor_already_open */ {335544842, "{0}"}, /* stack_trace */ - {335544843, "Context variable {0} is not found in namespace {1}"}, /* ctx_var_not_found */ - {335544844, "Invalid namespace name {0} passed to {1}"}, /* ctx_namespace_invalid */ + {335544843, "Context variable '{0}' is not found in namespace '{1}'"}, /* ctx_var_not_found */ + {335544844, "Invalid namespace name '{0}' passed to {1}"}, /* ctx_namespace_invalid */ {335544845, "Too many context variables"}, /* ctx_too_big */ {335544846, "Invalid argument passed to {0}"}, /* ctx_bad_argument */ {335544847, "BLR syntax error. Identifier {0}... is too long"}, /* identifier_too_long */ @@ -624,15 +624,12 @@ internal static class IscErrorMessages {335544918, "Attachment handle is busy"}, /* att_handle_busy */ {335544919, "Bad written UDF detected: pointer returned in FREE_IT function was not allocated by ib_util_malloc"}, /* bad_udf_freeit */ {335544920, "External Data Source provider '{0}' not found"}, /* eds_provider_not_found */ - {335544921, @"Execute statement error at {0} : -{1}Data source : {2}"}, /* eds_connection */ + {335544921, "Execute statement error at {0} :\n{1}Data source : {2}"}, /* eds_connection */ {335544922, "Execute statement preprocess SQL error"}, /* eds_preprocess */ {335544923, "Statement expected"}, /* eds_stmt_expected */ {335544924, "Parameter name expected"}, /* eds_prm_name_expected */ {335544925, "Unclosed comment found near '{0}'"}, /* eds_unclosed_comment */ - {335544926, @"Execute statement error at {0} : -{1}Statement : {2} -Data source : {3}"}, /* eds_statement */ + {335544926, "Execute statement error at {0} :\n{1}Statement : {2}\nData source : {3}"}, /* eds_statement */ {335544927, "Input parameters mismatch"}, /* eds_input_prm_mismatch */ {335544928, "Output parameters mismatch"}, /* eds_output_prm_mismatch */ {335544929, "Input parameter '{0}' have no value set"}, /* eds_input_prm_not_set */ @@ -690,7 +687,7 @@ internal static class IscErrorMessages {335544981, "Floating point overflow in built-in function {0}"}, /* sysf_fp_overflow */ {335544982, "Floating point overflow in result from UDF {0}"}, /* udf_fp_overflow */ {335544983, "Invalid floating point value returned by UDF {0}"}, /* udf_fp_nan */ - {335544984, "Database is probably already opened by another engine instance in another Windows session"}, /* instance_conflict */ + {335544984, "Shared memory area is probably already created by another engine instance in another Windows session"}, /* instance_conflict */ {335544985, "No free space found in temporary directories"}, /* out_of_temp_space */ {335544986, "Explicit transaction control is not allowed"}, /* eds_expl_tran_ctrl */ {335544987, "Use of TRUSTED switches in spb_command_line is prohibited"}, /* no_trusted_spb */ @@ -824,7 +821,7 @@ internal static class IscErrorMessages {335545115, "Cannot open cursor for non-SELECT statement"}, /* no_cursor */ {335545116, "If specifies {0}, then shall not specify {1}"}, /* dsql_window_incompat_frames */ {335545117, "RANGE based window with {PRECEDING | FOLLOWING} cannot have ORDER BY with more than one value"}, /* dsql_window_range_multi_key */ - {335545118, "RANGE based window must have an ORDER BY key of numerical, date, time or timestamp types"}, /* dsql_window_range_inv_key_type */ + {335545118, "RANGE based window with PRECEDING/FOLLOWING must have a single ORDER BY key of numerical, date, time or timestamp types"}, /* dsql_window_range_inv_key_type */ {335545119, "Window RANGE/ROWS PRECEDING/FOLLOWING value must be of a numerical type"}, /* dsql_window_frame_value_inv_type */ {335545120, "Invalid PRECEDING or FOLLOWING offset in window function: cannot be negative"}, /* window_frame_value_invalid */ {335545121, "Window {0} not found"}, /* dsql_window_not_found */ @@ -843,7 +840,7 @@ internal static class IscErrorMessages {335545134, "OVERRIDING clause can be used only when an identity column is present in the INSERT's field list for table/view {0}"}, /* overriding_without_identity */ {335545135, "OVERRIDING SYSTEM VALUE can be used only for identity column defined as 'GENERATED ALWAYS' in INSERT for table/view {0}"}, /* overriding_system_invalid */ {335545136, "OVERRIDING USER VALUE can be used only for identity column defined as 'GENERATED BY DEFAULT' in INSERT for table/view {0}"}, /* overriding_user_invalid */ - {335545137, "OVERRIDING SYSTEM VALUE should be used to override the value of an identity column defined as 'GENERATED ALWAYS' in table/view {0}"}, /* overriding_system_missing */ + {335545137, "OVERRIDING clause should be used when an identity column defined as 'GENERATED ALWAYS' is present in the INSERT's field list for table table/view {0}"}, /* overriding_missing */ {335545138, "DecFloat precision must be 16 or 34"}, /* decprecision_err */ {335545139, "Decimal float divide by zero. The code attempted to divide a DECFLOAT value by zero."}, /* decfloat_divide_by_zero */ {335545140, "Decimal float inexact result. The result of an operation cannot be represented as a decimal fraction."}, /* decfloat_inexact_result */ @@ -884,7 +881,7 @@ internal static class IscErrorMessages {335545175, "Segment size ({0}) should not exceed 65535 (64K - 1) when using segmented blob"}, /* big_segment */ {335545176, "Invalid blob policy in the batch for {0}() call"}, /* batch_policy */ {335545177, "Can't change default BPB after adding any data to batch"}, /* batch_defbpb */ - {335545178, "Unexpected info buffer structure querying for default blob alignment"}, /* batch_align */ + {335545178, "Unexpected info buffer structure querying for server batch parameters"}, /* batch_align */ {335545179, "Duplicated segment {0} in multisegment connect block parameter"}, /* multi_segment_dup */ {335545180, "Plugin not supported by network protocol"}, /* non_plugin_protocol */ {335545181, "Error parsing message format"}, /* message_format */ @@ -981,14 +978,31 @@ internal static class IscErrorMessages {335545272, "Reset of user session failed. Connection is shut down."}, /* ses_reset_failed */ {335545273, "File size is less than expected"}, /* block_size */ {335545274, "Invalid key length {0}, need >{1}"}, /* tom_key_length */ + {335545275, "Invalid information arguments"}, /* inf_invalid_args */ + {335545276, "Empty or NULL parameter {0} is not accepted"}, /* sysf_invalid_null_empty */ + {335545277, "Undefined local table number {0}"}, /* bad_loctab_num */ + {335545278, "Invalid text <{0}> after quoted string"}, /* quoted_str_bad */ + {335545279, "Missing terminating quote <{0}> in the end of quoted string"}, /* quoted_str_miss */ + {335545280, "{0}: inconsistent shared memory type/version; found {1}, expected {2}"}, /* wrong_shmem_ver */ + {335545281, "{0}-bit engine can't open database already opened by {1}-bit engine"}, /* wrong_shmem_bitness */ + {335545282, "Procedures cannot specify access type other than NATURAL in the plan"}, /* wrong_proc_plan */ + {335545283, "Invalid RDB$BLOB_UTIL handle"}, /* invalid_blob_util_handle */ + {335545284, "Invalid temporary BLOB ID"}, /* bad_temp_blob_id */ + {335545285, "ODS upgrade failed while adding new system {0}"}, /* ods_upgrade_err */ + {335545286, "Wrong parallel workers value {0}, valid range are from 1 to {1}"}, /* bad_par_workers */ + {335545287, "Definition of index expression is not found for index {0}"}, /* idx_expr_not_found */ + {335545288, "Definition of index condition is not found for index {0}"}, /* idx_cond_not_found */ {335740929, "data base file name ({0}) already given"}, /* gfix_db_name */ {335740930, "invalid switch {0}"}, /* gfix_invalid_sw */ + {335740931, "gfix version {0}"}, /* gfix_version */ {335740932, "incompatible switch combination"}, /* gfix_incmp_sw */ {335740933, "replay log pathname required"}, /* gfix_replay_req */ {335740934, "number of page buffers for cache required"}, /* gfix_pgbuf_req */ {335740935, "numeric value required"}, /* gfix_val_req */ {335740936, "positive numeric value required"}, /* gfix_pval_req */ {335740937, "number of transactions per sweep required"}, /* gfix_trn_req */ + {335740938, "transaction number or \"all\" required"}, /* gfix_trn_all_req */ + {335740939, "\"sync\" or \"async\" required"}, /* gfix_sync_req */ {335740940, "\"full\" or \"reserve\" required"}, /* gfix_full_req */ {335740941, "user name required"}, /* gfix_usrname_req */ {335740942, "password required"}, /* gfix_pass_req */ @@ -998,21 +1012,128 @@ internal static class IscErrorMessages {335740946, "numeric value between 0 and 32767 inclusive required"}, /* gfix_nval_req */ {335740947, "must specify type of shutdown"}, /* gfix_type_shut */ {335740948, "please retry, specifying an option"}, /* gfix_retry */ + {335740949, "plausible options are:"}, /* gfix_opt */ + {335740950, "\\n Options can be abbreviated to the unparenthesized characters"}, /* gfix_qualifiers */ {335740951, "please retry, giving a database name"}, /* gfix_retry_db */ + {335740952, "Summary of validation errors"}, /* gfix_summary */ + {335740953, " -ac(tivate_shadow) activate shadow file for database usage"}, /* gfix_opt_active */ + {335740954, " -at(tach) shutdown new database attachments"}, /* gfix_opt_attach */ + {335740955, "\t-begin_log\tbegin logging for replay utility"}, /* gfix_opt_begin_log */ + {335740956, " -b(uffers) set page buffers "}, /* gfix_opt_buffers */ + {335740957, " -co(mmit) commit transaction "}, /* gfix_opt_commit */ + {335740958, " -ca(che) shutdown cache manager"}, /* gfix_opt_cache */ + {335740959, "\t-disable\tdisable WAL"}, /* gfix_opt_disable */ + {335740960, " -fu(ll) validate record fragments (-v)"}, /* gfix_opt_full */ + {335740961, " -fo(rce_shutdown) force database shutdown"}, /* gfix_opt_force */ + {335740962, " -h(ousekeeping) set sweep interval "}, /* gfix_opt_housekeep */ + {335740963, " -i(gnore) ignore checksum errors"}, /* gfix_opt_ignore */ + {335740964, " -k(ill_shadow) kill all unavailable shadow files"}, /* gfix_opt_kill */ + {335740965, " -l(ist) show limbo transactions"}, /* gfix_opt_list */ + {335740966, " -me(nd) prepare corrupt database for backup"}, /* gfix_opt_mend */ + {335740967, " -n(o_update) read-only validation (-v)"}, /* gfix_opt_no_update */ + {335740968, " -o(nline) database online "}, /* gfix_opt_online */ + {335740969, " -pr(ompt) prompt for commit/rollback (-l)"}, /* gfix_opt_prompt */ + {335740970, " -pa(ssword) default password"}, /* gfix_opt_password */ + {335740971, "\t-quit_log\tquit logging for replay utility"}, /* gfix_opt_quit_log */ + {335740972, " -r(ollback) rollback transaction "}, /* gfix_opt_rollback */ + {335740973, " -sw(eep) force garbage collection"}, /* gfix_opt_sweep */ + {335740974, " -sh(utdown) shutdown "}, /* gfix_opt_shut */ + {335740975, " -tw(o_phase) perform automated two-phase recovery"}, /* gfix_opt_two_phase */ + {335740976, " -tra(nsaction) shutdown transaction startup"}, /* gfix_opt_tran */ + {335740977, " -u(se) use full or reserve space for versions"}, /* gfix_opt_use */ + {335740978, " -user default user name"}, /* gfix_opt_user */ + {335740979, " -v(alidate) validate database structure"}, /* gfix_opt_validate */ + {335740980, " -w(rite) write synchronously or asynchronously"}, /* gfix_opt_write */ + {335740981, " -x set debug on"}, /* gfix_opt_x */ + {335740982, " -z print software version number"}, /* gfix_opt_z */ + {335740983, "\\n\tNumber of record level errors\t: {0}"}, /* gfix_rec_err */ + {335740984, "\tNumber of Blob page errors\t: {0}"}, /* gfix_blob_err */ + {335740985, "\tNumber of data page errors\t: {0}"}, /* gfix_data_err */ + {335740986, "\tNumber of index page errors\t: {0}"}, /* gfix_index_err */ + {335740987, "\tNumber of pointer page errors\t: {0}"}, /* gfix_pointer_err */ + {335740988, "\tNumber of transaction page errors\t: {0}"}, /* gfix_trn_err */ + {335740989, "\tNumber of database page errors\t: {0}"}, /* gfix_db_err */ + {335740990, "bad block type"}, /* gfix_bad_block */ {335740991, "internal block exceeds maximum size"}, /* gfix_exceed_max */ {335740992, "corrupt pool"}, /* gfix_corrupt_pool */ {335740993, "virtual memory exhausted"}, /* gfix_mem_exhausted */ {335740994, "bad pool id"}, /* gfix_bad_pool */ {335740995, "Transaction state {0} not in valid range."}, /* gfix_trn_not_valid */ + {335740996, "ATTACH_DATABASE: attempted attach of {0},"}, /* gfix_dbg_attach */ + {335740997, " failed"}, /* gfix_dbg_failed */ + {335740998, " succeeded"}, /* gfix_dbg_success */ + {335740999, "Transaction {0} is in limbo."}, /* gfix_trn_limbo */ + {335741000, "More limbo transactions than fit. Try again"}, /* gfix_try_again */ + {335741001, "Unrecognized info item {0}"}, /* gfix_unrec_item */ + {335741002, "A commit of transaction {0} will violate two-phase commit."}, /* gfix_commit_violate */ + {335741003, "A rollback of transaction {0} is needed to preserve two-phase commit."}, /* gfix_preserve */ + {335741004, "Transaction {0} has already been partially committed."}, /* gfix_part_commit */ + {335741005, "A rollback of this transaction will violate two-phase commit."}, /* gfix_rback_violate */ + {335741006, "Transaction {0} has been partially committed."}, /* gfix_part_commit2 */ + {335741007, "A commit is necessary to preserve the two-phase commit."}, /* gfix_commit_pres */ + {335741008, "Insufficient information is available to determine"}, /* gfix_insuff_info */ + {335741009, "a proper action for transaction {0}."}, /* gfix_action */ + {335741010, "Transaction {0}: All subtransactions have been prepared."}, /* gfix_all_prep */ + {335741011, "Either commit or rollback is possible."}, /* gfix_comm_rback */ {335741012, "unexpected end of input"}, /* gfix_unexp_eoi */ + {335741013, "Commit, rollback, or neither (c, r, or n)?"}, /* gfix_ask */ + {335741014, "Could not reattach to database for transaction {0}."}, /* gfix_reattach_failed */ + {335741015, "Original path: {0}"}, /* gfix_org_path */ + {335741016, "Enter a valid path:"}, /* gfix_enter_path */ + {335741017, "Attach unsuccessful."}, /* gfix_att_unsucc */ {335741018, "failed to reconnect to a transaction in database {0}"}, /* gfix_recon_fail */ + {335741019, "Transaction {0}:"}, /* gfix_trn2 */ + {335741020, " Multidatabase transaction:"}, /* gfix_mdb_trn */ + {335741021, " Host Site: {0}"}, /* gfix_host_site */ + {335741022, " Transaction {0}"}, /* gfix_trn */ + {335741023, "has been prepared."}, /* gfix_prepared */ + {335741024, "has been committed."}, /* gfix_committed */ + {335741025, "has been rolled back."}, /* gfix_rolled_back */ + {335741026, "is not available."}, /* gfix_not_available */ + {335741027, "is not found, assumed not prepared."}, /* gfix_not_prepared */ + {335741028, "is not found, assumed to be committed."}, /* gfix_be_committed */ + {335741029, " Remote Site: {0}"}, /* gfix_rmt_site */ + {335741030, " Database Path: {0}"}, /* gfix_db_path */ + {335741031, " Automated recovery would commit this transaction."}, /* gfix_auto_comm */ + {335741032, " Automated recovery would rollback this transaction."}, /* gfix_auto_rback */ + {335741033, "Warning: Multidatabase transaction is in inconsistent state for recovery."}, /* gfix_warning */ + {335741034, "Transaction {0} was committed, but prior ones were rolled back."}, /* gfix_trn_was_comm */ + {335741035, "Transaction {0} was rolled back, but prior ones were committed."}, /* gfix_trn_was_rback */ {335741036, "Transaction description item unknown"}, /* gfix_trn_unknown */ + {335741037, " -mo(de) read_only or read_write database"}, /* gfix_opt_mode */ {335741038, "\"read_only\" or \"read_write\" required"}, /* gfix_mode_req */ + {335741039, " -sq(l_dialect) set database dialect n"}, /* gfix_opt_SQL_dialect */ + {335741040, "database SQL dialect must be one of '{0}'"}, /* gfix_SQL_dialect */ + {335741041, "dialect number required"}, /* gfix_dialect_req */ {335741042, "positive or zero numeric value required"}, /* gfix_pzval_req */ + {335741043, " -tru(sted) use trusted authentication"}, /* gfix_opt_trusted */ + {335741044, "could not open password file {0}, errno {1}"}, + {335741045, "could not read password file {0}, errno {1}"}, + {335741046, "empty password file {0}"}, + {335741047, " -fe(tch_password) fetch password from file"}, + {335741048, "usage: gfix [options] "}, + {335741049, " -nol(inger) close database ignoring linger setting for it"}, /* gfix_opt_nolinger */ + {335741050, "\tNumber of inventory page errors\t: {0}"}, /* gfix_pip_err */ + {335741051, "\tNumber of record level warnings\t: {0}"}, /* gfix_rec_warn */ + {335741052, "\tNumber of blob page warnings\t: {0}"}, /* gfix_blob_warn */ + {335741053, "\tNumber of data page warnings\t: {0}"}, /* gfix_data_warn */ + {335741054, "\tNumber of index page warnings\t: {0}"}, /* gfix_index_warn */ + {335741055, "\tNumber of pointer page warnings\t: {0}"}, /* gfix_pointer_warn */ + {335741056, "\tNumber of transaction page warnings\t: {0}"}, /* gfix_trn_warn */ + {335741057, "\tNumber of database page warnings\t: {0}"}, /* gfix_db_warn */ + {335741058, "\tNumber of inventory page warnings\t: {0}"}, /* gfix_pip_warn */ + {335741059, " -icu fix database to be usable with present ICU version"}, /* gfix_opt_icu */ + {335741060, " -role set SQL role name"}, /* gfix_opt_role */ + {335741061, "SQL role name required"}, /* gfix_role_req */ + {335741062, " -repl(ica) replica mode "}, /* gfix_opt_repl */ + {335741063, "replica mode (none / read_only / read_write) required"}, /* gfix_repl_mode_req */ + {335741064, " -par(allel) parallel workers (-sweep, -icu)"}, /* gfix_opt_parallel */ + {335741065, " -up(grade) upgrade database ODS"}, /* gfix_opt_upgrade */ {336003074, "Cannot SELECT RDB$DB_KEY from a stored procedure."}, /* dsql_dbkey_from_non_table */ {336003075, "Precision 10 to 18 changed from DOUBLE PRECISION in SQL dialect 1 to 64-bit scaled integer in SQL dialect 3"}, /* dsql_transitional_numeric */ {336003076, "Use of {0} expression that returns different results in dialect 1 and dialect 3"}, /* dsql_dialect_warning_expr */ {336003077, "Database SQL dialect {0} does not support reference to {1} datatype"}, /* sql_db_dialect_dtype_unsupport */ + {336003078, ""}, {336003079, "DB dialect {0} and client dialect {1} conflict with respect to numeric precision {2}."}, /* sql_dialect_conflict_num */ {336003080, "WARNING: Numeric literal {0} is interpreted as a floating-point"}, /* dsql_warning_number_ambiguous */ {336003081, "value in SQL dialect 1, but as an exact numeric value in SQL dialect 3."}, /* dsql_warning_number_ambiguous1 */ @@ -1048,22 +1169,192 @@ internal static class IscErrorMessages {336003111, "Wrong number of parameters (expected {0}, got {1})"}, /* dsql_wrong_param_num */ {336003112, "Invalid DROP SQL SECURITY clause"}, /* dsql_invalid_drop_ss_clause */ {336003113, "UPDATE OR INSERT value for field {0}, part of the implicit or explicit MATCHING clause, cannot be DEFAULT"}, /* upd_ins_cannot_default */ + {336068609, "ODS version not supported by DYN"}, + {336068610, "unsupported DYN verb"}, + {336068611, "STORE RDB$FIELD_DIMENSIONS failed"}, + {336068612, "unsupported DYN verb"}, + {336068613, "{0}"}, + {336068614, "unsupported DYN verb"}, + {336068615, "DEFINE BLOB FILTER failed"}, + {336068616, "DEFINE GENERATOR failed"}, + {336068617, "DEFINE GENERATOR unexpected DYN verb"}, + {336068618, "DEFINE FUNCTION failed"}, + {336068619, "unsupported DYN verb"}, + {336068620, "DEFINE FUNCTION ARGUMENT failed"}, + {336068621, "STORE RDB$FIELDS failed"}, + {336068622, "No table specified for index"}, + {336068623, "STORE RDB$INDEX_SEGMENTS failed"}, + {336068624, "unsupported DYN verb"}, + {336068625, "PRIMARY KEY column lookup failed"}, + {336068626, "could not find UNIQUE or PRIMARY KEY constraint in table {0} with specified columns"}, + {336068627, "PRIMARY KEY lookup failed"}, + {336068628, "could not find PRIMARY KEY index in specified table {0}"}, + {336068629, "STORE RDB$INDICES failed"}, + {336068630, "STORE RDB$FIELDS failed"}, + {336068631, "STORE RDB$RELATION_FIELDS failed"}, + {336068632, "STORE RDB$RELATIONS failed"}, + {336068633, "STORE RDB$USER_PRIVILEGES failed defining a table"}, + {336068634, "unsupported DYN verb"}, + {336068635, "STORE RDB$RELATIONS failed"}, + {336068636, "STORE RDB$FIELDS failed"}, + {336068637, "STORE RDB$RELATION_FIELDS failed"}, + {336068638, "unsupported DYN verb"}, + {336068639, "DEFINE TRIGGER failed"}, + {336068640, "unsupported DYN verb"}, + {336068641, "DEFINE TRIGGER MESSAGE failed"}, + {336068642, "STORE RDB$VIEW_RELATIONS failed"}, + {336068643, "ERASE RDB$FIELDS failed"}, + {336068644, "ERASE BLOB FILTER failed"}, {336068645, "BLOB Filter {0} not found"}, /* dyn_filter_not_found */ + {336068646, "unsupported DYN verb"}, + {336068647, "ERASE RDB$FUNCTION_ARGUMENTS failed"}, + {336068648, "ERASE RDB$FUNCTIONS failed"}, {336068649, "Function {0} not found"}, /* dyn_func_not_found */ + {336068650, "unsupported DYN verb"}, + {336068651, "Domain {0} is used in table {1} (local name {2}) and cannot be dropped"}, + {336068652, "ERASE RDB$FIELDS failed"}, + {336068653, "ERASE RDB$FIELDS failed"}, + {336068654, "Column not found"}, + {336068655, "ERASE RDB$INDICES failed"}, {336068656, "Index not found"}, /* dyn_index_not_found */ + {336068657, "ERASE RDB$INDEX_SEGMENTS failed"}, + {336068658, "No segments found for index"}, + {336068659, "No table specified in ERASE RFR"}, + {336068660, "Column {0} from table {1} is referenced in view {2}"}, + {336068661, "ERASE RDB$RELATION_FIELDS failed"}, {336068662, "View {0} not found"}, /* dyn_view_not_found */ + {336068663, "Column not found for table"}, + {336068664, "ERASE RDB$INDEX_SEGMENTS failed"}, + {336068665, "ERASE RDB$INDICES failed"}, + {336068666, "ERASE RDB$RELATION_FIELDS failed"}, + {336068667, "ERASE RDB$VIEW_RELATIONS failed"}, + {336068668, "ERASE RDB$RELATIONS failed"}, + {336068669, "Table not found"}, + {336068670, "ERASE RDB$USER_PRIVILEGES failed"}, + {336068671, "ERASE RDB$FILES failed"}, + {336068672, "unsupported DYN verb"}, + {336068673, "ERASE RDB$TRIGGER_MESSAGES failed"}, + {336068674, "ERASE RDB$TRIGGERS failed"}, + {336068675, "Trigger not found"}, + {336068676, "MODIFY RDB$VIEW_RELATIONS failed"}, + {336068677, "unsupported DYN verb"}, + {336068678, "TRIGGER NAME expected"}, + {336068679, "ERASE TRIGGER MESSAGE failed"}, + {336068680, "Trigger Message not found"}, + {336068681, "unsupported DYN verb"}, + {336068682, "ERASE RDB$SECURITY_CLASSES failed"}, + {336068683, "Security class not found"}, + {336068684, "unsupported DYN verb"}, + {336068685, "SELECT RDB$USER_PRIVILEGES failed in grant"}, + {336068686, "SELECT RDB$USER_PRIVILEGES failed in grant"}, + {336068687, "STORE RDB$USER_PRIVILEGES failed in grant"}, + {336068688, "Specified domain or source column does not exist"}, + {336068689, "Generation of column name failed"}, + {336068690, "Generation of index name failed"}, + {336068691, "Generation of trigger name failed"}, + {336068692, "MODIFY DATABASE failed"}, + {336068693, "MODIFY RDB$CHARACTER_SETS failed"}, + {336068694, "MODIFY RDB$COLLATIONS failed"}, + {336068695, "MODIFY RDB$FIELDS failed"}, + {336068696, "MODIFY RDB$BLOB_FILTERS failed"}, {336068697, "Domain not found"}, /* dyn_domain_not_found */ + {336068698, "unsupported DYN verb"}, + {336068699, "MODIFY RDB$INDICES failed"}, + {336068700, "MODIFY RDB$FUNCTIONS failed"}, + {336068701, "Index column not found"}, + {336068702, "MODIFY RDB$GENERATORS failed"}, + {336068703, "MODIFY RDB$RELATION_FIELDS failed"}, + {336068704, "Local column {0} not found"}, + {336068705, "add EXTERNAL FILE not allowed"}, + {336068706, "drop EXTERNAL FILE not allowed"}, + {336068707, "MODIFY RDB$RELATIONS failed"}, + {336068708, "MODIFY RDB$PROCEDURE_PARAMETERS failed"}, + {336068709, "Table column not found"}, + {336068710, "MODIFY TRIGGER failed"}, + {336068711, "TRIGGER NAME expected"}, + {336068712, "unsupported DYN verb"}, + {336068713, "MODIFY TRIGGER MESSAGE failed"}, + {336068714, "Create metadata BLOB failed"}, + {336068715, "Write metadata BLOB failed"}, + {336068716, "Close metadata BLOB failed"}, {336068717, "Triggers created automatically cannot be modified"}, /* dyn_cant_modify_auto_trig */ + {336068718, "unsupported DYN verb"}, + {336068719, "ERASE RDB$USER_PRIVILEGES failed in revoke(1)"}, + {336068720, "Access to RDB$USER_PRIVILEGES failed in revoke(2)"}, + {336068721, "ERASE RDB$USER_PRIVILEGES failed in revoke (3)"}, + {336068722, "Access to RDB$USER_PRIVILEGES failed in revoke (4)"}, + {336068723, "CREATE VIEW failed"}, + {336068724, " attempt to index BLOB column in INDEX {0}"}, + {336068725, " attempt to index array column in index {0}"}, + {336068726, "key size too big for index {0}"}, + {336068727, "no keys for index {0}"}, + {336068728, "Unknown columns in index {0}"}, + {336068729, "STORE RDB$RELATION_CONSTRAINTS failed"}, + {336068730, "STORE RDB$CHECK_CONSTRAINTS failed"}, + {336068731, "Column: {0} not defined as NOT NULL - cannot be used in PRIMARY KEY constraint definition"}, + {336068732, "A column name is repeated in the definition of constraint: {0}"}, + {336068733, "Integrity Constraint lookup failed"}, + {336068734, "Same set of columns cannot be used in more than one PRIMARY KEY and/or UNIQUE constraint definition"}, + {336068735, "STORE RDB$REF_CONSTRAINTS failed"}, + {336068736, "No table specified in delete_constraint"}, + {336068737, "ERASE RDB$RELATION_CONSTRAINTS failed"}, + {336068738, "CONSTRAINT {0} does not exist."}, + {336068739, "Generation of constraint name failed"}, {336068740, "Table {0} already exists"}, /* dyn_dup_table */ + {336068741, "Number of referencing columns do not equal number of referenced columns"}, + {336068742, "STORE RDB$PROCEDURES failed"}, + {336068743, "Procedure {0} already exists"}, /* dyn_dup_procedure */ + {336068744, "STORE RDB$PROCEDURE_PARAMETERS failed"}, + {336068745, "Store into system table {0} failed"}, + {336068746, "ERASE RDB$PROCEDURE_PARAMETERS failed"}, + {336068747, "ERASE RDB$PROCEDURES failed"}, {336068748, "Procedure {0} not found"}, /* dyn_proc_not_found */ + {336068749, "MODIFY RDB$PROCEDURES failed"}, + {336068750, "DEFINE EXCEPTION failed"}, + {336068751, "ERASE EXCEPTION failed"}, {336068752, "Exception not found"}, /* dyn_exception_not_found */ + {336068753, "MODIFY EXCEPTION failed"}, {336068754, "Parameter {0} in procedure {1} not found"}, /* dyn_proc_param_not_found */ {336068755, "Trigger {0} not found"}, /* dyn_trig_not_found */ + {336068756, "Only one data type change to the domain {0} allowed at a time"}, + {336068757, "Only one data type change to the field {0} allowed at a time"}, + {336068758, "STORE RDB$FILES failed"}, {336068759, "Character set {0} not found"}, /* dyn_charset_not_found */ {336068760, "Collation {0} not found"}, /* dyn_collation_not_found */ + {336068761, "ERASE RDB$LOG_FILES failed"}, + {336068762, "STORE RDB$LOG_FILES failed"}, {336068763, "Role {0} not found"}, /* dyn_role_not_found */ + {336068764, "Difference file lookup failed"}, + {336068765, "DEFINE SHADOW failed"}, + {336068766, "MODIFY RDB$ROLES failed"}, {336068767, "Name longer than database column size"}, /* dyn_name_longer */ + {336068768, "\"Only one constraint allowed for a domain\""}, + {336068770, "Looking up column position failed"}, + {336068771, "A node name is not permitted in a table with external file definition"}, + {336068772, "Shadow lookup failed"}, + {336068773, "Shadow {0} already exists"}, + {336068774, "Cannot add file with the same name as the database or added files"}, + {336068775, "no grant option for privilege {0} on column {1} of table/view {2}"}, + {336068776, "no grant option for privilege {0} on column {1} of base table/view {2}"}, + {336068777, "no grant option for privilege {0} on table/view {1} (for column {2})"}, + {336068778, "no grant option for privilege {0} on base table/view {1} (for column {2})"}, + {336068779, "no {0} privilege with grant option on table/view {1} (for column {2})"}, + {336068780, "no {0} privilege with grant option on base table/view {1} (for column {2})"}, + {336068781, "no grant option for privilege {0} on table/view {1}"}, + {336068782, "no {0} privilege with grant option on table/view {1}"}, + {336068783, "table/view {0} does not exist"}, {336068784, "column {0} does not exist in table/view {1}"}, /* dyn_column_does_not_exist */ + {336068785, "Can not alter a view"}, + {336068786, "EXTERNAL FILE table not supported in this context"}, + {336068787, "attempt to index COMPUTED BY column in INDEX {0}"}, + {336068788, "Table Name lookup failed"}, + {336068789, "attempt to index a view"}, + {336068790, "SELECT RDB$RELATIONS failed in grant"}, + {336068791, "SELECT RDB$RELATION_FIELDS failed in grant"}, + {336068792, "SELECT RDB$RELATIONS/RDB$OWNER_NAME failed in grant"}, + {336068793, "SELECT RDB$USER_PRIVILEGES failed in grant"}, + {336068794, "SELECT RDB$VIEW_RELATIONS/RDB$RELATION_FIELDS/... failed in grant"}, + {336068795, "column {0} from table {1} is referenced in index {2}"}, {336068796, "SQL role {0} does not exist"}, /* dyn_role_does_not_exist */ {336068797, "user {0} has no grant admin option on SQL role {1}"}, /* dyn_no_grant_admin_opt */ {336068798, "user {0} is not a member of SQL role {1}"}, /* dyn_user_not_role_member */ @@ -1080,24 +1371,51 @@ internal static class IscErrorMessages {336068816, "New size specified for column {0} must be at least {1} characters."}, /* dyn_char_fld_too_small */ {336068817, "Cannot change datatype for {0}. Conversion from base type {1} to {2} is not supported."}, /* dyn_invalid_dtype_conversion */ {336068818, "Cannot change datatype for column {0} from a character type to a non-character type."}, /* dyn_dtype_conv_invalid */ + {336068819, "unable to allocate memory from the operating system"}, /* dyn_virmemexh */ {336068820, "Zero length identifiers are not allowed"}, /* dyn_zero_len_id */ + {336068821, "ERASE RDB$GENERATORS failed"}, /* del_gen_fail */ {336068822, "Sequence {0} not found"}, /* dyn_gen_not_found */ + {336068823, "Difference file is not defined"}, + {336068824, "Difference file is already defined"}, + {336068825, "Database is already in the physical backup mode"}, + {336068826, "Database is not in the physical backup mode"}, + {336068827, "DEFINE COLLATION failed"}, + {336068828, "CREATE COLLATION statement is not supported in older versions of the database. A backup and restore is required."}, {336068829, "Maximum number of collations per character set exceeded"}, /* max_coll_per_charset */ {336068830, "Invalid collation attributes"}, /* invalid_coll_attr */ + {336068831, "Collation {0} not installed for character set {1}"}, + {336068832, "Cannot use the internal domain {0} as new type for field {1}"}, + {336068833, "Default value is not allowed for array type in field {0}"}, + {336068834, "Default value is not allowed for array type in domain {0}"}, + {336068835, "DYN_UTIL_is_array failed for domain {0}"}, + {336068836, "DYN_UTIL_copy_domain failed for domain {0}"}, + {336068837, "Local column {0} doesn't have a default"}, + {336068838, "Local column {0} default belongs to domain {1}"}, + {336068839, "File name is invalid"}, {336068840, "{0} cannot reference {1}"}, /* dyn_wrong_gtt_scope */ + {336068841, "Local column {0} is computed, cannot set a default value"}, + {336068842, "ERASE RDB$COLLATIONS failed"}, /* del_coll_fail */ {336068843, "Collation {0} is used in table {1} (field name {2}) and cannot be dropped"}, /* dyn_coll_used_table */ {336068844, "Collation {0} is used in domain {1} and cannot be dropped"}, /* dyn_coll_used_domain */ {336068845, "Cannot delete system collation"}, /* dyn_cannot_del_syscoll */ {336068846, "Cannot delete default collation of CHARACTER SET {0}"}, /* dyn_cannot_del_def_coll */ + {336068847, "Domain {0} is used in procedure {1} (parameter name {2}) and cannot be dropped"}, + {336068848, "Field {0} cannot be used twice in index {1}"}, {336068849, "Table {0} not found"}, /* dyn_table_not_found */ + {336068850, "attempt to reference a view ({0}) in a foreign key"}, {336068851, "Collation {0} is used in procedure {1} (parameter name {2}) and cannot be dropped"}, /* dyn_coll_used_procedure */ {336068852, "New scale specified for column {0} must be at most {1}."}, /* dyn_scale_too_big */ {336068853, "New precision specified for column {0} must be at least {1}."}, /* dyn_precision_too_small */ + {336068854, "{0} is not grantor of {1} on {2} to {3}."}, {336068855, "Warning: {0} on {1} is not granted to {2}."}, /* dyn_miss_priv_warning */ {336068856, "Feature '{0}' is not supported in ODS {1}.{2}"}, /* dyn_ods_not_supp_feature */ {336068857, "Cannot add or remove COMPUTED from column {0}"}, /* dyn_cannot_addrem_computed */ {336068858, "Password should not be empty string"}, /* dyn_no_empty_pw */ {336068859, "Index {0} already exists"}, /* dyn_dup_index */ + {336068860, "Only {0} or user with privilege USE_GRANTED_BY_CLAUSE can use GRANTED BY clause"}, /* dyn_locksmith_use_granted */ + {336068861, "Exception {0} already exists"}, /* dyn_dup_exception */ + {336068862, "Sequence {0} already exists"}, /* dyn_dup_generator */ + {336068863, "ERASE RDB$USER_PRIVILEGES failed in REVOKE ALL ON ALL"}, {336068864, "Package {0} not found"}, /* dyn_package_not_found */ {336068865, "Schema {0} not found"}, /* dyn_schema_not_found */ {336068866, "Cannot ALTER or DROP system procedure {0}"}, /* dyn_cannot_mod_sysproc */ @@ -1110,22 +1428,37 @@ internal static class IscErrorMessages {336068873, "Function {0} has a signature mismatch on package body {1}"}, /* dyn_funcsignat_package */ {336068874, "Procedure {0} has a signature mismatch on package body {1}"}, /* dyn_procsignat_package */ {336068875, "Default values for parameters are not allowed in the definition of a previously declared packaged procedure {0}.{1}"}, /* dyn_defvaldecl_package_proc */ + {336068876, "Function {0} already exists"}, /* dyn_dup_function */ {336068877, "Package body {0} already exists"}, /* dyn_package_body_exists */ {336068878, "Invalid DDL statement for function {0}"}, /* dyn_invalid_ddl_func */ {336068879, "Cannot alter new style function {0} with ALTER EXTERNAL FUNCTION. Use ALTER FUNCTION instead."}, /* dyn_newfc_oldsyntax */ + {336068880, "Cannot delete system generator {0}"}, + {336068881, "Identity column {0} of table {1} must be of exact number type with zero scale"}, + {336068882, "Identity column {0} of table {1} cannot be changed to NULLable"}, + {336068883, "Identity column {0} of table {1} cannot have default value"}, + {336068884, "Domain {0} must be of exact number type with zero scale because it's used in an identity column"}, + {336068885, "Generation of generator name failed"}, {336068886, "Parameter {0} in function {1} not found"}, /* dyn_func_param_not_found */ {336068887, "Parameter {0} of routine {1} not found"}, /* dyn_routine_param_not_found */ {336068888, "Parameter {0} of routine {1} is ambiguous (found in both procedures and functions). Use a specifier keyword."}, /* dyn_routine_param_ambiguous */ {336068889, "Collation {0} is used in function {1} (parameter name {2}) and cannot be dropped"}, /* dyn_coll_used_function */ {336068890, "Domain {0} is used in function {1} (parameter name {2}) and cannot be dropped"}, /* dyn_domain_used_function */ {336068891, "ALTER USER requires at least one clause to be specified"}, /* dyn_alter_user_no_clause */ + {336068892, "Cannot delete system SQL role {0}"}, + {336068893, "Column {0} is not an identity column"}, {336068894, "Duplicate {0} {1}"}, /* dyn_duplicate_package_item */ {336068895, "System {0} {1} cannot be modified"}, /* dyn_cant_modify_sysobj */ {336068896, "INCREMENT BY 0 is an illegal option for sequence {0}"}, /* dyn_cant_use_zero_increment */ {336068897, "Can't use {0} in FOREIGN KEY constraint"}, /* dyn_cant_use_in_foreignkey */ {336068898, "Default values for parameters are not allowed in the definition of a previously declared packaged function {0}.{1}"}, /* dyn_defvaldecl_package_func */ + {336068899, "Password must be specified when creating user"}, /* dyn_create_user_no_password */ {336068900, "role {0} can not be granted to role {1}"}, /* dyn_cyclic_role */ + {336068901, "DROP SYSTEM PRIVILEGES should not be used in CREATE ROLE operator"}, + {336068902, "Access to SYSTEM PRIVILEGES in ROLES denied to {0}"}, + {336068903, "Only {0}, DB owner {1} or user with privilege USE_GRANTED_BY_CLAUSE can use GRANTED BY clause"}, {336068904, "INCREMENT BY 0 is an illegal option for identity column {0} of table {1}"}, /* dyn_cant_use_zero_inc_ident */ + {336068905, "Concurrent ALTER DATABASE is not supported"}, /* dyn_concur_alter_database */ + {336068906, "Incompatible ALTER DATABASE clauses: '{0}' and '{1}'"}, /* dyn_incompat_alter_database */ {336068907, "no {0} privilege with grant option on DDL {1}"}, /* dyn_no_ddl_grant_opt_priv */ {336068908, "no {0} privilege with grant option on object {1}"}, /* dyn_no_grant_opt_priv */ {336068909, "Function {0} does not exist"}, /* dyn_func_not_exist */ @@ -1137,6 +1470,7 @@ internal static class IscErrorMessages {336068915, "Exception {0} does not exist"}, /* dyn_exc_not_exist */ {336068916, "Generator/Sequence {0} does not exist"}, /* dyn_gen_not_exist */ {336068917, "Field {0} of table {1} does not exist"}, /* dyn_fld_not_exist */ + {336330752, "could not locate appropriate error message"}, {336330753, "found unknown switch"}, /* gbak_unknown_switch */ {336330754, "page size parameter missing"}, /* gbak_page_size_missing */ {336330755, "Page size specified ({0}) greater than limit (32768 bytes)"}, /* gbak_page_size_toobig */ @@ -1152,6 +1486,10 @@ internal static class IscErrorMessages {336330765, "REPLACE specified, but the first file {0} is a database"}, /* gbak_db_specified */ {336330766, "database {0} already exists. To replace it, use the -REP switch"}, /* gbak_db_exists */ {336330767, "device type not specified"}, /* gbak_unk_device */ + {336330768, "cannot create APOLLO tape descriptor file {0}"}, + {336330769, "cannot set APOLLO tape descriptor attribute for {0}"}, + {336330770, "cannot create APOLLO cartridge descriptor file {0}"}, + {336330771, "cannot close APOLLO tape descriptor file {0}"}, {336330772, "gds_$blob_info failed"}, /* gbak_blob_info_failed */ {336330773, "do not understand BLOB INFO item {0}"}, /* gbak_unk_blob_item */ {336330774, "gds_$get_segment failed"}, /* gbak_get_seg_failed */ @@ -1185,27 +1523,212 @@ internal static class IscErrorMessages {336330802, "unexpected end of file on backup file"}, /* gbak_unexp_eof */ {336330803, "database format {0} is too old to restore to"}, /* gbak_db_format_too_old */ {336330804, "array dimension for column {0} is invalid"}, /* gbak_inv_array_dim */ + {336330805, "expected array version number {0} but instead found {1}"}, + {336330806, "expected array dimension {0} but instead found {1}"}, {336330807, "Expected XDR record length"}, /* gbak_xdr_len_expected */ + {336330808, "Unexpected I/O error while {0} backup file"}, + {336330809, "adding file {0}, starting at page {1}"}, + {336330810, "array"}, + {336330811, "backup"}, + {336330812, " {0}B(ACKUP_DATABASE) backup database to file"}, + {336330813, "\t\tbackup file is compressed"}, + {336330814, " {0}D(EVICE) backup file device type on APOLLO (CT or MT)"}, + {336330815, " {0}M(ETA_DATA) backup or restore metadata only"}, + {336330816, "blob"}, {336330817, "cannot open backup file {0}"}, /* gbak_open_bkup_error */ {336330818, "cannot open status and error output file {0}"}, /* gbak_open_error */ + {336330819, "closing file, committing, and finishing"}, + {336330820, "committing metadata"}, + {336330821, "commit failed on table {0}"}, + {336330822, "committing secondary files"}, + {336330823, "creating index {0}"}, + {336330824, "committing data for table {0}"}, + {336330825, " {0}C(REATE_DATABASE) create database from backup file (restore)"}, + {336330826, "created database {0}, page_size {1} bytes"}, + {336330827, "creating file {0}"}, + {336330828, "creating indexes"}, + {336330829, "database {0} has a page size of {1} bytes."}, + {336330830, " {0}I(NACTIVE) deactivate indexes during restore"}, + {336330831, "do not understand BLOB INFO item {0}"}, + {336330832, "do not recognize {0} attribute {1} -- continuing"}, + {336330833, "error accessing BLOB column {0} -- continuing"}, + {336330834, "Exiting before completion due to errors"}, + {336330835, "Exiting before completion due to errors"}, + {336330836, "column"}, + {336330837, "file"}, + {336330838, "file length"}, + {336330839, "filter"}, + {336330840, "finishing, closing, and going home"}, + {336330841, "function"}, + {336330842, "function argument"}, + {336330843, "gbak version {0}"}, + {336330844, "domain"}, + {336330845, "index"}, + {336330846, "trigger {0} is invalid"}, + {336330847, "legal switches are:"}, + {336330848, "length given for initial file ({0}) is less than minimum ({1})"}, + {336330849, " {0}E(XPAND) no data compression"}, + {336330850, " {0}L(IMBO) ignore transactions in limbo"}, + {336330851, " {0}O(NE_AT_A_TIME) restore one table at a time"}, + {336330852, "opened file {0}"}, + {336330853, " {0}P(AGE_SIZE) override default page size"}, + {336330854, "page size"}, + {336330855, "page size specified ({0} bytes) rounded up to {1} bytes"}, + {336330856, " {0}Z print version number"}, + {336330857, "privilege"}, + {336330858, " {0} records ignored"}, + {336330859, " {0} records restored"}, + {336330860, "{0} records written"}, + {336330861, " {0}Y redirect/suppress status message output"}, + {336330862, "Reducing the database page size from {0} bytes to {1} bytes"}, + {336330863, "table"}, + {336330864, " {0}REP(LACE_DATABASE) replace database from backup file (restore)"}, + {336330865, " {0}V(ERIFY) report each action taken"}, + {336330866, "restore failed for record in table {0}"}, + {336330867, " restoring column {0}"}, + {336330868, " restoring file {0}"}, + {336330869, " restoring filter {0}"}, + {336330870, "restoring function {0}"}, + {336330871, " restoring argument for function {0}"}, + {336330872, " restoring gen id value of: {0}"}, + {336330873, "restoring domain {0}"}, + {336330874, " restoring index {0}"}, + {336330875, " restoring privilege for user {0}"}, + {336330876, "restoring data for table {0}"}, + {336330877, "restoring security class {0}"}, + {336330878, " restoring trigger {0}"}, + {336330879, " restoring trigger message for {0}"}, + {336330880, " restoring type {0} for column {1}"}, + {336330881, "started transaction"}, + {336330882, "starting transaction"}, + {336330883, "security class"}, + {336330884, "switches can be abbreviated to the unparenthesized characters"}, + {336330885, "transportable backup -- data in XDR format"}, + {336330886, "trigger"}, + {336330887, "trigger message"}, + {336330888, "trigger type"}, + {336330889, "unknown switch \"{0}\""}, + {336330890, "validation error on column in table {0}"}, + {336330891, " Version(s) for database \"{0}\""}, + {336330892, "view"}, + {336330893, " writing argument for function {0}"}, + {336330894, " writing data for table {0}"}, + {336330895, " writing gen id of: {0}"}, + {336330896, " writing column {0}"}, + {336330897, " writing filter {0}"}, + {336330898, "writing filters"}, + {336330899, " writing function {0}"}, + {336330900, "writing functions"}, + {336330901, " writing domain {0}"}, + {336330902, "writing domains"}, + {336330903, " writing index {0}"}, + {336330904, " writing privilege for user {0}"}, + {336330905, " writing table {0}"}, + {336330906, "writing tables"}, + {336330907, " writing security class {0}"}, + {336330908, " writing trigger {0}"}, + {336330909, " writing trigger message for {0}"}, + {336330910, "writing trigger messages"}, + {336330911, "writing triggers"}, + {336330912, " writing type {0} for column {1}"}, + {336330913, "writing types"}, + {336330914, "writing shadow files"}, + {336330915, " writing shadow file {0}"}, + {336330916, "writing id generators"}, + {336330917, " writing generator {0} value {1}"}, + {336330918, "readied database {0} for backup"}, + {336330919, "restoring table {0}"}, + {336330920, "type"}, + {336330921, "gbak:"}, + {336330922, "committing metadata for table {0}"}, + {336330923, "error committing metadata for table {0}"}, + {336330924, " {0}K(ILL) restore without creating shadows"}, + {336330925, "cannot commit index {0}"}, + {336330926, "cannot commit files"}, + {336330927, " {0}T(RANSPORTABLE) transportable backup -- data in XDR format"}, + {336330928, "closing file, committing, and finishing. {0} bytes written"}, + {336330929, " {0}G(ARBAGE_COLLECT) inhibit garbage collection"}, + {336330930, " {0}IG(NORE) ignore bad checksums"}, + {336330931, "\tcolumn {0} used in index {1} seems to have vanished"}, + {336330932, "index {0} omitted because {1} of the expected {2} keys were found"}, + {336330933, " {0}FA(CTOR) blocking factor"}, {336330934, "blocking factor parameter missing"}, /* gbak_missing_block_fac */ {336330935, "expected blocking factor, encountered \"{0}\""}, /* gbak_inv_block_fac */ {336330936, "a blocking factor may not be used in conjunction with device CT"}, /* gbak_block_fac_specified */ + {336330937, "restoring generator {0} value: {1}"}, + {336330938, " {0}OL(D_DESCRIPTIONS) save old style metadata descriptions"}, + {336330939, " {0}N(O_VALIDITY) do not restore database validity conditions"}, {336330940, "user name parameter missing"}, /* gbak_missing_username */ {336330941, "password parameter missing"}, /* gbak_missing_password */ + {336330942, " {0}PAS(SWORD) Firebird password"}, + {336330943, " {0}USER Firebird user name"}, + {336330944, "writing stored procedures"}, + {336330945, "writing stored procedure {0}"}, + {336330946, "writing parameter {0} for stored procedure"}, + {336330947, "restoring stored procedure {0}"}, + {336330948, " restoring parameter {0} for stored procedure"}, + {336330949, "writing exceptions"}, + {336330950, "writing exception {0}"}, + {336330951, "restoring exception {0}"}, {336330952, " missing parameter for the number of bytes to be skipped"}, /* gbak_missing_skipped_bytes */ {336330953, "expected number of bytes to be skipped, encountered \"{0}\""}, /* gbak_inv_skipped_bytes */ + {336330954, "adjusting an invalid decompression length from {0} to {1}"}, + {336330955, "skipped {0} bytes after reading a bad attribute {1}"}, + {336330956, " {0}S(KIP_BAD_DATA) skip number of bytes after reading bad data"}, + {336330957, "skipped {0} bytes looking for next valid attribute, encountered attribute {1}"}, + {336330958, "writing table constraints"}, + {336330959, "writing constraint {0}"}, + {336330960, "table constraint"}, + {336330961, "writing referential constraints"}, + {336330962, "writing check constraints"}, + {336330963, "writing character sets"}, /* msgVerbose_write_charsets */ + {336330964, "writing collations"}, /* msgVerbose_write_collations */ {336330965, "character set"}, /* gbak_err_restore_charset */ + {336330966, "writing character set {0}"}, /* msgVerbose_restore_charset */ {336330967, "collation"}, /* gbak_err_restore_collation */ + {336330968, "writing collation {0}"}, /* msgVerbose_restore_collation */ {336330972, "Unexpected I/O error while reading from backup file"}, /* gbak_read_error */ {336330973, "Unexpected I/O error while writing to backup file"}, /* gbak_write_error */ + {336330974, "\n\nCould not open file name \"{0}\""}, + {336330975, "\n\nCould not write to file \"{0}\""}, + {336330976, "\n\nCould not read from file \"{0}\""}, + {336330977, "Done with volume #{0}, \"{1}\""}, + {336330978, "\tPress return to reopen that file, or type a new\n\tname followed by return to open a different file."}, + {336330979, "Type a file name to open and hit return"}, + {336330980, " Name: "}, + {336330981, "\n\nERROR: Backup incomplete"}, + {336330982, "Expected backup start time {0}, found {1}"}, + {336330983, "Expected backup database {0}, found {1}"}, + {336330984, "Expected volume number {0}, found volume {1}"}, {336330985, "could not drop database {0} (no privilege or database might be in use)"}, /* gbak_db_in_use */ + {336330986, "Skipped bad security class entry: {0}"}, + {336330987, "Unknown V3 SUB_TYPE: {0} in FIELD: {1}."}, + {336330988, "Converted V3 sub_type: {0} to character_set_id: {1} and collate_id: {2}."}, + {336330989, "Converted V3 scale: {0} to character_set_id: {1} and callate_id: {2}."}, {336330990, "System memory exhausted"}, /* gbak_sysmemex */ + {336330991, " {0}NT Non-Transportable backup file format"}, + {336330992, "Index \"{0}\" failed to activate because:"}, + {336330993, " The unique index has duplicate values or NULLs."}, + {336330994, " Delete or Update duplicate values or NULLs, and activate index with"}, + {336330995, " ALTER INDEX \"{0}\" ACTIVE;"}, + {336330996, " Not enough disk space to create the sort file for an index."}, + {336330997, " Set the TMP environment variable to a directory on a filesystem that does have enough space, and activate index with"}, + {336330998, "Database is not online due to failure to activate one or more indices."}, + {336330999, "Run gfix -online to bring database online without active indices."}, + {336331000, "writing SQL roles"}, /* write_role_1 */ + {336331001, " writing SQL role: {0}"}, /* write_role_2 */ {336331002, "SQL role"}, /* gbak_restore_role_failed */ + {336331003, " restoring SQL role: {0}"}, /* restore_role */ + {336331004, " {0}RO(LE) Firebird SQL role"}, /* gbak_role_op */ {336331005, "SQL role parameter missing"}, /* gbak_role_op_missing */ + {336331006, " {0}CO(NVERT) backup external files as tables"}, /* gbak_convert_ext_tables */ + {336331007, "gbak: WARNING:"}, /* gbak_warning */ + {336331008, "gbak: ERROR:"}, /* gbak_error */ + {336331009, " {0}BU(FFERS) override page buffers default"}, /* gbak_page_buffers */ {336331010, "page buffers parameter missing"}, /* gbak_page_buffers_missing */ {336331011, "expected page buffers, encountered \"{0}\""}, /* gbak_page_buffers_wrong_param */ {336331012, "page buffers is allowed only on restore or create"}, /* gbak_page_buffers_restore */ + {336331013, "Starting with volume #{0}, \"{1}\""}, {336331014, "size specification either missing or incorrect for file {0}"}, /* gbak_inv_size */ {336331015, "file {0} out of sequence"}, /* gbak_file_outof_sequence */ {336331016, "can't join -- one of the files missing"}, /* gbak_join_file_missing */ @@ -1216,25 +1739,300 @@ internal static class IscErrorMessages {336331021, "can't write a header record to file {0}"}, /* gbak_hdr_write_failed */ {336331022, "free disk space exhausted"}, /* gbak_disk_space_ex */ {336331023, "file size given ({0}) is less than minimum allowed ({1})"}, /* gbak_size_lt_min */ + {336331024, "Warning -- free disk space exhausted for file {0}, the rest of the bytes ({1}) will be written to file {2}"}, {336331025, "service name parameter missing"}, /* gbak_svc_name_missing */ {336331026, "Cannot restore over current database, must be SYSDBA or owner of the existing database."}, /* gbak_not_ownr */ + {336331027, ""}, + {336331028, " {0}USE_(ALL_SPACE) do not reserve space for record versions"}, + {336331029, " {0}SE(RVICE) use services manager"}, + {336331030, " {0}MO(DE) \"read_only\" or \"read_write\" access"}, /* gbak_opt_mode */ {336331031, "\"read_only\" or \"read_write\" required"}, /* gbak_mode_req */ + {336331032, "setting database to read-only access"}, {336331033, "just data ignore all constraints etc."}, /* gbak_just_data */ {336331034, "restoring data only ignoring foreign key, unique, not null & other constraints"}, /* gbak_data_only */ + {336331035, "closing file, committing, and finishing. {0} bytes written"}, + {336331036, " {0}R(ECREATE_DATABASE) [O(VERWRITE)] create (or replace if OVERWRITE used)\\n\t\t\t\tdatabase from backup file (restore)"}, + {336331037, " activating and creating deferred index {0}"}, /* gbak_activating_idx */ + {336331038, "check constraint"}, + {336331039, "exception"}, + {336331040, "array dimensions"}, + {336331041, "generator"}, + {336331042, "procedure"}, + {336331043, "procedure parameter"}, + {336331044, "referential constraint"}, + {336331045, "type (in RDB$TYPES)"}, + {336331046, " {0}NOD(BTRIGGERS) do not run database triggers"}, + {336331047, " {0}TRU(STED) use trusted authentication"}, + {336331048, "writing names mapping"}, /* write_map_1 */ + {336331049, " writing map for {0}"}, /* write_map_2 */ + {336331050, " restoring map for {0}"}, /* get_map_1 */ + {336331051, "name mapping"}, /* get_map_2 */ + {336331052, "cannot restore arbitrary mapping"}, /* get_map_3 */ + {336331053, "restoring names mapping"}, /* get_map_4 */ + {336331054, " {0}FIX_FSS_D(ATA) fix malformed UNICODE_FSS data"}, + {336331055, " {0}FIX_FSS_M(ETADATA) fix malformed UNICODE_FSS metadata"}, + {336331056, "Character set parameter missing"}, + {336331057, "Character set {0} not found"}, + {336331058, " {0}FE(TCH_PASSWORD) fetch password from file"}, + {336331059, "too many passwords provided"}, + {336331060, "could not open password file {0}, errno {1}"}, + {336331061, "could not read password file {0}, errno {1}"}, + {336331062, "empty password file {0}"}, + {336331063, "Attribute {0} was already processed for exception {1}"}, + {336331064, "Skipping attribute {0} because the message already exists for exception {1}"}, + {336331065, "Trying to recover from unexpected attribute {0} due to wrong message length for exception {1}"}, + {336331066, "Attribute not specified for storing text bigger than 255 bytes"}, + {336331067, "Unable to store text bigger than 65536 bytes"}, + {336331068, "Failed while adjusting the security class name"}, + {336331069, "Usage:"}, + {336331070, " gbak -b [backup options] [general options]"}, + {336331071, " gbak -c [restore options] [general options]"}, + {336331072, " = | ... (size in db pages)"}, + {336331073, " = | ... (size in bytes = n[K|M|G])"}, + {336331074, " -recreate overwrite and -replace can be used instead of -c"}, + {336331075, "backup options are:"}, + {336331076, "restore options are:"}, + {336331077, "general options are:"}, {336331078, "verbose interval value parameter missing"}, /* gbak_missing_interval */ {336331079, "verbose interval value cannot be smaller than {0}"}, /* gbak_wrong_interval */ + {336331080, " {0}VERBI(NT) verbose information with explicit interval"}, {336331081, "verify (verbose) and verbint options are mutually exclusive"}, /* gbak_verify_verbint */ {336331082, "option -{0} is allowed only on restore or create"}, /* gbak_option_only_restore */ {336331083, "option -{0} is allowed only on backup"}, /* gbak_option_only_backup */ {336331084, "options -{0} and -{1} are mutually exclusive"}, /* gbak_option_conflict */ {336331085, "parameter for option -{0} was already specified with value \"{1}\""}, /* gbak_param_conflict */ {336331086, "option -{0} was already specified"}, /* gbak_option_repeated */ + {336331087, "writing package {0}"}, + {336331088, "writing packages"}, + {336331089, "restoring package {0}"}, + {336331090, "package"}, {336331091, "dependency depth greater than {0} for view {1}"}, /* gbak_max_dbkey_recursion */ {336331092, "value greater than {0} when calculating length of rdb$db_key for view {1}"}, /* gbak_max_dbkey_length */ {336331093, "Invalid metadata detected. Use -FIX_FSS_METADATA option."}, /* gbak_invalid_metadata */ {336331094, "Invalid data detected. Use -FIX_FSS_DATA option."}, /* gbak_invalid_data */ + {336331095, "text for attribute {0} is too large in {1}, truncating to {2} bytes"}, {336331096, "Expected backup version {1}..{2}. Found {0}"}, /* gbak_inv_bkup_ver2 */ + {336331097, " writing view {0}"}, + {336331098, " table {0} is a view"}, + {336331099, "writing security classes"}, {336331100, "database format {0} is too old to backup"}, /* gbak_db_format_too_old2 */ + {336331101, "backup version is {0}"}, + {336331102, "adjusting system generators"}, + {336331103, "Error closing database, but backup file is OK"}, + {336331104, "database"}, + {336331105, "required mapping attributes are missing in backup file"}, + {336331106, "missing regular expression to skip tables"}, + {336331107, " {0}SKIP_D(ATA) skip data for table"}, + {336331108, "regular expression to skip tables was already set"}, + {336331109, "adjusting views dbkey length"}, + {336331110, "updating ownership of packages, procedures and tables"}, + {336331111, "adding missing privileges"}, + {336331112, "adjusting the ONLINE and FORCED WRITES flags"}, + {336331113, " {0}ST(ATISTICS) TDRW show statistics:"}, + {336331114, " T time from start"}, + {336331115, " D delta time"}, + {336331116, " R page reads"}, + {336331117, " W page writes"}, + {336331118, "statistics parameter missing"}, /* gbak_missing_perf */ + {336331119, "wrong char \"{0}\" at statistics parameter"}, /* gbak_wrong_perf */ + {336331120, "too many chars at statistics parameter"}, /* gbak_too_long_perf */ + {336331121, "total statistics"}, + {336331122, "could not append BLOB data to batch"}, + {336331123, "could not start batch when restoring table {0}, trying old way"}, + {336331124, " {0}KEYNAME name of a key to be used for encryption"}, + {336331125, " {0}CRYPT crypt plugin name"}, + {336331126, " {0}ZIP backup file is in zip compressed format"}, + {336331127, "Keyname parameter missing"}, + {336331128, "Key holder parameter missing but backup file is encrypted"}, + {336331129, "CryptPlugin parameter missing"}, + {336331130, "Unknown crypt plugin name - use -CRYPT switch"}, + {336331131, "Inflate error {0}"}, + {336331132, "Deflate error {0}"}, + {336331133, "Key holder parameter missing"}, + {336331134, " {0}KEYHOLDER name of a key holder plugin"}, + {336331135, "Decompression stream init error {0}"}, + {336331136, "Compression stream init error {0}"}, + {336331137, "Invalid reply from getInfo() when waiting for DB encryption"}, + {336331138, "Problems with just created database encryption"}, + {336331139, "Skipped trigger {0} on system table {1}"}, + {336331140, " {0}INCLUDE(_DATA) backup data of table(s)"}, + {336331141, "missing regular expression to include tables"}, + {336331142, "regular expression to include tables was already set"}, + {336331143, "writing database create grants"}, + {336331144, " database create grant for {0}"}, + {336331145, " restoring database create grant for {0}"}, + {336331146, "restoring database create grants"}, + {336331147, "database create grant"}, + {336331148, "writing publications"}, + {336331149, " writing publication {0}"}, + {336331150, " writing publication for table {0}"}, + {336331151, "restoring publication {0}"}, + {336331152, "publication"}, + {336331153, "restoring publication for table {0}"}, + {336331154, "publication for table"}, + {336331155, " {0}REPLICA \"none\", \"read_only\" or \"read_write\" replica mode"}, /* gbak_opt_replica */ + {336331156, "\"none\", \"read_only\" or \"read_write\" required"}, /* gbak_replica_req */ + {336331157, "could not access batch parameters"}, + {336331158, " {0}PAR(ALLEL) parallel workers"}, + {336331159, "parallel workers parameter missing"}, /* gbak_missing_prl_wrks */ + {336331160, "expected parallel workers, encountered \"{0}\""}, /* gbak_inv_prl_wrks */ + {336331161, " {0}D(IRECT_IO) direct IO for backup file(s)"}, + {336331162, "use up to {0} parallel workers"}, + {336396289, "Firebird error"}, + {336396362, "Rollback not performed"}, + {336396364, "Connection error"}, + {336396365, "Connection not established"}, + {336396366, "Connection authorization failure."}, + {336396375, "deadlock"}, + {336396376, "Unsuccessful execution caused by deadlock."}, + {336396377, "record from transaction {0} is stuck in limbo"}, + {336396379, "operation completed with errors"}, + {336396382, "the SQL statement cannot be executed"}, + {336396384, "Unsuccessful execution caused by an unavailable resource."}, + {336396386, "Unsuccessful execution caused by a system error that precludes successful execution of subsequent statements"}, + {336396387, "Unsuccessful execution caused by system error that does not preclude successful execution of subsequent statements"}, + {336396446, "Wrong numeric type"}, + {336396447, "too many versions"}, + {336396448, "intermediate journal file full"}, + {336396449, "journal file wrong format"}, + {336396450, "database {0} shutdown in {1} seconds"}, + {336396451, "restart shared cache manager"}, + {336396452, "exception {0}"}, + {336396453, "bad checksum"}, + {336396454, "refresh range number {0} not found"}, + {336396455, "expression evaluation not supported"}, + {336396456, "FOREIGN KEY column count does not match PRIMARY KEY"}, + {336396457, "Attempt to define a second PRIMARY KEY for the same table"}, + {336396458, "column used with aggregate"}, + {336396459, "invalid column reference"}, + {336396460, "invalid key position"}, + {336396461, "invalid direction for find operation"}, + {336396462, "Invalid statement handle"}, + {336396463, "invalid lock handle"}, + {336396464, "invalid lock level {0}"}, + {336396465, "invalid bookmark handle"}, + {336396468, "wrong or obsolete version"}, + {336396471, "The INSERT, UPDATE, DELETE, DDL or authorization statement cannot be executed because the transaction is inquiry only"}, + {336396472, "external file could not be opened for output"}, + {336396477, "multiple rows in singleton select"}, + {336396478, "No subqueries permitted for VIEW WITH CHECK OPTION"}, + {336396479, "DISTINCT, GROUP or HAVING not permitted for VIEW WITH CHECK OPTION"}, + {336396480, "Only one table allowed for VIEW WITH CHECK OPTION"}, + {336396481, "No WHERE clause for VIEW WITH CHECK OPTION"}, + {336396482, "Only simple column names permitted for VIEW WITH CHECK OPTION"}, + {336396484, "An error was found in the application program input parameters for the SQL statement."}, + {336396485, "Invalid insert or update value(s): object columns are constrained - no 2 table rows can have duplicate column values"}, + {336396486, "Arithmetic overflow or division by zero has occurred."}, + {336396594, "cannot access column {0} in view {1}"}, + {336396595, "Too many concurrent executions of the same request"}, + {336396596, "maximum indexes per table ({0}) exceeded"}, + {336396597, "new record size of {0} bytes is too big"}, + {336396598, "segments not allowed in expression index {0}"}, + {336396599, "wrong page type"}, + {336396603, "invalid ARRAY or BLOB operation"}, + {336396611, "{0} extension error"}, + {336396624, "key size exceeds implementation restriction for index \"{0}\""}, + {336396625, "definition error for index {0}"}, + {336396628, "cannot create index"}, + {336396651, "duplicate specification of {0} - not supported"}, + {336396663, "The insert failed because a column definition includes validation constraints."}, + {336396670, "Cannot delete object referenced by another object"}, + {336396671, "Cannot modify object referenced by another object"}, + {336396672, "Object is referenced by another object"}, + {336396673, "lock on conflicts with existing lock"}, + {336396681, "This operation is not defined for system tables."}, + {336396683, "Inappropriate self-reference of column"}, + {336396684, "Illegal array dimension range"}, + {336396687, "database or file exists"}, + {336396688, "sort error: corruption in data structure"}, + {336396689, "node not supported"}, + {336396690, "Shadow number must be a positive integer"}, + {336396691, "Preceding file did not specify length, so {0} must include starting page number"}, + {336396692, "illegal operation when at beginning of stream"}, + {336396693, "the current position is on a crack"}, + {336396735, "cannot modify an existing user privilege"}, + {336396736, "user does not have the privilege to perform operation"}, + {336396737, "This user does not have privilege to perform this operation on this object."}, + {336396756, "transaction marked invalid by I/O error"}, + {336396757, "Cannot prepare a CREATE DATABASE/SCHEMA statement"}, + {336396758, "violation of FOREIGN KEY constraint \"{0}\""}, + {336396769, "The prepare statement identifies a prepare statement with an open cursor"}, + {336396770, "Unknown statement or request"}, + {336396778, "Attempt to update non-updatable cursor"}, + {336396780, "The cursor identified in the UPDATE or DELETE statement is not positioned on a row."}, + {336396784, "Unknown cursor"}, + {336396786, "The cursor identified in an OPEN statement is already open."}, + {336396787, "The cursor identified in a FETCH or CLOSE statement is not open."}, + {336396875, "Overflow occurred during data type conversion."}, + {336396881, "null segment of UNIQUE KEY"}, + {336396882, "subscript out of bounds"}, + {336396886, "data operation not supported"}, + {336396887, "invalid comparison operator for find operation"}, + {336396974, "Cannot transliterate character between character sets"}, + {336396975, "count of column list and variable list do not match"}, + {336396985, "Incompatible column/host variable data type"}, + {336396991, "Operation violates CHECK constraint {0} on view or table"}, + {336396992, "internal Firebird consistency check (invalid RDB$CONSTRAINT_TYPE)"}, + {336396993, "Cannot update constraints (RDB$RELATION_CONSTRAINTS)."}, + {336396994, "Cannot delete CHECK constraint entry (RDB$CHECK_CONSTRAINTS)"}, + {336396995, "Cannot update constraints (RDB$CHECK_CONSTRAINTS)."}, + {336396996, "Cannot update constraints (RDB$REF_CONSTRAINTS)."}, + {336396997, "Column used in a PRIMARY constraint must be NOT NULL."}, + {336397004, "index {0} cannot be used in the specified plan"}, + {336397005, "table {0} is referenced in the plan but not the from list"}, + {336397006, "the table {0} is referenced twice; use aliases to differentiate"}, + {336397007, "table {0} is not referenced in plan"}, + {336397027, "Log file specification partition error"}, + {336397028, "Cache or Log redefined"}, + {336397029, "Write-ahead Log with shadowing configuration not allowed"}, + {336397030, "Overflow log specification required for round-robin log"}, + {336397031, "WAL defined; Cache Manager must be started first"}, + {336397033, "Write-ahead Log without shared cache configuration not allowed"}, + {336397034, "Cannot start WAL writer for the database {0}"}, + {336397035, "WAL writer synchronization error for the database {0}"}, + {336397036, "WAL setup error. Please see Firebird log."}, + {336397037, "WAL buffers cannot be increased. Please see Firebird log."}, + {336397038, "WAL writer - Journal server communication error. Please see Firebird log."}, + {336397039, "WAL I/O error. Please see Firebird log."}, + {336397040, "Unable to roll over; please see Firebird log."}, + {336397041, "obsolete"}, + {336397042, "obsolete"}, + {336397043, "obsolete"}, + {336397044, "obsolete"}, + {336397045, "database does not use Write-ahead Log"}, + {336397046, "Cannot roll over to the next log file {0}"}, + {336397047, "obsolete"}, + {336397048, "obsolete"}, + {336397049, "Cache or Log size too small"}, + {336397050, "Log record header too small at offset {0} in log file {1}"}, + {336397051, "Incomplete log record at offset {0} in log file {1}"}, + {336397052, "Unexpected end of log file {0} at offset {1}"}, + {336397053, "Database name in the log file {0} is different"}, + {336397054, "Log file {0} not closed properly; database recovery may be required"}, + {336397055, "Log file {0} not latest in the chain but open flag still set"}, + {336397056, "Invalid version of log file {0}"}, + {336397057, "Log file header of {0} too small"}, + {336397058, "obsolete"}, + {336397069, "table {0} is not defined"}, + {336397080, "invalid ORDER BY clause"}, + {336397082, "Column does not belong to referenced table"}, + {336397083, "column {0} is not defined in table {1}"}, + {336397084, "Undefined name"}, + {336397085, "Ambiguous column reference."}, + {336397116, "function {0} is not defined"}, + {336397117, "Invalid data type, length, or value"}, + {336397118, "Invalid number of arguments"}, + {336397126, "dbkey not available for multi-table views"}, + {336397130, "number of columns does not match select list"}, + {336397131, "must specify column name for view select expression"}, + {336397133, "{0} is not a valid base table of the specified view"}, + {336397137, "This column cannot be updated because it is derived from an SQL function or expression."}, + {336397138, "The object of the INSERT, DELETE or UPDATE statement is a view for which the requested operation is not permitted."}, + {336397183, "Invalid String"}, + {336397184, "Invalid token"}, + {336397185, "Invalid numeric literal"}, + {336397203, "An error occurred while trying to update the security database"}, + {336397204, "non-SQL security class defined"}, {336397205, "ODS versions before ODS{0} are not supported"}, /* dsql_too_old_ods */ {336397206, "Table {0} does not exist"}, /* dsql_table_not_found */ {336397207, "View {0} does not exist"}, /* dsql_view_not_found */ @@ -1365,6 +2163,388 @@ internal static class IscErrorMessages {336397332, "String literal with {0} characters exceeds the maximum length of {1} characters for the {2} character set"}, /* dsql_string_char_length */ {336397333, "Too many BEGIN...END nesting. Maximum level is {0}"}, /* dsql_max_nesting */ {336397334, "RECREATE USER {0} failed"}, /* dsql_recreate_user_failed */ + {336461924, "Row not found for fetch, update or delete, or the result of a query is an empty table."}, + {336461925, "segment buffer length shorter than expected"}, + {336462125, "Datatype needs modification"}, + {336462436, "Duplicate column or domain name found."}, + {336527507, "invalid block type encountered"}, + {336527508, "wrong packet type"}, + {336527509, "cannot map page"}, + {336527510, "request to allocate invalid block type"}, + {336527511, "request to allocate block type larger than maximum size"}, + {336527512, "memory pool free list is invalid"}, + {336527513, "invalid pool id encountered"}, + {336527514, "attempt to release free block"}, + {336527515, "attempt to release block overlapping following free block"}, + {336527516, "attempt to release block overlapping prior free block"}, + {336527517, "cannot sort on a field that does not exist"}, + {336527518, "database file not available"}, + {336527519, "cannot assert logical lock"}, + {336527520, "wrong ACL version"}, + {336527521, "shadow block not found"}, + {336527522, "shadow lock not synchronized properly"}, + {336527523, "root file name not listed for shadow"}, + {336527524, "failed to remove symbol from hash table"}, + {336527525, "cannot find tip page"}, + {336527526, "invalid rsb type"}, + {336527527, "invalid SEND request"}, + {336527528, "looper: action not yet implemented"}, + {336527529, "return data type not supported"}, + {336527530, "unexpected reply from journal server"}, + {336527531, "journal server is incompatible version"}, + {336527532, "journal server refused connection"}, + {336527533, "referenced index description not found"}, + {336527534, "index key too big"}, + {336527535, "partner index description not found"}, + {336527536, "bad difference record"}, + {336527537, "applied differences will not fit in record"}, + {336527538, "record length inconsistent"}, + {336527539, "decompression overran buffer"}, + {336527540, "cannot reposition for update after sort for RMS"}, + {336527541, "external access type not implemented"}, + {336527542, "differences record too long"}, + {336527543, "wrong record length"}, + {336527544, "limbo impossible"}, + {336527545, "wrong record version"}, + {336527546, "record disappeared"}, + {336527547, "cannot delete system tables"}, + {336527548, "cannot update erased record"}, + {336527549, "comparison not supported for specified data types"}, + {336527550, "conversion not supported for specified data types"}, + {336527551, "conversion error"}, + {336527552, "overflow during conversion"}, + {336527553, "null or invalid array"}, + {336527554, "BLOB not found"}, + {336527555, "cannot update old BLOB"}, + {336527556, "relation for array not known"}, + {336527557, "field for array not known"}, + {336527558, "array subscript computation error"}, + {336527559, "expected field node"}, + {336527560, "invalid BLOB ID"}, + {336527561, "cannot find BLOB page"}, + {336527562, "unknown data type"}, + {336527563, "shadow block not found for extend file"}, + {336527564, "index inconsistent"}, + {336527565, "index bucket overfilled"}, + {336527566, "exceeded index level"}, + {336527567, "page already in use"}, + {336527568, "page not accessed for write"}, + {336527569, "attempt to release page not acquired"}, + {336527570, "page in use during flush"}, + {336527571, "attempt to remove page from dirty page list when not there"}, + {336527572, "CCH_precedence: block marked"}, + {336527573, "insufficient cache size"}, + {336527574, "no cache buffers available for reuse"}, + {336527575, "page {0}, page type {1} lock conversion denied"}, + {336527576, "page {0}, page type {1} lock denied"}, + {336527577, "buffer marked for update"}, + {336527578, "CCH: {0}, status = {1} (218)"}, + {336527579, "request of unknown resource"}, + {336527580, "release of unknown resource"}, + {336527581, "(CMP) copy: cannot remap"}, + {336527582, "bad BLR -- invalid stream"}, + {336527583, "argument of scalar operation must be an array"}, + {336527584, "quad word arithmetic not supported"}, + {336527585, "data type not supported for arithmetic"}, + {336527586, "request size limit exceeded"}, + {336527587, "cannot access field {0} in view {1}"}, + {336527588, "cannot access field in view {0}"}, + {336527589, "EVL_assign_to: invalid operation"}, + {336527590, "EVL_bitmap: invalid operation"}, + {336527591, "EVL_boolean: invalid operation"}, + {336527592, "EVL_expr: invalid operation"}, + {336527593, "eval_statistical: invalid operation"}, + {336527594, "Unimplemented conversion, FAO directive O,Z,S"}, + {336527595, "Unimplemented conversion, FAO directive X,U"}, + {336527596, "Error parsing RDB FAO msg string"}, + {336527597, "Error parsing RDB FAO msg str"}, + {336527598, "unknown parameter in RdB status vector"}, + {336527599, "Firebird status vector inconsistent"}, + {336527600, "Firebird/RdB message parameter inconsistency"}, + {336527601, "error parsing RDB FAO message string"}, + {336527602, "unimplemented FAO directive"}, + {336527603, "missing pointer page in DPM_data_pages"}, + {336527604, "Fragment does not exist"}, + {336527605, "pointer page disappeared in DPM_delete"}, + {336527606, "pointer page lost from DPM_delete_relation"}, + {336527607, "missing pointer page in DPM_dump"}, + {336527608, "cannot find record fragment"}, + {336527609, "pointer page vanished from DPM_next"}, + {336527610, "temporary page buffer too small"}, + {336527611, "damaged data page"}, + {336527612, "header fragment length changed"}, + {336527613, "pointer page vanished from extend_relation"}, + {336527614, "pointer page vanished from relation list in locate_space"}, + {336527615, "cannot find free space"}, + {336527616, "pointer page vanished from mark_full"}, + {336527617, "bad record in RDB$PAGES"}, + {336527618, "page slot not empty"}, + {336527619, "bad pointer page"}, + {336527620, "index unexpectedly deleted"}, + {336527621, "scalar operator used on field which is not an array"}, + {336527622, "active"}, + {336527623, "committed"}, + {336527624, "rolled back"}, + {336527625, "in an ill-defined state"}, + {336527626, "next transaction older than oldest active transaction"}, + {336527627, "next transaction older than oldest transaction"}, + {336527628, "buffer marked during cache unwind"}, + {336527629, "error in recovery! database corrupted"}, + {336527630, "error in recovery! wrong data page record"}, + {336527631, "error in recovery! no space on data page"}, + {336527632, "error in recovery! wrong header page record"}, + {336527633, "error in recovery! wrong generator page record"}, + {336527634, "error in recovery! wrong b-tree page record"}, + {336527635, "error in recovery! wrong page inventory page record"}, + {336527636, "error in recovery! wrong pointer page record"}, + {336527637, "error in recovery! wrong index root page record"}, + {336527638, "error in recovery! wrong transaction page record"}, + {336527639, "error in recovery! out of sequence log record encountered"}, + {336527640, "error in recovery! unknown page type"}, + {336527641, "error in recovery! unknown record type"}, + {336527642, "journal server cannot archive to specified archive directory"}, + {336527643, "checksum error in log record when reading from log file"}, + {336527644, "cannot restore singleton select data"}, + {336527645, "lock not found in internal lock manager"}, + {336527646, "size of opt block exceeded"}, + {336527647, "Too many savepoints"}, + {336527648, "garbage collect record disappeared"}, + {336527649, "Unknown BLOB FILTER ACTION_"}, + {336527650, "error during savepoint backout"}, /* savepoint_error */ + {336527651, "cannot find record back version"}, + {336527652, "Illegal user_type."}, + {336527653, "bad ACL"}, + {336527654, "inconsistent LATCH_mark release"}, + {336527655, "inconsistent LATCH_mark call"}, + {336527656, "inconsistent latch downgrade call"}, + {336527657, "bdb is unexpectedly marked"}, + {336527658, "missing exclusive latch"}, + {336527659, "exceeded maximum number of shared latches on a bdb"}, + {336527660, "can't find shared latch"}, + {336527661, "Non-zero use_count of a buffer in the empty que"}, /* cache_non_zero_use_count */ + {336527662, "Unexpected page change from latching"}, /* unexpected_page_change */ + {336527663, "Invalid expression for evaluation"}, + {336527664, "RDB$FLAGS for trigger {0} in RDB$TRIGGERS is corrupted"}, /* rdb$triggers_rdb$flags_corrupt */ + {336527665, "Blobs accounting is inconsistent"}, + {336527666, "Found array data type with more than 16 dimensions"}, + {336658432, "Statement failed, SQLSTATE = {0}"}, /* GEN_ERR */ + {336658433, "usage: isql [options] []"}, /* USAGE */ + {336658434, "Unknown switch: {0}"}, /* SWITCH */ + {336658435, "Use CONNECT or CREATE DATABASE to specify a database"}, /* NO_DB */ + {336658436, "Unable to open {0}"}, /* FILE_OPEN_ERR */ + {336658437, "Commit current transaction (y/n)?"}, /* COMMIT_PROMPT */ + {336658438, "Committing."}, /* COMMIT_MSG */ + {336658439, "Rolling back work."}, /* ROLLBACK_MSG */ + {336658440, "Command error: {0}"}, /* CMD_ERR */ + {336658441, "Enter data or NULL for each column. RETURN to end."}, /* ADD_PROMPT */ + {336658442, "ISQL Version: {0}"}, /* VERSION */ + {336658443, "\t-a(ll) extract metadata incl. legacy non-SQL tables"}, /* USAGE_ALL */ + {336658444, "Number of DB pages allocated = {0}"}, /* NUMBER_PAGES */ + {336658445, "Sweep interval = {0}"}, /* SWEEP_INTERV */ + {336658446, "Number of wal buffers = {0}"}, /* NUM_WAL_BUFF */ + {336658447, "Wal buffer size = {0}"}, /* WAL_BUFF_SIZE */ + {336658448, "Check point length = {0}"}, /* CKPT_LENGTH */ + {336658449, "Check point interval = {0}"}, /* CKPT_INTERV */ + {336658450, "Wal group commit wait = {0}"}, /* WAL_GRPC_WAIT */ + {336658451, "Base level = {0}"}, /* BASE_LEVEL */ + {336658452, "Transaction in limbo = {0}"}, /* LIMBO */ + {336658453, "Frontend commands:"}, /* HLP_FRONTEND */ + {336658454, "BLOBVIEW -- view BLOB in text editor"}, /* HLP_BLOBED */ + {336658455, "BLOBDUMP -- dump BLOB to a file"}, /* HLP_BLOBDMP */ + {336658456, "EDIT [] -- edit SQL script file and execute"}, /* HLP_EDIT */ + {336658457, "INput -- take input from the named SQL file"}, /* HLP_INPUT */ + {336658458, "OUTput [] -- write output to named file"}, /* HLP_OUTPUT */ + {336658459, "SHELL -- execute Operating System command in sub-shell"}, /* HLP_SHELL */ + {336658460, "HELP -- display this menu"}, /* HLP_HELP */ + {336658461, "Set commands:"}, /* HLP_SETCOM */ + {336658462, " SET -- display current SET options"}, /* HLP_SET */ + {336658463, " SET AUTOddl -- toggle autocommit of DDL statements"}, /* HLP_SETAUTO */ + {336658464, " SET BLOB [ALL|] -- display BLOBS of subtype or ALL"}, /* HLP_SETBLOB */ + {336658465, " SET COUNT -- toggle count of selected rows on/off"}, /* HLP_SETCOUNT */ + {336658466, " SET ECHO -- toggle command echo on/off"}, /* HLP_SETECHO */ + {336658467, " SET STATs -- toggle display of performance statistics"}, /* HLP_SETSTAT */ + {336658468, " SET TERM -- change statement terminator string"}, /* HLP_SETTERM */ + {336658469, "SHOW [] -- display system information"}, /* HLP_SHOW */ + {336658470, " = CHECK, COLLATION, DATABASE, DOMAIN, EXCEPTION, FILTER, FUNCTION,"}, /* HLP_OBJTYPE */ + {336658471, "EXIT -- exit and commit changes"}, /* HLP_EXIT */ + {336658472, "QUIT -- exit and roll back changes"}, /* HLP_QUIT */ + {336658473, "All commands may be abbreviated to letters in CAPitals"}, /* HLP_ALL */ + {336658474, "\tSET SCHema/DB -- changes current database"}, /* HLP_SETSCHEMA */ + {336658475, "Yes"}, /* YES_ANS */ + {336658476, "Current memory = !c\nDelta memory = !d\nMax memory = !x\nElapsed time = !e sec\n"}, /* REPORT1 */ + {336658477, "Cpu = !u sec\nBuffers = !b\nReads = !r\nWrites = !w\nFetches = !f"}, /* REPORT2 */ + {336658478, "BLOB display set to subtype {0}. This BLOB: subtype = {1}"}, /* BLOB_SUBTYPE */ + {336658479, "BLOB: {0}, type 'edit' or filename to load>"}, /* BLOB_PROMPT */ + {336658480, "Enter {0} as Y/M/D>"}, /* DATE_PROMPT */ + {336658481, "Enter {0}>"}, /* NAME_PROMPT */ + {336658482, "Bad date {0}"}, /* DATE_ERR */ + {336658483, "CON> "}, /* CON_PROMPT */ + {336658484, " SET LIST -- toggle column or table display format"}, /* HLP_SETLIST */ + {336658485, "{0} not found"}, /* NOT_FOUND */ + {336658486, "Errors occurred (possibly duplicate domains) in creating {0} in {1}"}, /* COPY_ERR */ + {336658487, "Server version too old to support the isql command"}, /* SERVER_TOO_OLD */ + {336658488, "Records affected: {0}"}, /* REC_COUNT */ + {336658489, "Unlicensed for database \"{0}\""}, /* UNLICENSED */ + {336658490, " SET WIDTH [] -- set/unset print width to for column "}, /* HLP_SETWIDTH */ + {336658491, " SET PLAN -- toggle display of query access plan"}, /* HLP_SETPLAN */ + {336658492, " SET TIME -- toggle display of timestamp with DATE values"}, /* HLP_SETTIME */ + {336658493, "EDIT -- edit current command buffer and execute"}, /* HLP_EDIT2 */ + {336658494, "OUTput -- return output to stdout"}, /* HLP_OUTPUT2 */ + {336658495, " SET NAMES -- set name of runtime character set"}, /* HLP_SETNAMES */ + {336658496, " GENERATOR, GRANT, INDEX, PACKAGE, PROCEDURE, ROLE, SQL DIALECT,"}, /* HLP_OBJTYPE2 */ + {336658497, " SET BLOB -- turn off BLOB display"}, /* HLP_SETBLOB2 */ + {336658498, "SET