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 ma...@apache.org on 2011/06/04 02:09:42 UTC

svn commit: r1131296 - in /db/derby/code/branches/10.7: ./ java/testing/org/apache/derbyTesting/functionTests/tests/upgradeTests/BasicSetup.java

Author: mamta
Date: Sat Jun  4 00:09:41 2011
New Revision: 1131296

URL: http://svn.apache.org/viewvc?rev=1131296&view=rev
Log:
DERBY-1482/DERBY-5121

Migrating changes 1130895 from trunk to 10.7


Modified:
    db/derby/code/branches/10.7/   (props changed)
    db/derby/code/branches/10.7/java/testing/org/apache/derbyTesting/functionTests/tests/upgradeTests/BasicSetup.java

Propchange: db/derby/code/branches/10.7/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Sat Jun  4 00:09:41 2011
@@ -1 +1 @@
-/db/derby/code/trunk:1035603,1036769,1038514,1038813,1039084,1039268,1040658,1041338,1043227,1043389,1044096,1051026,1053724,1055169,1059888,1060480,1062096,1063809,1065061,1066290,1067250,1067357,1069661,1071463,1071886,1076387,1078461,1078693,1081455,1085078,1091000,1097247,1103681,1103718,1129136
+/db/derby/code/trunk:1035603,1036769,1038514,1038813,1039084,1039268,1040658,1041338,1043227,1043389,1044096,1051026,1053724,1055169,1059888,1060480,1062096,1063809,1065061,1066290,1067250,1067357,1069661,1071463,1071886,1076387,1078461,1078693,1081455,1085078,1091000,1097247,1103681,1103718,1129136,1130895

Modified: db/derby/code/branches/10.7/java/testing/org/apache/derbyTesting/functionTests/tests/upgradeTests/BasicSetup.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.7/java/testing/org/apache/derbyTesting/functionTests/tests/upgradeTests/BasicSetup.java?rev=1131296&r1=1131295&r2=1131296&view=diff
==============================================================================
--- db/derby/code/branches/10.7/java/testing/org/apache/derbyTesting/functionTests/tests/upgradeTests/BasicSetup.java (original)
+++ db/derby/code/branches/10.7/java/testing/org/apache/derbyTesting/functionTests/tests/upgradeTests/BasicSetup.java Sat Jun  4 00:09:41 2011
@@ -25,8 +25,8 @@ import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.sql.Statement;
+import java.util.ArrayList;
 
-import org.apache.derby.iapi.services.io.DerbyIOException;
 import org.apache.derbyTesting.junit.JDBC;
 import org.apache.derbyTesting.junit.TestConfiguration;
 
@@ -245,4 +245,462 @@ public class BasicSetup extends UpgradeC
             break;
         }
     }
+    final   int TEST_COUNT = 0;
+    final   int FAILURES = TEST_COUNT + 1;
+    final   String  A_COL = "a";
+    final   String  B_COL = "b";
+
+    //This test has been contributed by Rick Hillegas for DERBY-5121
+    // The test exhaustively walks through all subsets and permutations 
+    // of columns for a trigger which inserts into a side table based on 
+    // updates to a master table.
+    public void testExhuastivePermutationOfTriggerColumns() throws Exception
+    {
+        final   int STATUS_COUNTERS = FAILURES + 1;
+        int columnCount = 3;
+        int[][]   powerSet = constructPowerSet( columnCount );
+        int[][] permutations = permute( powerSet );
+        int[]   statusCounters = new int[ STATUS_COUNTERS ];
+
+        switch ( getPhase() )
+        {
+        case PH_CREATE: // create with old version
+            for ( int triggerCols = 0; triggerCols < powerSet.length; triggerCols++ )
+            {
+                for ( int perm = 0; perm < permutations.length; perm++ )
+                {
+                    createT1( powerSet[ triggerCols ], permutations[ perm ] );
+                    createT2( columnCount, powerSet[ triggerCols ], permutations[ perm ]  );
+                    createTrigger( powerSet[ triggerCols ], permutations[ perm ] );
+                }
+            }
+        	break;
+
+        case PH_SOFT_UPGRADE:
+            for ( int triggerCols = 0; triggerCols < powerSet.length; triggerCols++ )
+            {
+                for ( int perm = 0; perm < permutations.length; perm++ )
+                {
+                    for ( int i = 0; i < permutations.length; i++ )
+                    {
+                        runTrigger( statusCounters, columnCount, powerSet[ triggerCols ], permutations[ perm ], permutations[ i ] );
+                    }
+                }
+            }
+        	break;
+        }
+        summarize( statusCounters );
+    }
+    
+    //Start of helper methods for testExhuastivePermutationOfTriggerColumns
+
+    ////////////////////////
+    //
+    // make power set of N
+    //
+    ////////////////////////
+
+    private int[][] constructPowerSet( int count )
+    {
+    	java.util.ArrayList list = new java.util.ArrayList();
+        boolean[]           inclusions = new boolean[ count ];
+
+        include( list, 0, inclusions );
+        
+        int[][] result = new int[ list.size() ][];
+        list.toArray( result );
+
+        return result;
+    }
+
+    private void    include( ArrayList list, int idx, boolean[] inclusions )
+    {
+        if ( idx >= inclusions.length )
+        {
+            int totalLength = inclusions.length;
+            int count = 0;
+            for ( int i = 0; i < totalLength; i++ )
+            {
+                if ( inclusions[ i ] ) { count++; }
+            }
+
+            if ( count > 0 )
+            {
+                int[]   result = new int[ count ];
+                int     index = 0;
+                for ( int i = 0; i < totalLength; i++ )
+                {
+                    if ( inclusions[ i ] ) { result[ index++ ] = i; }
+                }
+                
+                list.add( result );
+            }
+
+            return;
+        }
+
+        include( list, idx, inclusions, false );
+        include( list, idx, inclusions, true );
+    }
+
+    private void    include( ArrayList list, int idx, boolean[] inclusions, boolean currentCell )
+    {
+        inclusions[ idx++ ] = currentCell;
+
+        // this is where the recursion happens
+        include( list, idx, inclusions );
+    }
+
+    ////////////////////////////////////////////////
+    //
+    // create all permutations of an array of numbers
+    //
+    ////////////////////////////////////////////////
+    private int[][] permute( int[][] original )
+    {
+        ArrayList list = new ArrayList();
+
+        for ( int i = 0; i < original.length; i++ )
+        {
+            permute( list, new int[0], original[ i ] );
+        }
+        
+        int[][] result = new int[ list.size() ][];
+        list.toArray( result );
+
+        return result;
+    }
+
+    private void   permute( ArrayList list, int[] start, int[] remainder )
+    {
+        int startLength = start.length;
+        int remainderLength = remainder.length;
+        
+        for ( int idx = 0; idx < remainder.length; idx++ )
+        {
+            int[] newStart = new int[ startLength + 1 ];
+            for ( int i = 0; i < startLength; i++ ) { newStart[ i ] = start[ i ]; }
+            newStart[ startLength ] = remainder[ idx ];
+
+            if ( remainderLength <= 1 ) { list.add( newStart ); }
+            else
+            {
+                int[]   newRemainder = new int[ remainderLength - 1 ];
+                int     index = 0;
+                for ( int i = 0; i < remainderLength; i++ )
+                {
+                    if ( i != idx ) { newRemainder[ index++ ] = remainder[ i ]; }
+                }
+
+                // this is where the recursion happens
+                permute( list, newStart, newRemainder );
+            }
+        }   // end loop through all remainder elements
+    }
+
+    private String  columnName( String stub, int idx ) { return (stub + '_' + idx ); }
+
+    private void createT1(int[] triggerCols, int[] permutation )
+    throws Exception
+    {
+        StringBuffer   buffer = new StringBuffer();
+        buffer.append( "create table " + makeTableName( "t1", triggerCols, permutation ) + "( " );
+        for ( int i = 0; i < permutation.length; i++ )
+        {
+            if ( i > 0 ) { buffer.append( ", " ); }
+            buffer.append( columnName( B_COL, i ) );
+            buffer.append( " int" );
+        }
+        buffer.append( " )" );
+        Statement s = createStatement();
+        s.execute(buffer.toString());
+    }    
+    
+    private void    createT2(int columnCount, int[] triggerCols, int[] permutation  )
+    throws Exception
+    {
+        StringBuffer   buffer = new StringBuffer();
+        buffer.append( "create table " + makeTableName( "t2", triggerCols, permutation ) + "( " );
+        for ( int i = 0; i < columnCount; i++ )
+        {
+            if ( i > 0 ) { buffer.append( ", " ); }
+            buffer.append( columnName( A_COL, i ) );
+            buffer.append( " int" );
+        }
+        buffer.append( " )" );
+        Statement s = createStatement();
+        s.execute(buffer.toString());
+    }
+
+    private String  makeTableName( String stub, int[] triggerCols, int[] permutation )
+    {
+        StringBuffer   buffer = new StringBuffer();
+
+        buffer.append( stub );
+        for ( int i = 0; i < triggerCols.length; i++ )
+        {
+            buffer.append( "_" );
+            buffer.append( triggerCols[ i ] );
+        }
+       buffer.append( "__" );
+        for ( int i = 0; i < permutation.length; i++ )
+        {
+            buffer.append( "_" );
+            buffer.append( permutation[ i ] );
+        }
+
+        return buffer.toString();
+    }
+
+    private void    createTrigger(int[] triggerCols, int[] permutation )
+    throws Exception
+    {
+        boolean modeDb2SqlOptional = oldAtLeast(10, 3);
+        StringBuffer   buffer = new StringBuffer();
+        buffer.append( "create trigger " + makeTriggerName( "UTrg", triggerCols, permutation ) + " after update of " );
+        for ( int i = 0; i < triggerCols.length; i++ )
+        {
+            if ( i > 0 ) { buffer.append( ", " ); }
+            buffer.append( columnName( A_COL, triggerCols[ i ] ) );
+        }
+        		
+        buffer.append( "\n\ton " + makeTableName( "t2", triggerCols, permutation ) + " referencing new as nr for each row " );
+        buffer.append( modeDb2SqlOptional?"":"\n\tMODE DB2SQL ");
+        buffer.append( "\n\tinsert into " + makeTableName( "t1", triggerCols, permutation ) + " values ( " );
+        for ( int i = 0; i < permutation.length; i++ )
+        {
+            if ( i > 0 ) { buffer.append( ", " ); }
+            buffer.append( "nr." + columnName( A_COL, permutation[ i ] ) );
+        }
+        buffer.append( " )" );
+
+        Statement s = createStatement();
+        s.execute(buffer.toString());
+    }
+
+    private String  makeTriggerName( String stub, int[] triggerCols, int[] permutation )
+    {
+        StringBuffer   buffer = new StringBuffer();
+
+        buffer.append( stub );
+        for ( int i = 0; i < triggerCols.length; i++ )
+        {
+            buffer.append( "_" );
+            buffer.append( triggerCols[ i ] );
+        }
+        buffer.append( "__" );
+        for ( int i = 0; i < permutation.length; i++ )
+        {
+            buffer.append( "_" );
+            buffer.append( permutation[ i ] );
+        }
+        
+        return buffer.toString();
+    }
+
+    private int[]   getResults( int rowLength, String text )
+        throws Exception
+    {
+        PreparedStatement   ps = prepareStatement(text );
+        ResultSet               rs = ps.executeQuery();
+
+        if ( !rs.next() ) { return new int[0]; }
+
+        int[]                       result = new int[ rowLength ];
+        for ( int i = 0; i < rowLength; i++ )
+        {
+            result[ i ] = rs.getInt( i + 1 );
+        }
+
+        rs.close();
+        ps.close();
+
+        return result;
+    }
+
+    private boolean overlap( int[] left, int[] right )
+    {
+        for ( int i = 0; i < left.length; i++ )
+        {
+            for ( int j = 0; j < right.length; j++ )
+            {
+                if ( left[ i ] == right[ j ] )
+                {
+                    //println( true, stringify( left ) + " overlaps " + stringify( right ) );
+                    return true;
+                }
+            }
+        }
+
+        //println( true, stringify( left ) + " DOES NOT overlap " + stringify( right ) );
+        return false;
+    }
+
+    private void    vetData
+    ( int[] statusCounters, int[] triggerCols, int[] permutation, int[] updateColumns, String updateStatement )
+    throws Exception
+    {
+        String  t1Name = makeTableName( "t1", triggerCols, permutation );
+        String  t2Name = makeTableName( "t2", triggerCols, permutation );
+        int     rowLength = permutation.length;
+        int[]   t1Row = getResults( rowLength, "select * from " + t1Name );
+
+        if ( !overlap( triggerCols, updateColumns ) )
+        {
+            if ( t1Row.length != 0 )
+            {
+                fail
+                    (
+                     statusCounters,
+                     triggerCols,
+                     permutation,
+                     updateColumns,
+                     "No row should have been inserted into t1! updateStatement = '" + updateStatement + "' and t1Row = " + stringify( t1Row )
+                     );
+            }
+
+            return;
+        }
+        
+        StringBuffer   buffer = new StringBuffer();
+        buffer.append( "select " );
+        for ( int i = 0; i < permutation.length; i++ )
+        {
+            if ( i > 0 ) { buffer.append( ", " ); }
+            buffer.append( columnName( A_COL, permutation[ i ] ) );
+        }
+        buffer.append( " from " + t2Name );
+        int[]   t2Row = getResults( rowLength, buffer.toString() );
+
+        if ( !stringify( t1Row ).equals( stringify( t2Row ) ) )
+        {
+            String  detail = "Wrong data inserted into t1! " +
+                "updateStatement = '" + updateStatement + "'. " +
+                "Expected " + stringify( t2Row ) +
+                " but found " + stringify( t1Row );
+                
+            fail( statusCounters, triggerCols, permutation, updateColumns, detail );
+        }
+    }
+
+    private void    runTrigger( int[] statusCounters, int columnCount, int[] triggerCols, int[] permutation, int[] updateColumns )
+    throws Exception
+    {
+        statusCounters[ TEST_COUNT ]++;
+
+        loadData( columnCount, triggerCols, permutation );
+        String  updateStatement = updateData( statusCounters, triggerCols, permutation, updateColumns );
+        vetData( statusCounters, triggerCols, permutation, updateColumns, updateStatement );
+    }
+
+    private void    loadData( int columnCount, int[] triggerCols, int[] permutation )
+    throws Exception
+    {
+        String  t1Name = makeTableName( "t1", triggerCols, permutation );
+        String  t2Name = makeTableName( "t2", triggerCols, permutation );
+        Statement s = createStatement();
+        s.execute("delete from " + t1Name);
+        s.execute("delete from " + t2Name);
+        
+        StringBuffer   buffer = new StringBuffer();
+        buffer.append( "insert into " + t2Name + " values ( " );
+        for ( int i = 0; i < columnCount; i++ )
+        {
+            if ( i > 0 ) { buffer.append( ", " ); }
+            buffer.append( i );
+        }
+        buffer.append( " )" );
+        s.execute(buffer.toString());
+    }
+    
+    private String    updateData( int[] statusCounters, int[] triggerCols, int[] permutation, int[] updateColumns )
+    throws Exception
+    {
+        String  t2Name = makeTableName( "t2", triggerCols, permutation );
+
+        StringBuffer   buffer = new StringBuffer();
+        buffer.append( "update " + t2Name + " set " );
+        for ( int i = 0; i < updateColumns.length; i++ )
+        {
+            if ( i > 0 ) { buffer.append( ", " ); }
+            buffer.append( columnName( A_COL, updateColumns[ i ] ) );
+            buffer.append( " = " );
+            buffer.append( (100 + i) );
+        }
+
+        String  updateStatement = buffer.toString();
+
+        try {
+            Statement s = createStatement();
+            s.execute(updateStatement);
+        }
+        catch (SQLException se)
+        {
+            fail
+                (
+                 statusCounters,
+                 triggerCols,
+                 permutation,
+                 updateColumns,
+                 "Update statement failed! updateStatement = '" + updateStatement
+                 );
+        }
+
+        return updateStatement;
+    }
+
+    private void    fail( int[] statusCounters, int[] triggerCols, int[] permutation, int[] updateColumns, String detail )
+    {
+        statusCounters[ FAILURES ]++;
+        
+        String  message = "FAILED for triggerCols = " +
+            stringify( triggerCols ) +
+            " and permutation = " + stringify( permutation ) +
+            " and updateColumns = " + stringify( updateColumns ) +
+            ". " + detail;
+
+        System.out.println( message );
+    }
+    
+    private void    summarize( int[] statusCounters )
+    {
+        int testCount = statusCounters[ TEST_COUNT ];
+        int failures = statusCounters[ FAILURES ];
+
+        if ( failures != 0 )
+        {
+        	System.out.println( "FAILURE! " + testCount + " test cases run, of which " + failures + " failed." );
+        }
+    }
+
+    private String    stringify( int[][] array )
+    {
+        StringBuffer   buffer = new StringBuffer();
+
+        buffer.append( "[" );
+        for ( int i = 0; i < array.length; i++ )
+        {
+            buffer.append( "\n\t" );
+            buffer.append( stringify( array[ i ] ) );
+        }
+        buffer.append( "\n]\n" );
+
+        return buffer.toString();
+    }
+
+    private String  stringify( int[] array )
+    {
+        StringBuffer   buffer = new StringBuffer();
+
+        buffer.append( "[" );
+        for ( int j = 0; j < array.length; j++ )
+        {
+            if ( j > 0 ) { buffer.append( ", " ); }
+            buffer.append( array[ j ] );
+        }
+        buffer.append( "]" );
+
+        return buffer.toString();
+    }
+    //End of helper methods for testExhuastivePermutationOfTriggerColumns
 }