[jira] [Comment Edited] (CASSANDRA-6875) CQL3: select multiple CQL rows in a single partition using IN

2014-05-26 Thread Bill Mitchell (JIRA)

[ 
https://issues.apache.org/jira/browse/CASSANDRA-6875?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=14009075#comment-14009075
 ] 

Bill Mitchell edited comment on CASSANDRA-6875 at 5/26/14 8:52 PM:
---

To try this out, I cobbled up a test case by accessing the TupleType directly 
on the client side, as this feature is not yet supported in the Java driver.  
My approach was to serialize my two ordering column values, then use 
TupleType.buildValue() to concatenate them into a single ByteBuffer, build a 
List of all these, then use serialize on a ListTypeByteBuffer instance to get 
a single ByteBuffer representing the entire list, and bind that using 
setBytesUnsafe().  I'm not totally sure of all this, but it seems reasonable.  

My SELECT statement syntax followed the first of the three Tyler suggested: ... 
WHERE (c1, c2) IN ?, as this allows the statement to be prepared only once, 
irrespective of the number of compound keys provided.  

What I saw was the following traceback on the server:
14/05/26 14:33:09 ERROR messages.ErrorMessage: Unexpected exception during 
request
java.util.NoSuchElementException
at 
java.util.LinkedHashMap$LinkedHashIterator.nextEntry(LinkedHashMap.java:396)
at java.util.LinkedHashMap$ValueIterator.next(LinkedHashMap.java:409)
at 
org.apache.cassandra.cql3.statements.SelectStatement.buildMultiColumnInBound(SelectStatement.java:941)
at 
org.apache.cassandra.cql3.statements.SelectStatement.buildBound(SelectStatement.java:814)
at 
org.apache.cassandra.cql3.statements.SelectStatement.getRequestedBound(SelectStatement.java:977)
at 
org.apache.cassandra.cql3.statements.SelectStatement.makeFilter(SelectStatement.java:444)
at 
org.apache.cassandra.cql3.statements.SelectStatement.getSliceCommands(SelectStatement.java:340)
at 
org.apache.cassandra.cql3.statements.SelectStatement.execute(SelectStatement.java:210)
at 
org.apache.cassandra.cql3.statements.SelectStatement.execute(SelectStatement.java:61)
at 
org.apache.cassandra.cql3.QueryProcessor.processStatement(QueryProcessor.java:158)
at 
org.apache.cassandra.cql3.QueryProcessor.processPrepared(QueryProcessor.java:309)
at 
org.apache.cassandra.transport.messages.ExecuteMessage.execute(ExecuteMessage.java:132)
at 
org.apache.cassandra.transport.Message$Dispatcher.messageReceived(Message.java:304)

Stepping through the code, it appears to have analyzed my statement correctly.  
In BuildMultiColumnInBound, splitInValues contains 1426 tuples, which is the 
number I intended to pass.  The names parameter identifies two columns, 
createdate and emailcrypt.  The loop executes twice, but on the third iteration 
there are no more elements in names, thus the exception. 

Moving the construction of the iterator within the loop fixed my Exception.  
The code still looks suspect, though, as it calculates a bound b based on 
whether the first column is reversed, then uses bound, not b, in the following 
statement.  I've not researched which would be correct, as this appears closely 
related to the fix Sylvain just developed for CASSANDRA-7105.  In my test case, 
where the columns were declared as DESC, the code as written did return all the 
expected rows. 

{code}
TreeSetByteBuffer inValues = new TreeSet(isReversed ? 
cfDef.cfm.comparator.reverseComparator : cfDef.cfm.comparator);
for (ListByteBuffer components : splitInValues)
{
ColumnNameBuilder nameBuilder = builder.copy();
for (ByteBuffer component : components)
nameBuilder.add(component);

IteratorCFDefinition.Name iter = names.iterator();
Bound b = isReversed == isReversedType(iter.next()) ? bound : 
Bound.reverse(bound);
inValues.add((bound == Bound.END  nameBuilder.remainingCount()  
0) ? nameBuilder.buildAsEndOfRange() : nameBuilder.build());
}
return new ArrayList(inValues);
{code}  


was (Author: wtmitchell3):
To try this out, I cobbled up a test case by accessing the TupleType directly 
on the client side, as this feature is not yet supported in the Java driver.  
My approach was to serialize my two ordering column values, then use 
TupleType.buildValue() to concatenate them into a single ByteBuffer, build a 
List of all these, then use serialize on a ListTypeByteBuffer instance to get 
a single ByteBuffer representing the entire list, and bind that using 
setBytesUnsafe().  I'm not totally sure of all this, but it seems reasonable.  

My SELECT statement syntax followed the first of the three Tyler suggested: ... 
WHERE (c1, c2) IN ?, as this allows the statement to be prepared only once, 
irrespective of the number of compound keys provided.  

What I saw was the following traceback on the server:
14/05/26 14:33:09 ERROR messages.ErrorMessage: Unexpected 

[jira] [Comment Edited] (CASSANDRA-6875) CQL3: select multiple CQL rows in a single partition using IN

2014-05-26 Thread Bill Mitchell (JIRA)

[ 
https://issues.apache.org/jira/browse/CASSANDRA-6875?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=14009075#comment-14009075
 ] 

Bill Mitchell edited comment on CASSANDRA-6875 at 5/27/14 2:16 AM:
---

To try this out, I cobbled up a test case by accessing the TupleType directly 
on the client side, as this feature is not yet supported in the Java driver.  
My approach was to serialize my two ordering column values, then use 
TupleType.buildValue() to concatenate them into a single ByteBuffer, build a 
List of all these, then use serialize on a ListTypeByteBuffer instance to get 
a single ByteBuffer representing the entire list, and bind that using 
setBytesUnsafe().  I'm not totally sure of all this, but it seems reasonable.  

My SELECT statement syntax followed the first of the three Tyler suggested: ... 
WHERE (c1, c2) IN ?, as this allows the statement to be prepared only once, 
irrespective of the number of compound keys provided.  

What I saw was the following traceback on the server:
14/05/26 14:33:09 ERROR messages.ErrorMessage: Unexpected exception during 
request
java.util.NoSuchElementException
at 
java.util.LinkedHashMap$LinkedHashIterator.nextEntry(LinkedHashMap.java:396)
at java.util.LinkedHashMap$ValueIterator.next(LinkedHashMap.java:409)
at 
org.apache.cassandra.cql3.statements.SelectStatement.buildMultiColumnInBound(SelectStatement.java:941)
at 
org.apache.cassandra.cql3.statements.SelectStatement.buildBound(SelectStatement.java:814)
at 
org.apache.cassandra.cql3.statements.SelectStatement.getRequestedBound(SelectStatement.java:977)
at 
org.apache.cassandra.cql3.statements.SelectStatement.makeFilter(SelectStatement.java:444)
at 
org.apache.cassandra.cql3.statements.SelectStatement.getSliceCommands(SelectStatement.java:340)
at 
org.apache.cassandra.cql3.statements.SelectStatement.execute(SelectStatement.java:210)
at 
org.apache.cassandra.cql3.statements.SelectStatement.execute(SelectStatement.java:61)
at 
org.apache.cassandra.cql3.QueryProcessor.processStatement(QueryProcessor.java:158)
at 
org.apache.cassandra.cql3.QueryProcessor.processPrepared(QueryProcessor.java:309)
at 
org.apache.cassandra.transport.messages.ExecuteMessage.execute(ExecuteMessage.java:132)
at 
org.apache.cassandra.transport.Message$Dispatcher.messageReceived(Message.java:304)

Stepping through the code, it appears to have analyzed my statement correctly.  
In BuildMultiColumnInBound, splitInValues contains 1426 tuples, which is the 
number I intended to pass.  The names parameter identifies two columns, 
createdate and emailcrypt.  The loop executes twice, but on the third iteration 
there are no more elements in names, thus the exception. 

Moving the construction of the iterator within the loop fixed my Exception.  
The code still looks suspect, though, as it calculates a bound b based on 
whether the first column is reversed, then uses bound, not b, in the following 
statement.  I've not researched which would be correct, as this appears closely 
related to the fix Sylvain just developed for CASSANDRA-7105.  In my test case, 
where the columns were declared as DESC, the code as fixed below did return all 
the expected rows. 

{code}
TreeSetByteBuffer inValues = new TreeSet(isReversed ? 
cfDef.cfm.comparator.reverseComparator : cfDef.cfm.comparator);
for (ListByteBuffer components : splitInValues)
{
ColumnNameBuilder nameBuilder = builder.copy();
for (ByteBuffer component : components)
nameBuilder.add(component);

IteratorCFDefinition.Name iter = names.iterator();
Bound b = isReversed == isReversedType(iter.next()) ? bound : 
Bound.reverse(bound);
inValues.add((bound == Bound.END  nameBuilder.remainingCount()  
0) ? nameBuilder.buildAsEndOfRange() : nameBuilder.build());
}
return new ArrayList(inValues);
{code}  

P.S. I changed my test configuration to declare the ordering columns as ASC 
instead of DESC and reran the tests.  There was no failure with the code as 
changed.  So apparently the comparison of bound == and not b == works fine, 
which should mean that both iter and b can be dropped.  


was (Author: wtmitchell3):
To try this out, I cobbled up a test case by accessing the TupleType directly 
on the client side, as this feature is not yet supported in the Java driver.  
My approach was to serialize my two ordering column values, then use 
TupleType.buildValue() to concatenate them into a single ByteBuffer, build a 
List of all these, then use serialize on a ListTypeByteBuffer instance to get 
a single ByteBuffer representing the entire list, and bind that using 
setBytesUnsafe().  I'm not totally sure of all this, but it seems reasonable.  

My SELECT statement syntax followed 

[jira] [Comment Edited] (CASSANDRA-6875) CQL3: select multiple CQL rows in a single partition using IN

2014-04-17 Thread Tyler Hobbs (JIRA)

[ 
https://issues.apache.org/jira/browse/CASSANDRA-6875?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13973391#comment-13973391
 ] 

Tyler Hobbs edited comment on CASSANDRA-6875 at 4/17/14 8:50 PM:
-

Regarding prepared statements, I assume we want to support all of the following:
* {{... WHERE (c1, c2) IN ?}}
* {{... WHERE (c1, c2) IN (?, ?, ...)}}
* {{... WHERE (c1, c2) IN ((?, ?), (?, ?), ...)}}


was (Author: thobbs):
Regarding prepared statements, I assume we want to support all of the following:
* {{... WHERE (k, c1) IN ?}}
* {{... WHERE (k, c1) IN (?, ?, ...)}}
* {{... WHERE (k, c1) IN ((?, ?), (?, ?), ...)}}

 CQL3: select multiple CQL rows in a single partition using IN
 -

 Key: CASSANDRA-6875
 URL: https://issues.apache.org/jira/browse/CASSANDRA-6875
 Project: Cassandra
  Issue Type: Bug
  Components: API
Reporter: Nicolas Favre-Felix
Assignee: Tyler Hobbs
Priority: Minor
 Fix For: 2.0.8


 In the spirit of CASSANDRA-4851 and to bring CQL to parity with Thrift, it is 
 important to support reading several distinct CQL rows from a given partition 
 using a distinct set of coordinates for these rows within the partition.
 CASSANDRA-4851 introduced a range scan over the multi-dimensional space of 
 clustering keys. We also need to support a multi-get of CQL rows, 
 potentially using the IN keyword to define a set of clustering keys to 
 fetch at once.
 (reusing the same example\:)
 Consider the following table:
 {code}
 CREATE TABLE test (
   k int,
   c1 int,
   c2 int,
   PRIMARY KEY (k, c1, c2)
 );
 {code}
 with the following data:
 {code}
  k | c1 | c2
 ---++
  0 |  0 |  0
  0 |  0 |  1
  0 |  1 |  0
  0 |  1 |  1
 {code}
 We can fetch a single row or a range of rows, but not a set of them:
 {code}
  SELECT * FROM test WHERE k = 0 AND (c1, c2) IN ((0, 0), (1,1)) ;
 Bad Request: line 1:54 missing EOF at ','
 {code}
 Supporting this syntax would return:
 {code}
  k | c1 | c2
 ---++
  0 |  0 |  0
  0 |  1 |  1
 {code}
 Being able to fetch these two CQL rows in a single read is important to 
 maintain partition-level isolation.



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