Fixes to Db2 & Sql Server platforms and the model comparator

git-svn-id: https://svn.apache.org/repos/asf/db/ddlutils/trunk@630531 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/src/java/org/apache/ddlutils/alteration/AddIndexChange.java b/src/java/org/apache/ddlutils/alteration/AddIndexChange.java
index e727ad1..21c1ab0 100644
--- a/src/java/org/apache/ddlutils/alteration/AddIndexChange.java
+++ b/src/java/org/apache/ddlutils/alteration/AddIndexChange.java
@@ -19,9 +19,11 @@
  * under the License.

  */

 

-import org.apache.ddlutils.DdlUtilsException;

+import org.apache.ddlutils.model.Column;

 import org.apache.ddlutils.model.Database;

 import org.apache.ddlutils.model.Index;

+import org.apache.ddlutils.model.IndexColumn;

+import org.apache.ddlutils.model.Table;

 

 /**

  * Represents the addition of an index to a table.

@@ -60,16 +62,15 @@
      */

     public void apply(Database model, boolean caseSensitive)

     {

-        Index newIndex = null;

+        Table table = findChangedTable(model, caseSensitive);

 

-        try

+        table.addIndex(_newIndex);

+        for (int idx = 0; idx < _newIndex.getColumnCount(); idx++)

         {

-            newIndex = (Index)_newIndex.clone();

+            IndexColumn idxColumn = _newIndex.getColumn(idx);

+            Column      tmpColumn = idxColumn.getColumn();

+

+            idxColumn.setColumn(table.findColumn(tmpColumn.getName(), caseSensitive));

         }

-        catch (CloneNotSupportedException ex)

-        {

-            throw new DdlUtilsException(ex);

-        }

-        findChangedTable(model, caseSensitive).addIndex(newIndex);

     }

 }

diff --git a/src/java/org/apache/ddlutils/alteration/ModelComparator.java b/src/java/org/apache/ddlutils/alteration/ModelComparator.java
index 1b4972e..8102a9c 100644
--- a/src/java/org/apache/ddlutils/alteration/ModelComparator.java
+++ b/src/java/org/apache/ddlutils/alteration/ModelComparator.java
@@ -239,13 +239,15 @@
         {

             Table targetTable       = targetModel.getTable(tableIdx);

             Table intermediateTable = intermediateModel.findTable(targetTable.getName(), _caseSensitive);

+            Table sourceTable       = sourceModel.findTable(targetTable.getName(), _caseSensitive);

 

             for (int fkIdx = 0; fkIdx < targetTable.getForeignKeyCount(); fkIdx++)

             {

                 ForeignKey targetFk       = targetTable.getForeignKey(fkIdx);

                 ForeignKey intermediateFk = findCorrespondingForeignKey(intermediateTable, targetFk);

+                ForeignKey sourceFk       = sourceTable == null ? null : findCorrespondingForeignKey(sourceTable, targetFk);

 

-                if (intermediateFk == null)

+                if ((sourceFk == null) && (intermediateFk == null))

                 {

                     if (_log.isInfoEnabled())

                     {

@@ -515,10 +517,11 @@
 

         for (int indexIdx = 0; indexIdx < targetTable.getIndexCount(); indexIdx++)

         {

-            Index targetIndex = targetTable.getIndex(indexIdx);

-            Index sourceIndex = findCorrespondingIndex(intermediateTable, targetIndex);

+            Index targetIndex       = targetTable.getIndex(indexIdx);

+            Index intermediateIndex = findCorrespondingIndex(intermediateTable, targetIndex);

+            Index sourceIndex       = findCorrespondingIndex(sourceTable, targetIndex);

 

-            if (sourceIndex == null)

+            if ((sourceIndex == null) && (intermediateIndex == null))

             {

                 if (_log.isInfoEnabled())

                 {

diff --git a/src/java/org/apache/ddlutils/platform/db2/Db2Builder.java b/src/java/org/apache/ddlutils/platform/db2/Db2Builder.java
index f56aa4c..1476992 100644
--- a/src/java/org/apache/ddlutils/platform/db2/Db2Builder.java
+++ b/src/java/org/apache/ddlutils/platform/db2/Db2Builder.java
@@ -23,6 +23,7 @@
 import java.sql.Types;
 
 import org.apache.ddlutils.Platform;
+import org.apache.ddlutils.alteration.ColumnDefinitionChange;
 import org.apache.ddlutils.model.Column;
 import org.apache.ddlutils.model.Index;
 import org.apache.ddlutils.model.Table;
@@ -130,7 +131,8 @@
         String sourceNativeType = getBareNativeType(sourceColumn);
         String targetNativeType = getBareNativeType(targetColumn);
 
-        if (sourceNativeType.equals(targetNativeType))
+        if (sourceNativeType.equals(targetNativeType) &&
+            !ColumnDefinitionChange.isSizeChanged(getPlatformInfo(), sourceColumn, targetColumn))
         {
             printIdentifier(getColumnName(sourceColumn));
         }
diff --git a/src/java/org/apache/ddlutils/platform/mssql/MSSqlBuilder.java b/src/java/org/apache/ddlutils/platform/mssql/MSSqlBuilder.java
index 01bd8e5..4ee6428 100644
--- a/src/java/org/apache/ddlutils/platform/mssql/MSSqlBuilder.java
+++ b/src/java/org/apache/ddlutils/platform/mssql/MSSqlBuilder.java
@@ -27,6 +27,7 @@
 
 import org.apache.commons.lang.StringUtils;
 import org.apache.ddlutils.Platform;
+import org.apache.ddlutils.alteration.ColumnDefinitionChange;
 import org.apache.ddlutils.model.Column;
 import org.apache.ddlutils.model.Database;
 import org.apache.ddlutils.model.ForeignKey;
@@ -511,4 +512,26 @@
         print("END");
         printEndOfStatement();
     }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected void writeCastExpression(Column sourceColumn, Column targetColumn) throws IOException
+    {
+        boolean sizeChanged = ColumnDefinitionChange.isSizeChanged(getPlatformInfo(), sourceColumn, targetColumn);
+        boolean typeChanged = ColumnDefinitionChange.isTypeChanged(getPlatformInfo(), sourceColumn, targetColumn);
+
+        if (sizeChanged || typeChanged)
+        {
+            print("CAST(");
+            printIdentifier(getColumnName(sourceColumn));
+            print(" AS ");
+            print(getSqlType(targetColumn));
+            print(")");
+        }
+        else
+        {
+            printIdentifier(getColumnName(sourceColumn));
+        }
+    }
 }
diff --git a/src/java/org/apache/ddlutils/platform/mssql/MSSqlModelComparator.java b/src/java/org/apache/ddlutils/platform/mssql/MSSqlModelComparator.java
index 4a6c113..4c463ac 100644
--- a/src/java/org/apache/ddlutils/platform/mssql/MSSqlModelComparator.java
+++ b/src/java/org/apache/ddlutils/platform/mssql/MSSqlModelComparator.java
@@ -36,6 +36,7 @@
 import org.apache.ddlutils.model.Database;
 import org.apache.ddlutils.model.ForeignKey;
 import org.apache.ddlutils.model.Index;
+import org.apache.ddlutils.model.IndexColumn;
 import org.apache.ddlutils.model.Table;
 import org.apache.ddlutils.util.StringUtils;
 
diff --git a/src/java/org/apache/ddlutils/platform/mssql/MSSqlPlatform.java b/src/java/org/apache/ddlutils/platform/mssql/MSSqlPlatform.java
index b19e160..7b040b9 100644
--- a/src/java/org/apache/ddlutils/platform/mssql/MSSqlPlatform.java
+++ b/src/java/org/apache/ddlutils/platform/mssql/MSSqlPlatform.java
@@ -211,7 +211,10 @@
                     Column                 curColumn    = intermediateTable.findColumn(colDefChange.getChangedColumn(), isDelimitedIdentifierModeOn());

 

                     // Sql Server has no way of adding or removing an IDENTITY constraint

-                    return curColumn.isAutoIncrement() == colDefChange.getNewColumn().isAutoIncrement();

+                    // Also, reducing the size of a column should be handled by recreation to avoid truncation errors 

+                    return (curColumn.isAutoIncrement() == colDefChange.getNewColumn().isAutoIncrement()) &&

+                           (ColumnDefinitionChange.isTypeChanged(getPlatformInfo(), curColumn, colDefChange.getNewColumn()) ||

+                           !ColumnDefinitionChange.isSizeChanged(getPlatformInfo(), curColumn, colDefChange.getNewColumn()));

                 }

                 else

                 {

diff --git a/src/java/org/apache/ddlutils/platform/postgresql/PostgreSqlBuilder.java b/src/java/org/apache/ddlutils/platform/postgresql/PostgreSqlBuilder.java
index 064e84b..8655911 100644
--- a/src/java/org/apache/ddlutils/platform/postgresql/PostgreSqlBuilder.java
+++ b/src/java/org/apache/ddlutils/platform/postgresql/PostgreSqlBuilder.java
@@ -23,6 +23,7 @@
 import java.util.Map;
 
 import org.apache.ddlutils.Platform;
+import org.apache.ddlutils.alteration.ColumnDefinitionChange;
 import org.apache.ddlutils.model.Column;
 import org.apache.ddlutils.model.Database;
 import org.apache.ddlutils.model.Index;
@@ -198,4 +199,26 @@
             dropAutoIncrementSequence(table, column);
         }
     }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected void writeCastExpression(Column sourceColumn, Column targetColumn) throws IOException
+    {
+        boolean sizeChanged = ColumnDefinitionChange.isSizeChanged(getPlatformInfo(), sourceColumn, targetColumn);
+        boolean typeChanged = ColumnDefinitionChange.isTypeChanged(getPlatformInfo(), sourceColumn, targetColumn);
+
+        if (sizeChanged || typeChanged)
+        {
+            print("CAST(");
+            printIdentifier(getColumnName(sourceColumn));
+            print(" AS ");
+            print(getSqlType(targetColumn));
+            print(")");
+        }
+        else
+        {
+            printIdentifier(getColumnName(sourceColumn));
+        }
+    }
 }
diff --git a/src/test/org/apache/ddlutils/io/TestChangeColumn.java b/src/test/org/apache/ddlutils/io/TestChangeColumn.java
index bbd1783..0a2e68a 100644
--- a/src/test/org/apache/ddlutils/io/TestChangeColumn.java
+++ b/src/test/org/apache/ddlutils/io/TestChangeColumn.java
@@ -20,7 +20,6 @@
  */

 

 import java.math.BigDecimal;

-import java.math.BigInteger;

 import java.sql.Timestamp;

 import java.text.ParseException;

 import java.util.Date;

@@ -3107,6 +3106,9 @@
         Object    value = isSybase ? (Object)new BigDecimal("0") : new Integer(0);

         Timestamp time  = new Timestamp(new Date().getTime());

 

+        // to avoid problems with the database's time resolution

+        time.setNanos(0);

+

         insertRow("roundtrip", new Object[] { new Integer(1), value, time });

 

         alterDatabase(model2Xml);

@@ -3289,6 +3291,9 @@
 

         Timestamp time  = new Timestamp(new Date().getTime());

 

+        // to avoid problems with the database's time resolution

+        time.setNanos(0);

+

         insertRow("roundtrip", new Object[] { new Integer(1), null, time });

 

         alterDatabase(model2Xml);