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
}