Updated Branches:
  refs/heads/trunk 6cc509463 -> 371e7bf69

Better validation when accessing CQL3 table from thrift

patch by slebresne; reviewed by jbellis for CASSANDRA-5138


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

Branch: refs/heads/trunk
Commit: 371e7bf69bbfdca0f5415e32a8c0f652711f5257
Parents: 6cc5094
Author: Sylvain Lebresne <sylv...@datastax.com>
Authored: Mon Jul 22 16:48:24 2013 +0200
Committer: Sylvain Lebresne <sylv...@datastax.com>
Committed: Wed Jul 24 17:04:13 2013 +0200

----------------------------------------------------------------------
 CHANGES.txt                                     |  1 +
 .../cassandra/thrift/ThriftValidation.java      | 34 ++++++++++++++++++++
 2 files changed, 35 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/371e7bf6/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index c9e229c..c081b45 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,6 +1,7 @@
 2.0.0-rc1
  * fix potential spurious wakeup in AsyncOneResponse (CASSANDRA-5690)
  * fix schema-related trigger issues (CASSANDRA-5774)
+ * Better validation when accessing CQL3 table from thrift (CASSANDRA-5138)
 
 
 2.0.0-beta2

http://git-wip-us.apache.org/repos/asf/cassandra/blob/371e7bf6/src/java/org/apache/cassandra/thrift/ThriftValidation.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/thrift/ThriftValidation.java 
b/src/java/org/apache/cassandra/thrift/ThriftValidation.java
index 23d21f8..ce8fdcb 100644
--- a/src/java/org/apache/cassandra/thrift/ThriftValidation.java
+++ b/src/java/org/apache/cassandra/thrift/ThriftValidation.java
@@ -25,13 +25,17 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import org.apache.cassandra.config.*;
+import org.apache.cassandra.cql3.CFDefinition;
+import org.apache.cassandra.cql3.ColumnIdentifier;
 import org.apache.cassandra.db.*;
 import org.apache.cassandra.db.filter.IDiskAtomFilter;
 import org.apache.cassandra.db.filter.NamesQueryFilter;
 import org.apache.cassandra.db.filter.SliceQueryFilter;
 import org.apache.cassandra.db.index.SecondaryIndexManager;
 import org.apache.cassandra.db.marshal.AbstractType;
+import org.apache.cassandra.db.marshal.ColumnToCollectionType;
 import org.apache.cassandra.db.marshal.CompositeType;
+import org.apache.cassandra.db.marshal.UTF8Type;
 import org.apache.cassandra.dht.IPartitioner;
 import org.apache.cassandra.dht.Token;
 import org.apache.cassandra.service.StorageService;
@@ -207,6 +211,8 @@ public class ThriftValidation
                 throw new 
org.apache.cassandra.exceptions.InvalidRequestException("supercolumn specified 
to ColumnFamily " + metadata.cfName + " containing normal columns");
         }
         AbstractType<?> comparator = SuperColumns.getComparatorFor(metadata, 
superColumnName);
+        CFDefinition cfDef = metadata.getCfDef();
+        boolean isCQL3Table = cfDef.isComposite && !cfDef.isCompact && 
!metadata.isSuper();
         for (ByteBuffer name : column_names)
         {
             if (name.remaining() > maxNameLength)
@@ -221,6 +227,34 @@ public class ThriftValidation
             {
                 throw new 
org.apache.cassandra.exceptions.InvalidRequestException(e.getMessage());
             }
+
+            if (isCQL3Table)
+            {
+                // CQL3 table don't support having only part of their 
composite column names set
+                CompositeType composite = (CompositeType)comparator;
+                ByteBuffer[] components = composite.split(name);
+                int minComponents = composite.types.size() - 
(cfDef.hasCollections ? 1 : 0);
+                if (components.length < minComponents)
+                    throw new 
org.apache.cassandra.exceptions.InvalidRequestException(String.format("Not 
enough component (found %d but %d expected) for column name since %s is a CQL3 
table",
+                                                                               
                     metadata.cfName, components.length, minComponents));
+
+                // Furthermore, the column name must be a declared one.
+                int columnIndex = composite.types.size() - 
(cfDef.hasCollections ? 2 : 1);
+                ByteBuffer CQL3ColumnName = components[columnIndex];
+                ColumnIdentifier columnId = new 
ColumnIdentifier(CQL3ColumnName, composite.types.get(columnIndex));
+                if (cfDef.columns.get(columnId) == null)
+                    throw new 
org.apache.cassandra.exceptions.InvalidRequestException(String.format("Invalid 
cell for CQL3 table %s. The CQL3 column component (%s) does not correspond to a 
defined CQL3 column",
+                                                                               
                     metadata.cfName, columnId));
+
+                // On top of that, if we have a collection component, he 
(CQL3) column must be a collection
+                if (cfDef.hasCollections && components.length == 
composite.types.size())
+                {
+                    assert components.length >= 2;
+                    ColumnToCollectionType collectionType = 
(ColumnToCollectionType)composite.types.get(composite.types.size() - 1);
+                    if (!collectionType.defined.containsKey(CQL3ColumnName))
+                        throw new 
org.apache.cassandra.exceptions.InvalidRequestException(String.format("Invalid 
collection component, %s is not a collection", 
UTF8Type.instance.getString(CQL3ColumnName)));
+                }
+            }
         }
     }
 

Reply via email to