Updated Branches:
  refs/heads/cassandra-1.2 b664c55c3 -> 189131631

Fix inserting empty maps

patch by slebresne; reviewed by jbellis for CASSANDRA-5141


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

Branch: refs/heads/cassandra-1.2
Commit: 189131631bc11d851965856b7926cc1574d9d597
Parents: b664c55
Author: Sylvain Lebresne <sylv...@datastax.com>
Authored: Fri Jan 11 17:59:40 2013 +0100
Committer: Sylvain Lebresne <sylv...@datastax.com>
Committed: Fri Jan 11 17:59:40 2013 +0100

----------------------------------------------------------------------
 CHANGES.txt                                        |    1 +
 .../cassandra/cql3/operations/SetOperation.java    |   20 +++++++++++++++
 .../cassandra/cql3/statements/UpdateStatement.java |   15 +++++++++-
 3 files changed, 34 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/18913163/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index eae8dbb..b3d5dd7 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -31,6 +31,7 @@
  * Pick the correct value validator in sstable2json for cql3 tables 
(CASSANDRA-5134)
  * Validate login for describe_keyspace, describe_keyspaces and set_keyspace
    (CASSANDRA-5144)
+ * Fix inserting empty maps (CASSANDRA-5141)
 Merged from 1.1:
  * Simplify CompressedRandomAccessReader to work around JDK FD bug 
(CASSANDRA-5088)
  * Improve handling a changing target throttle rate mid-compaction 
(CASSANDRA-5087)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/18913163/src/java/org/apache/cassandra/cql3/operations/SetOperation.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/operations/SetOperation.java 
b/src/java/org/apache/cassandra/cql3/operations/SetOperation.java
index e7f01c6..bec0e1a 100644
--- a/src/java/org/apache/cassandra/cql3/operations/SetOperation.java
+++ b/src/java/org/apache/cassandra/cql3/operations/SetOperation.java
@@ -18,6 +18,7 @@
 package org.apache.cassandra.cql3.operations;
 
 import java.nio.ByteBuffer;
+import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Set;
@@ -73,6 +74,25 @@ public class SetOperation implements Operation
         }
     }
 
+    public Operation maybeConvertToEmptyMapOperation()
+    {
+        // If it's not empty or a DISCARD, it's a proper invalid query, not
+        // just the parser that hasn't been able to distinguish empty set from
+        // empty map. However, we just this as it will be rejected later and
+        // there is no point in duplicating validation
+        if (!values.isEmpty())
+            return this;
+
+        switch (kind)
+        {
+            case SET:
+                return MapOperation.Set(Collections.<Term, Term>emptyMap());
+            case ADD:
+                return MapOperation.Put(Collections.<Term, Term>emptyMap());
+        }
+        return this;
+    }
+
     public static void doSetFromPrepared(ColumnFamily cf, ColumnNameBuilder 
builder, SetType validator, Term values, UpdateParameters params) throws 
InvalidRequestException
     {
         if (!values.isBindMarker())

http://git-wip-us.apache.org/repos/asf/cassandra/blob/18913163/src/java/org/apache/cassandra/cql3/statements/UpdateStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/UpdateStatement.java 
b/src/java/org/apache/cassandra/cql3/statements/UpdateStatement.java
index 46b1b18..7db2bdb 100644
--- a/src/java/org/apache/cassandra/cql3/statements/UpdateStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/UpdateStatement.java
@@ -26,6 +26,7 @@ import org.apache.cassandra.cql3.*;
 import org.apache.cassandra.config.CFMetaData;
 import org.apache.cassandra.cql3.operations.ColumnOperation;
 import org.apache.cassandra.cql3.operations.Operation;
+import org.apache.cassandra.cql3.operations.SetOperation;
 import org.apache.cassandra.cql3.operations.PreparedOperation;
 import org.apache.cassandra.db.*;
 import org.apache.cassandra.db.marshal.*;
@@ -302,7 +303,7 @@ public class UpdateStatement extends ModificationStatement
                     case COLUMN_METADATA:
                         if (processedColumns.containsKey(name))
                             throw new 
InvalidRequestException(String.format("Multiple definitions found for column 
%s", name));
-                        processedColumns.put(name, operation);
+                        addNewOperation(name, operation);
                         break;
                 }
             }
@@ -352,7 +353,7 @@ public class UpdateStatement extends ModificationStatement
                                 throw new 
InvalidRequestException(String.format("Multiple definitions found for column 
%s", name));
 
                         operation.addBoundNames(name, boundNames);
-                        processedColumns.put(name, operation);
+                        addNewOperation(name, operation);
                         break;
                 }
             }
@@ -362,6 +363,16 @@ public class UpdateStatement extends ModificationStatement
         return new ParsedStatement.Prepared(this, 
Arrays.<ColumnSpecification>asList(boundNames));
     }
 
+    private void addNewOperation(CFDefinition.Name name, Operation operation)
+    {
+        // On the parser side, we're unable to differentiate an empty map from 
an empty set for add and set operations.
+        // Fix it now that we have the actual type.
+        if (operation.getType() == Operation.Type.SET && (name.type instanceof 
MapType))
+            operation = 
((SetOperation)operation).maybeConvertToEmptyMapOperation();
+
+        processedColumns.put(name, operation);
+    }
+
     public ParsedStatement.Prepared prepare() throws InvalidRequestException
     {
         ColumnSpecification[] names = new 
ColumnSpecification[getBoundsTerms()];

Reply via email to