You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by if...@apache.org on 2017/04/04 07:49:59 UTC

cassandra git commit: Improve error messages for +/- operations on maps and tuples

Repository: cassandra
Updated Branches:
  refs/heads/trunk 2c6924b56 -> f87ec773f


Improve error messages for +/- operations on maps and tuples 

Patch by Alex Petrov; reviewed by Andr�s de la Pe�a for CASSANDRA-13197

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

Branch: refs/heads/trunk
Commit: f87ec773fe1c698d738e9735f6e8ee513c2ba510
Parents: 2c6924b
Author: Alex Petrov <ol...@gmail.com>
Authored: Tue Apr 4 09:49:14 2017 +0200
Committer: Alex Petrov <ol...@gmail.com>
Committed: Tue Apr 4 09:49:14 2017 +0200

----------------------------------------------------------------------
 CHANGES.txt                                     |  1 +
 .../org/apache/cassandra/cql3/Operation.java    | 34 ++++++++++++++++----
 .../validation/entities/CollectionsTest.java    | 30 +++++++++++++++--
 .../cql3/validation/entities/TupleTypeTest.java | 10 +++++-
 4 files changed, 65 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/f87ec773/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 3632903..3147eb9 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
 4.0
+ * Improve error messages for +/- operations on maps and tuples (CASSANDRA-13197)
  * Remove deprecated repair JMX APIs (CASSANDRA-11530)
  * Fix version check to enable streaming keep-alive (CASSANDRA-12929)
  * Make it possible to monitor an ideal consistency level separate from actual consistency level (CASSANDRA-13289)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/f87ec773/src/java/org/apache/cassandra/cql3/Operation.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/Operation.java b/src/java/org/apache/cassandra/cql3/Operation.java
index 8db9306..85214f1 100644
--- a/src/java/org/apache/cassandra/cql3/Operation.java
+++ b/src/java/org/apache/cassandra/cql3/Operation.java
@@ -300,13 +300,14 @@ public abstract class Operation
 
         public Operation prepare(TableMetadata metadata, ColumnMetadata receiver) throws InvalidRequestException
         {
-            Term v = value.prepare(metadata.keyspace, receiver);
-
             if (!(receiver.type instanceof CollectionType))
             {
+                if (receiver.type instanceof TupleType)
+                    throw new InvalidRequestException(String.format("Invalid operation (%s) for tuple column %s", toString(receiver), receiver.name));
+
                 if (!(receiver.type instanceof CounterColumnType))
                     throw new InvalidRequestException(String.format("Invalid operation (%s) for non counter column %s", toString(receiver), receiver.name));
-                return new Constants.Adder(receiver, v);
+                return new Constants.Adder(receiver, value.prepare(metadata.keyspace, receiver));
             }
             else if (!(receiver.type.isMultiCell()))
                 throw new InvalidRequestException(String.format("Invalid operation (%s) for frozen collection column %s", toString(receiver), receiver.name));
@@ -314,11 +315,21 @@ public abstract class Operation
             switch (((CollectionType)receiver.type).kind)
             {
                 case LIST:
-                    return new Lists.Appender(receiver, v);
+                    return new Lists.Appender(receiver, value.prepare(metadata.keyspace, receiver));
                 case SET:
-                    return new Sets.Adder(receiver, v);
+                    return new Sets.Adder(receiver, value.prepare(metadata.keyspace, receiver));
                 case MAP:
-                    return new Maps.Putter(receiver, v);
+                    Term term;
+                    try
+                    {
+                        term = value.prepare(metadata.keyspace, receiver);
+                    }
+                    catch (InvalidRequestException e)
+                    {
+                        throw new InvalidRequestException(String.format("Value for a map addition has to be a map, but was: '%s'", value));
+                    }
+
+                    return new Maps.Putter(receiver, term);
             }
             throw new AssertionError();
         }
@@ -366,7 +377,16 @@ public abstract class Operation
                                                                      receiver.cfName,
                                                                      receiver.name,
                                                                      SetType.getInstance(((MapType)receiver.type).getKeysType(), false));
-                    return new Sets.Discarder(receiver, value.prepare(metadata.keyspace, vr));
+                    Term term;
+                    try
+                    {
+                        term = value.prepare(metadata.keyspace, vr);
+                    }
+                    catch (InvalidRequestException e)
+                    {
+                        throw new InvalidRequestException(String.format("Value for a map substraction has to be a set, but was: '%s'", value));
+                    }
+                    return new Sets.Discarder(receiver, term);
             }
             throw new AssertionError();
         }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/f87ec773/test/unit/org/apache/cassandra/cql3/validation/entities/CollectionsTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/cql3/validation/entities/CollectionsTest.java b/test/unit/org/apache/cassandra/cql3/validation/entities/CollectionsTest.java
index 6292308..56ba0a0 100644
--- a/test/unit/org/apache/cassandra/cql3/validation/entities/CollectionsTest.java
+++ b/test/unit/org/apache/cassandra/cql3/validation/entities/CollectionsTest.java
@@ -115,13 +115,14 @@ public class CollectionsTest extends CQLTester
         );
 
         execute("UPDATE %s SET s += ? WHERE k = 0", set("v5"));
-        execute("UPDATE %s SET s += ? WHERE k = 0", set("v6"));
+        execute("UPDATE %s SET s += {'v6'} WHERE k = 0");
 
         assertRows(execute("SELECT s FROM %s WHERE k = 0"),
                    row(set("v5", "v6", "v7"))
         );
 
-        execute("UPDATE %s SET s -= ? WHERE k = 0", set("v6", "v5"));
+        execute("UPDATE %s SET s -= ? WHERE k = 0", set("v5"));
+        execute("UPDATE %s SET s -= {'v6'} WHERE k = 0");
 
         assertRows(execute("SELECT s FROM %s WHERE k = 0"),
                    row(set("v7"))
@@ -144,6 +145,15 @@ public class CollectionsTest extends CQLTester
     {
         createTable("CREATE TABLE %s (k int PRIMARY KEY, m map<text, int>)");
 
+        assertInvalidMessage("Value for a map addition has to be a map, but was: '{1}'",
+                             "UPDATE %s SET m = m + {1} WHERE k = 0;");
+        assertInvalidMessage("Not enough bytes to read a map",
+                             "UPDATE %s SET m += ? WHERE k = 0", set("v1"));
+        assertInvalidMessage("Value for a map substraction has to be a set, but was: '{'v1': 1}'",
+                             "UPDATE %s SET m = m - {'v1': 1} WHERE k = 0", map("v1", 1));
+        assertInvalidMessage("Unexpected extraneous bytes after set value",
+                             "UPDATE %s SET m -= ? WHERE k = 0", map("v1", 1));
+
         execute("INSERT INTO %s(k, m) VALUES (0, ?)", map("v1", 1, "v2", 2));
 
         assertRows(execute("SELECT m FROM %s WHERE k = 0"),
@@ -193,6 +203,18 @@ public class CollectionsTest extends CQLTester
                    row(map("v5", 5, "v6", 6))
         );
 
+        execute("UPDATE %s SET m += {'v7': 7} WHERE k = 0");
+
+        assertRows(execute("SELECT m FROM %s WHERE k = 0"),
+                   row(map("v5", 5, "v6", 6, "v7", 7))
+        );
+
+        execute("UPDATE %s SET m -= {'v7'} WHERE k = 0");
+
+        assertRows(execute("SELECT m FROM %s WHERE k = 0"),
+                   row(map("v5", 5, "v6", 6))
+        );
+
         execute("DELETE m[?] FROM %s WHERE k = 0", "v6");
 
         assertRows(execute("SELECT m FROM %s WHERE k = 0"),
@@ -276,6 +298,10 @@ public class CollectionsTest extends CQLTester
         execute("UPDATE %s SET l = l - ? WHERE k=0", list("v11"));
 
         assertRows(execute("SELECT l FROM %s WHERE k = 0"), row((Object) null));
+
+        execute("UPDATE %s SET l = l + ? WHERE k = 0", list("v1", "v2", "v1", "v2", "v1", "v2"));
+        execute("UPDATE %s SET l = l - ? WHERE k=0", list("v1", "v2"));
+        assertRows(execute("SELECT l FROM %s WHERE k = 0"), row((Object) null));
     }
 
     @Test

http://git-wip-us.apache.org/repos/asf/cassandra/blob/f87ec773/test/unit/org/apache/cassandra/cql3/validation/entities/TupleTypeTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/cql3/validation/entities/TupleTypeTest.java b/test/unit/org/apache/cassandra/cql3/validation/entities/TupleTypeTest.java
index c369ecd..353a40a 100644
--- a/test/unit/org/apache/cassandra/cql3/validation/entities/TupleTypeTest.java
+++ b/test/unit/org/apache/cassandra/cql3/validation/entities/TupleTypeTest.java
@@ -203,4 +203,12 @@ public class TupleTypeTest extends CQLTester
         assertInvalidMessage("Not enough bytes to read 0th component",
                              "INSERT INTO %s (pk, t) VALUES (?, ?)", 1, Long.MAX_VALUE);
     }
-}
+
+    @Test
+    public void testTupleModification() throws Throwable
+    {
+        createTable("CREATE TABLE %s(pk int PRIMARY KEY, value tuple<int, int>)");
+        assertInvalidMessage("Invalid operation (value = value + (1, 1)) for tuple column value",
+                             "UPDATE %s SET value += (1, 1) WHERE k=0;");
+    }
+}
\ No newline at end of file