http://git-wip-us.apache.org/repos/asf/cassandra/blob/9583b6b3/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java
--
diff --cc src/java/org/apache/cassandra/cql3/statements/SelectStatement.java
index 8820ff7,40f3f33..edf8e47
--- a/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java
@@@ -181,8 -247,11 +181,11 @@@ public class SelectStatement implement
private Pageable getPageableCommand(QueryOptions options, int limit, long
now) throws RequestValidationException
{
-if (isNotReturningAnyRows(options))
++if (restrictions.isNotReturningAnyRows(options))
+ return null;
+
int limitForQuery = updateLimitForQuery(limit);
-if (isKeyRange || usesSecondaryIndexing)
+if (restrictions.isKeyRange() || restrictions.usesSecondaryIndexing())
return getRangeCommand(options, limitForQuery, now);
List commands = getSliceCommands(options, limitForQuery,
now);
@@@ -596,52 -961,338 +599,58 @@@
}
}
-/** Returns true if a non-frozen collection is selected, false otherwise.
*/
-private boolean selectACollection()
+/**
+ * May be used by custom QueryHandler implementations
+ */
+public List getValidatedIndexExpressions(QueryOptions
options) throws InvalidRequestException
{
-if (!cfm.comparator.hasCollections())
-return false;
+if (!restrictions.usesSecondaryIndexing())
+return Collections.emptyList();
-for (ColumnDefinition def : selection.getColumns())
-{
-if (def.type.isCollection() && def.type.isMultiCell())
-return true;
-}
+ColumnFamilyStore cfs =
Keyspace.open(keyspace()).getColumnFamilyStore(columnFamily());
+SecondaryIndexManager secondaryIndexManager = cfs.indexManager;
-return false;
+List expressions =
restrictions.getIndexExpressions(secondaryIndexManager, options);
+secondaryIndexManager.validateIndexSearchersForQuery(expressions);
+
+return expressions;
}
-@VisibleForTesting
-static List buildBound(Bound bound,
- List defs,
- Restriction[] restrictions,
- boolean isReversed,
- CType type,
- QueryOptions options) throws
InvalidRequestException
+private CellName makeExclusiveSliceBound(Bound bound, CellNameType type,
QueryOptions options) throws InvalidRequestException
{
-CBuilder builder = type.builder();
-
-// The end-of-component of composite doesn't depend on whether the
-// component type is reversed or not (i.e. the ReversedType is applied
-// to the component comparator but not to the end-of-component
itself),
-// it only depends on whether the slice is reversed
-Bound eocBound = isReversed ? Bound.reverse(bound) : bound;
-for (int i = 0, m = defs.size(); i < m; i++)
-{
-ColumnDefinition def = defs.get(i);
-
-// In a restriction, we always have Bound.START < Bound.END for
the "base" comparator.
-// So if we're doing a reverse slice, we must inverse the bounds
when giving them as start and end of the slice filter.
-// But if the actual comparator itself is reversed, we must
inversed the bounds too.
-Bound b = isReversed == isReversedType(def) ? bound :
Bound.reverse(bound);
-Restriction r = restrictions[def.position()];
-if (isNullRestriction(r, b) || !r.canEvaluateWithSlices())
-{
-// There wasn't any non EQ relation on that key, we select
all records having the preceding component as prefix.
-// For composites, if there was preceding component and we're
computing the end, we must change the last component
-// End-Of-Component, otherwise we would be selecting only one
record.
-Composite prefix = builder.build();
-return Collections.singletonList(eocBound == Bound.END ?
prefix.end() : prefix.start());
-}
-if (r.isSlice())
-{
-if (r.isMultiColumn())
-{
-MultiColumnRestriction.Slice slice =
(MultiColumnRestriction.Slice) r;
+// clusteringColumnBounds may reverse bound if clustering order is
reversed
+// but areRequestedBoundsInclusive checks for
Restriction::isInclusive and never
+// reverses the order. In order to avoid inconsistencies and check
inclusive
+// bounds correctly, we need to check for column order and