You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by mi...@apache.org on 2007/07/12 23:36:38 UTC

svn commit: r555778 - in /db/derby/code/trunk/java: engine/org/apache/derby/impl/store/access/heap/Heap_v10_2.java testing/org/apache/derbyTesting/functionTests/tests/upgradeTests/Changes10_3.java

Author: mikem
Date: Thu Jul 12 14:36:37 2007
New Revision: 555778

URL: http://svn.apache.org/viewvc?view=rev&rev=555778
Log:
DERBY-2931

In soft upgrade mode the format id of the new heap format was being written
out along with the old format metadata.  On reboot system would try to read
new format and fail.  Problem was that wrong format id was associated with
the soft upgrade version of the heap conglomerate class (Heap_v10_2.java).

The code change is just changing that format id from 
StoredFormatIds.ACCESS_HEAP_V3_ID to StoredFormatIds.ACCESS_HEAP_V2_ID.  The
rest of the changes is comments in the code and updates to the upgrade test
suite.  The changes to the upgrade suite showed the problem before the fix in
both 10.3 branch and trunk and then passed once the fix was applied.  Adding
those tests actually caused some other tests in the upgrade suite to fail 
which passed previously, and those cases were also fixed by this change.


Modified:
    db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/heap/Heap_v10_2.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/upgradeTests/Changes10_3.java

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/heap/Heap_v10_2.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/heap/Heap_v10_2.java?view=diff&rev=555778&r1=555777&r2=555778
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/heap/Heap_v10_2.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/heap/Heap_v10_2.java Thu Jul 12 14:36:37 2007
@@ -35,18 +35,46 @@
  * @format_id ACCESS_HEAP_V2_ID
  *
  * @purpose   The tag that describes the on disk representation of the Heap
- *            conglomerate object.  The Heap conglomerate object is stored in
- *            a field of a row in the Conglomerate directory.
+ *            conglomerate object.  Access contains no "directory" of 
+ *            conglomerate information.  In order to bootstrap opening a file
+ *            it encodes the factory that can open the conglomerate in the 
+ *            conglomerate id itself.  There exists a single HeapFactory which
+ *            must be able to read all heap format id's.  
+ *
+ *            This format was used for all Derby database Heap's in version
+ *            10.2 and previous versions.
  *
  * @upgrade   The format id of this object is currently always read from disk
- *            as a separate column in the conglomerate directory.  To read
- *            A conglomerate object from disk and upgrade it to the current
- *            version do the following:
+ *            as the first field of the conglomerate itself.  A bootstrap
+ *            problem exists as we don't know the format id of the heap 
+ *            until we are in the "middle" of reading the Heap.  Thus the
+ *            base Heap implementation must be able to read and write 
+ *            all formats based on the reading the 
+ *            "format_of_this_conglomerate". 
+ *
+ *            soft upgrade to ACCESS_HEAP_V3_ID:
+ *                read:
+ *                    old format is readable by current Heap implementation,
+ *                    with automatic in memory creation of default collation
+ *                    id needed by new format.  No code other than
+ *                    readExternal and writeExternal need know about old format.
+ *                write:
+ *                    will never write out new format id in soft upgrade mode.
+ *                    Code in readExternal and writeExternal handles writing
+ *                    correct version.  Code in the factory handles making
+ *                    sure new conglomerates use the Heap_v10_2 class
+ *                    that will write out old format info.
  *
- *                format_id = get format id from a separate column
- *                Upgradable conglom_obj = instantiate empty obj(format_id)
- *                read in conglom_obj from disk
- *                conglom = conglom_obj.upgradeToCurrent();
+ *            hard upgrade to ACCESS_HEAP_V3_ID:
+ *                read:
+ *                    old format is readable by current Heap implementation,
+ *                    with automatic in memory creation of default collation
+ *                    id needed by new format.
+ *                write:
+ *                    Only "lazy" upgrade will happen.  New format will only
+ *                    get written for new conglomerate created after the 
+ *                    upgrade.  Old conglomerates continue to be handled the
+ *                    same as soft upgrade.
  *
  * @disk_layout
  *     format_of_this_conlgomerate(byte[])
@@ -79,17 +107,17 @@
     /**
      * Return my format identifier.
      * <p>
-     * This identifier was used for Heap in all Derby versions prior to and
-     * including 10.2.  Databases hard upgraded to a version subsequent
-     * to 10.2 will write the new format, see Heap.  Databases created in
-     * a version subsequent to 10.2 will also write the new formate, see
-     * Heap.
+     * This identifier was used for Heap in all Derby versions prior to 10.3.
+     * Databases hard upgraded to a version 10.3 and later will write the new 
+     * format, see Heap.  Databases created in 10.3 and later will also write 
+     * the new format, see Heap.
      *
      * @see org.apache.derby.iapi.services.io.TypedFormat#getTypeFormatId
      **/
 	public int getTypeFormatId() 
     {
-		return StoredFormatIds.ACCESS_HEAP_V3_ID;
+        // return identifier used for Heap in all derby versions prior to 10.3
+		return StoredFormatIds.ACCESS_HEAP_V2_ID;
 	}
 
     /**

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/upgradeTests/Changes10_3.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/upgradeTests/Changes10_3.java?view=diff&rev=555778&r1=555777&r2=555778
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/upgradeTests/Changes10_3.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/upgradeTests/Changes10_3.java Thu Jul 12 14:36:37 2007
@@ -31,6 +31,8 @@
 import junit.framework.TestSuite;
 import org.apache.derbyTesting.junit.SupportFilesSetup;
 import org.apache.derbyTesting.junit.JDBC;
+import org.apache.derbyTesting.junit.JDBCDataSource;
+import org.apache.derbyTesting.junit.TestConfiguration;
 
 import org.apache.derbyTesting.functionTests.tests.jdbcapi.BlobStoredProcedureTest;
 import org.apache.derbyTesting.functionTests.tests.jdbcapi.ClobStoredProcedureTest;
@@ -80,7 +82,50 @@
     }
     
 
+    /**
+     * Make sure table created in soft upgrade mode can be 
+     * accessed after shutdown.  DERBY-2931
+     * @throws SQLException
+     */
+    public void testCreateTable() throws SQLException
+    {
+        
+        Statement stmt = createStatement();
+        try {
+            stmt.executeUpdate("DROP table t");
+        } catch (SQLException se) {
+            // ignore table does not exist error on
+            // on drop table.
+            assertSQLState("42Y55",se ); 
+        }
+        stmt.executeUpdate("CREATE TABLE T (I INT)");
+        TestConfiguration.getCurrent().shutdownDatabase();
+        stmt = createStatement();
+        ResultSet rs = stmt.executeQuery("SELECT * from t");
+        JDBC.assertEmpty(rs);  
+        rs.close();
+    }
     
+    public void testIndex() throws SQLException 
+    {
+        Statement stmt = createStatement();
+        try {
+            stmt.executeUpdate("DROP table ti");
+        } catch (SQLException se) {
+            // ignore table does not exist error on
+            // on drop table.
+            assertSQLState("42Y55",se ); 
+        }
+        stmt.executeUpdate("CREATE TABLE TI (I INT primary key not null)");
+        stmt.executeUpdate("INSERT INTO  TI values(1)");
+        stmt.executeUpdate("INSERT INTO  TI values(2)");
+        stmt.executeUpdate("INSERT INTO  TI values(3)");
+        TestConfiguration.getCurrent().shutdownDatabase();
+        stmt = createStatement();
+        ResultSet rs = stmt.executeQuery("SELECT * from TI ORDER BY I");
+        JDBC.assertFullResultSet(rs, new String[][] {{"1"},{"2"},{"3"}});
+        rs.close();        
+    }
     /**
      * Verify the compilation schema is nullable after upgrade to 10.3
      * or later. (See DERBY-630)
@@ -360,6 +405,125 @@
         }
 
         assertEquals( "Reloading results.", shouldSucceed, didSucceed );
+    }
+
+    /**
+     * Check if we can open the heap.
+     * <p>
+     * This test just does a simple select to verify that 10.3 heap conglomerate
+     * format id's are working right for all the various upgrade scenarios.
+     **/
+    private void checkNewHeap(
+    String  tableName,
+    String  value)
+        throws SQLException
+    {
+        // verify table has correct data after performing import/export.
+        Statement s = createStatement();
+        ResultSet rs = s.executeQuery("select * from " + tableName);
+        JDBC.assertFullResultSet(rs, new String[][] {{value}});
+        s.close();
+        rs.close();
+    }
+
+    /**
+     * Test that new format id for Heap is not used in soft upgrade.
+     **/
+    public void testNewHeap()
+        throws SQLException
+    {
+        // create tables in all 3 phases: boot old db, after 1st soft upgrade,
+        // and after hard upgrade.
+        switch (getPhase())
+        {
+            case PH_CREATE: 
+            {
+                // setup create of testNewHeap1 in old db
+
+                Statement s = createStatement();
+                s.execute("create table testNewHeap1(keycol char(20))");
+                s.close();
+                PreparedStatement insert_stmt = 
+                    prepareStatement("insert into testNewHeap1 values(?)");;
+                insert_stmt.setString(1, "create"); 
+                insert_stmt.execute();
+                insert_stmt.close();
+
+                break;
+            }
+
+            case PH_SOFT_UPGRADE:
+            {
+                // setup create of testNewHeap2 once soft upgrade to current
+                // version has happened.
+
+                Statement s = createStatement();
+                s.execute("create table testNewHeap2(keycol char(20))");
+                s.close();
+                PreparedStatement insert_stmt = 
+                    prepareStatement("insert into testNewHeap2 values(?)");;
+                insert_stmt.setString(1, "soft"); 
+                insert_stmt.execute();
+                insert_stmt.close();
+
+                break;
+            }
+
+            case PH_HARD_UPGRADE:
+            {
+                // setup create of testNewHeap3 once hard upgrade to current
+                // version has happened.
+
+                Statement s = createStatement();
+                s.execute("create table testNewHeap3(keycol char(20))");
+                s.close();
+                PreparedStatement insert_stmt = 
+                    prepareStatement("insert into testNewHeap3 values(?)");
+                insert_stmt.setString(1, "hard"); 
+                insert_stmt.execute();
+                insert_stmt.close();
+
+                break;
+            }
+        }
+
+        // Now verify you can access the tables 
+        switch (getPhase())
+        {
+            case PH_CREATE: 
+            {
+                checkNewHeap("testNewHeap1", "create");
+                break;
+            }
+            case PH_SOFT_UPGRADE:
+            {
+                checkNewHeap("testNewHeap1", "create");
+                checkNewHeap("testNewHeap2", "soft");
+                break;
+            }
+            case PH_POST_SOFT_UPGRADE:
+            {
+                checkNewHeap("testNewHeap1", "create");
+                checkNewHeap("testNewHeap2", "soft");
+                break;
+            }
+            case PH_HARD_UPGRADE:
+            {
+                checkNewHeap("testNewHeap1", "create");
+                checkNewHeap("testNewHeap2", "soft");
+                checkNewHeap("testNewHeap3", "hard");
+                break;
+            }
+
+            case PH_POST_HARD_UPGRADE:
+            {
+                checkNewHeap("testNewHeap1", "create");
+                checkNewHeap("testNewHeap2", "soft");
+                checkNewHeap("testNewHeap3", "hard");
+                break;
+            }
+        }
+
     }
     
 }