cassandra-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Sam Tunnicliffe (JIRA)" <j...@apache.org>
Subject [jira] [Commented] (CASSANDRA-7525) Querying by multiple secondary indexes gives java.lang.IllegalArgumentException on some cases
Date Wed, 16 Jul 2014 17:44:05 GMT

    [ https://issues.apache.org/jira/browse/CASSANDRA-7525?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14063778#comment-14063778
] 

Sam Tunnicliffe commented on CASSANDRA-7525:
--------------------------------------------

Pushed a branch here: https://github.com/beobal/cassandra/tree/7525

The first commit is Tyler's and fixes the reported problem with selecting from multiple candidate
indexes. That uncovered a second issue whereby under certain conditions querying an collection
value index would throw NPE

The problem is in CompositesSearcher, when building the Composite prefixes to use for the
slices to read from the index column family. If the values of the partition and clustering
columns are restricted, the Composite built by {{CompositesIndexOnCollectionValues.makeIndexColumnPrefix}}
incorrectly includes a null element as it mistakenly attempts to add the collection key to
the Composite. This is necessary for indexing but not for searching, because we don't yet
know the collection key, only the target value.

So a query like 

{code}
 SELECT * FROM %s WHERE account = 'test' AND id = 5 AND categories CONTAINS 'foo' ALLOW FILTERING
{code}

where account is the partition key and id is a clustering column, results in an error such
as:

{code}
   [junit] Testcase: testQueryMultipleIndexTypes(org.apache.cassandra.cql3.ContainsRelationTest):
  Caused an ERROR
    [junit] null
    [junit] java.lang.NullPointerException
    [junit]     at org.apache.cassandra.utils.FastByteOperations$UnsafeOperations.compare(FastByteOperations.java:225)
    [junit]     at org.apache.cassandra.utils.FastByteOperations.compareUnsigned(FastByteOperations.java:62)
    [junit]     at org.apache.cassandra.utils.ByteBufferUtil.compareUnsigned(ByteBufferUtil.java:83)
    [junit]     at org.apache.cassandra.db.marshal.UTF8Type.compare(UTF8Type.java:35)
    [junit]     at org.apache.cassandra.db.marshal.UTF8Type.compare(UTF8Type.java:27)
    [junit]     at org.apache.cassandra.db.composites.AbstractCType.compare(AbstractCType.java:125)
    [junit]     at org.apache.cassandra.db.composites.AbstractCType.compare(AbstractCType.java:40)
    [junit]     at org.apache.cassandra.db.AtomicBTreeColumns$3.compare(AtomicBTreeColumns.java:234)
    [junit]     at org.apache.cassandra.utils.btree.BTree.find(BTree.java:277)
    [junit]     at org.apache.cassandra.utils.btree.Path.find(Path.java:122)
    [junit]     at org.apache.cassandra.utils.btree.Cursor._reset(Cursor.java:107)
    [junit]     at org.apache.cassandra.utils.btree.Cursor.reset(Cursor.java:91)
    [junit]     at org.apache.cassandra.utils.btree.BTree.slice(BTree.java:238)
    [junit]     at org.apache.cassandra.db.AtomicBTreeColumns.slice(AtomicBTreeColumns.java:453)
    [junit]     at org.apache.cassandra.db.AtomicBTreeColumns.iterator(AtomicBTreeColumns.java:283)
    [junit]     at org.apache.cassandra.db.filter.SliceQueryFilter.getColumnIterator(SliceQueryFilter.java:138)
    [junit]     at org.apache.cassandra.db.filter.QueryFilter.getIterator(QueryFilter.java:57)
    [junit]     at org.apache.cassandra.db.CollationController.collectAllData(CollationController.java:206)
    [junit]     at org.apache.cassandra.db.CollationController.getTopLevelColumns(CollationController.java:59)
    [junit]     at org.apache.cassandra.db.ColumnFamilyStore.getTopLevelColumns(ColumnFamilyStore.java:1873)
    [junit]     at org.apache.cassandra.db.ColumnFamilyStore.getColumnFamily(ColumnFamilyStore.java:1681)
    [junit]     at org.apache.cassandra.db.index.composites.CompositesSearcher$1.computeNext(CompositesSearcher.java:183)
    [junit]     at org.apache.cassandra.db.index.composites.CompositesSearcher$1.computeNext(CompositesSearcher.java:121)
    [junit]     at com.google.common.collect.AbstractIterator.tryToComputeNext(AbstractIterator.java:143)
    [junit]     at com.google.common.collect.AbstractIterator.hasNext(AbstractIterator.java:138)
    [junit]     at org.apache.cassandra.db.ColumnFamilyStore.filter(ColumnFamilyStore.java:2077)
    [junit]     at org.apache.cassandra.db.index.composites.CompositesSearcher.search(CompositesSearcher.java:68)
    [junit]     at org.apache.cassandra.db.index.SecondaryIndexManager.search(SecondaryIndexManager.java:591)
    [junit]     at org.apache.cassandra.db.ColumnFamilyStore.search(ColumnFamilyStore.java:2065)
    [junit]     at org.apache.cassandra.db.RangeSliceCommand.executeLocally(RangeSliceCommand.java:131)
    [junit]     at org.apache.cassandra.cql3.statements.SelectStatement.executeInternal(SelectStatement.java:302)
    [junit]     at org.apache.cassandra.cql3.statements.SelectStatement.executeInternal(SelectStatement.java:60)
    [junit]     at org.apache.cassandra.cql3.QueryProcessor.executeOnceInternal(QueryProcessor.java:307)
    [junit]     at org.apache.cassandra.cql3.CQLTester.execute(CQLTester.java:185)
    [junit]     at org.apache.cassandra.cql3.ContainsRelationTest.testQueryMultipleIndexTypes(ContainsRelationTest.java:117)
{code}

Second commit in the branch fixes CIOCV so the slice filters are built correctly & adds
tests which fail without that.

> Querying by multiple secondary indexes gives java.lang.IllegalArgumentException on some
cases
> ---------------------------------------------------------------------------------------------
>
>                 Key: CASSANDRA-7525
>                 URL: https://issues.apache.org/jira/browse/CASSANDRA-7525
>             Project: Cassandra
>          Issue Type: Bug
>            Reporter: Tuukka Mustonen
>            Assignee: Sam Tunnicliffe
>             Fix For: 2.1.0
>
>
> Querying by:
> * non-primary key column with secondary index + collection with secondary index
> * primary key column with secondary index + non-primary key column with secondary index
> gives {{<ErrorMessage code=0000 [Server error] message="java.lang.IllegalArgumentException:
expected one element but was: <org.apache.cassandra.db.index.composites.CompositesSearcher@156b5576,
org.apache.cassandra.db.index.composites.CompositesSearcher@39b7c0f6>">}}
> Steps to reproduce:
> {code}
> cqlsh:cs> CREATE TABLE test (
>       ...   id1 text,
>       ...   id2 text,
>       ...   column1 text,
>       ...   column2 text,
>       ...   collection set<text>,
>       ...   PRIMARY KEY (id1, id2)
>       ... );
> cqlsh:cs> 
> {code}
> Simple query by primary key works as should:
> {code}
> cqlsh:cs> SELECT * FROM test WHERE id1 = 'foo';
> (0 rows)
> cqlsh:cs> SELECT * FROM test WHERE id1 = 'foo' AND id2 = 'bar';
> (0 rows)
> {code}
> Query by secondary index + non-indexed column:
> {code}
> cqlsh:cs> CREATE INDEX test_column1s ON test(column1);
> cqlsh:cs> SELECT * FROM test WHERE column1 = 'foo';
> (0 rows)
> cqlsh:cs> SELECT * FROM test WHERE column1 = 'foo' AND column2 = 'bar' ALLOW FILTERING;
> (0 rows)
> {code}
> Add secondary index also for the second column:
> {code}
> cqlsh:cs> CREATE INDEX test_column2s ON test(column2);
> cqlsh:cs> SELECT * FROM test WHERE column1 = 'foo' AND column2 = 'bar' ALLOW FILTERING;
> (0 rows)
> {code}
> Doesn't matter if we bring primary key or the collection there as well:
> {code}
> cqlsh:cs> SELECT * FROM test WHERE id1 = 'blah' AND column1 = 'foo' AND column2 =
'bar' ALLOW FILTERING;
> (0 rows)
> cqlsh:cs> SELECT * FROM test WHERE column1 = 'foo' AND collection CONTAINS 'bar' ALLOW
FILTERING;
> (0 rows)
> {code}
> Let's add index for the collection:
> {code}
> cqlsh:cs> CREATE INDEX test_collections ON test(collection);
> cqlsh:cs> SELECT * FROM test WHERE collection CONTAINS 'bar';
> (0 rows)
> {code}
> But then combine secondary index column and collection with secondary index:
> {code}
> cqlsh:cs> SELECT * FROM test WHERE column1 = 'foo' AND collection CONTAINS 'bar' ALLOW
FILTERING;
> <ErrorMessage code=0000 [Server error] message="java.lang.IllegalArgumentException:
expected one element but was: <org.apache.cassandra.db.index.composites.CompositesSearcher@68e37722,
org.apache.cassandra.db.index.composites.CompositesSearcher@2da28efa>">
> {code}
> Furthermore, query by primary key field with secondary index + non-primary key column
with secondary index:
> {code}
> cqlsh:cs> CREATE INDEX test_id2s ON test(id2);
> cqlsh:cs> SELECT * FROM test WHERE id2 = 'foo' AND column1 = 'bar' ALLOW FILTERING;
> <ErrorMessage code=0000 [Server error] message="java.lang.IllegalArgumentException:
expected one element but was: <org.apache.cassandra.db.index.composites.CompositesSearcher@3ca899f1,
org.apache.cassandra.db.index.composites.CompositesSearcher@6112bc53>">
> {code}
> I'm a cassandra noob so maybe I'm trying to do things the db is not meant to do?



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

Mime
View raw message