cassandra-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "DOAN DuyHai (JIRA)" <j...@apache.org>
Subject [jira] [Commented] (CASSANDRA-12149) NullPointerException on SELECT with SASI index
Date Sat, 09 Jul 2016 19:43:11 GMT

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

DOAN DuyHai commented on CASSANDRA-12149:
-----------------------------------------

The query used = {{SELECT namespace, entity, timestamp, feature1, feature2 FROM mykeyspace.myrecordtable
WHERE namespace = 'ns2' AND entity = 'entity2' AND feature1= 11 AND token(namespace, entity)
<= 9223372036854775807;}}

Ok, after successfully re-producing the NPE in debug mode, it is *not* a SASI bug but is rather
related to how Cassandra optimises the *WHERE* clause in general.

 NPE root cause is {{slice.bound(b) == null}} in {{TokenRestriction.bounds(Bound b, QueryOptions
options)}}:

{code:java}
        public List<ByteBuffer> bounds(Bound b, QueryOptions options) throws InvalidRequestException
        {
            return Collections.singletonList(slice.bound(b).bindAndGet(options));
        }
{code}

Going up the call stack, the culprit is at {{StatementRestrictions.getPartitionKeyBounds(IPartitioner
p, QueryOptions options)}}:

{code:java}
    private AbstractBounds<PartitionPosition> getPartitionKeyBounds(IPartitioner p,
                                                                    QueryOptions options)
    {
        ByteBuffer startKeyBytes = getPartitionKeyBound(Bound.START, options);
        ByteBuffer finishKeyBytes = getPartitionKeyBound(Bound.END, options);
        ....
{code}

 Since we have no lower bound restriction on the {{token(namespace, entity)}}, the call to
{{getPartitionKeyBound(Bound.START, options)}} generates the NPE.

 I try another query without using secondary index {{SELECT namespace, entity, timestamp,
feature1, feature2 FROM mykeyspace.myrecordtable WHERE namespace = 'ns2' AND entity = 'entity2'
AND token(namespace, entity) <= 9223372036854775807;}} and this time, no NPE.

 The place in the call stack where both queries diverge is at {{SelectStatements.getQuery(QueryOptions
options, int nowInSec, int userLimit, int perPartitionLimit)}}:

{code:java}
    public ReadQuery getQuery(QueryOptions options, int nowInSec, int userLimit, int perPartitionLimit)
throws RequestValidationException
    {
        DataLimits limit = getDataLimits(userLimit, perPartitionLimit);
        if (restrictions.isKeyRange() || restrictions.usesSecondaryIndexing())
            return getRangeCommand(options, limit, nowInSec);

        return getSliceCommands(options, limit, nowInSec);
    }
{code}

 When using secondary index, we fall in the *if* condition obviously. When NOT using secondary
index as per my 2nd SELECT statement, the *if* condition is not verified so the code path
is {{return getSliceCommands(options, limit, nowInSec);}}.

 Strangely enough, even with the 2nd SELECT, {{restrictions.isKeyRange()}} should be *true*,
why is it *false* ????

 The culprit is at {{StatementRestrictions.processPartitionKeyRestrictions(boolean hasQueriableIndex)}}

{code:java}
...
if (partitionKeyRestrictions.isOnToken())
            isKeyRange = true;

            if (hasUnrestrictedPartitionKeyComponents())
            {
                if (!partitionKeyRestrictions.isEmpty())
                {
                    if (!hasQueriableIndex)
                        throw invalidRequest("Partition key parts: %s must be restricted as
other parts are",
                                             Joiner.on(", ").join(getPartitionKeyUnrestrictedComponents()));
                }

                isKeyRange = true;
                usesSecondaryIndexing = hasQueriableIndex;
            }
        }
{code}

 Condition {{if (partitionKeyRestrictions.isOnToken())}} evaluates to *false* so variable
_isKeyRange_ is never set to *true*.

 Condition {{if (partitionKeyRestrictions.isOnToken())}} evaluates to *false* because of {{TokenFilter.isOnToken()}}:

{code:java}
    public boolean isOnToken()
    {
        // if all partition key columns have non-token restrictions, we can simply use the
token range to filter
        // those restrictions and then ignore the token range
        return restrictions.size() < tokenRestriction.size();
    }
{code}

 Here, since there are *more* conditions on primary key than on token restriction, the SELECT
is not considered to be a token restriction, which is sensible.

 By the way, if we look at the original WHERE clause {{WHERE namespace = 'ns2' AND entity
= 'entity2' AND feature1= 11 AND token(namespace, entity) <= 9223372036854775807;}}, the
restriction using *token* function is *useless* because we already provide the complete partition
key restriction.

 And I tried the original query by removing {{token(namespace, entity) <= 9223372036854775807}}
and it works like a charm.

 I would consider this JIRA to be *not an issue*

cc [~xedin]  [~beobal] and [~avkonst]
 




> NullPointerException on SELECT with SASI index
> ----------------------------------------------
>
>                 Key: CASSANDRA-12149
>                 URL: https://issues.apache.org/jira/browse/CASSANDRA-12149
>             Project: Cassandra
>          Issue Type: Bug
>          Components: sasi
>            Reporter: Andrey Konstantinov
>         Attachments: CASSANDRA-12149.txt
>
>
> If I execute the sequence of queries (see the attached file), Cassandra aborts a connection
reporting NPE on server side. SELECT query without token range filter works, but does not
work when token range filter is specified. My intent was to issue multiple SELECT queries
targeting the same single partition, filtered by a column indexed by SASI, partitioning results
by different token ranges.
> Output from cqlsh on SELECT is the following:
> cqlsh> SELECT namespace, entity, timestamp, feature1, feature2 FROM mykeyspace.myrecordtable
WHERE namespace = 'ns2' AND entity = 'entity2' AND feature1 > 11 AND feature1 < 31 
AND token(namespace, entity) <= 9223372036854775807;
> ServerError: <ErrorMessage code=0000 [Server error] message="java.lang.NullPointerException">



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

Mime
View raw message