You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by sl...@apache.org on 2012/04/11 17:24:18 UTC
[2/3] git commit: CQL3: Support slice with exclusive start and stop
CQL3: Support slice with exclusive start and stop
patch by slebresne; reviewed by jbellis for CASSANDRA-3785
Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/d49113fa
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/d49113fa
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/d49113fa
Branch: refs/heads/cassandra-1.1
Commit: d49113fad1bf7a15ca052156b872b9bdc01b6d73
Parents: fc7e864
Author: Sylvain Lebresne <sy...@datastax.com>
Authored: Thu Jan 26 10:49:56 2012 +0100
Committer: Sylvain Lebresne <sy...@datastax.com>
Committed: Wed Apr 11 17:17:59 2012 +0200
----------------------------------------------------------------------
CHANGES.txt | 1 +
.../cassandra/cql3/statements/SelectStatement.java | 61 ++++++++++++--
2 files changed, 53 insertions(+), 9 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cassandra/blob/d49113fa/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index df030b9..4ef47c5 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -13,6 +13,7 @@
(CASSANDRA-4128)
* Move CfDef and KsDef validation out of thrift (CASSANDRA-4037)
* Fix get_paged_slice (CASSANDRA-4136)
+ * CQL3: Support slice with exclusive start and stop (CASSANDRA-3785)
Merged from 1.0:
* add auto_snapshot option allowing disabling snapshot before drop/truncate
(CASSANDRA-3710)
http://git-wip-us.apache.org/repos/asf/cassandra/blob/d49113fa/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java b/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java
index 5bcd37a..0485857 100644
--- a/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java
@@ -91,6 +91,7 @@ public class SelectStatement implements CQLStatement
private Restriction keyRestriction;
private final Restriction[] columnRestrictions;
private final Map<CFDefinition.Name, Restriction> metadataRestrictions = new HashMap<CFDefinition.Name, Restriction>();
+ private Restriction sliceRestriction;
private static enum Bound
{
@@ -323,10 +324,13 @@ public class SelectStatement implements CQLStatement
private int getLimit()
{
+ // Internally, we don't support exclusive bounds for slices. Instead,
+ // we query one more element if necessary and exclude
+ int limit = sliceRestriction != null && !sliceRestriction.isInclusive(Bound.START) ? parameters.limit + 1 : parameters.limit;
// For sparse, we'll end up merging all defined colums into the same CqlRow. Thus we should query up
// to 'defined columns' * 'asked limit' to be sure to have enough columns. We'll trim after query if
// this end being too much.
- return cfDef.isCompact ? parameters.limit : cfDef.metadata.size() * parameters.limit;
+ return cfDef.isCompact ? limit : cfDef.metadata.size() * limit;
}
private boolean isKeyRange()
@@ -602,9 +606,20 @@ public class SelectStatement implements CQLStatement
thriftColumns = new ArrayList<Column>();
- ByteBuffer[] components = cfDef.isComposite
- ? ((CompositeType)cfDef.cfm.comparator).split(c.name())
- : null;
+ ByteBuffer[] components = null;
+
+ if (cfDef.isComposite)
+ {
+ components = ((CompositeType)cfDef.cfm.comparator).split(c.name());
+ }
+ else if (sliceRestriction != null)
+ {
+ // For dynamic CF, the column could be out of the requested bounds, filter here
+ if (!sliceRestriction.isInclusive(Bound.START) && c.name().equals(sliceRestriction.bound(Bound.START).getByteBuffer(cfDef.cfm.comparator, variables)))
+ continue;
+ if (!sliceRestriction.isInclusive(Bound.END) && c.name().equals(sliceRestriction.bound(Bound.END).getByteBuffer(cfDef.cfm.comparator, variables)))
+ continue;
+ }
// Respect selection order
for (Pair<CFDefinition.Name, ColumnIdentifier> p : selection)
@@ -711,9 +726,9 @@ public class SelectStatement implements CQLStatement
if (parameters.isColumnsReversed)
Collections.reverse(cqlRows);
+ // Trim result if needed to respect the limit
cqlRows = cqlRows.size() > parameters.limit ? cqlRows.subList(0, parameters.limit) : cqlRows;
- // Trim result if needed to respect the limit
return cqlRows;
}
@@ -880,14 +895,26 @@ public class SelectStatement implements CQLStatement
CFDefinition.Name cname = iter.next();
Restriction restriction = stmt.columnRestrictions[i];
if (restriction == null)
+ {
shouldBeDone = true;
+ }
else if (shouldBeDone)
+ {
throw new InvalidRequestException(String.format("PRIMARY KEY part %s cannot be restricted (preceding part %s is either not restricted or by a non-EQ relation)", cname, previous));
+ }
else if (!restriction.isEquality())
+ {
shouldBeDone = true;
+ // For non-composite slices, we don't support internally the difference between exclusive and
+ // inclusive bounds, so we deal with it manually.
+ if (!cfDef.isComposite && (!restriction.isInclusive(Bound.START) || !restriction.isInclusive(Bound.END)))
+ stmt.sliceRestriction = restriction;
+ }
// We only support IN for the last name so far
else if (restriction.eqValues.size() > 1 && i != stmt.columnRestrictions.length - 1)
+ {
throw new InvalidRequestException(String.format("PRIMARY KEY part %s cannot be restricted by IN relation (only the first and last parts can)", cname));
+ }
previous = cname;
}
@@ -1039,7 +1066,7 @@ public class SelectStatement implements CQLStatement
public boolean isInclusive(Bound b)
{
- return boundInclusive[b.idx];
+ return bounds[b.idx] == null || boundInclusive[b.idx];
}
public Relation.Type getRelation(Bound b)
@@ -1080,11 +1107,11 @@ public class SelectStatement implements CQLStatement
b = Bound.START;
inclusive = true;
break;
- case LTE:
+ case LT:
b = Bound.END;
- inclusive = true;
+ inclusive = false;
break;
- case LT:
+ case LTE:
b = Bound.END;
inclusive = true;
break;
@@ -1095,6 +1122,22 @@ public class SelectStatement implements CQLStatement
bounds[b.idx] = t;
boundInclusive[b.idx] = inclusive;
}
+
+ @Override
+ public String toString()
+ {
+ if (eqValues == null)
+ {
+ return String.format("SLICE(%s %s, %s %s)", boundInclusive[0] ? ">=" : ">",
+ bounds[0],
+ boundInclusive[1] ? "<=" : "<",
+ bounds[1]);
+ }
+ else
+ {
+ return String.format("EQ(%s)", eqValues);
+ }
+ }
}
public static class Parameters