db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rhille...@apache.org
Subject svn commit: r1330877 - in /db/derby/code/trunk/java: engine/org/apache/derby/impl/store/raw/data/StoredPage.java testing/org/apache/derbyTesting/functionTests/tests/lang/AlterTableTest.java
Date Thu, 26 Apr 2012 14:38:45 GMT
Author: rhillegas
Date: Thu Apr 26 14:38:44 2012
New Revision: 1330877

URL: http://svn.apache.org/viewvc?rev=1330877&view=rev
Log:
DERBY-5679: Fill nonexistent columns with NULLS during update of later column in the row.

Modified:
    db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/data/StoredPage.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/AlterTableTest.java

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/data/StoredPage.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/data/StoredPage.java?rev=1330877&r1=1330876&r2=1330877&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/data/StoredPage.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/data/StoredPage.java Thu
Apr 26 14:38:44 2012
@@ -327,10 +327,15 @@ public class StoredPage extends CachedPa
      *     COLUMN_LONG   - this is a known long column, therefore we will 
      *                     store part of the column on the current page and 
      *                     overflow the rest if necessary.
+     *     COLUMN_CREATE_NULL   - the column was recently added.
+     *                  it doesn't actually exist in the on-disk row yet.
+     *                  we will need to put a null in it as soon as possible.
+     *                  see DERBY-5679.
      **/
     protected static final int COLUMN_NONE  = 0;
     protected static final int COLUMN_FIRST = 1;
     protected static final int COLUMN_LONG  = 2;
+    protected static final int COLUMN_CREATE_NULL  = 3;
 
 
     /**
@@ -3968,12 +3973,14 @@ public class StoredPage extends CachedPa
                     else 
                     {
                         // this is an update that is increasing the number of 
-                        // columns but not providing any value, strange ...
-
+                        // columns but not providing any value. this can happen
+                        // if you are updating a new column after using
+                        // ALTER TABLE to add a couple new columns.
+                        // see DERBY-5679.
                         spaceAvailable = 
                             logColumn(
                                 null, 0, out, spaceAvailable, 
-                                columnFlag, overflowThreshold);
+                                COLUMN_CREATE_NULL, overflowThreshold);
                     }
 
                 } 
@@ -6177,7 +6184,7 @@ public class StoredPage extends CachedPa
             }
         }
 
-        if (column == null)
+        if ( (column == null) && (columnFlag != COLUMN_CREATE_NULL))
         {
             fieldStatus  = StoredFieldHeader.setNonexistent(fieldStatus);
             headerLength =
@@ -6300,11 +6307,28 @@ public class StoredPage extends CachedPa
             }
         
         } 
+        else if ( columnFlag == COLUMN_CREATE_NULL )
+        {
+            //
+            // This block handles the case when a couple columns have been added
+            // recently and now one of the later columns is being updated. Newly added columns
+            // which appear in the row before the updated column don't actually have
+            // any values yet. We stuff NULLs into those newly added columns here.
+            // This fixes DERBY-5679.
+            //
+            fieldStatus = StoredFieldHeader.setNull(fieldStatus, true);
+
+            // header is written with 0 length here.
+            headerLength = 
+                StoredFieldHeader.write(
+                    logicalDataOut, fieldStatus, 
+                    fieldDataLength, slotFieldSize);
+        }
         else if (column instanceof DataValueDescriptor)
         {
             DataValueDescriptor sColumn = (DataValueDescriptor) column;
 
-            boolean isNull = sColumn.isNull();
+            boolean isNull = (columnFlag == COLUMN_CREATE_NULL) || sColumn.isNull();
             if (isNull) 
             {
                 fieldStatus = StoredFieldHeader.setNull(fieldStatus, true);

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/AlterTableTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/AlterTableTest.java?rev=1330877&r1=1330876&r2=1330877&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/AlterTableTest.java
(original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/AlterTableTest.java
Thu Apr 26 14:38:44 2012
@@ -3667,4 +3667,42 @@ public final class AlterTableTest extend
         s.execute("alter table \"\"\"\".\"\"\"\" " +
                   "alter column \"\"\"\" set increment by 2");
     }
+    
+    /**
+     * Verify that rollback works properly if a column with a null default
+     * is added and then the table is updated. See DERBY-5679.
+     */
+    public void test_5679() throws Exception
+    {
+        Statement s = createStatement();
+        ResultSet   rs;
+
+        String[][]  rowBefore = new String[][]{ { "before", null, "before" }  };
+        String[][]  rowAfter = new String[][]{ { "after", "after", "after" }  };
+
+        // create a table, insert a row, add two columns, then update one of the columns
+        s.execute( "create table t_5679(name1 varchar(10))" );
+        s.execute( "insert into t_5679(name1) values('before')" );
+        s.execute( "alter table t_5679 add column str1 varchar(10)" );
+        s.execute( "alter table t_5679 add column str2 varchar(10)" );
+        s.execute( "update t_5679 set str2 = 'before'" );
+
+        rs = s.executeQuery( "select * from t_5679" );
+        JDBC.assertFullResultSet( rs, rowBefore );
+
+        // now update the row and rollback
+        setAutoCommit( false );
+        s.execute( "update t_5679 set name1='after', str1='after', str2='after'" );
+        rs = s.executeQuery( "select * from t_5679" );
+        JDBC.assertFullResultSet( rs, rowAfter );
+        rollback();
+        setAutoCommit( true );
+
+        // all columns of the row should have reverted
+        rs = s.executeQuery( "select * from t_5679" );
+        JDBC.assertFullResultSet( rs, rowBefore );
+
+        s.execute( "drop table t_5679" );
+    }
+    
 }



Mime
View raw message