From d258b3284b26bfcf9f49d26d8c4e54c38005222b Mon Sep 17 00:00:00 2001 From: jogibear9988 Date: Wed, 23 Sep 2026 23:30:03 +0200 Subject: [PATCH] Disambiguate Oracle column alterations for Element identifiers Oracle interprets Element as syntax in an unparenthesized MODIFY clause, blocking KCC migrations with ORA-00903 and ORA-01735. Use the column-list form for default removal and column changes. Add live regressions that preserve existing values and verify new rows no longer receive the removed default; both failed before the fix and pass afterward. Unit and SQLite suites pass 382 tests. --- docs/migration-guide-12.1-to-13.md | 6 ++- .../OracleDefaultSyntaxTests.cs | 43 +++++++++++++++++++ .../Oracle/OracleTransformationProvider.cs | 4 +- 3 files changed, 50 insertions(+), 3 deletions(-) create mode 100644 src/Migrator.Tests/Providers/OracleProvider/OracleDefaultSyntaxTests.cs diff --git a/docs/migration-guide-12.1-to-13.md b/docs/migration-guide-12.1-to-13.md index 560db5c7..4cf37c92 100644 --- a/docs/migration-guide-12.1-to-13.md +++ b/docs/migration-guide-12.1-to-13.md @@ -305,7 +305,11 @@ a UNIQUE table clause. No ownership decision may be inferred from that syntax. Oracle now rejects nonempty `Index.IncludeColumns` and `Index.Clustered = true` before DDL. Version 12.1 silently ignored them. Remove these options for an ordinary Oracle index or author an explicit Oracle-specific design; a SQL Server clustered-index -request is not translated to an Oracle index-organized table. +request is not translated to an Oracle index-organized table. + +Oracle column changes and default removal use `MODIFY (...)`. This disambiguates +valid column names such as `Element`, which Oracle can interpret as syntax in the +unparenthesized form, rejecting the statement with ORA-00903 or ORA-01735. Structured metadata preserves SQL Server nonclustered primary keys and Oracle ordered foreign-key pairs/delete actions. Foreign-key constructor arrays are copied, diff --git a/src/Migrator.Tests/Providers/OracleProvider/OracleDefaultSyntaxTests.cs b/src/Migrator.Tests/Providers/OracleProvider/OracleDefaultSyntaxTests.cs new file mode 100644 index 00000000..9d8f2860 --- /dev/null +++ b/src/Migrator.Tests/Providers/OracleProvider/OracleDefaultSyntaxTests.cs @@ -0,0 +1,43 @@ +using System; +using System.Data; +using DotNetProjects.Migrator.Framework; +using DotNetProjects.Migrator.Providers.Impl.Oracle; +using Migrator.Tests.Settings; +using NUnit.Framework; +using Oracle.ManagedDataAccess.Client; + +namespace Migrator.Tests.Providers.OracleProvider; + +[TestFixture] +[Category("Oracle")] +public class OracleDefaultSyntaxTests +{ + [TestCase(false)] + [TestCase(true)] + public void ElementColumnDefaultCanBeRemoved(bool throughChangeColumn) + { + var connectionString = new ConfigurationReader().GetDatabaseConnectionConfigById("Oracle")?.ConnectionString; + if (string.IsNullOrEmpty(connectionString)) Assert.Ignore("No Oracle connection configured."); + using var connection = new OracleConnection(connectionString); + connection.Open(); + using var provider = new OracleTransformationProvider(new OracleDialect(), connection, null, "default", "Oracle.ManagedDataAccess.Client"); + var table = "Default_" + Guid.NewGuid().ToString("N")[..12]; + provider.AddTable(table, new Column("Id", DbType.Int32), + new Column("Element", DbType.String, 32) { DefaultValue = "fallback" }); + try + { + provider.Insert(table, ["Id"], [1]); + if (throughChangeColumn) + provider.ChangeColumn(table, new Column("Element", DbType.String, 64)); + else + provider.RemoveColumnDefaultValue(table, "Element"); + provider.Insert(table, ["Id"], [2]); + Assert.That(provider.ExecuteScalar("SELECT Element FROM " + table + " WHERE Id=1"), Is.EqualTo("fallback")); + Assert.That(provider.ExecuteScalar("SELECT Element FROM " + table + " WHERE Id=2"), Is.EqualTo(DBNull.Value)); + } + finally + { + provider.RemoveTable(table); + } + } +} diff --git a/src/Migrator/Providers/Impl/Oracle/OracleTransformationProvider.cs b/src/Migrator/Providers/Impl/Oracle/OracleTransformationProvider.cs index 9e163db1..5c123a28 100644 --- a/src/Migrator/Providers/Impl/Oracle/OracleTransformationProvider.cs +++ b/src/Migrator/Providers/Impl/Oracle/OracleTransformationProvider.cs @@ -248,7 +248,7 @@ public override void ChangeColumn(string table, string sqlColumn) table = QuoteTableNameIfRequired(table); - ExecuteNonQuery(string.Format("ALTER TABLE {0} MODIFY {1}", table, sqlColumn)); + ExecuteNonQuery(string.Format("ALTER TABLE {0} MODIFY ({1})", table, sqlColumn)); } public override void AddColumn(string table, string sqlColumn) @@ -655,7 +655,7 @@ public override void CopyDataFromTableToTable(string sourceTableName, List