Author: jbellis
Date: Fri Aug 19 01:54:25 2011
New Revision: 1159473

URL: http://svn.apache.org/viewvc?rev=1159473&view=rev
Log:
return an InvalidRequestException if an indexed column is assigned a value 
larger than 64K
patch by pyaskevich and jbellis for CASSANDRA-3057

Modified:
    cassandra/branches/cassandra-0.8/CHANGES.txt
    
cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/config/CFMetaData.java
    
cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/thrift/ThriftValidation.java
    
cassandra/branches/cassandra-0.8/test/unit/org/apache/cassandra/thrift/ThriftValidationTest.java

Modified: cassandra/branches/cassandra-0.8/CHANGES.txt
URL: 
http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.8/CHANGES.txt?rev=1159473&r1=1159472&r2=1159473&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.8/CHANGES.txt (original)
+++ cassandra/branches/cassandra-0.8/CHANGES.txt Fri Aug 19 01:54:25 2011
@@ -13,8 +13,11 @@
    (rows containing nothing but expired tombstones) (CASSANDRA-3039)
  * work around native memory leak in com.sun.management.GarbageCollectorMXBean
    (CASSANDRA-2868)
- * validate that column names in column_metadata does not equal to key_alias
+ * validate that column names in column_metadata are not equal to key_alias
    on create/update of the ColumnFamily and CQL 'ALTER' statement 
(CASSANDRA-3036)
+ * return an InvalidRequestException if an indexed column is assigned
+   a value larger than 64KB (CASSANDRA-3057)
+
 
 0.8.4
  * include files-to-be-streamed in StreamInSession.getSources (CASSANDRA-2972)

Modified: 
cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/config/CFMetaData.java
URL: 
http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/config/CFMetaData.java?rev=1159473&r1=1159472&r2=1159473&view=diff
==============================================================================
--- 
cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/config/CFMetaData.java
 (original)
+++ 
cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/config/CFMetaData.java
 Fri Aug 19 01:54:25 2011
@@ -602,13 +602,16 @@ public final class CFMetaData
 
     public AbstractType getValueValidator(ByteBuffer column)
     {
-        AbstractType validator = defaultValidator;
-        ColumnDefinition columnDefinition = column_metadata.get(column);
-        if (columnDefinition != null)
-            validator = columnDefinition.getValidator();
-        return validator;
+        return getValueValidator(column_metadata.get(column));
     }
-    
+
+    public AbstractType getValueValidator(ColumnDefinition columnDefinition)
+    {
+        return columnDefinition == null
+               ? defaultValidator
+               : columnDefinition.getValidator();
+    }
+
     /** applies implicit defaults to cf definition. useful in updates */
     public static void applyImplicitDefaults(org.apache.cassandra.thrift.CfDef 
cf_def) 
     {

Modified: 
cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/thrift/ThriftValidation.java
URL: 
http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/thrift/ThriftValidation.java?rev=1159473&r1=1159472&r2=1159473&view=diff
==============================================================================
--- 
cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/thrift/ThriftValidation.java
 (original)
+++ 
cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/thrift/ThriftValidation.java
 Fri Aug 19 01:54:25 2011
@@ -410,9 +410,11 @@ public class ThriftValidation
             throw new InvalidRequestException("Column value is required");
         if (!column.isSetTimestamp())
             throw new InvalidRequestException("Column timestamp is required");
+
+        ColumnDefinition columnDef = metadata.getColumnDefinition(column.name);
         try
         {
-            AbstractType validator = metadata.getValueValidator(column.name);
+            AbstractType validator = metadata.getValueValidator(columnDef);
             if (validator != null)
                 validator.validate(column.value);
         }
@@ -426,6 +428,14 @@ public class ThriftValidation
                                                             metadata.cfName,
                                                             (isSubColumn ? 
metadata.subcolumnComparator : metadata.comparator).getString(column.name)));
         }
+
+        // Indexed column values cannot be larger than 64K.  See 
CASSANDRA-3057 for more details
+        if (columnDef != null && columnDef.getIndexType() != null && 
column.value.remaining() > FBUtilities.MAX_UNSIGNED_SHORT)
+            throw new InvalidRequestException(String.format("Can't index 
column value of size %d for index %s in CF %s of KS %s",
+                                                            
column.value.remaining(),
+                                                            
columnDef.getIndexName(),
+                                                            metadata.cfName,
+                                                            metadata.ksName));
     }
 
     /**

Modified: 
cassandra/branches/cassandra-0.8/test/unit/org/apache/cassandra/thrift/ThriftValidationTest.java
URL: 
http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.8/test/unit/org/apache/cassandra/thrift/ThriftValidationTest.java?rev=1159473&r1=1159472&r2=1159473&view=diff
==============================================================================
--- 
cassandra/branches/cassandra-0.8/test/unit/org/apache/cassandra/thrift/ThriftValidationTest.java
 (original)
+++ 
cassandra/branches/cassandra-0.8/test/unit/org/apache/cassandra/thrift/ThriftValidationTest.java
 Fri Aug 19 01:54:25 2011
@@ -21,6 +21,8 @@ package org.apache.cassandra.thrift;
  */
 
 
+import java.nio.ByteBuffer;
+
 import org.apache.cassandra.config.CFMetaData;
 import org.apache.cassandra.config.DatabaseDescriptor;
 import org.apache.cassandra.db.marshal.AsciiType;
@@ -29,6 +31,12 @@ import org.apache.cassandra.db.marshal.U
 import org.junit.Test;
 
 import org.apache.cassandra.CleanupHelper;
+import org.apache.cassandra.config.CFMetaData;
+import org.apache.cassandra.config.ConfigurationException;
+import org.apache.cassandra.config.DatabaseDescriptor;
+import org.apache.cassandra.db.marshal.AsciiType;
+import org.apache.cassandra.db.marshal.UTF8Type;
+import org.apache.cassandra.utils.FBUtilities;
 
 import java.util.concurrent.Callable;
 
@@ -47,6 +55,55 @@ public class ThriftValidationTest extend
     }
 
     @Test
+    public void testColumnValueSizeForIndexedColumn() throws 
ConfigurationException, InvalidRequestException
+    {
+        CfDef cfDef = 
CFMetaData.convertToThrift(DatabaseDescriptor.getCFMetaData("Keyspace1", 
"Standard1"));
+        ByteBuffer columnName = AsciiType.instance.fromString("indexed");
+
+        // add an indexed column definition
+        cfDef.addToColumn_metadata(new ColumnDef(columnName, 
UTF8Type.class.getCanonicalName())
+                                                 .setIndex_type(IndexType.KEYS)
+                                                 
.setIndex_name("indexed_col"));
+
+        CFMetaData metaData = CFMetaData.fromThrift(cfDef);
+
+        Column column = new Column(columnName)
+                            .setValue(new byte[FBUtilities.MAX_UNSIGNED_SHORT 
+ 1])
+                            .setTimestamp(System.currentTimeMillis());
+
+        boolean gotException = false;
+
+        try
+        {
+            // this run should throw an exception
+            ThriftValidation.validateColumnData(metaData, column, false);
+        }
+        catch (InvalidRequestException e)
+        {
+            gotException = true;
+        }
+
+        assert gotException : "expected InvalidRequestException but not 
received.";
+
+        // change value to be less than unsigned short size
+        column.setValue(new byte[12]);
+
+        gotException = false; // reset flag
+
+        try
+        {
+            // this run should run clean
+            ThriftValidation.validateColumnData(metaData, column, false);
+        }
+        catch (InvalidRequestException e)
+        {
+            gotException = true;
+        }
+
+        assert !gotException : "got unexpected InvalidRequestException";
+    }
+
+    @Test
     public void testColumnNameEqualToKeyAlias()
     {
         CFMetaData metaData = DatabaseDescriptor.getCFMetaData("Keyspace1", 
"Standard1");


Reply via email to