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

Sylvain Lebresne commented on CASSANDRA-6875:
---------------------------------------------

The overall principle looks good, but I feel this could use some more comments 
and/or made a little more clear. Mainly, the {{isMultiColumn}} path in 
{{SelectStatement.buildBound}} looks weird at face value: we're inside a loop 
that populates a {{ColumnNameBuilder}}, but the {{isMultiColumn}} path 
completely ignores both the iterated object and the builder. This work because 
it relies on the fact that when there is a multi-column restriction then it's 
the only one restriction (which is duplicated in the 
{{SelectStatement.columnRestrictions}} array), and that the value from such 
restriction is not a single column value but rather a fully built composite 
serialized value (which is not self evident from the method naming in 
particular).  But it's hard to piece it all that together when you look at 
{{buildBound}} currently.  Some comments would help, but I'd prefer going even 
further and move the {{isMultiColumn}} path outside of the loop (by looking up 
first if the first restriction in {{columnRestrictions}} is a multi-column one 
or not) since it has no reason to be in the loop. In fact, I'd go a tad further 
by making SelectStatement abstract and have 2 subClass, one for single-column 
restrictions with a {{SingleColumnRelation[] columnRestrictions}} array field 
as we have now, and one for multi-column that has just one non-array 
{{MultiColumnRestriction columnsRestriction}} field. After all, both cases 
exclude one another in the current implementation.

Somewhat related, I'm slightly afraid that the parts about multi-column 
restrictions returning fully serialized composites (through Tuples.Value.get()) 
will not play nice with the 2.1 code, where we don't manipulate composites as 
opaque ByteBuffers anymore (concretely, Tuples will serialize the composite, 
but SelectStatement will have to deserialize it back right away to get a 
Composite, which will be both ugly and inefficient).  So to avoid having to 
change everything on merge, I think it would be cleaner to make Tuples.Value 
return a list of (individual column) values instead of just one, and let 
SelectStatement build back the full composite name using a ColumnNameBuilder.  
Especially if you make the per-column and multi-column paths a tad more 
separated as suggested above, I suspect it might clarify things a bit.  

Other than that, a bunch of more minor comments and nits:
* The {{SelectStatement.RawStatement.prepare()}} re-org patch breaks proper 
indentation at places (for instance, the indentation of parameters to 'new 
ColumnSpecification' in the first branch of udpateSingleColumnRestriction, 
though there is a few other places). Would be nice to fix those.
* Can't we use {{QueryProcessor.instance.getPrepared}} instead of creating a 
only-for-test {{QueryProcessor.staticGetPrepared}}? Or at the very least leave 
such shortcuts in the tests where it belongs.
* In Tuples.Literal.prepare, I'd prefer good ol'fashion indexed loop to iterate 
over 2 lists (feels clearer, and saves the allocator creation as a bonus).
* In Tuples.Raw.makeInReceiver should probably be called makeReceiver (it's not 
related to "IN"). I'd also drop the spaces in the string generated (if only for 
consistency with the string generated in INRaw). As a side node, 
Raw.makeReceiver uses indexed iteration while INRaw.makeInReceiver don't, can't 
we make both consistent style wise for OCD sakes?
* Why make methods of CQLStatement abstract (it's an interface)?  Also, I'd 
rather add the QueryOptions parameter to the existing executeInternal and 
default to QueryOptions.DEFAULT when calling it, rather than having 2 methods. 
Though tbh, my preference would be to move the tests to dtest and leave those 
somewhat unrelated changes to another ticket, see below.
* SingleColumnRelation.previousInTuple is now unused but not removed.
* We could save one list allocation (instead of both toCreate and toUpdate) in 
SelectStatement.updateRestrictionsForRelation (for EQ and IN, we know it can 
only be a create, and for slices we can lookup with getExisting).
* In Restriction, the {{values}} method is already at top-level, no reason to 
re-declare it for EQ.
* It bothers me to start adding unit tests for CQL queries when all of our CQL 
tests are currently in dtest. I'd *much* rather keep it all in the dtests to 
avoid the confusion on where is what tested.


> 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)

Reply via email to