[ https://issues.apache.org/jira/browse/CASSANDRA-8473?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Samuel Klock updated CASSANDRA-8473: ------------------------------------ Attachment: trunk-8473-v2.txt cassandra-2.1-8473-v2.txt Attaching new versions of the patch (for 2.1 and trunk) that are intended to address your feedback. Details: * {{SingleColumnRelation}} ** bq. For lists, this error message may be confusing: {{checkTrue(receiver.type instanceof MapType, "Column \"%s\" cannot be used as a map", receiver.name);}}. For example, if you do {{WHERE mylist\[0\] = 'foo'}}, you're not really trying to use it as a map. You may want to handle lists specially. Done: lists get a different error message now. (In the 2.1 patch, this change is made in {{SelectStatement}}.) ** bq. The {{checkFalse()}} statement below this is starting to get confusing, I would break it up Agreed. Refactored the condition into a couple of extracted methods. (In the 2.1 patch, a similar change is made in {{SelectStatement}}.) ** bq. Use curly braces on the "if" clause when they're used on the "else" Done in trunk patch. No equivalent issue in 2.1 patch. ** bq. I'm not sure that frozen maps are handled correctly here (e.g. WHERE myfrozenmap\['foo'\] = 'bar'). May want to double-check that. Added a test. I think trunk is okay (although the error message is imperfect: "Invalid STRING constant (foo) for "myfrozenmap" of type frozen<map<text, text>>"). The 2.1 patch incorrectly gave no error for queries with this condition; that's been fixed. * {{SingleColumnRelation.Contains()}} ** bq. Update class-level comment (should be a javadoc) to include map entry restrictions Updated the comment in the trunk patch (it was already updated in the 2.1 version). Making it a Javadoc would be inconsistent with the other nested classes in {{SingleColumnRestriction}} (which have no Javadoc), so I'm reluctant to do so. But I wouldn't forcefully object. ** bq. entries(): no need for curly braces with a single-line for-loop Moot because the for-loop is now multiline. No equivalent issue in the 2.1 patch. * {{CreateIndexStatement}} ** bq. switch on target.type could be clearer if re-organized; also, the error message about 'keys' is slightly misleading for 'entries' indexes Corrected both error messages. It's not obvious to me how to reorganize the {{switch}} to make it clearer (very likely because I wrote it) -- did you have something specific in mind? * {{IndexTarget.TargetType.fromIndexOptions()}} ** bq. Should this return FULL if index_values isn't present? Also, no curlies needed for single-line clauses. Removed the braces. On the return value: no index options will be present if the column isn't a non-frozen collection. Even so, this is a correctness issue: the v1 patch would yield the wrong error message if a user attempted to create a {{FULL}} index on a frozen map that already had one. Fixed in v2. * {{ExtendedFilter}} ** bq. {{else if (expr.isContains())}} will always be false (due to the {{isContains()}} check above). The block has been removed. Note that it was an attempt to preserve the logic that existed in the {{MAP}} case previously if {{expr.isContainsKey()}} were false; since the only kind of expressions apart from {{CONTAINS KEY}} that were valid for map columns were {{CONTAINS}} relations, this seemed like the right choice. But your analysis appears to be correct. Is there some other way that code would have been reachable? (It _looks_ like the code may have been intended to check {{map\[key\] = value}} conditions, but AFAIK there would have been no way to trigger its execution.) * {{CompositesIndex}} ** bq. No nested ternaries, please Rewritten as {{if}} statements. * {{CompositesIndexOnCollectionKeyAndValue}} ** bq. makeIndexColumnPrefix(): need to use {{min(count - 1, cellName.size())}} for loop end (see CASSANDRA-8053 for why) Fixed by extending {{CompositesIndexOnCollectionKey}}. (Also, did you mean CASSANDRA-8073?) ** bq. by extending CompositesIndexOnCollectionKey, you could eliminate about half of the methods Done, although I'm not positive the abstractions are quite right (is {{CompositesIndexOnCollectionKeyAndValue}} really a kind of {{CompositesIndexOnCollectionKey}}? Would it be better to use a common superclass?). But the reduced duplication is very nice. ** bq. isStale(): instead of building a new composite to compare with the index entry key, why not compare the cell value with the second item in the index entry composite? This method could also use a comment or two Good point -- the implementation no longer builds a new composite for the comparison. I've also refactored the code for clarity; if you still think it needs comments, I'll certainly add them. (Also: fixed the return value for when the cell in the indexed table is dead.) * {{SecondaryIndexOnMapEntriesTest}} ** bq. Unusued and commented out imports Removed the commented imports. I don't think any were unused. ** bq. Add a test for {{map\[element\] = null}} being invalid. (While we could support this when filtering, we couldn't support it with a 2ary index lookup.) Added a test and made it pass (these queries would fail with NPEs). It's worth noting that the null check for map entries occurs in a different place than that for {{CONTAINS}}/{{CONTAINS KEY}} relations for implementation reasons (the keys for index entries are structured differently). I'd be interested if anyone has an opinion on how to do this better. > Secondary index support for key-value pairs in CQL3 maps > -------------------------------------------------------- > > Key: CASSANDRA-8473 > URL: https://issues.apache.org/jira/browse/CASSANDRA-8473 > Project: Cassandra > Issue Type: Improvement > Reporter: Samuel Klock > Assignee: Samuel Klock > Fix For: 3.0 > > Attachments: cassandra-2.1-8473-actual-v1.txt, > cassandra-2.1-8473-v2.txt, cassandra-2.1-8473.txt, trunk-8473-v2.txt > > > CASSANDRA-4511 and CASSANDRA-6383 made substantial progress on secondary > indexes on CQL3 maps, but support for a natural use case is still missing: > queries to find rows with map columns containing some key-value pair. For > example (from a comment on CASSANDRA-4511): > {code:sql} > SELECT * FROM main.users WHERE notify['email'] = true; > {code} > Cassandra should add support for this kind of index. One option is to expose > a CQL interface like the following: > * Creating an index: > {code:sql} > cqlsh:mykeyspace> CREATE TABLE mytable (key TEXT PRIMARY KEY, value MAP<TEXT, > TEXT>); > cqlsh:mykeyspace> CREATE INDEX ON mytable(ENTRIES(value)); > {code} > * Querying the index: > {code:sql} > cqlsh:mykeyspace> INSERT INTO mytable (key, value) VALUES ('foo', {'a': '1', > 'b': '2', 'c': '3'}); > cqlsh:mykeyspace> INSERT INTO mytable (key, value) VALUES ('bar', {'a': '1', > 'b': '4'}); > cqlsh:mykeyspace> INSERT INTO mytable (key, value) VALUES ('baz', {'b': '4', > 'c': '3'}); > cqlsh:mykeyspace> SELECT * FROM mytable WHERE value['a'] = '1'; > key | value > -----+-------------------------------- > bar | {'a': '1', 'b': '4'} > foo | {'a': '1', 'b': '2', 'c': '3'} > (2 rows) > cqlsh:mykeyspace> SELECT * FROM mytable WHERE value['a'] = '1' AND value['b'] > = '2' ALLOW FILTERING; > key | value > -----+-------------------------------- > foo | {'a': '1', 'b': '2', 'c': '3'} > (1 rows) > cqlsh:mykeyspace> SELECT * FROM mytable WHERE value['b'] = '2' ALLOW > FILTERING; > key | value > -----+-------------------------------- > foo | {'a': '1', 'b': '2', 'c': '3'} > (1 rows) > cqlsh:mykeyspace> SELECT * FROM mytable WHERE value['b'] = '4'; > key | value > -----+---------------------- > bar | {'a': '1', 'b': '4'} > baz | {'b': '4', 'c': '3'} > (2 rows) > {code} > A patch against the Cassandra-2.1 branch that implements this interface will > be attached to this issue shortly. -- This message was sent by Atlassian JIRA (v6.3.4#6332)