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 rh...@apache.org on 2009/06/22 18:42:30 UTC

svn commit: r787310 - in /db/derby/code/trunk/java: engine/org/apache/derby/impl/sql/catalog/ testing/org/apache/derbyTesting/functionTests/tests/upgradeTests/

Author: rhillegas
Date: Mon Jun 22 16:42:29 2009
New Revision: 787310

URL: http://svn.apache.org/viewvc?rev=787310&view=rev
Log:
DERBY-4214: Fix signature of CLOBGETSUBSTRING during hard-upgrade to 10.6.

Modified:
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/DD_Version.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/DataDictionaryImpl.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/upgradeTests/Changes10_6.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/upgradeTests/Version.java

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/DD_Version.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/DD_Version.java?rev=787310&r1=787309&r2=787310&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/DD_Version.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/DD_Version.java Mon Jun 22 16:42:29 2009
@@ -451,6 +451,19 @@
             bootingDictionary.create_10_5_system_procedures(tc, newlyCreatedRoutines);
         }
 
+        // change the return type of SYSIBM.CLOBGETSUBSTRING if necessary. See
+        // DERBY-4214. That function was added in 10.3 and the return type was
+        // changed (but not upgraded) in 10.5. We can't distinguish
+        // between databases which were originally created by 10.5 and databases
+        // which were upgraded to 10.5.
+        if (
+            ( fromMajorVersionNumber > DataDictionary.DD_VERSION_DERBY_10_2) &&
+            ( fromMajorVersionNumber < DataDictionary.DD_VERSION_DERBY_10_6)
+            )
+        {
+            bootingDictionary.upgradeCLOBGETSUBSTRING_10_6( tc );
+        }
+        
         // Grant PUBLIC access to some system routines
         bootingDictionary.grantPublicAccessToSystemRoutines(newlyCreatedRoutines, tc, aid);
 	}

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/DataDictionaryImpl.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/DataDictionaryImpl.java?rev=787310&r1=787309&r2=787310&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/DataDictionaryImpl.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/DataDictionaryImpl.java Mon Jun 22 16:42:29 2009
@@ -2410,6 +2410,77 @@
 					 tc);
 	}
 
+    /**
+     * 10.6 upgrade logic to update the return type of SYSIBM.CLOBGETSUBSTRING. The length of the
+     * return type was changed in 10.5 but old versions of the metadata were not
+     * upgraded at that time. See DERBY-4214.
+     */
+    void upgradeCLOBGETSUBSTRING_10_6( TransactionController tc )
+        throws StandardException
+    {
+		TabInfoImpl          ti = getNonCoreTI(SYSALIASES_CATALOG_NUM);
+		ExecIndexRow         keyRow = exFactory.getIndexableRow(3);
+		DataValueDescriptor  aliasNameOrderable = new SQLVarchar( "CLOBGETSUBSTRING" );;
+		DataValueDescriptor	 nameSpaceOrderable = new SQLChar
+            ( new String( new char[] { AliasInfo.ALIAS_TYPE_FUNCTION_AS_CHAR } ) );
+        
+		keyRow.setColumn(1, new SQLChar( SchemaDescriptor.SYSIBM_SCHEMA_UUID ));
+		keyRow.setColumn(2, aliasNameOrderable);
+		keyRow.setColumn(3, nameSpaceOrderable);
+
+        AliasDescriptor      oldAD = (AliasDescriptor) getDescriptorViaIndex
+            (
+             SYSALIASESRowFactory.SYSALIASES_INDEX1_ID,
+             keyRow,
+             (ScanQualifier [][]) null,
+             ti,
+             (TupleDescriptor) null,
+             (List) null,
+             true,
+             TransactionController.ISOLATION_REPEATABLE_READ,
+             tc);
+        RoutineAliasInfo   oldRai = (RoutineAliasInfo) oldAD.getAliasInfo();
+        TypeDescriptor     newReturnType = DataTypeDescriptor.getCatalogType( Types.VARCHAR, LOBStoredProcedure.MAX_CLOB_RETURN_LEN );
+        RoutineAliasInfo   newRai = new RoutineAliasInfo
+            (
+             oldRai.getMethodName(),
+             oldRai.getParameterCount(),
+             oldRai.getParameterNames(),
+             oldRai.getParameterTypes(),
+             oldRai.getParameterModes(),
+             oldRai.getMaxDynamicResultSets(),
+             oldRai.getParameterStyle(),
+             oldRai.getSQLAllowed(),
+             oldRai.isDeterministic(),
+             oldRai.calledOnNullInput(),
+             newReturnType
+             );
+        AliasDescriptor      newAD = new AliasDescriptor
+            (
+             this,
+             oldAD.getUUID(),
+             oldAD.getObjectName(),
+             oldAD.getSchemaUUID(),
+             oldAD.getJavaClassName(),
+             oldAD.getAliasType(),
+             oldAD.getNameSpace(),
+             oldAD.getSystemAlias(),
+             newRai,
+             oldAD.getSpecificName()
+             );
+        ExecRow             newRow = ti.getCatalogRowFactory().makeRow( newAD, null );
+
+		ti.updateRow
+            (
+             keyRow,
+             newRow, 
+             SYSALIASESRowFactory.SYSALIASES_INDEX1_ID,
+             new boolean[] { false, false, false },
+             (int[])null,
+             tc
+             );
+    }
+
 	/**
 	 * Drop all table descriptors for a schema.
 	 *

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/upgradeTests/Changes10_6.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/upgradeTests/Changes10_6.java?rev=787310&r1=787309&r2=787310&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/upgradeTests/Changes10_6.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/upgradeTests/Changes10_6.java Mon Jun 22 16:42:29 2009
@@ -23,16 +23,22 @@
 import org.apache.derbyTesting.junit.SupportFilesSetup;
 
 import org.apache.derbyTesting.junit.JDBCDataSource;
+import java.lang.reflect.Method;
 import java.sql.SQLException;
 import java.sql.Statement;
 import java.sql.Connection;
 import java.sql.CallableStatement;
+import java.sql.ResultSet;
 
 import javax.sql.DataSource;
 
 import junit.framework.Test;
 import junit.framework.TestSuite;
 
+import org.apache.derby.catalog.types.RoutineAliasInfo;
+import org.apache.derby.catalog.TypeDescriptor;
+
+
 /**
  * Upgrade test cases for 10.6.
  * If the old version is 10.6 or later then these tests
@@ -109,4 +115,95 @@
         }
     }
 
+    /**
+     * Make sure that SYSIBM.CLOBGETSUBSTRING has the correct return value.
+     * See https://issues.apache.org/jira/browse/DERBY-4214
+     */
+    public void testCLOBGETSUBSTRING() throws Exception
+    {
+        Version initialVersion = new Version( getOldMajor(), getOldMinor(), 0, 0 );
+        Version firstVersionHavingThisFunction = new Version( 10, 3, 0, 0 );
+        Version firstVersionHavingCorrectReturnType = new Version( 10, 5, 0, 0 );
+        int     wrongLength = 32672;
+        int     correctLength = 10890;
+        int     actualJdbcType;
+        int     actualLength;
+        
+        Object   returnType;
+
+        boolean hasFunction = initialVersion.compareTo( firstVersionHavingThisFunction ) >= 0;
+        boolean hasCorrectReturnType = initialVersion.compareTo( firstVersionHavingCorrectReturnType ) >= 0;
+        
+    	Statement s = createStatement();
+        ResultSet rs = s.executeQuery
+            (
+             "select a.aliasinfo\n" +
+             "from sys.sysschemas s, sys.sysaliases a\n" +
+             "where s.schemaid = a.schemaid\n" +
+             "and s.schemaname = 'SYSIBM'\n" +
+             "and alias = 'CLOBGETSUBSTRING'\n"
+             );
+        rs.next();
+        
+        switch (getPhase())
+        {
+        case PH_CREATE:
+        case PH_SOFT_UPGRADE:
+        case PH_POST_SOFT_UPGRADE:
+            
+            if ( !hasFunction ) { break; }
+
+            returnType = getTypeDescriptor( rs.getObject( 1 ) );
+            actualJdbcType = getJDBCTypeId( returnType );
+            actualLength = getMaximumWidth( returnType );
+            int              expectedLength = hasCorrectReturnType ? correctLength : wrongLength;
+
+            assertEquals( java.sql.Types.VARCHAR, actualJdbcType );
+            assertEquals( expectedLength, actualLength );
+            
+            break;
+
+        case PH_HARD_UPGRADE:
+
+            RoutineAliasInfo rai = (RoutineAliasInfo) rs.getObject( 1 );
+            TypeDescriptor   td = (TypeDescriptor) rai.getReturnType();
+
+            assertEquals( java.sql.Types.VARCHAR, td.getJDBCTypeId() );
+            assertEquals( correctLength, td.getMaximumWidth() );
+            
+            break;
+        }
+
+        rs.close();
+        s.close();
+    }
+
+    /**
+     * We would like to just cast the alias descriptor to
+     * RoutineAliasDescriptor. However, this doesn't work if we are running on
+     * an old version because the descriptor comes from a different class
+     * loader. We use reflection to get the information we need.
+     */
+    private Object getTypeDescriptor( Object routineAliasDescriptor )
+        throws Exception
+    {
+        Method  meth = routineAliasDescriptor.getClass().getMethod( "getReturnType", null );
+
+        return meth.invoke( routineAliasDescriptor, null );
+    }
+    private int getJDBCTypeId( Object typeDescriptor )
+        throws Exception
+    {
+        Method  meth = typeDescriptor.getClass().getMethod( "getJDBCTypeId", null );
+
+        return ((Integer) meth.invoke( typeDescriptor, null )).intValue();
+    }
+    private int getMaximumWidth( Object typeDescriptor )
+        throws Exception
+    {
+        Method  meth = typeDescriptor.getClass().getMethod( "getMaximumWidth", null );
+
+        return ((Integer) meth.invoke( typeDescriptor, null )).intValue();
+    }
+    
 }

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/upgradeTests/Version.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/upgradeTests/Version.java?rev=787310&r1=787309&r2=787310&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/upgradeTests/Version.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/upgradeTests/Version.java Mon Jun 22 16:42:29 2009
@@ -70,15 +70,15 @@
     /** Construct a version from its legs */
     public Version( int[] legs )
     {
-        constructorMinion( legs, null );
+        constructorMinion( legs );
     }
 
-    /** Construct from a Derby ProductVersionHolder and a classloader */
-    public Version( ProductVersionHolder pvh, ClassLoader classLoader )
+    /** Construct from a Derby ProductVersionHolder  */
+    public Version( ProductVersionHolder pvh )
     {
-        constructorMinion( getLegs( pvh ), classLoader );
+        constructorMinion( getLegs( pvh ) );
     }
-    private void constructorMinion( int[] legs, ClassLoader classLoader )
+    private void constructorMinion( int[] legs )
     {
         if ( legs == null ) { legs = new int[] {}; }
         int count = legs.length;
@@ -90,8 +90,8 @@
 
         _legs = new int[ count ];
         for ( int i = 0; i < count; i++ ) { _legs[ i ] = legs[ i ]; }
-        
-        addClassLoader( classLoader );
+
+        makeKey();
     }
     private int[] getLegs( ProductVersionHolder pvh )
     {
@@ -144,6 +144,11 @@
      */
     public ClassLoader getClassLoader()
     {
+        ClassLoader retval = (ClassLoader) _classLoaders.get( _key );
+        if ( retval != null ) { return retval; }
+        
+        addClassLoader( );
+        
         return (ClassLoader) _classLoaders.get( _key );
     }
     
@@ -184,19 +189,11 @@
      * Add the class loader for this version if it doesn't already exist.
      * </p>
      */
-    private void addClassLoader( ClassLoader classLoader)
+    private void addClassLoader( )
     {
-        makeKey();
-
-        if ( classLoader == null ) { classLoader = getClassLoader(); }
-        else { _classLoaders.put( _key, classLoader ); }
+        ClassLoader classLoader = UpgradeClassLoader.makeClassLoader( _legs );
 
-        if ( classLoader == null )
-        {
-            classLoader = UpgradeClassLoader.makeClassLoader( _legs );
-
-            _classLoaders.put( _key, classLoader );
-        }
+        _classLoaders.put( _key, classLoader );
     }
 
     /**