Updated Branches: refs/heads/cassandra-2.0.0 8f367fdf9 -> c8b220ba1
Properly handle parsing huge map and set literals patch by Aleksey Yeschenko; reviewed by Sylvain Lebresne for CASSANDRA-5893 Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/dd65e88a Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/dd65e88a Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/dd65e88a Branch: refs/heads/cassandra-2.0.0 Commit: dd65e88a76c5f76b5747030742b3e4829663521f Parents: 55fed33 Author: Aleksey Yeschenko <alek...@apache.org> Authored: Wed Aug 21 18:37:30 2013 +0300 Committer: Aleksey Yeschenko <alek...@apache.org> Committed: Wed Aug 21 18:37:30 2013 +0300 ---------------------------------------------------------------------- CHANGES.txt | 4 +-- src/java/org/apache/cassandra/cql3/Cql.g | 37 +++++++++----------- .../apache/cassandra/cql3/QueryProcessor.java | 12 +++---- 3 files changed, 23 insertions(+), 30 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cassandra/blob/dd65e88a/CHANGES.txt ---------------------------------------------------------------------- diff --git a/CHANGES.txt b/CHANGES.txt index 74890ea..1ffec7d 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -23,11 +23,11 @@ * Don't announce schema version until we've loaded the changes locally (CASSANDRA-5904) * Add -no-snapshot option to scrub (CASSANDRA-5891) + * Fix to support off heap bloom filters size greater than 2 GB (CASSANDRA-5903) + * Properly handle parsing huge map and set literals (CASSANDRA-5893) Merged from 1.1: * Correctly validate sparse composite cells in scrub (CASSANDRA-5855) -1.2.9 - * Fix to support off heap bloom filters size greater than 2 GB (CASSANDRA-5903) 1.2.8 * Fix reading DeletionTime from 1.1-format sstables (CASSANDRA-5814) http://git-wip-us.apache.org/repos/asf/cassandra/blob/dd65e88a/src/java/org/apache/cassandra/cql3/Cql.g ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/cql3/Cql.g b/src/java/org/apache/cassandra/cql3/Cql.g index 6b31da5..218c541 100644 --- a/src/java/org/apache/cassandra/cql3/Cql.g +++ b/src/java/org/apache/cassandra/cql3/Cql.g @@ -390,7 +390,7 @@ batchStatement returns [BatchStatement expr] : K_BEGIN ( K_UNLOGGED { type = BatchStatement.Type.UNLOGGED; } | K_COUNTER { type = BatchStatement.Type.COUNTER; } )? K_BATCH ( usingClause[attrs] )? - s1=batchStatementObjective ';'? { statements.add(s1); } ( sN=batchStatementObjective ';'? { statements.add(sN); } )* + ( s=batchStatementObjective ';'? { statements.add(s); } )+ K_APPLY K_BATCH { return new BatchStatement(type, statements, attrs); @@ -676,33 +676,28 @@ constant returns [Constants.Literal constant] | t=HEXNUMBER { $constant = Constants.Literal.hex($t.text); } ; -set_tail[List<Term.Raw> s] - : '}' - | ',' t=term { s.add(t); } set_tail[s] - ; - -map_tail[List<Pair<Term.Raw, Term.Raw>> m] - : '}' - | ',' k=term ':' v=term { m.add(Pair.create(k, v)); } map_tail[m] - ; - map_literal returns [Maps.Literal map] - : '{' '}' { $map = new Maps.Literal(Collections.<Pair<Term.Raw, Term.Raw>>emptyList()); } - | '{' { List<Pair<Term.Raw, Term.Raw>> m = new ArrayList<Pair<Term.Raw, Term.Raw>>(); } - k1=term ':' v1=term { m.add(Pair.create(k1, v1)); } map_tail[m] - { $map = new Maps.Literal(m); } + : '{' { List<Pair<Term.Raw, Term.Raw>> m = new ArrayList<Pair<Term.Raw, Term.Raw>>(); } + ( k1=term ':' v1=term { m.add(Pair.create(k1, v1)); } ( ',' kn=term ':' vn=term { m.add(Pair.create(kn, vn)); } )* )? + '}' { $map = new Maps.Literal(m); } ; set_or_map[Term.Raw t] returns [Term.Raw value] - : ':' v=term { List<Pair<Term.Raw, Term.Raw>> m = new ArrayList<Pair<Term.Raw, Term.Raw>>(); m.add(Pair.create(t, v)); } map_tail[m] { $value = new Maps.Literal(m); } - | { List<Term.Raw> s = new ArrayList<Term.Raw>(); s.add(t); } set_tail[s] { $value = new Sets.Literal(s); } + : ':' v=term { List<Pair<Term.Raw, Term.Raw>> m = new ArrayList<Pair<Term.Raw, Term.Raw>>(); m.add(Pair.create(t, v)); } + ( ',' kn=term ':' vn=term { m.add(Pair.create(kn, vn)); } )* + { $value = new Maps.Literal(m); } + | { List<Term.Raw> s = new ArrayList<Term.Raw>(); s.add(t); } + ( ',' tn=term { s.add(tn); } )* + { $value = new Sets.Literal(s); } ; -// This is a bit convoluted but that's because I haven't found a much better to have antl disambiguate between sets and maps collection_literal returns [Term.Raw value] - : '[' { List<Term.Raw> l = new ArrayList<Term.Raw>(); } ( t1=term { l.add(t1); } ( ',' tn=term { l.add(tn); } )* )? ']' { $value = new Lists.Literal(l); } - | '{' t=term v=set_or_map[t] { $value = v; } - // Note that we have an ambiguity between maps and set for "{}". So we force it to a set literal, and deal with it later based on the type of the column (SetLiteral.java). + : '[' { List<Term.Raw> l = new ArrayList<Term.Raw>(); } + ( t1=term { l.add(t1); } ( ',' tn=term { l.add(tn); } )* )? + ']' { $value = new Lists.Literal(l); } + | '{' t=term v=set_or_map[t] { $value = v; } '}' + // Note that we have an ambiguity between maps and set for "{}". So we force it to a set literal, + // and deal with it later based on the type of the column (SetLiteral.java). | '{' '}' { $value = new Sets.Literal(Collections.<Term.Raw>emptyList()); } ; http://git-wip-us.apache.org/repos/asf/cassandra/blob/dd65e88a/src/java/org/apache/cassandra/cql3/QueryProcessor.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/cql3/QueryProcessor.java b/src/java/org/apache/cassandra/cql3/QueryProcessor.java index 4ae1e90..f3cea48 100644 --- a/src/java/org/apache/cassandra/cql3/QueryProcessor.java +++ b/src/java/org/apache/cassandra/cql3/QueryProcessor.java @@ -27,10 +27,7 @@ import org.slf4j.LoggerFactory; import org.apache.cassandra.cql3.statements.*; import org.apache.cassandra.transport.messages.ResultMessage; -import org.apache.cassandra.config.*; import org.apache.cassandra.db.*; -import org.apache.cassandra.db.filter.*; -import org.apache.cassandra.db.marshal.AbstractType; import org.apache.cassandra.exceptions.*; import org.apache.cassandra.service.ClientState; import org.apache.cassandra.service.QueryState; @@ -262,13 +259,14 @@ public class QueryProcessor } catch (RuntimeException re) { - SyntaxException ire = new SyntaxException("Failed parsing statement: [" + queryStr + "] reason: " + re.getClass().getSimpleName() + " " + re.getMessage()); - throw ire; + throw new SyntaxException(String.format("Failed parsing statement: [%s] reason: %s %s", + queryStr, + re.getClass().getSimpleName(), + re.getMessage())); } catch (RecognitionException e) { - SyntaxException ire = new SyntaxException("Invalid or malformed CQL query string: " + e.getMessage()); - throw ire; + throw new SyntaxException("Invalid or malformed CQL query string: " + e.getMessage()); } } }