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 kr...@apache.org on 2011/09/24 16:20:22 UTC

svn commit: r1175171 - in /db/derby/code/branches/10.8: ./ java/client/org/apache/derby/client/net/ java/engine/org/apache/derby/impl/store/access/btree/ java/engine/org/apache/derby/impl/store/access/btree/index/ java/engine/org/apache/derby/impl/stor...

Author: kristwaa
Date: Sat Sep 24 14:20:22 2011
New Revision: 1175171

URL: http://svn.apache.org/viewvc?rev=1175171&view=rev
Log:
DERBY-5367: Stale data retrieved when using new collation=TERRITORY_BASED:PRIMARY feature

Merged fix from trunk (revision 1174436).

Modified:
    db/derby/code/branches/10.8/   (props changed)
    db/derby/code/branches/10.8/java/client/org/apache/derby/client/net/NetCursor.java   (props changed)
    db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/store/access/btree/BTree.java
    db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/store/access/btree/BTreeController.java
    db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/store/access/btree/OpenBTree.java
    db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/store/access/btree/index/B2I.java
    db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/store/access/conglomerate/ConglomerateUtil.java
    db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/store/access/conglomerate/GenericConglomerate.java
    db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/store/access/conglomerate/OpenConglomerate.java
    db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/store/access/conglomerate/OpenConglomerateScratchSpace.java
    db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/store/access/heap/Heap.java
    db/derby/code/branches/10.8/java/testing/org/apache/derbyTesting/functionTests/tests/lang/CollationTest2.java

Propchange: db/derby/code/branches/10.8/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Sat Sep 24 14:20:22 2011
@@ -1,2 +1,2 @@
 /db/derby/code/branches/10.7:1061570,1061578,1082235
-/db/derby/code/trunk:1063809,1088633,1089795,1091000,1091221,1091285,1092067,1092795,1094315,1094572,1094728,1095247,1096741,1096890,1096991,1097247,1097249,1097460,1097469,1097471,1098033,1101059,1101839,1102620,1102826,1103681,1103718,1103742,1104365,1125305,1126358,1126468,1127825,1127883,1128243,1128942,1129136,1129764,1129797,1130077,1130084,1130632,1130895,1131030,1131272,1132546,1132664,1132747,1132860,1132928,1133304,1133317,1133741,1133752,1134139,1136363,1136371,1136397,1136844,1137213,1138201,1138341,1138444,1138787,1138795,1139449,1139451,1140222,1140744,1141924,1142583,1142635,1145057,1146644,1146915,1146962,1147219,1147242,1147335,1148344,1148354,1148429,1148658,1149054,1149090,1149270,1149482,1149662,1151101,1151612,1158108,1160593,1160597,1161208,1162737,1163131,1163616,1164358,1164370,1164495,1165221,1167017,1167470,1169692,1171665,1171672,1173446,1173647,1174646
+/db/derby/code/trunk:1063809,1088633,1089795,1091000,1091221,1091285,1092067,1092795,1094315,1094572,1094728,1095247,1096741,1096890,1096991,1097247,1097249,1097460,1097469,1097471,1098033,1101059,1101839,1102620,1102826,1103681,1103718,1103742,1104365,1125305,1126358,1126468,1127825,1127883,1128243,1128942,1129136,1129764,1129797,1130077,1130084,1130632,1130895,1131030,1131272,1132546,1132664,1132747,1132860,1132928,1133304,1133317,1133741,1133752,1134139,1136363,1136371,1136397,1136844,1137213,1138201,1138341,1138444,1138787,1138795,1139449,1139451,1140222,1140744,1141924,1142583,1142635,1145057,1146644,1146915,1146962,1147219,1147242,1147335,1148344,1148354,1148429,1148658,1149054,1149090,1149270,1149482,1149662,1151101,1151612,1158108,1160593,1160597,1161208,1162737,1163131,1163616,1164358,1164370,1164495,1165221,1167017,1167470,1169692,1171665,1171672,1173446,1173647,1174436,1174646

Propchange: db/derby/code/branches/10.8/java/client/org/apache/derby/client/net/NetCursor.java
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Sat Sep 24 14:20:22 2011
@@ -1,2 +1,2 @@
 /db/derby/code/branches/10.7/java/client/org/apache/derby/client/net/NetCursor.java:1061570,1061578,1082235
-/db/derby/code/trunk/java/client/org/apache/derby/client/net/NetCursor.java:1063809,1088633,1089795,1091000,1091221,1091285,1092067,1092795,1094315,1094572,1094728,1095247,1096741,1096890,1096991,1097247,1097249,1097460,1097469,1097471,1098033,1101059,1101839,1102620,1102826,1103681,1103718,1103742,1104365,1125305,1126358,1126468,1127825,1127883,1128243,1128942,1129136,1129764,1129797,1130077,1130084,1130632,1130895,1131030,1131272,1132546,1132664,1132747,1132860,1132928,1133304,1133317,1133741,1133752,1134139,1136363,1136371,1136397,1136844,1137213,1138201,1138341,1138444,1138787,1138795,1139449,1139451,1140222,1140744,1141924,1142583,1142635,1145057,1145961,1146644,1146915,1146962,1147219,1147242,1147335,1148344,1148354,1148429,1148658,1149054,1149090,1149270,1149482,1149662,1151101,1151612,1158108,1160593,1160597,1161208,1162737,1163131,1163616,1164358,1164370,1164495,1165221,1167017,1167470,1169692,1171665,1171672,1173647
+/db/derby/code/trunk/java/client/org/apache/derby/client/net/NetCursor.java:1063809,1088633,1089795,1091000,1091221,1091285,1092067,1092795,1094315,1094572,1094728,1095247,1096741,1096890,1096991,1097247,1097249,1097460,1097469,1097471,1098033,1101059,1101839,1102620,1102826,1103681,1103718,1103742,1104365,1125305,1126358,1126468,1127825,1127883,1128243,1128942,1129136,1129764,1129797,1130077,1130084,1130632,1130895,1131030,1131272,1132546,1132664,1132747,1132860,1132928,1133304,1133317,1133741,1133752,1134139,1136363,1136371,1136397,1136844,1137213,1138201,1138341,1138444,1138787,1138795,1139449,1139451,1140222,1140744,1141924,1142583,1142635,1145057,1145961,1146644,1146915,1146962,1147219,1147242,1147335,1148344,1148354,1148429,1148658,1149054,1149090,1149270,1149482,1149662,1151101,1151612,1158108,1160593,1160597,1161208,1162737,1163131,1163616,1164358,1164370,1164495,1165221,1167017,1167470,1169692,1171665,1171672,1173647,1174436

Modified: db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/store/access/btree/BTree.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/store/access/btree/BTree.java?rev=1175171&r1=1175170&r2=1175171&view=diff
==============================================================================
--- db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/store/access/btree/BTree.java (original)
+++ db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/store/access/btree/BTree.java Sat Sep 24 14:20:22 2011
@@ -57,8 +57,6 @@ import java.io.ObjectInput;
 
 import java.util.Properties;
 
-import org.apache.derby.iapi.services.io.ArrayUtil;
-
 /**
 
   A b-tree object corresponds to an instance of a b-tree conglomerate.  It 
@@ -192,6 +190,11 @@ public abstract class BTree extends Gene
     The array of collation id's for each column in the template.
     **/
     protected int[]   collation_ids;
+    /**
+     * Tells if there is at least one column in the conglomerate whose collation
+     * isn't StringDataValue.COLLATION_TYPE_UCS_BASIC.
+     */
+    protected boolean hasCollatedTypes;
 
 
 	/*
@@ -586,7 +589,8 @@ public abstract class BTree extends Gene
     public DynamicCompiledOpenConglomInfo getDynamicCompiledConglomInfo()
 		throws StandardException
     {
-        return(new OpenConglomerateScratchSpace(format_ids, collation_ids));
+        return(new OpenConglomerateScratchSpace(
+                format_ids, collation_ids, hasCollatedTypes));
     }
 
 

Modified: db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/store/access/btree/BTreeController.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/store/access/btree/BTreeController.java?rev=1175171&r1=1175170&r2=1175171&view=diff
==============================================================================
--- db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/store/access/btree/BTreeController.java (original)
+++ db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/store/access/btree/BTreeController.java Sat Sep 24 14:20:22 2011
@@ -51,7 +51,6 @@ import org.apache.derby.iapi.types.RowLo
 
 import org.apache.derby.iapi.services.io.FormatableBitSet;
 import org.apache.derby.impl.store.access.conglomerate.ConglomerateUtil;
-import org.apache.derby.impl.store.access.conglomerate.TemplateRow;
 
 /**
 
@@ -845,17 +844,44 @@ public class BTreeController extends Ope
                             insert_slot, false, this.btree_undo);
 
                         boolean update_succeeded = true;
-
                         try 
                         {
-                            int rowloc_index = 
-                                this.getConglomerate().nKeyFields - 1;
-                            targetleaf.page.updateFieldAtSlot(
-                                insert_slot, rowloc_index, 
-                                (DataValueDescriptor) RowUtil.getColumn(
-                                    rowToInsert, 
-                                    (FormatableBitSet) null, rowloc_index),
-                                this.btree_undo);
+                            if (runtime_mem.hasCollatedTypes())
+                            {
+                                // See DERBY-5367.
+                                // There are types in the BTree with a 
+                                // collation different than UCS BASIC, we
+                                // update all fields to make sure they hold
+                                // the correct values.
+                                // NOTE: We could optimize here by only
+                                // updating the fields that actually hold
+                                // collated types.
+                                int rowsToUpdate = getConglomerate().nKeyFields;
+                                for (int i=0; i < rowsToUpdate; i++) {
+                                targetleaf.page.updateFieldAtSlot(
+                                    insert_slot, i, 
+                                    (DataValueDescriptor) RowUtil.getColumn(
+                                        rowToInsert, 
+                                        (FormatableBitSet) null, i),
+                                    this.btree_undo);
+                                }
+                            }
+                            else
+                            {
+                                // There are no collated types in the BTree,
+                                // which means that the values currently
+                                // stored in the undeleted row are correct.
+                                // We simply update the row location to point
+                                // to the correct row in the heap.
+                                int rowloc_index =
+                                        this.getConglomerate().nKeyFields - 1;
+                                targetleaf.page.updateFieldAtSlot(
+                                    insert_slot, rowloc_index, 
+                                    (DataValueDescriptor) RowUtil.getColumn(
+                                        rowToInsert, 
+                                        (FormatableBitSet) null, rowloc_index),
+                                    this.btree_undo);
+                            }
                         }
                         catch (StandardException se)
                         {

Modified: db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/store/access/btree/OpenBTree.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/store/access/btree/OpenBTree.java?rev=1175171&r1=1175170&r2=1175171&view=diff
==============================================================================
--- db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/store/access/btree/OpenBTree.java (original)
+++ db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/store/access/btree/OpenBTree.java Sat Sep 24 14:20:22 2011
@@ -34,7 +34,6 @@ import org.apache.derby.iapi.store.acces
 import org.apache.derby.iapi.store.access.SpaceInfo;
 import org.apache.derby.iapi.store.raw.ContainerHandle;
 import org.apache.derby.iapi.store.raw.LockingPolicy;
-import org.apache.derby.iapi.store.raw.RecordHandle;
 import org.apache.derby.iapi.store.raw.Transaction;
 
 import org.apache.derby.iapi.types.DataValueDescriptor;
@@ -91,7 +90,6 @@ public class OpenBTree 
     **/
     protected int                           init_lock_level;
 
-    private DynamicCompiledOpenConglomInfo  init_dynamic_info;
     private boolean                         init_hold;
 
     /**
@@ -414,8 +412,6 @@ public class OpenBTree 
         // Isolation level of this btree.
         init_lock_level     = lock_level;
 
-        init_dynamic_info   = dynamic_info;
-
         init_hold           = hold;
 
 
@@ -429,9 +425,8 @@ public class OpenBTree 
         this.runtime_mem    = 
             (dynamic_info != null ? 
              ((OpenConglomerateScratchSpace) dynamic_info) : 
-             new OpenConglomerateScratchSpace(
-                 conglomerate.format_ids, 
-                 conglomerate.collation_ids));
+              (OpenConglomerateScratchSpace)
+                conglomerate.getDynamicCompiledConglomInfo());
 
 	}
 

Modified: db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/store/access/btree/index/B2I.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/store/access/btree/index/B2I.java?rev=1175171&r1=1175170&r2=1175171&view=diff
==============================================================================
--- db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/store/access/btree/index/B2I.java (original)
+++ db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/store/access/btree/index/B2I.java Sat Sep 24 14:20:22 2011
@@ -29,12 +29,9 @@ import java.util.Properties;
 import org.apache.derby.iapi.reference.SQLState;
 
 import org.apache.derby.iapi.services.io.ArrayInputStream;
-import org.apache.derby.iapi.services.io.FormatableBitSet;
 
 import org.apache.derby.iapi.services.sanity.SanityManager;
 import org.apache.derby.iapi.error.StandardException;
-import org.apache.derby.iapi.store.raw.Page;
-import org.apache.derby.impl.store.access.btree.ControlRow;
 
 import org.apache.derby.impl.store.access.conglomerate.ConglomerateUtil;
 import org.apache.derby.iapi.store.access.conglomerate.LogicalUndo;
@@ -66,7 +63,6 @@ import org.apache.derby.impl.store.acces
 
 import org.apache.derby.iapi.services.cache.ClassSize;
 
-import org.apache.derby.iapi.services.io.CompressedNumber;
 import org.apache.derby.iapi.services.io.FormatableBitSet;
 import org.apache.derby.iapi.services.io.StoredFormatIds;
 
@@ -596,6 +592,7 @@ public class B2I extends BTree
         // conglom state.
         collation_ids = 
             ConglomerateUtil.createCollationIds(template.length, collationIds);
+        hasCollatedTypes = hasCollatedColumns(collation_ids);
 
 		// Do the generic part of creating the b-tree.
 		super.create(
@@ -1156,6 +1153,9 @@ public class B2I extends BTree
         
         // In memory maintain a collation id per column in the template.
         collation_ids = new int[format_ids.length];
+        if (SanityManager.DEBUG) {
+            SanityManager.ASSERT(!hasCollatedTypes);
+        }
 
         // initialize all the entries to COLLATION_TYPE_UCS_BASIC, 
         // and then reset as necessary.  For version ACCESS_B2I_V3_ID,
@@ -1181,7 +1181,8 @@ public class B2I extends BTree
                     "length = " + collation_ids.length);
             }
 
-            ConglomerateUtil.readCollationIdArray(collation_ids, in);
+            hasCollatedTypes =
+                    ConglomerateUtil.readCollationIdArray(collation_ids, in);
         }
         else if (conglom_format_id != StoredFormatIds.ACCESS_B2I_V3_ID)
         {

Modified: db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/store/access/conglomerate/ConglomerateUtil.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/store/access/conglomerate/ConglomerateUtil.java?rev=1175171&r1=1175170&r2=1175171&view=diff
==============================================================================
--- db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/store/access/conglomerate/ConglomerateUtil.java (original)
+++ db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/store/access/conglomerate/ConglomerateUtil.java Sat Sep 24 14:20:22 2011
@@ -28,7 +28,6 @@ import org.apache.derby.iapi.services.io
 import org.apache.derby.iapi.services.io.Formatable;
 import org.apache.derby.iapi.services.io.FormatIdUtil;
 
-import org.apache.derby.iapi.store.access.ColumnOrdering;
 import org.apache.derby.iapi.store.access.RowUtil;
 
 import org.apache.derby.iapi.store.raw.FetchDescriptor;
@@ -310,9 +309,11 @@ public final class ConglomerateUtil
      *                           the sparse array from the stream.
      *                           
      * @param in                 The stream to read the collation info from.
+     * @return {@code true} if at least one column has a different collation
+     *      than UCS BASIC, {@code false} otherwise.
      *
      **/
-    public static void readCollationIdArray(
+    public static boolean readCollationIdArray(
     int[]           collation_id_array,
     ObjectInput     in)
         throws IOException
@@ -332,6 +333,7 @@ public final class ConglomerateUtil
             int array_index = CompressedNumber.readInt(in);
             collation_id_array[array_index] = CompressedNumber.readInt(in);
         }
+        return num_compressed_entries > 0;
 	}
 
 	/**

Modified: db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/store/access/conglomerate/GenericConglomerate.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/store/access/conglomerate/GenericConglomerate.java?rev=1175171&r1=1175170&r2=1175171&view=diff
==============================================================================
--- db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/store/access/conglomerate/GenericConglomerate.java (original)
+++ db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/store/access/conglomerate/GenericConglomerate.java Sat Sep 24 14:20:22 2011
@@ -30,8 +30,8 @@ import org.apache.derby.iapi.error.Stand
 import org.apache.derby.iapi.store.access.conglomerate.Conglomerate;
 
 import org.apache.derby.iapi.types.DataValueDescriptor;
-
 import org.apache.derby.iapi.types.DataType;
+import org.apache.derby.iapi.types.StringDataValue;
 
 import java.sql.ResultSet;
 import java.sql.SQLException;
@@ -210,4 +210,20 @@ public abstract class GenericConglomerat
         throw(StandardException.newException(
                 SQLState.HEAP_UNIMPLEMENTED_FEATURE));
 	}
+
+    /**
+     * Tells if there are columns with collations (other than UCS BASIC) in the
+     * given list of collation ids.
+     *
+     * @param collationIds collation ids for the conglomerate columns
+     * @return {@code true} if a collation other than UCS BASIC was found.
+     */
+    public static boolean hasCollatedColumns(int[] collationIds) {
+        for (int i=0; i < collationIds.length; i++) {
+            if (collationIds[i] != StringDataValue.COLLATION_TYPE_UCS_BASIC) {
+                return true;
+            }
+        }
+        return false;
+    }
 }

Modified: db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/store/access/conglomerate/OpenConglomerate.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/store/access/conglomerate/OpenConglomerate.java?rev=1175171&r1=1175170&r2=1175171&view=diff
==============================================================================
--- db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/store/access/conglomerate/OpenConglomerate.java (original)
+++ db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/store/access/conglomerate/OpenConglomerate.java Sat Sep 24 14:20:22 2011
@@ -876,7 +876,8 @@ public abstract class OpenConglomerate
         this.runtime_mem    = 
             (dynamic_info != null ? 
              ((OpenConglomerateScratchSpace) dynamic_info) : 
-             new OpenConglomerateScratchSpace(format_ids, collation_ids));
+             ((OpenConglomerateScratchSpace)
+                conglomerate.getDynamicCompiledConglomInfo()));
 
         // Is this an open for update or read?  This will
 		// be passed down to the raw store fetch methods, which allows

Modified: db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/store/access/conglomerate/OpenConglomerateScratchSpace.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/store/access/conglomerate/OpenConglomerateScratchSpace.java?rev=1175171&r1=1175170&r2=1175171&view=diff
==============================================================================
--- db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/store/access/conglomerate/OpenConglomerateScratchSpace.java (original)
+++ db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/store/access/conglomerate/OpenConglomerateScratchSpace.java Sat Sep 24 14:20:22 2011
@@ -32,6 +32,8 @@ import org.apache.derby.iapi.types.DataV
 
 import org.apache.derby.iapi.services.io.FormatableBitSet;
 
+import org.apache.derby.iapi.services.sanity.SanityManager;
+
 /**
 
 A utility class to store and use temporary scratch space associated with
@@ -74,8 +76,15 @@ public class OpenConglomerateScratchSpac
     /**
      * A complete array of format id's and collation_ids for this conglomerate.
      **/
-    private int[]                   format_ids;
-    private int[]                   collation_ids;
+    private final int[] format_ids;
+    private final int[] collation_ids;
+    /**
+     * Tells if there is at least one type in the conglomerate whose collation
+     * isn't StringDataValue.COLLATION_TYPE_UCS_BASIC. This can be determined
+     * by looking at the collation ids, but now the caller is passing in the
+     * value to avoid having to look at all the collation ids multiple times.
+     */
+    private final boolean hasCollatedTypes;
 
 
     /**
@@ -96,13 +105,21 @@ public class OpenConglomerateScratchSpac
      *
      * @param format_ids format identifiers for columns in the row
      * @param collation_ids collation identifiers for the columns in the row
+     * @param hasCollatedTypes whether there is at least one collated type with
+     *      a collation other than UCS BASIC in the conglomerate
      */
     public OpenConglomerateScratchSpace(
     int[]   format_ids,
-    int[]   collation_ids)
+    int[]   collation_ids,
+    boolean hasCollatedTypes)
     {
         this.format_ids     = format_ids;
         this.collation_ids  = collation_ids;
+        this.hasCollatedTypes = hasCollatedTypes;
+        if (SanityManager.DEBUG) {
+            SanityManager.ASSERT(GenericConglomerate.hasCollatedColumns(
+                        collation_ids) == hasCollatedTypes);
+        }
     }
 
     /**************************************************************************
@@ -220,4 +237,15 @@ public class OpenConglomerateScratchSpac
 
         return(scratch_row_position);
     }
+    
+    /**
+     * Tells if there is at least one column with a collation different
+     * than UCS BASIC in the conglomerate.
+     *
+     * @return {@code true} if there is at least one column with a collation
+     *      different than UCS BASIC.
+     */
+    public boolean hasCollatedTypes() {
+        return hasCollatedTypes;
+    }
 }

Modified: db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/store/access/heap/Heap.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/store/access/heap/Heap.java?rev=1175171&r1=1175170&r2=1175171&view=diff
==============================================================================
--- db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/store/access/heap/Heap.java (original)
+++ db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/store/access/heap/Heap.java Sat Sep 24 14:20:22 2011
@@ -42,7 +42,6 @@ import org.apache.derby.iapi.error.Stand
 
 import org.apache.derby.iapi.store.access.conglomerate.Conglomerate;
 import org.apache.derby.iapi.store.access.conglomerate.LogicalUndo;
-import org.apache.derby.iapi.store.access.conglomerate.TransactionManager;
 import org.apache.derby.iapi.store.access.conglomerate.ScanManager;
 import org.apache.derby.iapi.store.access.conglomerate.TransactionManager;
 
@@ -190,6 +189,11 @@ public class Heap 
     The array of collation id's for each column in the template.
     **/
     protected int[]   collation_ids;
+    /**
+     * Tells if there is at least one column in the conglomerate whose collation
+     * isn't StringDataValue.COLLATION_TYPE_UCS_BASIC.
+     */
+    private boolean hasCollatedTypes;
 
     private static final int BASE_MEMORY_USAGE = ClassSize.estimateBaseFromCatalog( Heap.class);
     private static final int CONTAINER_KEY_MEMORY_USAGE = ClassSize.estimateBaseFromCatalog( ContainerKey.class);
@@ -305,6 +309,7 @@ public class Heap 
         collation_ids = 
             ConglomerateUtil.createCollationIds(
                 format_ids.length, collationIds);
+        hasCollatedTypes = hasCollatedColumns(collation_ids);
 
         // need to open the container and insert the row.  Since we are
         // creating it no need to bother with locking since no one can get
@@ -580,7 +585,8 @@ public class Heap 
     public DynamicCompiledOpenConglomInfo getDynamicCompiledConglomInfo()
 		throws StandardException
     {
-        return(new OpenConglomerateScratchSpace(format_ids, collation_ids));
+        return(new OpenConglomerateScratchSpace(
+                format_ids, collation_ids, hasCollatedTypes));
     }
 
     /**
@@ -1202,6 +1208,9 @@ public class Heap 
 
         // In memory maintain a collation id per column in the template.
         collation_ids = new int[format_ids.length];
+        if (SanityManager.DEBUG) {
+            SanityManager.ASSERT(!hasCollatedTypes);
+        }
 
         // initialize all the entries to COLLATION_TYPE_UCS_BASIC, 
         // and then reset as necessary.  For version ACCESS_HEAP_V2_ID,
@@ -1213,7 +1222,8 @@ public class Heap 
         {
             // current format id, read collation info from disk
 
-            ConglomerateUtil.readCollationIdArray(collation_ids, in);
+            hasCollatedTypes =
+                    ConglomerateUtil.readCollationIdArray(collation_ids, in);
         }
         else if (conglom_format_id != StoredFormatIds.ACCESS_HEAP_V2_ID)
         {

Modified: db/derby/code/branches/10.8/java/testing/org/apache/derbyTesting/functionTests/tests/lang/CollationTest2.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.8/java/testing/org/apache/derbyTesting/functionTests/tests/lang/CollationTest2.java?rev=1175171&r1=1175170&r2=1175171&view=diff
==============================================================================
--- db/derby/code/branches/10.8/java/testing/org/apache/derbyTesting/functionTests/tests/lang/CollationTest2.java (original)
+++ db/derby/code/branches/10.8/java/testing/org/apache/derbyTesting/functionTests/tests/lang/CollationTest2.java Sat Sep 24 14:20:22 2011
@@ -34,25 +34,17 @@ import java.text.RuleBasedCollator;
 import java.util.Locale;
 import java.util.Properties; 
 
-import javax.sql.DataSource;
-
 import junit.framework.Assert;
 import junit.framework.Test;
 import junit.framework.TestSuite;
 
 import org.apache.derbyTesting.junit.BaseJDBCTestCase;
-import org.apache.derbyTesting.junit.DatabasePropertyTestSetup;
 import org.apache.derbyTesting.junit.Decorator;
 import org.apache.derbyTesting.junit.JDBC;
-import org.apache.derbyTesting.junit.JDBCDataSource;
 import org.apache.derbyTesting.junit.SystemPropertyTestSetup;
 import org.apache.derbyTesting.junit.SupportFilesSetup;
-import org.apache.derbyTesting.junit.SQLUtilities;
 import org.apache.derbyTesting.junit.TestConfiguration;
 
-import org.apache.derby.iapi.services.sanity.SanityManager;
-
-
 /**
 Junit test targeted at testing language based Collation.
 
@@ -94,6 +86,10 @@ T24: (DONE) DERBY-2669 If no territory a
             of Database.
 
 
+<p>
+NOTE: The prefix "ci_test" is used for tests that require a case insensitive
+      collation order.
+
 **/
 
 public class CollationTest2 extends BaseJDBCTestCase 
@@ -902,6 +898,55 @@ public class CollationTest2 extends Base
         dropTable();
     }
 
+    /**
+     * Tests that DERBY-5367 is fixed, a bug where updating the index in a
+     * database with a case insensitive collation resulted in data corruption.
+     * <p>
+     * The bug tested is where a deleted row with an incorrect key value in
+     * the index is undeleted as an optimized insert. In this case it was
+     * caused by the a case insensitive collation order, but other collation
+     * rules could cause this to happen as well.
+     */
+    public void ci_testDerby5367()
+            throws SQLException {
+        assertFalse(isDatabaseBasicCollation());
+        setAutoCommit(true);
+        String TABLE = "DERBY_5367";
+        Statement stmt = createStatement();
+        stmt.executeUpdate("create table " + TABLE + "(" +
+                "VAL varchar(10) not null unique)");
+        
+        // Run first time when the congloms were newly created.
+        runDerby5367TestCode(TABLE);
+
+        // Shut down the database, reboot. This will trigger the code to
+        // read the congloms from disk.
+        TestConfiguration.getCurrent().shutdownDatabase();
+        getConnection();
+
+        // Run second time, read congloms from disk.
+        runDerby5367TestCode(TABLE);
+        dropTable(TABLE);
+    }
+
+    /** Runs the core code for the DERBY-5367 test. */
+    private void runDerby5367TestCode(String table)
+            throws SQLException {
+        PreparedStatement sel = prepareStatement("select val from " + table +
+                " where val = 'Test'");
+        PreparedStatement ins = prepareStatement("insert into " + table +
+                " values ?");
+        ins.setString(1, "Test");
+        ins.executeUpdate();
+        JDBC.assertFullResultSet(sel.executeQuery(), new String[][] {{"Test"}});
+        Statement stmt = createStatement();
+        stmt.executeUpdate("delete from " + table + " where val = 'Test'");
+        ins.setString(1, "test");
+        ins.executeUpdate();
+        JDBC.assertFullResultSet(sel.executeQuery(), new String[][] {{"test"}});
+        stmt.executeUpdate("delete from " + table);
+    }
+
     /**************************************************************************
      * Private/Protected tests of This class:
      **************************************************************************
@@ -1920,6 +1965,7 @@ public class CollationTest2 extends Base
         TestSuite suite = new TestSuite("CollationTest2");
         suite.addTest(new CollationTest2("testDefaultCollation"));
         suite.addTest(collatedTest("en", "testEnglishCollation"));
+        suite.addTest(caseInsensitiveCollationSuite());
         
         // Only add tests for other locales if they are in fact supported 
         // by the jvm.
@@ -1961,4 +2007,17 @@ public class CollationTest2 extends Base
         return Decorator.territoryCollatedDatabase(
                 new CollationTest2(fixture), locale);
     }
+
+    /**
+     * Returns a suite of tests running with a collation strength resulting
+     * in case insensitivity.
+     *
+     * @return A suite of tests.
+     */
+    private static Test caseInsensitiveCollationSuite() {
+        TestSuite suite = new TestSuite("Case insensitive specific tests");
+        suite.addTest(new CollationTest2("ci_testDerby5367")); 
+        return Decorator.territoryCollatedCaseInsensitiveDatabase(
+                suite, "en_US");
+    }
 }