You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by "Pavel Yaskevich (JIRA)" <ji...@apache.org> on 2016/05/09 19:44:12 UTC

[jira] [Commented] (CASSANDRA-11734) Enable partition component index for SASI

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

Pavel Yaskevich commented on CASSANDRA-11734:
---------------------------------------------

Thanks for taking a stub at this, [~doanduyhai]! By the nature of changes it looks like we will have to postpone this until I'm done with QueryPlan porting (CASSANDRA-10765) which is going to make it more sane to have indexed restrictions on partitions with(-out) ranges. From the patch I see couple of things right away: CFMetaData.getLiveIndices() you mentioned goes against the fact that some of the queries don't even allow usage of the indexes, which there is no way (currently) to check from inside of the SingleColumnRestrictions, checking {{QueryController#hasIndexFor(ColumnDefinition)}} on every run of the results checking logic is very inefficient and I think instead of using DecoratedKey separately we might be better off providing {{Operation.satisfiedBy}} methods with {{UnfilteredRowIterator}} and let it iterate it if needed instead of involving {{QueryPlan}}. So I would rather have this after CASSANDRA-10765, looks like it would make everybody's life a bit easier :)

> Enable partition component index for SASI
> -----------------------------------------
>
>                 Key: CASSANDRA-11734
>                 URL: https://issues.apache.org/jira/browse/CASSANDRA-11734
>             Project: Cassandra
>          Issue Type: Improvement
>          Components: CQL
>            Reporter: DOAN DuyHai
>            Assignee: DOAN DuyHai
>              Labels: doc-impacting, sasi, secondaryIndex
>             Fix For: 3.8
>
>         Attachments: patch.txt
>
>
> Enable partition component index for SASI
> For the given schema:
> {code:sql}
> CREATE TABLE test.comp (
>     pk1 int,
>     pk2 text,
>     val text,
>     PRIMARY KEY ((pk1, pk2))
> );
> CREATE CUSTOM INDEX comp_val_idx ON test.comp (val) USING 'org.apache.cassandra.index.sasi.SASIIndex';
> CREATE CUSTOM INDEX comp_pk2_idx ON test.comp (pk2) USING 'org.apache.cassandra.index.sasi.SASIIndex' WITH OPTIONS = {'mode': 'PREFIX', 'analyzer_class': 'org.apache.cassandra.index.sasi.analyzer.NonTokenizingAnalyzer', 'case_sensitive': 'false'};
> CREATE CUSTOM INDEX comp_pk1_idx ON test.comp (pk1) USING 'org.apache.cassandra.index.sasi.SASIIndex';
> {code}
> The following queries are possible:
> {code:sql}
> SELECT * FROM test.comp WHERE pk1=1;
> SELECT * FROM test.comp WHERE pk1>=1 AND pk1<=5;
> SELECT * FROM test.comp WHERE pk1=1 AND val='xxx' ALLOW FILTERING;
> SELECT * FROM test.comp WHERE pk1>=1 AND pk1<=5 AND val='xxx' ALLOW FILTERING;
> SELECT * FROM test.comp WHERE pk2='some text';
> SELECT * FROM test.comp WHERE pk2 LIKE 'prefix%';
> SELECT * FROM test.comp WHERE pk2='some text' AND val='xxx' ALLOW FILTERING;
> SELECT * FROM test.comp WHERE pk2 LIKE 'prefix%' AND val='xxx' ALLOW FILTERING;
> //Without using SASI
> SELECT * FROM test.comp WHERE pk1 = 1 AND pk2='some text';
> SELECT * FROM test.comp WHERE pk1 IN(1,2,3) AND pk2='some text';
> SELECT * FROM test.comp WHERE pk1 = 1 AND pk2 IN ('text1','text2');
> SELECT * FROM test.comp WHERE pk1 IN(1,2,3) AND pk2 IN ('text1','text2');
> {code}
> However, the following queries *are not possible*
> {code:sql}
> SELECT * FROM test.comp WHERE pk1=1 AND pk2 LIKE 'prefix%';
> SELECT * FROM test.comp WHERE pk1>=1 AND pk1<=5 AND pk2 = 'some text';
> SELECT * FROM test.comp WHERE pk1>=1 AND pk1<=5 AND pk2 LIKE 'prefix%';
> {code}
> All of them are throwing the following exception
> {noformat}
> ava.lang.UnsupportedOperationException: null
> 	at org.apache.cassandra.cql3.restrictions.SingleColumnRestriction$LikeRestriction.appendTo(SingleColumnRestriction.java:715) ~[main/:na]
> 	at org.apache.cassandra.cql3.restrictions.PartitionKeySingleRestrictionSet.values(PartitionKeySingleRestrictionSet.java:86) ~[main/:na]
> 	at org.apache.cassandra.cql3.restrictions.StatementRestrictions.getPartitionKeys(StatementRestrictions.java:585) ~[main/:na]
> 	at org.apache.cassandra.cql3.statements.SelectStatement.getSliceCommands(SelectStatement.java:473) ~[main/:na]
> 	at org.apache.cassandra.cql3.statements.SelectStatement.getQuery(SelectStatement.java:265) ~[main/:na]
> 	at org.apache.cassandra.cql3.statements.SelectStatement.execute(SelectStatement.java:230) ~[main/:na]
> 	at org.apache.cassandra.cql3.statements.SelectStatement.execute(SelectStatement.java:79) ~[main/:na]
> 	at org.apache.cassandra.cql3.QueryProcessor.processStatement(QueryProcessor.java:208) ~[main/:na]
> 	at org.apache.cassandra.cql3.QueryProcessor.process(QueryProcessor.java:239) ~[main/:na]
> 	at org.apache.cassandra.cql3.QueryProcessor.process(QueryProcessor.java:224) ~[main/:na]
> 	at org.apache.cassandra.transport.messages.QueryMessage.execute(QueryMessage.java:115) ~[main/:na]
> 	at org.apache.cassandra.transport.Message$Dispatcher.channelRead0(Message.java:507) [main/:na]
> 	at org.apache.cassandra.transport.Message$Dispatcher.channelRead0(Message.java:401) [main/:na]
> 	at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:105) [netty-all-4.0.36.Final.jar:4.0.36.Final]
> 	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:292) [netty-all-4.0.36.Final.jar:4.0.36.Final]
> 	at io.netty.channel.AbstractChannelHandlerContext.access$600(AbstractChannelHandlerContext.java:32) [netty-all-4.0.36.Final.jar:4.0.36.Final]
> 	at io.netty.channel.AbstractChannelHandlerContext$7.run(AbstractChannelHandlerContext.java:283) [netty-all-4.0.36.Final.jar:4.0.36.Final]
> 	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [na:1.8.0_45]
> 	at org.apache.cassandra.concurrent.AbstractLocalAwareExecutorService$FutureTask.run(AbstractLocalAwareExecutorService.java:164) [main/:na]
> 	at org.apache.cassandra.concurrent.SEPWorker.run(SEPWorker.java:106) [main/:na]
> {noformat}
> Indeed, to allow the above queries we'll need to update the class {{StatementRestrictions}} and introduce a new class {{PartitionKeyMultipleRestrictionsSet}} and I don't feel like doing it, afraid of breaking existing code.
> WDYT [~xedin] [~jrwest]  [~blerer] ?
> I attach a patch for this JIRA.
> I have added new tests to {{OperationTest}} and {{SASIIndexTest}} with flushing & non-flushing before queries to test in-memory & on disk read paths.
> To enable operators other than {{=}} and {{IN}} on the partition key component, I modified the {{SingleColumnRelation}} to add this code:
> {code:java}
>  else if (isSlice() || isLIKE())
>         {
>             // Non EQ relation is not supported without token(), unless SASI index is used
>             final boolean hasSASIIndex = metaData.getLiveIndices()
>                                       .stream()
>                                       .filter(index -> index.dependsOn(columnDef))
>                                       .anyMatch(index -> index instanceof SASIIndex);
>             checkFalse(columnDef.isPartitionKey() && !hasSASIIndex, "Only EQ and IN relation are supported on the partition key (unless you use the token() function or SASI index)");
>         }
> {code}
> This implies adding the method {{getLiveIndices()}} on {{CFMetaData}} which accesses the index manager by creating an instance of {{ColumnFamilyStore}}, don't know whether it is expensive or not, please advise
> {code:java}
> //CFMetaData
>     public Collection<Index> getLiveIndices()
>     {
>         return Keyspace.openAndGetStore(this).indexManager.listIndexes();
>     }
> {code}



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)