Merge branch 'cassandra-2.0' into cassandra-2.1 Conflicts: build.xml debian/changelog src/java/org/apache/cassandra/cql3/statements/SelectStatement.java
Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/d5e5659e Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/d5e5659e Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/d5e5659e Branch: refs/heads/trunk Commit: d5e5659e419833a39e19b20e267312c41f99d685 Parents: e88b888 5b878ce Author: Sylvain Lebresne <sylv...@datastax.com> Authored: Thu Jun 26 18:01:35 2014 +0200 Committer: Sylvain Lebresne <sylv...@datastax.com> Committed: Thu Jun 26 18:01:35 2014 +0200 ---------------------------------------------------------------------- CHANGES.txt | 4 +++ .../cassandra/cql3/SingleColumnRelation.java | 10 ++++++ .../cql3/statements/SelectStatement.java | 34 ++++++++++++++++++++ 3 files changed, 48 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cassandra/blob/d5e5659e/CHANGES.txt ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cassandra/blob/d5e5659e/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java ---------------------------------------------------------------------- diff --cc src/java/org/apache/cassandra/cql3/statements/SelectStatement.java index 1e1b03f,98bd99a..a4a5553 --- a/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java +++ b/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java @@@ -1950,24 -1977,42 +1950,58 @@@ public class SelectStatement implement "thus may have unpredictable performance. If you want to execute " + "this query despite the performance unpredictability, use ALLOW FILTERING"); } + + // We don't internally support exclusive slice bounds on non-composite tables. To deal with it we do an + // inclusive slice and remove post-query the value that shouldn't be returned. One problem however is that + // if there is a user limit, that limit may make the query return before the end of the slice is reached, + // in which case, once we'll have removed bound post-query, we might end up with less results than + // requested which would be incorrect. For single-partition query, this is not a problem, we just ask for + // one more result (see updateLimitForQuery()) since that's enough to compensate for that problem. For key + // range however, each returned row may include one result that will have to be trimmed, so we would have + // to bump the query limit by N where N is the number of rows we will return, but we don't know that in + // advance. So, since we currently don't have a good way to handle such query, we refuse it (#7059) rather + // than answering with something that is wrong. + if (stmt.sliceRestriction != null && stmt.isKeyRange && limit != null) + { - SingleColumnRelation rel = findInclusiveClusteringRelationForCompact(stmt.cfDef); ++ SingleColumnRelation rel = findInclusiveClusteringRelationForCompact(stmt.cfm); + throw new InvalidRequestException(String.format("The query requests a restriction of rows with a strict bound (%s) over a range of partitions. " + + "This is not supported by the underlying storage engine for COMPACT tables if a LIMIT is provided. " + + "Please either make the condition non strict (%s) or remove the user LIMIT", rel, rel.withNonStrictOperator())); + } } - private SingleColumnRelation findInclusiveClusteringRelationForCompact(CFDefinition cfDef) + private int indexOf(ColumnDefinition def, Selection selection) + { + return indexOf(def, selection.getColumns().iterator()); + } + + private int indexOf(final ColumnDefinition def, Iterator<ColumnDefinition> defs) + { + return Iterators.indexOf(defs, new Predicate<ColumnDefinition>() + { + public boolean apply(ColumnDefinition n) + { + return def.name.equals(n.name); + } + }); + } + ++ private SingleColumnRelation findInclusiveClusteringRelationForCompact(CFMetaData cfm) + { + for (Relation r : whereClause) + { + // We only call this when sliceRestriction != null, i.e. for compact table with non composite comparator, + // so it can't be a MultiColumnRelation. + SingleColumnRelation rel = (SingleColumnRelation)r; - if (cfDef.get(rel.getEntity()).kind == CFDefinition.Name.Kind.COLUMN_ALIAS ++ if (cfm.getColumnDefinition(rel.getEntity()).kind == ColumnDefinition.Kind.CLUSTERING_COLUMN + && (rel.operator() == Relation.Type.GT || rel.operator() == Relation.Type.LT)) + return rel; + } + + // We're not supposed to call this method unless we know this can't happen + throw new AssertionError(); + } + private boolean containsAlias(final ColumnIdentifier name) { return Iterables.any(selectClause, new Predicate<RawSelector>()