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");