db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ma...@apache.org
Subject svn commit: r1338905 - in /db/derby/code/branches/10.4: ./ java/engine/org/apache/derby/iapi/sql/dictionary/ java/testing/org/apache/derbyTesting/functionTests/tests/lang/ java/testing/org/apache/derbyTesting/junit/
Date Tue, 15 May 2012 21:38:58 GMT
Author: mamta
Date: Tue May 15 21:38:58 2012
New Revision: 1338905

URL: http://svn.apache.org/viewvc?rev=1338905&view=rev
Log:
Backporting 2 jiras to 10.4 with some manual changes as described below

DERBY-5681 When a foreign key constraint on a table is dropped, the associated statistics
row for the conglomerate is not removed

DERBY-4834 Add helper class for working with index statistics in JUnit tests

DERBY-5681 added some tests to upgrade statistics procedure test but since that procedure
doesn't exist in 10.4 and before, I added those tests to a new class, namely Derby5681Test.java.
Also, because of the absence of update statisitcs procedure and DERBY-5702, we can't quite
create a hanging statistics row in 10.4 and before. The test in 10.4 will just have a test
to drop constraint(that shares a backing index with another constraint) and show that it doesn't
break anything.


Added:
    db/derby/code/branches/10.4/java/testing/org/apache/derbyTesting/functionTests/tests/lang/Derby5681Test.java
  (with props)
    db/derby/code/branches/10.4/java/testing/org/apache/derbyTesting/junit/IndexStatsUtil.java
      - copied unchanged from r1337032, db/derby/code/branches/10.5/java/testing/org/apache/derbyTesting/junit/IndexStatsUtil.java
Modified:
    db/derby/code/branches/10.4/   (props changed)
    db/derby/code/branches/10.4/java/engine/org/apache/derby/iapi/sql/dictionary/ConglomerateDescriptor.java
    db/derby/code/branches/10.4/java/testing/org/apache/derbyTesting/junit/Utilities.java

Propchange: db/derby/code/branches/10.4/
------------------------------------------------------------------------------
  Merged /db/derby/code/branches/10.5:r1337032
  Merged /db/derby/code/branches/10.7:r1336809
  Merged /db/derby/code/trunk:r1005347,1031559,1041374,1042537,1329359

Modified: db/derby/code/branches/10.4/java/engine/org/apache/derby/iapi/sql/dictionary/ConglomerateDescriptor.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.4/java/engine/org/apache/derby/iapi/sql/dictionary/ConglomerateDescriptor.java?rev=1338905&r1=1338904&r2=1338905&view=diff
==============================================================================
--- db/derby/code/branches/10.4/java/engine/org/apache/derby/iapi/sql/dictionary/ConglomerateDescriptor.java
(original)
+++ db/derby/code/branches/10.4/java/engine/org/apache/derby/iapi/sql/dictionary/ConglomerateDescriptor.java
Tue May 15 21:38:58 2012
@@ -474,11 +474,11 @@ public final class ConglomerateDescripto
 				physicalCD = null;
 		}
 
+        /* DERBY-5681 Drop statistics */
+        dd.dropStatisticsDescriptors(td.getUUID(), getUUID(), tc);
+
 	    if (dropConglom)
 	    {
-	        /* Drop statistics */
-	        dd.dropStatisticsDescriptors(td.getUUID(), getUUID(), tc);
-	        
 	        /* Drop the physical conglomerate */
 	        tc.dropConglomerate(getConglomerateNumber());
 	    }

Added: db/derby/code/branches/10.4/java/testing/org/apache/derbyTesting/functionTests/tests/lang/Derby5681Test.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.4/java/testing/org/apache/derbyTesting/functionTests/tests/lang/Derby5681Test.java?rev=1338905&view=auto
==============================================================================
--- db/derby/code/branches/10.4/java/testing/org/apache/derbyTesting/functionTests/tests/lang/Derby5681Test.java
(added)
+++ db/derby/code/branches/10.4/java/testing/org/apache/derbyTesting/functionTests/tests/lang/Derby5681Test.java
Tue May 15 21:38:58 2012
@@ -0,0 +1,184 @@
+/**
+ *  Derby - Class org.apache.derbyTesting.functionTests.tests.lang.Derby5681Test
+ *  
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.derbyTesting.functionTests.tests.lang;
+
+import java.sql.Connection;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import junit.framework.Test;
+
+import org.apache.derbyTesting.junit.BaseJDBCTestCase;
+import org.apache.derbyTesting.junit.CleanDatabaseTestSetup;
+import org.apache.derbyTesting.junit.JDBC;
+import org.apache.derbyTesting.junit.TestConfiguration;
+import org.apache.derbyTesting.junit.IndexStatsUtil;
+
+/**
+ * DERBY-5681(When a foreign key constraint on a table is dropped,
+ *  the associated statistics row for the conglomerate is not removed.)
+ * @throws Exception
+ */
+public class Derby5681Test extends BaseJDBCTestCase {
+
+    /**
+     * Basic constructor.
+     */
+    public Derby5681Test(String name) {
+        super(name);
+    }
+
+    /**
+     * Returns the implemented tests.
+     * 
+     * @return An instance of <code>Test</code> with the implemented tests to
+     *         run.
+     */
+    public static Test suite() {
+        return TestConfiguration.defaultSuite(Derby5681Test.class);
+    }
+
+    /**
+     * The test can't really demonstrate the fix for DERBY-5681 until 
+     *  DERBY-5702(Creating a foreign key constraint does not automatically
+     *  create a statistics row if foreign key constraint will share a backing
+     *  index created for a primary key) is fixed. The fix for DERBY-5681
+     *  is going to take care of the hanging statistics row left for a
+     *  constraint(which shares a backing index with another constraint) that 
+     *  is getting dropped. But because of DERBY-5702, the statistics row
+     *  never gets created for a constraint that shares a backing index. In
+     *  10.5 and higher, it is possible to create the missing statistics row
+     *  using update statistics procedure but that procedure is not available
+     *  in 10.4 and earlier releases.
+     * @throws SQLException
+     */
+    public void testBug4356() throws SQLException {
+        // Helper object to obtain information about index statistics.
+        IndexStatsUtil stats = new IndexStatsUtil(openDefaultConnection());
+        Statement s = createStatement();
+    	
+        //Test - primary key constraint
+        s.executeUpdate("CREATE TABLE TEST_TAB_1 (c11 int not null,"+
+                "c12 int not null, c13 int)");
+        stats.assertNoStatsTable("TEST_TAB_1");
+        //Insert data into table with no constraint and there will be no stat
+        // for that table at this point
+        s.executeUpdate("INSERT INTO TEST_TAB_1 VALUES(1,1,1),(2,2,2)");
+        stats.assertNoStatsTable("TEST_TAB_1");
+        //Add primary key constraint to the table and now we should find a 
+        // statistics row for it
+        s.executeUpdate("ALTER TABLE TEST_TAB_1 "+
+                "ADD CONSTRAINT TEST_TAB_1_PK_1 "+
+        		"PRIMARY KEY (c11)");
+        stats.assertTableStats("TEST_TAB_1",1);
+        //Dropping primary key constraint will drop the corresponding
+        // statistics
+        s.executeUpdate("ALTER TABLE TEST_TAB_1 "+
+                "DROP CONSTRAINT TEST_TAB_1_PK_1");
+        stats.assertNoStatsTable("TEST_TAB_1");
+        //Add the primary key constraint back since it will be used by the next
+        // test to create foreign key constraint
+        s.executeUpdate("ALTER TABLE TEST_TAB_1 "+
+                "ADD CONSTRAINT TEST_TAB_1_PK_1 "+
+        		"PRIMARY KEY (c11)");
+        //The statistics for primary key constraint has been added
+        stats.assertTableStats("TEST_TAB_1",1);
+
+        //Test - unique key constraint
+        s.executeUpdate("ALTER TABLE TEST_TAB_1 "+
+                "ADD CONSTRAINT TEST_TAB_1_UNQ_1 "+
+        		"UNIQUE (c12)");
+        stats.assertTableStats("TEST_TAB_1",2);
+        s.executeUpdate("ALTER TABLE TEST_TAB_1 "+
+                "DROP CONSTRAINT TEST_TAB_1_UNQ_1");
+        stats.assertTableStats("TEST_TAB_1",1);
+        s.executeUpdate("ALTER TABLE TEST_TAB_1 "+
+                "DROP CONSTRAINT TEST_TAB_1_PK_1");
+        stats.assertNoStatsTable("TEST_TAB_1");
+        s.executeUpdate("ALTER TABLE TEST_TAB_1 "+
+                "ADD CONSTRAINT TEST_TAB_1_PK_1 "+
+        		"PRIMARY KEY (c11)");
+        stats.assertTableStats("TEST_TAB_1",1);
+
+        //Test - unique key constraint on nullable column & non-nullable column
+        s.executeUpdate("ALTER TABLE TEST_TAB_1 "+
+                "ADD CONSTRAINT TEST_TAB_1_UNQ_2 "+
+        		"UNIQUE (c12, c13)");
+        stats.assertTableStats("TEST_TAB_1",3);
+        s.executeUpdate("ALTER TABLE TEST_TAB_1 "+
+                "DROP CONSTRAINT TEST_TAB_1_UNQ_2");
+        stats.assertTableStats("TEST_TAB_1",1);
+        s.executeUpdate("ALTER TABLE TEST_TAB_1 "+
+                "DROP CONSTRAINT TEST_TAB_1_PK_1");
+        stats.assertNoStatsTable("TEST_TAB_1");
+        s.executeUpdate("ALTER TABLE TEST_TAB_1 "+
+                "ADD CONSTRAINT TEST_TAB_1_PK_1 "+
+        		"PRIMARY KEY (c11)");
+        stats.assertTableStats("TEST_TAB_1",1);
+        
+        //Test - foreign key but no primary key constraint
+        s.executeUpdate("CREATE TABLE TEST_TAB_3 (c31 int not null)");
+        s.executeUpdate("INSERT INTO TEST_TAB_3 VALUES(1),(2)");
+        s.executeUpdate("ALTER TABLE TEST_TAB_3 "+
+                "ADD CONSTRAINT TEST_TAB_3_FK_1 "+
+        		"FOREIGN KEY(c31) REFERENCES TEST_TAB_1(c11)");
+        stats.assertTableStats("TEST_TAB_3",1);
+        s.executeUpdate("ALTER TABLE TEST_TAB_3 "+
+                "DROP CONSTRAINT TEST_TAB_3_FK_1");
+        stats.assertNoStatsTable("TEST_TAB_3");
+
+        //Test - foreign key and primary key constraint
+        s.executeUpdate("CREATE TABLE TEST_TAB_2 (c21 int not null)");
+        s.executeUpdate("INSERT INTO TEST_TAB_2 VALUES(1),(2)");
+        s.executeUpdate("ALTER TABLE TEST_TAB_2 "+
+                "ADD CONSTRAINT TEST_TAB_2_PK_1 "+
+        		"PRIMARY KEY (c21)");
+        stats.assertTableStats("TEST_TAB_2",1);
+        //DERBY-5702 Add a foreign key constraint and now we should find 2 rows
+        // of statistics for TEST_TAB_2 - 1 for primary key and other for
+        // foreign key constraint
+        s.executeUpdate("ALTER TABLE TEST_TAB_2 "+
+                "ADD CONSTRAINT TEST_TAB_2_FK_1 "+
+        		"FOREIGN KEY(c21) REFERENCES TEST_TAB_1(c11)");
+        //DERBY-5702 Like primary key earlier, adding foreign key constraint
+        // didn't automatically add a statistics row for it. And there is
+        // no update statistics procedure available in 10.4 and earlier
+        // releases and there is no way to create the statistics row for
+        // constraints which share the backing index with anothe constraint.
+        //After DERBY-5702 is fixed, we should see 2 rows below and not just
+        // one statistics row
+        stats.assertTableStats("TEST_TAB_2",1);
+        //Number of statistics row for TEST_TAB_1 will remain unchanged since
+        // it has only primary key defined on it
+        stats.assertTableStats("TEST_TAB_1",1);
+        s.executeUpdate("ALTER TABLE TEST_TAB_2 "+
+                "DROP CONSTRAINT TEST_TAB_2_FK_1");
+        //Dropping the foreign key constraint should remove one of the 
+        // statistics row for TEST_TAB_2. 
+        stats.assertTableStats("TEST_TAB_2",1);
+        s.execute("drop table TEST_TAB_2");
+        s.execute("drop table TEST_TAB_1");
+        stats.release();
+    }
+}

Propchange: db/derby/code/branches/10.4/java/testing/org/apache/derbyTesting/functionTests/tests/lang/Derby5681Test.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: db/derby/code/branches/10.4/java/testing/org/apache/derbyTesting/junit/Utilities.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.4/java/testing/org/apache/derbyTesting/junit/Utilities.java?rev=1338905&r1=1338904&r2=1338905&view=diff
==============================================================================
--- db/derby/code/branches/10.4/java/testing/org/apache/derbyTesting/junit/Utilities.java
(original)
+++ db/derby/code/branches/10.4/java/testing/org/apache/derbyTesting/junit/Utilities.java
Tue May 15 21:38:58 2012
@@ -1,6 +1,6 @@
 /*
  *
- * Derby - Class Utilities
+ * Derby - Class org.apache.derbyTesting.junit.Utilities
  *
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
@@ -22,142 +22,130 @@ package org.apache.derbyTesting.junit;
 import java.io.BufferedReader;
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
-import java.io.IOException;
 import java.io.InputStreamReader;
 import java.io.PrintWriter;
 import java.io.StringReader;
 import java.io.UnsupportedEncodingException;
-import java.security.AccessController;
-import java.security.PrivilegedActionException;
-import java.security.PrivilegedExceptionAction;
 import java.sql.ResultSet;
 import java.sql.ResultSetMetaData;
 import java.sql.SQLException;
+import java.util.Arrays;
 import java.util.StringTokenizer;
 
+import junit.framework.Assert;
 
 /**
- * General non-JDBC related utilities relocated from TestUtil
- *
- *
+ * General non-JDBC related utilities.
+ * Some of these were relocated from TestUtil.
  */
 public class Utilities {
 
-    public Utilities() {
-        // TODO Auto-generated constructor stub
-    }
-        /**
-         * Just converts a string to a hex literal to assist in converting test
-         * cases that used to insert strings into bit data tables
-         * Converts using UTF-16BE just like the old casts used to.
-         *
-         * @param s  String to convert  (e.g
-         * @return hex literal that can be inserted into a bit column.
-         */
-        public static String stringToHexLiteral(String s)
-        {
-                byte[] bytes;
-                String hexLiteral = null;
-                try {
-                        bytes = s.getBytes("UTF-16BE");
-                        hexLiteral = convertToHexString(bytes);
-                }
-                catch (UnsupportedEncodingException ue)
-                {
-                        System.out.println("This shouldn't happen as UTF-16BE should be supported");
-                        ue.printStackTrace();
-                }
+    private Utilities() { }
 
-                return hexLiteral;
+    /**
+     * Converts a string to a hex literal to assist in converting test
+     * cases that used to insert strings into bit data tables.
+     * <p>
+     * Converts using UTF-16BE just like the old casts used to.
+     *
+     * @param s string to convert
+     * @return hex literal that can be inserted into a bit column.
+     */
+    public static String stringToHexLiteral(String s) {
+        byte[] bytes;
+        String hexLiteral = null;
+        try {
+            bytes = s.getBytes("UTF-16BE");
+            hexLiteral = convertToHexString(bytes);
+        } catch (UnsupportedEncodingException ue) {
+            Assert.fail("Encoding UTF-16BE unavailable: " + ue.getMessage());
         }
 
-        /**
-         * Convert a byte array to a hex string suitable for insert 
-         * @param buf  byte array to convert
-         * @return     formated string representing byte array
-         */
-        private static String convertToHexString(byte [] buf)
-        {
-                StringBuffer str = new StringBuffer();
-                str.append("X'");
-                String val;
-                int byteVal;
-                for (int i = 0; i < buf.length; i++)
-                {
-                        byteVal = buf[i] & 0xff;
-                        val = Integer.toHexString(byteVal);
-                        if (val.length() < 2)
-                                str.append("0");
-                        str.append(val);
-                }
-                return str.toString() +"'";
+        return hexLiteral;
+    }
+
+    /**
+     * Convert a byte array to a hex string suitable for insert.
+     *
+     * @param buf  byte array to convert
+     * @return     formated string representing byte array
+     */
+    private static String convertToHexString(byte[] buf) {
+        StringBuffer str = new StringBuffer();
+        str.append("X'");
+        String val;
+        int byteVal;
+        for (int i = 0; i < buf.length; i++) {
+            byteVal = buf[i] & 0xff;
+            val = Integer.toHexString(byteVal);
+            if (val.length() < 2) {
+                str.append("0");
+            }
+            str.append(val);
         }
+        return str.toString() + "'";
+    }
+
+    /**
+     * Creates a string with the specified length.
+     * <p>
+     * Called from various tests to test edge cases and such.
+     *
+     * @param c             character to repeat
+     * @param repeatCount   Number of times to repeat character
+     * @return              String of repeatCount characters c
+     */
+    public static String repeatChar(String c, int repeatCount) {
+        char[] chArray = new char[repeatCount];
+        Arrays.fill(chArray, c.charAt(0));
+        return String.valueOf(chArray);
+    }
 
-    	/**
-    	 * repeatChar is used to create strings of varying lengths.
-    	 * called from various tests to test edge cases and such.
-    	 *
-    	 * @param c             character to repeat
-    	 * @param repeatCount   Number of times to repeat character
-    	 * @return              String of repeatCount characters c
-    	 */
-       public static String repeatChar(String c, int repeatCount)
-       {
-    	   char ch = c.charAt(0);
-
-    	   char[] chArray = new char[repeatCount];
-    	   for (int i = 0; i < repeatCount; i++)
-    	   {
-    		   chArray[i] = ch;
-    	   }
-
-    	   return new String(chArray);
-
-       }
-
-        /**
-         * Print out resultSet in two dimensional array format, for use by
-         * JDBC.assertFullResultSet(rs,expectedRows) expectedRows argument.
-         * Useful while converting tests to get output in correct format.
-         * 
-         * @param rs
-         * @throws SQLException
-         */
-        public static void showResultSet(ResultSet rs) throws SQLException {
+    /**
+     * Print out resultSet in two dimensional array format, for use by
+     * JDBC.assertFullResultSet(rs,expectedRows) expectedRows argument.
+     * Useful while converting tests to get output in correct format.
+     *
+     * @param rs result set to print
+     * @throws SQLException if accessing the result set fails
+     */
+    public static void showResultSet(ResultSet rs) throws SQLException {
+        System.out.print("{");
+        int row = 0;
+        boolean next = rs.next();
+        while (next) {
+            row++;
+            ResultSetMetaData rsmd = rs.getMetaData();
+            int nocols = rsmd.getColumnCount();
             System.out.print("{");
-            int row = 0;
-            boolean next = rs.next();
-            while (next) {
-                row++;
-                ResultSetMetaData rsmd = rs.getMetaData();
-                int nocols = rsmd.getColumnCount();
-                System.out.print("{");
-                
-                for (int i = 0; i < nocols; i++)
-                {
-                	String val = rs.getString(i+1);
-                	if (val == null)
-                		System.out.print("null");
-                	else
-                		System.out.print("\"" + rs.getString(i+1) + "\"");
-                    if (i == (nocols -1))
-                        System.out.print("}");
-                    else
-                        System.out.print(",");
-                           
+
+            for (int i = 0; i < nocols; i++) {
+                String val = rs.getString(i + 1);
+                if (val == null) {
+                    System.out.print("null");
+                } else {
+                    System.out.print("\"" + rs.getString(i + 1) + "\"");
+                }
+                if (i == (nocols - 1)) {
+                    System.out.print("}");
+                } else {
+                    System.out.print(",");
                 }
-                next = rs.next();
-                   
-                if (next)
-                    System.out.println(",");
-                else
-                    System.out.println("};\n");
+
+            }
+            next = rs.next();
+
+            if (next) {
+                System.out.println(",");
+            } else {
+                System.out.println("};\n");
             }
         }
-        
+    }
+
     /**
-     * Calls the public method <code>getInfo</code> of the sysinfo tool within
-     * this JVM and returns a <code>BufferedReader</code> for reading its 
+     * Calls the public method {@code getInfo} of the sysinfo tool within
+     * this JVM and returns a {@code BufferedReader} for reading its
      * output. This is useful for obtaining system information that could be 
      * used to verify, for example, values returned by Derby MBeans.
      * 
@@ -173,13 +161,13 @@ public class Utilities {
         pw.close();
         byte[] outBytes = byteStream.toByteArray();
         BufferedReader sysinfoOutput = new BufferedReader(
-                    new InputStreamReader(
-                            new ByteArrayInputStream(outBytes)));
+                new InputStreamReader(
+                new ByteArrayInputStream(outBytes)));
         return sysinfoOutput;
     }
-    
+
     /**
-     * <p>Calls the public method <code>getSysInfo()</code> of the Network

+     * <p>Calls the public method {@code getSysInfo} of the Network
      * Server instance associated with the current test configuration and 
      * returns the result as a BufferedReader, making it easy to analyse the 
      * output line by line.</p>
@@ -192,29 +180,24 @@ public class Utilities {
      * @see org.apache.derby.drda.NetworkServerControl#getSysinfo()
      */
     public static BufferedReader getSysinfoFromServer() throws Exception {
-        
+
         return new BufferedReader(new StringReader(
                 NetworkServerTestSetup.getNetworkServerControl().getSysinfo()));
     }
-    
+
     /**
      * Splits a string around matches of the given delimiter character.
      * Copied from org.apache.derby.iapi.util.StringUtil
      *
      * Where applicable, this method can be used as a substitute for
-     * <code>String.split(String regex)</code>, which is not available
+     * {@code String.split(String regex)}, which is not available
      * on a JSR169/Java ME platform.
      *
      * @param str the string to be split
      * @param delim the delimiter
      * @throws NullPointerException if str is null
      */
-    static public String[] split(String str, char delim)
-    {
-        if (str == null) {
-            throw new NullPointerException("str can't be null");
-        }
-
+    public static String[] split(String str, char delim) {
         // Note the javadoc on StringTokenizer:
         //     StringTokenizer is a legacy class that is retained for
         //     compatibility reasons although its use is discouraged in
@@ -231,4 +214,21 @@ public class Utilities {
         return s;
     }
 
+    /**
+     * Sleeps the specified number of milliseconds.
+     *
+     * @param millis sleep duration
+     */
+    public static void sleep(long millis) {
+        long started = System.currentTimeMillis();
+        long waited = 0;
+        while (waited < millis) {
+            try {
+                Thread.sleep(millis - waited);
+            } catch (InterruptedException ie) {
+                Thread.currentThread().interrupt();
+            }
+            waited = System.currentTimeMillis() - started;
+        }
+    }
 }



Mime
View raw message