cassandra-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ble...@apache.org
Subject [1/5] cassandra git commit: Allow range deletions in CQL
Date Fri, 04 Sep 2015 19:14:19 GMT
Repository: cassandra
Updated Branches:
  refs/heads/trunk 10fa32931 -> 86faf8cb3


http://git-wip-us.apache.org/repos/asf/cassandra/blob/2e3727e3/test/unit/org/apache/cassandra/cql3/validation/operations/UpdateTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/cql3/validation/operations/UpdateTest.java b/test/unit/org/apache/cassandra/cql3/validation/operations/UpdateTest.java
index c5d153f..b939b7f 100644
--- a/test/unit/org/apache/cassandra/cql3/validation/operations/UpdateTest.java
+++ b/test/unit/org/apache/cassandra/cql3/validation/operations/UpdateTest.java
@@ -18,8 +18,11 @@
 
 package org.apache.cassandra.cql3.validation.operations;
 
+import java.util.Arrays;
+
 import org.junit.Test;
 
+import static org.apache.commons.lang3.StringUtils.isEmpty;
 import org.apache.cassandra.cql3.CQLTester;
 import org.apache.cassandra.utils.ByteBufferUtil;
 
@@ -83,4 +86,448 @@ public class UpdateTest extends CQLTester
         assertInvalid("UPDATE %s SET d = (int)3 WHERE k = ?", 0);
         assertInvalid("UPDATE %s SET i = (double)3 WHERE k = ?", 0);
     }
+
+    @Test
+    public void testUpdate() throws Throwable
+    {
+        testUpdate(false);
+        testUpdate(true);
+    }
+
+    private void testUpdate(boolean forceFlush) throws Throwable
+    {
+        for (String compactOption : new String[] {"", " WITH COMPACT STORAGE" })
+        {
+            createTable("CREATE TABLE %s (partitionKey int," +
+                    "clustering_1 int," +
+                    "value int," +
+                    " PRIMARY KEY (partitionKey, clustering_1))" + compactOption);
+
+            execute("INSERT INTO %s (partitionKey, clustering_1, value) VALUES (0, 0, 0)");
+            execute("INSERT INTO %s (partitionKey, clustering_1, value) VALUES (0, 1, 1)");
+            execute("INSERT INTO %s (partitionKey, clustering_1, value) VALUES (0, 2, 2)");
+            execute("INSERT INTO %s (partitionKey, clustering_1, value) VALUES (0, 3, 3)");
+            execute("INSERT INTO %s (partitionKey, clustering_1, value) VALUES (1, 0, 4)");
+
+            flush(forceFlush);
+
+            execute("UPDATE %s SET value = ? WHERE partitionKey = ? AND clustering_1 = ?",
7, 0, 1);
+            flush(forceFlush);
+            assertRows(execute("SELECT value FROM %s WHERE partitionKey = ? AND clustering_1
= ?",
+                               0, 1),
+                       row(7));
+
+            execute("UPDATE %s SET value = ? WHERE partitionKey = ? AND (clustering_1) =
(?)", 8, 0, 2);
+            flush(forceFlush);
+            assertRows(execute("SELECT value FROM %s WHERE partitionKey = ? AND clustering_1
= ?",
+                               0, 2),
+                       row(8));
+
+            execute("UPDATE %s SET value = ? WHERE partitionKey IN (?, ?) AND clustering_1
= ?", 9, 0, 1, 0);
+            flush(forceFlush);
+            assertRows(execute("SELECT * FROM %s WHERE partitionKey IN (?, ?) AND clustering_1
= ?",
+                               0, 1, 0),
+                       row(0, 0, 9),
+                       row(1, 0, 9));
+
+            execute("UPDATE %s SET value = ? WHERE partitionKey IN ? AND clustering_1 = ?",
19, Arrays.asList(0, 1), 0);
+            flush(forceFlush);
+            assertRows(execute("SELECT * FROM %s WHERE partitionKey IN ? AND clustering_1
= ?",
+                               Arrays.asList(0, 1), 0),
+                       row(0, 0, 19),
+                       row(1, 0, 19));
+
+            execute("UPDATE %s SET value = ? WHERE partitionKey = ? AND clustering_1 IN (?,
?)", 10, 0, 1, 0);
+            flush(forceFlush);
+            assertRows(execute("SELECT * FROM %s WHERE partitionKey = ? AND clustering_1
IN (?, ?)",
+                               0, 1, 0),
+                       row(0, 0, 10),
+                       row(0, 1, 10));
+
+            execute("UPDATE %s SET value = ? WHERE partitionKey = ? AND (clustering_1) IN
((?), (?))", 20, 0, 0, 1);
+            flush(forceFlush);
+            assertRows(execute("SELECT * FROM %s WHERE partitionKey = ? AND (clustering_1)
IN ((?), (?))",
+                               0, 0, 1),
+                       row(0, 0, 20),
+                       row(0, 1, 20));
+
+            execute("UPDATE %s SET value = ? WHERE partitionKey = ? AND clustering_1 = ?",
null, 0, 0);
+            flush(forceFlush);
+
+            if (isEmpty(compactOption))
+            {
+                assertRows(execute("SELECT * FROM %s WHERE partitionKey = ? AND (clustering_1)
IN ((?), (?))",
+                                   0, 0, 1),
+                           row(0, 0, null),
+                           row(0, 1, 20));
+            }
+            else
+            {
+                assertRows(execute("SELECT * FROM %s WHERE partitionKey = ? AND (clustering_1)
IN ((?), (?))",
+                                   0, 0, 1),
+                           row(0, 1, 20));
+            }
+
+            // test invalid queries
+
+            // missing primary key element
+            assertInvalidMessage("Some partition key parts are missing: partitionkey",
+                                 "UPDATE %s SET value = ? WHERE clustering_1 = ? ", 7, 1);
+
+            assertInvalidMessage("Some clustering keys are missing: clustering_1",
+                                 "UPDATE %s SET value = ? WHERE partitionKey = ?", 7, 0);
+
+            assertInvalidMessage("Some clustering keys are missing: clustering_1",
+                                 "UPDATE %s SET value = ? WHERE partitionKey = ?", 7, 0);
+
+            // token function
+            assertInvalidMessage("The token function cannot be used in WHERE clauses for
UPDATE statements",
+                                 "UPDATE %s SET value = ? WHERE token(partitionKey) = token(?)
AND clustering_1 = ?",
+                                 7, 0, 1);
+
+            // multiple time the same value
+            assertInvalidSyntax("UPDATE %s SET value = ?, value = ? WHERE partitionKey =
? AND clustering_1 = ?", 7, 0, 1);
+
+            // multiple time same primary key element in WHERE clause
+            assertInvalidMessage("clustering_1 cannot be restricted by more than one relation
if it includes an Equal",
+                                 "UPDATE %s SET value = ? WHERE partitionKey = ? AND clustering_1
= ? AND clustering_1 = ?", 7, 0, 1, 1);
+
+            // unknown identifiers
+            assertInvalidMessage("Unknown identifier value1",
+                                 "UPDATE %s SET value1 = ? WHERE partitionKey = ? AND clustering_1
= ?", 7, 0, 1);
+
+            assertInvalidMessage("Undefined name partitionkey1 in where clause ('partitionkey1
= ?')",
+                                 "UPDATE %s SET value = ? WHERE partitionKey1 = ? AND clustering_1
= ?", 7, 0, 1);
+
+            assertInvalidMessage("Undefined name clustering_3 in where clause ('clustering_3
= ?')",
+                                 "UPDATE %s SET value = ? WHERE partitionKey = ? AND clustering_3
= ?", 7, 0, 1);
+
+            // Invalid operator in the where clause
+            assertInvalidMessage("Only EQ and IN relation are supported on the partition
key (unless you use the token() function)",
+                                 "UPDATE %s SET value = ? WHERE partitionKey > ? AND clustering_1
= ?", 7, 0, 1);
+
+            assertInvalidMessage("Cannot use CONTAINS on non-collection column partitionkey",
+                                 "UPDATE %s SET value = ? WHERE partitionKey CONTAINS ? AND
clustering_1 = ?", 7, 0, 1);
+
+            String expectedMsg = isEmpty(compactOption) ? "Non PRIMARY KEY columns found
in where clause: value"
+                                                        : "Predicates on the non-primary-key
column (value) of a COMPACT table are not yet supported";
+            assertInvalidMessage(expectedMsg,
+                                 "UPDATE %s SET value = ? WHERE partitionKey = ? AND clustering_1
= ? AND value = ?", 7, 0, 1, 3);
+
+            assertInvalidMessage("Slice restrictions are not supported on the clustering
columns in UPDATE statements",
+                                 "UPDATE %s SET value = ? WHERE partitionKey = ? AND clustering_1
> ?", 7, 0, 1);
+        }
+    }
+
+    @Test
+    public void testUpdateWithSecondaryIndices() throws Throwable
+    {
+        testUpdateWithSecondaryIndices(false);
+        testUpdateWithSecondaryIndices(true);
+    }
+
+    private void testUpdateWithSecondaryIndices(boolean forceFlush) throws Throwable
+    {
+        createTable("CREATE TABLE %s (partitionKey int," +
+                "clustering_1 int," +
+                "value int," +
+                "values set<int>," +
+                " PRIMARY KEY (partitionKey, clustering_1))");
+
+        createIndex("CREATE INDEX ON %s (value)");
+        createIndex("CREATE INDEX ON %s (clustering_1)");
+        createIndex("CREATE INDEX ON %s (values)");
+
+        execute("INSERT INTO %s (partitionKey, clustering_1, value, values) VALUES (0, 0,
0, {0})");
+        execute("INSERT INTO %s (partitionKey, clustering_1, value, values) VALUES (0, 1,
1, {0, 1})");
+        execute("INSERT INTO %s (partitionKey, clustering_1, value, values) VALUES (0, 2,
2, {0, 1, 2})");
+        execute("INSERT INTO %s (partitionKey, clustering_1, value, values) VALUES (0, 3,
3, {0, 1, 2, 3})");
+        execute("INSERT INTO %s (partitionKey, clustering_1, value, values) VALUES (1, 0,
4, {0, 1, 2, 3, 4})");
+
+        flush(forceFlush);
+
+        assertInvalidMessage("Non PRIMARY KEY columns found in where clause: value",
+                             "UPDATE %s SET values= {6} WHERE partitionKey = ? AND clustering_1
= ? AND value = ?", 3, 3, 3);
+        assertInvalidMessage("Non PRIMARY KEY columns found in where clause: values",
+                             "UPDATE %s SET value= ? WHERE partitionKey = ? AND clustering_1
= ? AND values CONTAINS ?", 6, 3, 3, 3);
+        assertInvalidMessage("Some clustering keys are missing: clustering_1",
+                             "UPDATE %s SET values= {6} WHERE partitionKey = ? AND value
= ?", 3, 3);
+        assertInvalidMessage("Some clustering keys are missing: clustering_1",
+                             "UPDATE %s SET value= ? WHERE partitionKey = ? AND values CONTAINS
?", 6, 3, 3);
+        assertInvalidMessage("Some partition key parts are missing: partitionkey",
+                             "UPDATE %s SET values= {6} WHERE clustering_1 = ?", 3);
+        assertInvalidMessage("Some partition key parts are missing: partitionkey",
+                             "UPDATE %s SET values= {6} WHERE value = ?", 3);
+        assertInvalidMessage("Some partition key parts are missing: partitionkey",
+                             "UPDATE %s SET value= ? WHERE values CONTAINS ?", 6, 3);
+    }
+
+    @Test
+    public void testUpdateWithTwoClusteringColumns() throws Throwable
+    {
+        testUpdateWithTwoClusteringColumns(false);
+        testUpdateWithTwoClusteringColumns(true);
+    }
+
+    private void testUpdateWithTwoClusteringColumns(boolean forceFlush) throws Throwable
+    {
+        for (String compactOption : new String[] { "", " WITH COMPACT STORAGE" })
+        {
+            createTable("CREATE TABLE %s (partitionKey int," +
+                    "clustering_1 int," +
+                    "clustering_2 int," +
+                    "value int," +
+                    " PRIMARY KEY (partitionKey, clustering_1, clustering_2))" + compactOption);
+
+            execute("INSERT INTO %s (partitionKey, clustering_1, clustering_2, value) VALUES
(0, 0, 0, 0)");
+            execute("INSERT INTO %s (partitionKey, clustering_1, clustering_2, value) VALUES
(0, 0, 1, 1)");
+            execute("INSERT INTO %s (partitionKey, clustering_1, clustering_2, value) VALUES
(0, 0, 2, 2)");
+            execute("INSERT INTO %s (partitionKey, clustering_1, clustering_2, value) VALUES
(0, 0, 3, 3)");
+            execute("INSERT INTO %s (partitionKey, clustering_1, clustering_2, value) VALUES
(0, 1, 1, 4)");
+            execute("INSERT INTO %s (partitionKey, clustering_1, clustering_2, value) VALUES
(0, 1, 2, 5)");
+            execute("INSERT INTO %s (partitionKey, clustering_1, clustering_2, value) VALUES
(1, 0, 0, 6)");
+            flush(forceFlush);
+
+            execute("UPDATE %s SET value = ? WHERE partitionKey = ? AND clustering_1 = ?
AND clustering_2 = ?", 7, 0, 1, 1);
+            flush(forceFlush);
+            assertRows(execute("SELECT value FROM %s WHERE partitionKey = ? AND clustering_1
= ? AND clustering_2 = ?",
+                               0, 1, 1),
+                       row(7));
+
+            execute("UPDATE %s SET value = ? WHERE partitionKey = ? AND (clustering_1, clustering_2)
= (?, ?)", 8, 0, 1, 2);
+            flush(forceFlush);
+            assertRows(execute("SELECT value FROM %s WHERE partitionKey = ? AND clustering_1
= ? AND clustering_2 = ?",
+                               0, 1, 2),
+                       row(8));
+
+            execute("UPDATE %s SET value = ? WHERE partitionKey IN (?, ?) AND clustering_1
= ? AND clustering_2 = ?", 9, 0, 1, 0, 0);
+            flush(forceFlush);
+            assertRows(execute("SELECT * FROM %s WHERE partitionKey IN (?, ?) AND clustering_1
= ? AND clustering_2 = ?",
+                               0, 1, 0, 0),
+                       row(0, 0, 0, 9),
+                       row(1, 0, 0, 9));
+
+            execute("UPDATE %s SET value = ? WHERE partitionKey IN ? AND clustering_1 = ?
AND clustering_2 = ?", 9, Arrays.asList(0, 1), 0, 0);
+            flush(forceFlush);
+            assertRows(execute("SELECT * FROM %s WHERE partitionKey IN ? AND clustering_1
= ? AND clustering_2 = ?",
+                               Arrays.asList(0, 1), 0, 0),
+                       row(0, 0, 0, 9),
+                       row(1, 0, 0, 9));
+
+            execute("UPDATE %s SET value = ? WHERE partitionKey = ? AND clustering_1 = ?
AND clustering_2 IN (?, ?)", 12, 0, 1, 1, 2);
+            flush(forceFlush);
+            assertRows(execute("SELECT * FROM %s WHERE partitionKey = ? AND clustering_1
= ? AND clustering_2 IN (?, ?)",
+                               0, 1, 1, 2),
+                       row(0, 1, 1, 12),
+                       row(0, 1, 2, 12));
+
+            execute("UPDATE %s SET value = ? WHERE partitionKey = ? AND clustering_1 IN (?,
?) AND clustering_2 IN (?, ?)", 10, 0, 1, 0, 1, 2);
+            flush(forceFlush);
+            assertRows(execute("SELECT * FROM %s WHERE partitionKey = ? AND clustering_1
IN (?, ?) AND clustering_2 IN (?, ?)",
+                               0, 1, 0, 1, 2),
+                       row(0, 0, 1, 10),
+                       row(0, 0, 2, 10),
+                       row(0, 1, 1, 10),
+                       row(0, 1, 2, 10));
+
+            execute("UPDATE %s SET value = ? WHERE partitionKey = ? AND (clustering_1, clustering_2)
IN ((?, ?), (?, ?))", 20, 0, 0, 2, 1, 2);
+            flush(forceFlush);
+            assertRows(execute("SELECT * FROM %s WHERE partitionKey = ? AND (clustering_1,
clustering_2) IN ((?, ?), (?, ?))",
+                               0, 0, 2, 1, 2),
+                       row(0, 0, 2, 20),
+                       row(0, 1, 2, 20));
+
+            execute("UPDATE %s SET value = ? WHERE partitionKey = ? AND clustering_1 = ?
AND clustering_2 = ?", null, 0, 0, 2);
+            flush(forceFlush);
+
+            if (isEmpty(compactOption))
+            {
+                assertRows(execute("SELECT * FROM %s WHERE partitionKey = ? AND (clustering_1,
clustering_2) IN ((?, ?), (?, ?))",
+                                   0, 0, 2, 1, 2),
+                           row(0, 0, 2, null),
+                           row(0, 1, 2, 20));
+            }
+            else
+            {
+                assertRows(execute("SELECT * FROM %s WHERE partitionKey = ? AND (clustering_1,
clustering_2) IN ((?, ?), (?, ?))",
+                                   0, 0, 2, 1, 2),
+                           row(0, 1, 2, 20));
+            }
+
+            // test invalid queries
+
+            // missing primary key element
+            assertInvalidMessage("Some partition key parts are missing: partitionkey",
+                                 "UPDATE %s SET value = ? WHERE clustering_1 = ? AND clustering_2
= ?", 7, 1, 1);
+
+            String errorMsg = isEmpty(compactOption) ? "Some clustering keys are missing:
clustering_1"
+                                                     : "PRIMARY KEY column \"clustering_2\"
cannot be restricted as preceding column \"clustering_1\" is not restricted";
+
+            assertInvalidMessage(errorMsg,
+                                 "UPDATE %s SET value = ? WHERE partitionKey = ? AND clustering_2
= ?", 7, 0, 1);
+
+            assertInvalidMessage("Some clustering keys are missing: clustering_1, clustering_2",
+                                 "UPDATE %s SET value = ? WHERE partitionKey = ?", 7, 0);
+
+            // token function
+            assertInvalidMessage("The token function cannot be used in WHERE clauses for
UPDATE statements",
+                                 "UPDATE %s SET value = ? WHERE token(partitionKey) = token(?)
AND clustering_1 = ? AND clustering_2 = ?",
+                                 7, 0, 1, 1);
+
+            // multiple time the same value
+            assertInvalidSyntax("UPDATE %s SET value = ?, value = ? WHERE partitionKey =
? AND clustering_1 = ? AND clustering_2 = ?", 7, 0, 1, 1);
+
+            // multiple time same primary key element in WHERE clause
+            assertInvalidMessage("clustering_1 cannot be restricted by more than one relation
if it includes an Equal",
+                                 "UPDATE %s SET value = ? WHERE partitionKey = ? AND clustering_1
= ? AND clustering_2 = ? AND clustering_1 = ?", 7, 0, 1, 1, 1);
+
+            // unknown identifiers
+            assertInvalidMessage("Unknown identifier value1",
+                                 "UPDATE %s SET value1 = ? WHERE partitionKey = ? AND clustering_1
= ? AND clustering_2 = ?", 7, 0, 1, 1);
+
+            assertInvalidMessage("Undefined name partitionkey1 in where clause ('partitionkey1
= ?')",
+                                 "UPDATE %s SET value = ? WHERE partitionKey1 = ? AND clustering_1
= ? AND clustering_2 = ?", 7, 0, 1, 1);
+
+            assertInvalidMessage("Undefined name clustering_3 in where clause ('clustering_3
= ?')",
+                                 "UPDATE %s SET value = ? WHERE partitionKey = ? AND clustering_1
= ? AND clustering_3 = ?", 7, 0, 1, 1);
+
+            // Invalid operator in the where clause
+            assertInvalidMessage("Only EQ and IN relation are supported on the partition
key (unless you use the token() function)",
+                                 "UPDATE %s SET value = ? WHERE partitionKey > ? AND clustering_1
= ? AND clustering_2 = ?", 7, 0, 1, 1);
+
+            assertInvalidMessage("Cannot use CONTAINS on non-collection column partitionkey",
+                                 "UPDATE %s SET value = ? WHERE partitionKey CONTAINS ? AND
clustering_1 = ? AND clustering_2 = ?", 7, 0, 1, 1);
+
+            String expectedMsg = isEmpty(compactOption) ? "Non PRIMARY KEY columns found
in where clause: value"
+                                                        : "Predicates on the non-primary-key
column (value) of a COMPACT table are not yet supported";
+            assertInvalidMessage(expectedMsg,
+                                 "UPDATE %s SET value = ? WHERE partitionKey = ? AND clustering_1
= ? AND clustering_2 = ? AND value = ?", 7, 0, 1, 1, 3);
+
+            assertInvalidMessage("Slice restrictions are not supported on the clustering
columns in UPDATE statements",
+                                 "UPDATE %s SET value = ? WHERE partitionKey = ? AND clustering_1
> ?", 7, 0, 1);
+
+            assertInvalidMessage("Slice restrictions are not supported on the clustering
columns in UPDATE statements",
+                                 "UPDATE %s SET value = ? WHERE partitionKey = ? AND (clustering_1,
clustering_2) > (?, ?)", 7, 0, 1, 1);
+        }
+    }
+
+    @Test
+    public void testUpdateWithMultiplePartitionKeyComponents() throws Throwable
+    {
+        testUpdateWithMultiplePartitionKeyComponents(false);
+        testUpdateWithMultiplePartitionKeyComponents(true);
+    }
+
+    public void testUpdateWithMultiplePartitionKeyComponents(boolean forceFlush) throws Throwable
+    {
+        for (String compactOption : new String[] { "", " WITH COMPACT STORAGE" })
+        {
+            createTable("CREATE TABLE %s (partitionKey_1 int," +
+                    "partitionKey_2 int," +
+                    "clustering_1 int," +
+                    "clustering_2 int," +
+                    "value int," +
+                    " PRIMARY KEY ((partitionKey_1, partitionKey_2), clustering_1, clustering_2))"
+ compactOption);
+
+            execute("INSERT INTO %s (partitionKey_1, partitionKey_2, clustering_1, clustering_2,
value) VALUES (0, 0, 0, 0, 0)");
+            execute("INSERT INTO %s (partitionKey_1, partitionKey_2, clustering_1, clustering_2,
value) VALUES (0, 1, 0, 1, 1)");
+            execute("INSERT INTO %s (partitionKey_1, partitionKey_2, clustering_1, clustering_2,
value) VALUES (0, 1, 1, 1, 2)");
+            execute("INSERT INTO %s (partitionKey_1, partitionKey_2, clustering_1, clustering_2,
value) VALUES (1, 0, 0, 1, 3)");
+            execute("INSERT INTO %s (partitionKey_1, partitionKey_2, clustering_1, clustering_2,
value) VALUES (1, 1, 0, 1, 3)");
+            flush(forceFlush);
+
+            execute("UPDATE %s SET value = ? WHERE partitionKey_1 = ? AND partitionKey_2
= ? AND clustering_1 = ? AND clustering_2 = ?", 7, 0, 0, 0, 0);
+            flush(forceFlush);
+            assertRows(execute("SELECT value FROM %s WHERE partitionKey_1 = ? AND partitionKey_2
= ? AND clustering_1 = ? AND clustering_2 = ?",
+                               0, 0, 0, 0),
+                       row(7));
+
+            execute("UPDATE %s SET value = ? WHERE partitionKey_1 IN (?, ?) AND partitionKey_2
= ? AND clustering_1 = ? AND clustering_2 = ?", 9, 0, 1, 1, 0, 1);
+            flush(forceFlush);
+            assertRows(execute("SELECT * FROM %s WHERE partitionKey_1 IN (?, ?) AND partitionKey_2
= ? AND clustering_1 = ? AND clustering_2 = ?",
+                               0, 1, 1, 0, 1),
+                       row(0, 1, 0, 1, 9),
+                       row(1, 1, 0, 1, 9));
+
+            execute("UPDATE %s SET value = ? WHERE partitionKey_1 IN (?, ?) AND partitionKey_2
IN (?, ?) AND clustering_1 = ? AND clustering_2 = ?", 10, 0, 1, 0, 1, 0, 1);
+            flush(forceFlush);
+            assertRows(execute("SELECT * FROM %s"),
+                       row(0, 0, 0, 0, 7),
+                       row(0, 0, 0, 1, 10),
+                       row(0, 1, 0, 1, 10),
+                       row(0, 1, 1, 1, 2),
+                       row(1, 0, 0, 1, 10),
+                       row(1, 1, 0, 1, 10));
+
+            // missing primary key element
+            assertInvalidMessage("Some partition key parts are missing: partitionkey_2",
+                                 "UPDATE %s SET value = ? WHERE partitionKey_1 = ? AND clustering_1
= ? AND clustering_2 = ?", 7, 1, 1);
+        }
+    }
+
+    @Test
+    public void testUpdateWithAStaticColumn() throws Throwable
+    {
+        testUpdateWithAStaticColumn(false);
+        testUpdateWithAStaticColumn(true);
+    }
+
+    private void testUpdateWithAStaticColumn(boolean forceFlush) throws Throwable
+    {
+        createTable("CREATE TABLE %s (partitionKey int," +
+                                      "clustering_1 int," +
+                                      "clustering_2 int," +
+                                      "value int," +
+                                      "staticValue text static," +
+                                      " PRIMARY KEY (partitionKey, clustering_1, clustering_2))");
+
+        execute("INSERT INTO %s (partitionKey, clustering_1, clustering_2, value, staticValue)
VALUES (0, 0, 0, 0, 'A')");
+        execute("INSERT INTO %s (partitionKey, clustering_1, clustering_2, value) VALUES
(0, 0, 1, 1)");
+        execute("INSERT INTO %s (partitionKey, clustering_1, clustering_2, value, staticValue)
VALUES (1, 0, 0, 6, 'B')");
+        flush(forceFlush);
+
+        execute("UPDATE %s SET staticValue = ? WHERE partitionKey = ?", "A2", 0);
+        flush(forceFlush);
+
+        assertRows(execute("SELECT DISTINCT staticValue FROM %s WHERE partitionKey = ?",
0),
+                   row("A2"));
+
+        assertInvalidMessage("Some clustering keys are missing: clustering_1, clustering_2",
+                             "UPDATE %s SET staticValue = ?, value = ? WHERE partitionKey
= ?", "A2", 7, 0);
+
+        execute("UPDATE %s SET staticValue = ?, value = ?  WHERE partitionKey = ? AND clustering_1
= ? AND clustering_2 = ?",
+                "A3", 7, 0, 0, 1);
+        flush(forceFlush);
+        assertRows(execute("SELECT * FROM %s WHERE partitionKey = ? AND clustering_1 = ?
AND clustering_2 = ?",
+                           0, 0, 1),
+                   row(0, 0, 1, "A3", 7));
+
+        assertInvalidMessage("Invalid restrictions on clustering columns since the UPDATE
statement modifies only static columns",
+                             "UPDATE %s SET staticValue = ? WHERE partitionKey = ? AND clustering_1
= ? AND clustering_2 = ?",
+                             "A3", 0, 0, 1);
+    }
+
+    @Test
+    public void testUpdateWithStaticList() throws Throwable
+    {
+        createTable("CREATE TABLE %s (k int," +
+                                      "clustering int," +
+                                      "value int," +
+                                      "l list<text> static," +
+                                      " PRIMARY KEY (k, clustering))");
+
+        execute("INSERT INTO %s(k, clustering, value, l) VALUES (?, ?, ?, ?)", 0, 0, 0 ,list("v1",
"v2", "v3"));
+
+        assertRows(execute("SELECT l FROM %s WHERE k = 0"), row(list("v1", "v2", "v3")));
+
+        execute("UPDATE %s SET l[?] = ? WHERE k = ?", 1, "v4", 0);
+
+        assertRows(execute("SELECT l FROM %s WHERE k = 0"), row(list("v1", "v4", "v3")));
+    }
+
+    private void flush(boolean forceFlush)
+    {
+        if (forceFlush)
+            flush();
+    }
 }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/2e3727e3/test/unit/org/apache/cassandra/db/RangeTombstoneListTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/db/RangeTombstoneListTest.java b/test/unit/org/apache/cassandra/db/RangeTombstoneListTest.java
index 79efb87..f40abe9 100644
--- a/test/unit/org/apache/cassandra/db/RangeTombstoneListTest.java
+++ b/test/unit/org/apache/cassandra/db/RangeTombstoneListTest.java
@@ -28,8 +28,6 @@ import com.google.common.base.Joiner;
 import org.junit.Test;
 import static org.junit.Assert.*;
 
-import org.apache.cassandra.Util;
-import org.apache.cassandra.db.*;
 import org.apache.cassandra.db.marshal.Int32Type;
 import org.apache.cassandra.utils.ByteBufferUtil;
 
@@ -346,6 +344,201 @@ public class RangeTombstoneListTest
         }
     }
 
+    @Test
+    public void nonSortedAdditionTestWithOneTombstoneWithEmptyEnd()
+    {
+        nonSortedAdditionTestWithOneRangeWithEmptyEnd(0);
+        nonSortedAdditionTestWithOneRangeWithEmptyEnd(10);
+    }
+
+  private static void nonSortedAdditionTestWithOneRangeWithEmptyEnd(int initialCapacity)
+    {
+        RangeTombstoneList l = new RangeTombstoneList(cmp, initialCapacity);
+        RangeTombstone rt1 = rt(1, 5, 3);
+        RangeTombstone rt2 = rt(7, 10, 2);
+        RangeTombstone rt3 = atLeast(11, 1, 0);
+
+        l.add(rt2);
+        l.add(rt3);
+        l.add(rt1);
+
+        Iterator<RangeTombstone> iter = l.iterator();
+        assertRT(rt1, iter.next());
+        assertRT(rt2, iter.next());
+        assertRT(rt3, iter.next());
+
+        assert !iter.hasNext();
+    }
+
+    @Test
+    public void addRangeWithEmptyEndWitchIncludeExistingRange()
+    {
+
+        RangeTombstoneList l = new RangeTombstoneList(cmp, 0);
+
+        l.add(rt(4, 10, 3));
+        l.add(atLeast(3, 4, 0));
+
+        Iterator<RangeTombstone> iter = l.iterator();
+        assertRT(atLeast(3, 4, 0), iter.next());
+        assertFalse(iter.hasNext());
+    }
+
+    @Test
+    public void addRangeWithEmptyStartAndEnd()
+    {
+
+        RangeTombstoneList l = new RangeTombstoneList(cmp, 0);
+
+        l.add(rt(4, 10, 3));
+        l.add(atMost(12, 4, 0));
+
+        Iterator<RangeTombstone> iter = l.iterator();
+        assertRT(atMost(12, 4, 0), iter.next());
+        assertFalse(iter.hasNext());
+    }
+
+    @Test
+    public void addRangeWithEmptyEndToRangeWithEmptyStartAndEnd()
+    {
+
+        RangeTombstoneList l = new RangeTombstoneList(cmp, 0);
+
+        l.add(new RangeTombstone(Slice.ALL, new DeletionTime(2, 0)));
+        l.add(atLeast(12, 4, 0));
+
+        Iterator<RangeTombstone> iter = l.iterator();
+        assertRT(lessThan(12, 2, 0), iter.next());
+        assertRT(atLeast(12, 4, 0), iter.next());
+        assertFalse(iter.hasNext());
+    }
+
+    @Test
+    public void addRangeWithEmptyEndWitchIncludeExistingRangeWithEmptyEnd()
+    {
+
+        RangeTombstoneList l = new RangeTombstoneList(cmp, 0);
+
+        l.add(atLeast(5, 3, 0));
+        l.add(atLeast(3, 4, 0));
+
+        Iterator<RangeTombstone> iter = l.iterator();
+        assertRT(atLeast(3, 4, 0), iter.next());
+        assertFalse(iter.hasNext());
+    }
+
+    @Test
+    public void addIncludedRangeToRangeWithEmptyEnd()
+    {
+
+        RangeTombstoneList l = new RangeTombstoneList(cmp, 0);
+
+        l.add(atLeast(3, 3, 0));
+        l.add(rt(4, 10, 4));
+
+        Iterator<RangeTombstone> iter = l.iterator();
+        assertRT(rtie(3, 4, 3), iter.next());
+        assertRT(rt(4, 10, 4), iter.next());
+        assertRT(greaterThan(10, 3, 0), iter.next());
+        assertFalse(iter.hasNext());
+    }
+
+    @Test
+    public void addIncludedRangeWithEmptyEndToRangeWithEmptyEnd()
+    {
+
+        RangeTombstoneList l = new RangeTombstoneList(cmp, 0);
+
+        l.add(atLeast(3, 3, 0));
+        l.add(atLeast(5, 4, 0));
+
+        Iterator<RangeTombstone> iter = l.iterator();
+        assertRT(rtie(3, 5, 3), iter.next());
+        assertRT(atLeast(5, 4, 0), iter.next());
+        assertFalse(iter.hasNext());
+    }
+
+    @Test
+    public void addRangeWithEmptyEndWitchOverlapExistingRange()
+    {
+
+        RangeTombstoneList l = new RangeTombstoneList(cmp, 0);
+
+        l.add(rt(4, 10, 3));
+        l.add(atLeast(6, 4, 0));
+
+        Iterator<RangeTombstone> iter = l.iterator();
+        assertRT(rtie(4, 6, 3), iter.next());
+        assertRT(atLeast(6, 4, 0), iter.next());
+        assertFalse(iter.hasNext());
+    }
+
+    @Test
+    public void addOverlappingRangeToRangeWithEmptyEnd()
+    {
+
+        RangeTombstoneList l = new RangeTombstoneList(cmp, 0);
+
+        l.add(atLeast(3, 3, 0));
+        l.add(rt(1, 10, 4));
+
+        Iterator<RangeTombstone> iter = l.iterator();
+        assertRT(rt(1, 10, 4), iter.next());
+        assertRT(greaterThan(10, 3, 0), iter.next());
+        assertFalse(iter.hasNext());
+    }
+
+    @Test
+    public void searchTestWithEmptyStart()
+    {
+        RangeTombstoneList l = new RangeTombstoneList(cmp, 0);
+        l.add(atMost(4, 5, 0));
+        l.add(rt(4, 6, 2));
+        l.add(rt(9, 12, 1));
+        l.add(rt(14, 15, 3));
+        l.add(rt(15, 17, 6));
+
+        assertEquals(5, l.searchDeletionTime(clustering(-1)).markedForDeleteAt());
+        assertEquals(5, l.searchDeletionTime(clustering(0)).markedForDeleteAt());
+        assertEquals(5, l.searchDeletionTime(clustering(3)).markedForDeleteAt());
+        assertEquals(5, l.searchDeletionTime(clustering(4)).markedForDeleteAt());
+
+        assertEquals(2, l.searchDeletionTime(clustering(5)).markedForDeleteAt());
+
+        assertEquals(null, l.searchDeletionTime(clustering(7)));
+
+        assertEquals(3, l.searchDeletionTime(clustering(14)).markedForDeleteAt());
+
+        assertEquals(6, l.searchDeletionTime(clustering(15)).markedForDeleteAt());
+        assertEquals(null, l.searchDeletionTime(clustering(18)));
+    }
+
+    @Test
+    public void searchTestWithRangeWithEmptyEnd()
+    {
+        RangeTombstoneList l = new RangeTombstoneList(cmp, 0);
+        l.add(rt(0, 4, 5));
+        l.add(rt(4, 6, 2));
+        l.add(rt(9, 12, 1));
+        l.add(rt(14, 15, 3));
+        l.add(atLeast(15, 6, 0));
+
+        assertEquals(null, l.searchDeletionTime(clustering(-1)));
+
+        assertEquals(5, l.searchDeletionTime(clustering(0)).markedForDeleteAt());
+        assertEquals(5, l.searchDeletionTime(clustering(3)).markedForDeleteAt());
+        assertEquals(5, l.searchDeletionTime(clustering(4)).markedForDeleteAt());
+
+        assertEquals(2, l.searchDeletionTime(clustering(5)).markedForDeleteAt());
+
+        assertEquals(null, l.searchDeletionTime(clustering(7)));
+
+        assertEquals(3, l.searchDeletionTime(clustering(14)).markedForDeleteAt());
+
+        assertEquals(6, l.searchDeletionTime(clustering(15)).markedForDeleteAt());
+        assertEquals(6, l.searchDeletionTime(clustering(1000)).markedForDeleteAt());
+    }
+
     private static void assertRT(RangeTombstone expected, RangeTombstone actual)
     {
         assertTrue(String.format("%s != %s", toString(expected), toString(actual)), cmp.compare(expected.deletedSlice().start(),
actual.deletedSlice().start()) == 0);
@@ -420,11 +613,6 @@ public class RangeTombstoneListTest
         return ByteBufferUtil.bytes(i);
     }
 
-    private static int i(Slice.Bound bound)
-    {
-        return ByteBufferUtil.toInt(bound.get(0));
-    }
-
     private static RangeTombstone rt(int start, int end, long tstamp)
     {
         return rt(start, end, tstamp, 0);
@@ -459,4 +647,24 @@ public class RangeTombstoneListTest
     {
         return new RangeTombstone(Slice.make(Slice.Bound.inclusiveStartOf(bb(start)), Slice.Bound.exclusiveEndOf(bb(end))),
new DeletionTime(tstamp, delTime));
     }
+
+    private static RangeTombstone atLeast(int start, long tstamp, int delTime)
+    {
+        return new RangeTombstone(Slice.make(Slice.Bound.inclusiveStartOf(bb(start)), Slice.Bound.TOP),
new DeletionTime(tstamp, delTime));
+    }
+
+    private static RangeTombstone atMost(int end, long tstamp, int delTime)
+    {
+        return new RangeTombstone(Slice.make(Slice.Bound.BOTTOM, Slice.Bound.inclusiveEndOf(bb(end))),
new DeletionTime(tstamp, delTime));
+    }
+
+    private static RangeTombstone lessThan(int end, long tstamp, int delTime)
+    {
+        return new RangeTombstone(Slice.make(Slice.Bound.BOTTOM, Slice.Bound.exclusiveEndOf(bb(end))),
new DeletionTime(tstamp, delTime));
+    }
+
+    private static RangeTombstone greaterThan(int start, long tstamp, int delTime)
+    {
+        return new RangeTombstone(Slice.make(Slice.Bound.exclusiveStartOf(bb(start)), Slice.Bound.TOP),
new DeletionTime(tstamp, delTime));
+    }
 }


Mime
View raw message