You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by sl...@apache.org on 2014/08/06 11:10:46 UTC

[3/4] git commit: Bogus deserialization of static cells from sstable

Bogus deserialization of static cells from sstable

patch by slebresne; reviewed by iamaleksey for CASSANDRA-7684


Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/cd84cc9e
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/cd84cc9e
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/cd84cc9e

Branch: refs/heads/cassandra-2.1
Commit: cd84cc9ec63a1b7831262b87f29e0f4313a6eab2
Parents: 1adc39f
Author: Sylvain Lebresne <sy...@datastax.com>
Authored: Wed Aug 6 10:17:39 2014 +0200
Committer: Sylvain Lebresne <sy...@datastax.com>
Committed: Wed Aug 6 10:17:39 2014 +0200

----------------------------------------------------------------------
 CHANGES.txt                                     |  1 +
 .../AbstractCompoundCellNameType.java           | 21 +++++++++++-------
 .../org/apache/cassandra/cql3/CQLTester.java    | 22 +++++++++++++++++++
 .../apache/cassandra/cql3/UserTypesTest.java    | 23 ++++++++++++++++++++
 4 files changed, 59 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/cd84cc9e/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index f650182..e8a0f6f 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -2,6 +2,7 @@
  * cqlsh DESC CLUSTER fails retrieving ring information (CASSANDRA-7687)
  * Fix binding null values inside UDT (CASSANDRA-7685)
  * Fix UDT field selection with empty fields (CASSANDRA-7670)
+ * Bogus deserialization of static cells from sstable (CASSANDRA-7684)
 Merged from 2.0:
  * Update java driver (for hadoop) (CASSANDRA-7618)
  * Support connecting to ipv6 jmx with nodetool (CASSANDRA-7669)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/cd84cc9e/src/java/org/apache/cassandra/db/composites/AbstractCompoundCellNameType.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/composites/AbstractCompoundCellNameType.java b/src/java/org/apache/cassandra/db/composites/AbstractCompoundCellNameType.java
index 641f14d..bf303a7 100644
--- a/src/java/org/apache/cassandra/db/composites/AbstractCompoundCellNameType.java
+++ b/src/java/org/apache/cassandra/db/composites/AbstractCompoundCellNameType.java
@@ -217,20 +217,17 @@ public abstract class AbstractCompoundCellNameType extends AbstractCellNameType
             return ((nextFull[nextIdx++] & 0xFF) << 8) | (nextFull[nextIdx++] & 0xFF);
         }
 
+        private int peekShort()
+        {
+            return ((nextFull[nextIdx] & 0xFF) << 8) | (nextFull[nextIdx+1] & 0xFF);
+        }
+
         private boolean deserializeOne()
         {
             if (allComponentsDeserialized())
                 return false;
 
-            nextIsStatic = false;
-
             int length = readShort();
-            if (length == CompositeType.STATIC_MARKER)
-            {
-                nextIsStatic = true;
-                length = readShort();
-            }
-
             ByteBuffer component = ByteBuffer.wrap(nextFull, nextIdx, length);
             nextIdx += length;
             nextComponents[nextSize++] = component;
@@ -267,6 +264,14 @@ public abstract class AbstractCompoundCellNameType extends AbstractCellNameType
 
             nextFull = new byte[length];
             in.readFully(nextFull);
+
+            // Is is a static?
+            nextIsStatic = false;
+            if (peekShort() == CompositeType.STATIC_MARKER)
+            {
+                nextIsStatic = true;
+                readShort(); // Skip the static marker
+            }
         }
 
         public Composite readNext() throws IOException

http://git-wip-us.apache.org/repos/asf/cassandra/blob/cd84cc9e/test/unit/org/apache/cassandra/cql3/CQLTester.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/cql3/CQLTester.java b/test/unit/org/apache/cassandra/cql3/CQLTester.java
index f3d0a6f..442c8b1 100644
--- a/test/unit/org/apache/cassandra/cql3/CQLTester.java
+++ b/test/unit/org/apache/cassandra/cql3/CQLTester.java
@@ -21,6 +21,7 @@ import java.io.File;
 import java.nio.ByteBuffer;
 import java.util.*;
 import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicInteger;
 
@@ -36,6 +37,7 @@ import org.slf4j.LoggerFactory;
 import org.apache.cassandra.SchemaLoader;
 import org.apache.cassandra.db.ConsistencyLevel;
 import org.apache.cassandra.db.Directories;
+import org.apache.cassandra.db.Keyspace;
 import org.apache.cassandra.db.marshal.*;
 import org.apache.cassandra.exceptions.*;
 import org.apache.cassandra.io.util.FileUtils;
@@ -121,6 +123,23 @@ public abstract class CQLTester
         });
     }
 
+    public void flush()
+    {
+        try
+        {
+            if (currentTable != null)
+                Keyspace.open(KEYSPACE).getColumnFamilyStore(currentTable).forceFlush().get();
+        }
+        catch (InterruptedException e)
+        {
+            throw new RuntimeException(e);
+        }
+        catch (ExecutionException e)
+        {
+            throw new RuntimeException(e);
+        }
+    }
+
     private static void removeAllSSTables(String ks, String table)
     {
         // clean up data directory which are stored as data directory/keyspace/data files
@@ -529,6 +548,9 @@ public abstract class CQLTester
         if (value instanceof String)
             return UTF8Type.instance;
 
+        if (value instanceof Boolean)
+            return BooleanType.instance;
+
         if (value instanceof List)
         {
             List l = (List)value;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/cd84cc9e/test/unit/org/apache/cassandra/cql3/UserTypesTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/cql3/UserTypesTest.java b/test/unit/org/apache/cassandra/cql3/UserTypesTest.java
index a8fd7a4..c7f1851 100644
--- a/test/unit/org/apache/cassandra/cql3/UserTypesTest.java
+++ b/test/unit/org/apache/cassandra/cql3/UserTypesTest.java
@@ -30,4 +30,27 @@ public class UserTypesTest extends CQLTester
         // 's' is not a field of myType
         assertInvalid("INSERT INTO %s (k, v) VALUES (?, {s : ?})", 0, 1);
     }
+
+
+    @Test
+    public void testFor7684() throws Throwable
+    {
+        String myType = createType("CREATE TYPE %s (x double)");
+        createTable("CREATE TABLE %s (k int, v " + myType + ", b boolean static, PRIMARY KEY (k, v))");
+
+        execute("INSERT INTO %s(k, v) VALUES (?, {x:?})", 1, -104.99251);
+        execute("UPDATE %s SET b = ? WHERE k = ?", true, 1);
+
+        System.out.println("-- First query");
+        assertRows(execute("SELECT v.x FROM %s WHERE k = ? AND v = {x:?}", 1, -104.99251),
+            row(-104.99251)
+        );
+
+        flush();
+
+        System.out.println("-- 2nd query");
+        assertRows(execute("SELECT v.x FROM %s WHERE k = ? AND v = {x:?}", 1, -104.99251),
+            row(-104.99251)
+        );
+    }
 }