db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From kahat...@apache.org
Subject svn commit: r730163 - in /db/derby/code/branches/10.4/java: engine/org/apache/derby/iapi/types/ testing/org/apache/derbyTesting/functionTests/tests/lang/
Date Tue, 30 Dec 2008 16:23:36 GMT
Author: kahatlen
Date: Tue Dec 30 08:23:36 2008
New Revision: 730163

URL: http://svn.apache.org/viewvc?rev=730163&view=rev
Log:
DERBY-3975: SELECT DISTINCT may return duplicates with territory-based collation

Merged revision 728822 from trunk.

Modified:
    db/derby/code/branches/10.4/java/engine/org/apache/derby/iapi/types/CollatorSQLChar.java
    db/derby/code/branches/10.4/java/engine/org/apache/derby/iapi/types/CollatorSQLClob.java
    db/derby/code/branches/10.4/java/engine/org/apache/derby/iapi/types/CollatorSQLLongvarchar.java
    db/derby/code/branches/10.4/java/engine/org/apache/derby/iapi/types/CollatorSQLVarchar.java
    db/derby/code/branches/10.4/java/engine/org/apache/derby/iapi/types/SQLChar.java
    db/derby/code/branches/10.4/java/testing/org/apache/derbyTesting/functionTests/tests/lang/CollationTest.java

Modified: db/derby/code/branches/10.4/java/engine/org/apache/derby/iapi/types/CollatorSQLChar.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.4/java/engine/org/apache/derby/iapi/types/CollatorSQLChar.java?rev=730163&r1=730162&r2=730163&view=diff
==============================================================================
--- db/derby/code/branches/10.4/java/engine/org/apache/derby/iapi/types/CollatorSQLChar.java
(original)
+++ db/derby/code/branches/10.4/java/engine/org/apache/derby/iapi/types/CollatorSQLChar.java
Tue Dec 30 08:23:36 2008
@@ -163,6 +163,16 @@
 		 return holderForCollationSensitiveInfo.stringCompare(char1, char2);
 	 }
 
+     /**
+      * Return a hash code that is consistent with
+      * {@link #stringCompare(SQLChar, SQLChar)}.
+      *
+      * @return hash code
+      */
+     public int hashCode() {
+         return hashCodeForCollation();
+     }
+
 	/**
 	 * This method implements the like function for char (with no escape value).
 	 * The difference in this method and the same method in superclass is that

Modified: db/derby/code/branches/10.4/java/engine/org/apache/derby/iapi/types/CollatorSQLClob.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.4/java/engine/org/apache/derby/iapi/types/CollatorSQLClob.java?rev=730163&r1=730162&r2=730163&view=diff
==============================================================================
--- db/derby/code/branches/10.4/java/engine/org/apache/derby/iapi/types/CollatorSQLClob.java
(original)
+++ db/derby/code/branches/10.4/java/engine/org/apache/derby/iapi/types/CollatorSQLClob.java
Tue Dec 30 08:23:36 2008
@@ -164,6 +164,16 @@
 		 return holderForCollationSensitiveInfo.stringCompare(char1, char2);
 	 }
 
+     /**
+      * Return a hash code that is consistent with
+      * {@link #stringCompare(SQLChar, SQLChar)}.
+      *
+      * @return hash code
+      */
+     public int hashCode() {
+         return hashCodeForCollation();
+     }
+
 	/**
 	 * This method implements the like function for char (with no escape value).
 	 * The difference in this method and the same method in superclass is that

Modified: db/derby/code/branches/10.4/java/engine/org/apache/derby/iapi/types/CollatorSQLLongvarchar.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.4/java/engine/org/apache/derby/iapi/types/CollatorSQLLongvarchar.java?rev=730163&r1=730162&r2=730163&view=diff
==============================================================================
--- db/derby/code/branches/10.4/java/engine/org/apache/derby/iapi/types/CollatorSQLLongvarchar.java
(original)
+++ db/derby/code/branches/10.4/java/engine/org/apache/derby/iapi/types/CollatorSQLLongvarchar.java
Tue Dec 30 08:23:36 2008
@@ -165,6 +165,16 @@
 		 return holderForCollationSensitiveInfo.stringCompare(char1, char2);
 	 }
 
+    /**
+      * Return a hash code that is consistent with
+      * {@link #stringCompare(SQLChar, SQLChar)}.
+      *
+      * @return hash code
+      */
+     public int hashCode() {
+         return hashCodeForCollation();
+     }
+
 	/**
 	 * This method implements the like function for char (with no escape value).
 	 * The difference in this method and the same method in superclass is that

Modified: db/derby/code/branches/10.4/java/engine/org/apache/derby/iapi/types/CollatorSQLVarchar.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.4/java/engine/org/apache/derby/iapi/types/CollatorSQLVarchar.java?rev=730163&r1=730162&r2=730163&view=diff
==============================================================================
--- db/derby/code/branches/10.4/java/engine/org/apache/derby/iapi/types/CollatorSQLVarchar.java
(original)
+++ db/derby/code/branches/10.4/java/engine/org/apache/derby/iapi/types/CollatorSQLVarchar.java
Tue Dec 30 08:23:36 2008
@@ -171,6 +171,16 @@
 		 return holderForCollationSensitiveInfo.stringCompare(char1, char2);
 	 }
 
+     /**
+      * Return a hash code that is consistent with
+      * {@link #stringCompare(SQLChar, SQLChar)}.
+      *
+      * @return hash code
+      */
+     public int hashCode() {
+         return hashCodeForCollation();
+     }
+
 	/**
 	 * This method implements the like function for char (with no escape value).
 	 * The difference in this method and the same method in superclass is that

Modified: db/derby/code/branches/10.4/java/engine/org/apache/derby/iapi/types/SQLChar.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.4/java/engine/org/apache/derby/iapi/types/SQLChar.java?rev=730163&r1=730162&r2=730163&view=diff
==============================================================================
--- db/derby/code/branches/10.4/java/engine/org/apache/derby/iapi/types/SQLChar.java (original)
+++ db/derby/code/branches/10.4/java/engine/org/apache/derby/iapi/types/SQLChar.java Tue Dec
30 08:23:36 2008
@@ -2655,6 +2655,11 @@
      */
     public int hashCode()
     {
+        if (SanityManager.DEBUG) {
+            SanityManager.ASSERT(!(this instanceof CollationElementsInterface),
+                    "SQLChar.hashCode() does not work with collation");
+        }
+
         try {
             if (getString() == null)
             {
@@ -2703,6 +2708,24 @@
     }
 
     /**
+     * Hash code implementation for collator sensitive subclasses.
+     */
+    int hashCodeForCollation() {
+        CollationKey key = null;
+
+        try {
+            key = getCollationKey();
+        } catch (StandardException se) {
+            // ignore exceptions, like we do in hashCode()
+            if (SanityManager.DEBUG) {
+                SanityManager.THROWASSERT("Unexpected exception", se);
+            }
+        }
+
+        return key == null ? 0 : key.hashCode();
+    }
+
+    /**
      * Get a SQLVarchar for a built-in string function.  
      *
      * @return a SQLVarchar.

Modified: db/derby/code/branches/10.4/java/testing/org/apache/derbyTesting/functionTests/tests/lang/CollationTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.4/java/testing/org/apache/derbyTesting/functionTests/tests/lang/CollationTest.java?rev=730163&r1=730162&r2=730163&view=diff
==============================================================================
--- db/derby/code/branches/10.4/java/testing/org/apache/derbyTesting/functionTests/tests/lang/CollationTest.java
(original)
+++ db/derby/code/branches/10.4/java/testing/org/apache/derbyTesting/functionTests/tests/lang/CollationTest.java
Tue Dec 30 08:23:36 2008
@@ -257,39 +257,58 @@
       //End of parameter testing
       
       s.close();
-      compareAgrave(1,1);
+      compareAgrave(1, 1, 2);
       }
       
 
 public void testFrenchCollation() throws SQLException {
-    compareAgrave(2,1);    
+    compareAgrave(2, 1, 1);
 }
 
 
 
- /**
- * For a TERRITORY_BASED collation french database, differences between pre-composed accents
such 
- * as "\u00C0" (A-grave) and combining accents such as "A\u0300" (A, combining-grave) should
match
- * for = and like. But they do not match for UCS_BASIC. We insert both into a table and search
- * based on equal and like. 
+/**
+ * For a TERRITORY_BASED collation french database, differences between
+ * pre-composed accents such as "\u00C0" (A-grave) and combining accents
+ * such as "A\u0300" (A, combining-grave) should match for {@code =}, but
+ * not for {@code LIKE}. They should never match for UCS_BASIC. We insert
+ * both into a table and search based on {@code =} and {@code LIKE}.
  *  
  * @param expectedMatchCountForEqual  number of rows we expect back for =. 
  * 	2 for French, 1 for English 
  * @param expectedMatchCountForLike  number of rows we expect back for LIKE. 
  * 	1 for French and English 
+ * @param expectedDistinctRows number of rows expected from SELECT DISTINCT
  * @throws SQLException
  */
 private void compareAgrave(int expectedMatchCountForEqual,
-		int expectedMatchCountForLike) throws SQLException {
-      
+        int expectedMatchCountForLike, int expectedDistinctRows)
+            throws SQLException {
+    String[] dataTypes = {"VARCHAR(5)", "CHAR(5)"};
+    for (int i = 0; i < dataTypes.length; i++) {
+        compareAgrave(dataTypes[i], expectedMatchCountForEqual,
+                expectedMatchCountForLike, expectedDistinctRows);
+    }
+}
+
+/**
+ * Helper for {@link #compareAgrave(int, int, int)} which performs the test
+ * for one data type.
+ */
+private void compareAgrave(String dataType, int expectedMatchCountForEqual,
+		int expectedMatchCountForLike, int expectedDistinctRows)
+            throws SQLException {
+
+      // Create the two strings that are supposed to be equal in French locale.
       String agrave = "\u00C0";
       String agraveCombined ="A\u0300";
+
       Statement s = createStatement();
       
       try {
           s.executeUpdate("DROP TABLE T");
       }catch (SQLException se) {}
-      s.executeUpdate("CREATE TABLE T (vc varchar(30))");
+      s.executeUpdate("CREATE TABLE T (vc " + dataType + ")");
       PreparedStatement ps = prepareStatement("INSERT INTO T VALUES (?)");
       ps.setString(1,agrave);
       ps.executeUpdate();
@@ -300,12 +319,18 @@
       ps.setString(1, agrave);
       ResultSet rs = ps.executeQuery();
       JDBC.assertSingleValueResultSet(rs, Integer.toString(expectedMatchCountForEqual));
-      ps = prepareStatement("SELECT COUNT(*) FROM T WHERE VC LIKE ?");
+      // Use '%' at the end of the pattern so that we also match the trailing
+      // blanks if the data type is CHAR instead of VARCHAR.
+      ps = prepareStatement("SELECT COUNT(*) FROM T WHERE VC LIKE ? || '%'");
       ps.setString(1, agrave);
       rs = ps.executeQuery();
       JDBC.assertSingleValueResultSet(rs, Integer.toString(expectedMatchCountForLike));
 
-
+      // DERBY-3975: They should match for distinct, the same way as for =
+      int distinctRows = JDBC.assertDrainResults(
+              s.executeQuery("SELECT DISTINCT VC FROM T"));
+      assertEquals("Unexpected number of distinct rows",
+              expectedDistinctRows, distinctRows);
   }
 
 



Mime
View raw message