cassandra-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Sylvain Lebresne (JIRA)" <j...@apache.org>
Subject [jira] [Updated] (CASSANDRA-6892) Cassandra 2.0.x validates Thrift columns incorrectly and causes InvalidRequestException
Date Mon, 31 Mar 2014 15:39:16 GMT

     [ https://issues.apache.org/jira/browse/CASSANDRA-6892?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]

Sylvain Lebresne updated CASSANDRA-6892:
----------------------------------------

    Attachment: 6892-2.0-v2.txt

The fact that a default alias could conflict with a column name introduced through thrift
is definitively not on purpose. And in fact, this is not really just limited to default aliases
since with a compact table with 1 clustering column, you currently cannot add a value for
that clustering column if it conflicts with any of the CQL column names (which don't have
to be "default" aliases in particular). Or rather, CQL will let you insert it, but if you
scrub later, it will tell you the data is invalid which is bogus.

All this to say that this is not really entirely thrift related, and is really a bug in getColumnDefinitionFromColumnName
(and that's what we should fix). This method should never return a definition that is not
a REGULAR or STATIC one, since that's the only 2 cases where a column definition is "stored"
inside an internal column/cell name.  That, plus the fact that getValueValidator() should
always use getColumnDefinitionFromColumnName, since it's really only ever used when dealing
with cell names. So anyway, attaching a v2 that does those modifications: it fixes getColumnDefinitionFromColumnName
and fix getValueValidator to use it (renaming it to getValueValidatorFromColumnName for consistency
sake). Also remove Schema.getValueValidator as it is a really unecessary (but that's more
of a nit). The patch does include the unit tests from the first patch and adds a new one for
the 'compact table with clustering column' case I describe above.


> Cassandra 2.0.x validates Thrift columns incorrectly and causes InvalidRequestException
> ---------------------------------------------------------------------------------------
>
>                 Key: CASSANDRA-6892
>                 URL: https://issues.apache.org/jira/browse/CASSANDRA-6892
>             Project: Cassandra
>          Issue Type: Bug
>          Components: API
>            Reporter: Christian Spriegel
>            Assignee: Tyler Hobbs
>            Priority: Minor
>             Fix For: 2.0.7
>
>         Attachments: 6892-2.0-v2.txt, 6892-2.0.txt, CASSANDRA-6892_V1.patch
>
>
> I just upgrade my local dev machine to Cassandra 2.0, which causes one of my automated
tests to fail now. With the latest 1.2.x it was working fine.
> The Exception I get on my client (using Hector) is:
> {code}
> me.prettyprint.hector.api.exceptions.HInvalidRequestException: InvalidRequestException(why:(Expected
8 or 0 byte long (21)) [MDS_0][MasterdataIndex][key2] failed validation)
> 	at me.prettyprint.cassandra.service.ExceptionsTranslatorImpl.translate(ExceptionsTranslatorImpl.java:52)
> 	at me.prettyprint.cassandra.connection.HConnectionManager.operateWithFailover(HConnectionManager.java:265)
> 	at me.prettyprint.cassandra.model.ExecutingKeyspace.doExecuteOperation(ExecutingKeyspace.java:113)
> 	at me.prettyprint.cassandra.model.MutatorImpl.execute(MutatorImpl.java:243)
> 	at me.prettyprint.cassandra.service.template.AbstractColumnFamilyTemplate.executeBatch(AbstractColumnFamilyTemplate.java:115)
> 	at me.prettyprint.cassandra.service.template.AbstractColumnFamilyTemplate.executeIfNotBatched(AbstractColumnFamilyTemplate.java:163)
> 	at me.prettyprint.cassandra.service.template.ColumnFamilyTemplate.update(ColumnFamilyTemplate.java:69)
> 	at com.mycompany.spring3utils.dataaccess.cassandra.AbstractCassandraDAO.doUpdate(AbstractCassandraDAO.java:482)
> 	....
> Caused by: InvalidRequestException(why:(Expected 8 or 0 byte long (21)) [MDS_0][MasterdataIndex][key2]
failed validation)
> 	at org.apache.cassandra.thrift.Cassandra$batch_mutate_result.read(Cassandra.java:20833)
> 	at org.apache.thrift.TServiceClient.receiveBase(TServiceClient.java:78)
> 	at org.apache.cassandra.thrift.Cassandra$Client.recv_batch_mutate(Cassandra.java:964)
> 	at org.apache.cassandra.thrift.Cassandra$Client.batch_mutate(Cassandra.java:950)
> 	at me.prettyprint.cassandra.model.MutatorImpl$3.execute(MutatorImpl.java:246)
> 	at me.prettyprint.cassandra.model.MutatorImpl$3.execute(MutatorImpl.java:1)
> 	at me.prettyprint.cassandra.service.Operation.executeAndSetResult(Operation.java:104)
> 	at me.prettyprint.cassandra.connection.HConnectionManager.operateWithFailover(HConnectionManager.java:258)
> 	... 46 more
> {code}
> The schema of my column family is:
> {code}
> create column family MasterdataIndex with
>     compression_options = {sstable_compression:SnappyCompressor, chunk_length_kb:64}
and
>     comparator = UTF8Type and
>     key_validation_class = 'CompositeType(UTF8Type,LongType)' and
>     default_validation_class = BytesType;
> {code}
> From the error message it looks like Cassandra is trying to validate the value with the
key-validator! (My value in this case it 21 bytes long)
> I studied the Cassandra 2.0 code and found something wrong. It seems in CFMetaData.addDefaultKeyAliases
it passes the KeyValidator into ColumnDefinition.partitionKeyDef. Inside ColumnDefinition
the validator is expected to be the value validator!
> In CFMetaData:
> {code}
>     private List<ColumnDefinition> addDefaultKeyAliases(List<ColumnDefinition>
pkCols)
>     {
>         for (int i = 0; i < pkCols.size(); i++)
>         {
>             if (pkCols.get(i) == null)
>             {
>                 Integer idx = null;
>                 AbstractType<?> type = keyValidator;
>                 if (keyValidator instanceof CompositeType)
>                 {
>                     idx = i;
>                     type = ((CompositeType)keyValidator).types.get(i);
>                 }
>                 // For compatibility sake, we call the first alias 'key' rather than
'key1'. This
>                 // is inconsistent with column alias, but it's probably not worth risking
breaking compatibility now.
>                 ByteBuffer name = ByteBufferUtil.bytes(i == 0 ? DEFAULT_KEY_ALIAS : DEFAULT_KEY_ALIAS
+ (i + 1));
>                 ColumnDefinition newDef = ColumnDefinition.partitionKeyDef(name, type,
idx); // type is LongType in my case, as it uses keyValidator !!!
>                 column_metadata.put(newDef.name, newDef);
>                 pkCols.set(i, newDef);
>             }
>         }
>         return pkCols;
>     }
> ...
>     public AbstractType<?> getValidator() // in ThriftValidation this is expected
to be the value validator!
>     {
>         return validator;
>     }
> {code}



--
This message was sent by Atlassian JIRA
(v6.2#6252)

Mime
View raw message