You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by bl...@apache.org on 2016/07/04 12:32:29 UTC
[3/3] cassandra git commit: Merge branch cassandra-2.2 into
cassandra-3.0
Merge branch cassandra-2.2 into cassandra-3.0
Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/9244531a
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/9244531a
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/9244531a
Branch: refs/heads/cassandra-3.0
Commit: 9244531ab7bb0f4d07cf9996a9bb89d5e4370f54
Parents: db61372 e06dae8
Author: Benjamin Lerer <b....@gmail.com>
Authored: Mon Jul 4 14:30:55 2016 +0200
Committer: Benjamin Lerer <b....@gmail.com>
Committed: Mon Jul 4 14:31:46 2016 +0200
----------------------------------------------------------------------
CHANGES.txt | 3 +
.../restrictions/MultiColumnRestriction.java | 2 +-
.../restrictions/PrimaryKeyRestrictionSet.java | 82 ++++----------------
.../restrictions/StatementRestrictions.java | 41 ++++++++--
.../SelectMultiColumnRelationTest.java | 33 +++++++-
.../cql3/validation/operations/SelectTest.java | 61 +++++++++++++++
6 files changed, 144 insertions(+), 78 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cassandra/blob/9244531a/CHANGES.txt
----------------------------------------------------------------------
diff --cc CHANGES.txt
index f12d704,451575c..2df77e1
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@@ -1,17 -1,11 +1,20 @@@
-2.2.8
+3.0.9
+ * Avoid digest mismatch with empty but static rows (CASSANDRA-12090)
+ * Fix EOF exception when altering column type (CASSANDRA-11820)
+Merged from 2.2:
* MemoryUtil.getShort() should return an unsigned short also for architectures not supporting unaligned memory accesses (CASSANDRA-11973)
+ Merged from 2.1:
+ * Fix filtering on clustering columns when 2i is used (CASSANDRA-11907)
- * Account for partition deletions in tombstone histogram (CASSANDRA-12112)
+
-2.2.7
+3.0.8
+ * Fix potential race in schema during new table creation (CASSANDRA-12083)
+ * cqlsh: fix error handling in rare COPY FROM failure scenario (CASSANDRA-12070)
+ * Disable autocompaction during drain (CASSANDRA-11878)
+ * Add a metrics timer to MemtablePool and use it to track time spent blocked on memory in MemtableAllocator (CASSANDRA-11327)
+ * Fix upgrading schema with super columns with non-text subcomparators (CASSANDRA-12023)
+ * Add TimeWindowCompactionStrategy (CASSANDRA-9666)
+Merged from 2.2:
* Allow nodetool info to run with readonly JMX access (CASSANDRA-11755)
* Validate bloom_filter_fp_chance against lowest supported
value when the table is created (CASSANDRA-11920)
http://git-wip-us.apache.org/repos/asf/cassandra/blob/9244531a/src/java/org/apache/cassandra/cql3/restrictions/MultiColumnRestriction.java
----------------------------------------------------------------------
diff --cc src/java/org/apache/cassandra/cql3/restrictions/MultiColumnRestriction.java
index 4329b6e,51e2ce4..9d33bb1
--- a/src/java/org/apache/cassandra/cql3/restrictions/MultiColumnRestriction.java
+++ b/src/java/org/apache/cassandra/cql3/restrictions/MultiColumnRestriction.java
@@@ -473,11 -471,11 +473,11 @@@ public abstract class MultiColumnRestri
}
@Override
- public final void addIndexExpressionTo(List<IndexExpression> expressions,
- SecondaryIndexManager indexManager,
- QueryOptions options) throws InvalidRequestException
+ public final void addRowFilterTo(RowFilter filter,
+ SecondaryIndexManager indexManager,
+ QueryOptions options) throws InvalidRequestException
{
- throw invalidRequest("Slice restrictions are not supported on indexed columns");
+ throw invalidRequest("Multi-column slice restrictions cannot be used for filtering.");
}
@Override
http://git-wip-us.apache.org/repos/asf/cassandra/blob/9244531a/src/java/org/apache/cassandra/cql3/restrictions/PrimaryKeyRestrictionSet.java
----------------------------------------------------------------------
diff --cc src/java/org/apache/cassandra/cql3/restrictions/PrimaryKeyRestrictionSet.java
index 061284b,e1cbc29..a5f4a24
--- a/src/java/org/apache/cassandra/cql3/restrictions/PrimaryKeyRestrictionSet.java
+++ b/src/java/org/apache/cassandra/cql3/restrictions/PrimaryKeyRestrictionSet.java
@@@ -25,14 -26,11 +25,13 @@@ import org.apache.cassandra.config.Colu
import org.apache.cassandra.cql3.QueryOptions;
import org.apache.cassandra.cql3.functions.Function;
import org.apache.cassandra.cql3.statements.Bound;
-import org.apache.cassandra.db.IndexExpression;
-import org.apache.cassandra.db.composites.*;
-import org.apache.cassandra.db.composites.Composite.EOC;
-import org.apache.cassandra.db.index.SecondaryIndexManager;
+import org.apache.cassandra.db.*;
+import org.apache.cassandra.db.filter.RowFilter;
import org.apache.cassandra.exceptions.InvalidRequestException;
+import org.apache.cassandra.index.SecondaryIndexManager;
+import org.apache.cassandra.utils.btree.BTreeSet;
+
- import static org.apache.cassandra.cql3.statements.RequestValidations.checkFalse;
+import static org.apache.cassandra.cql3.statements.RequestValidations.invalidRequest;
/**
* A set of single column restrictions on a primary key part (partition key or clustering key).
@@@ -64,72 -62,18 +63,26 @@@ final class PrimaryKeyRestrictionSet ex
*/
private boolean contains;
- public PrimaryKeyRestrictionSet(CType ctype)
+ /**
+ * <code>true</code> if the restrictions corresponding to a partition key, <code>false</code> if it's clustering columns.
+ */
+ private boolean isPartitionKey;
+
- /**
- * If restrictions apply to clustering columns, we need to check whether they can be satisfied by an index lookup
- * as this affects which other restrictions can legally be specified (if an index is present, we are more lenient
- * about what additional filtering can be performed on the results of a lookup - see CASSANDRA-11510).
- *
- * We don't hold a reference to the SecondaryIndexManager itself as this is not strictly a singleton (although
- * we often treat is as one), the field would also require annotation with @Unmetered to avoid blowing up the
- * object size (used when calculating the size of prepared statements for caching). Instead, we refer to the
- * CFMetaData and retrieve the index manager when necessary.
- *
- * There are a couple of scenarios where the CFM can be null (and we make sure and test for null when we use it):
- * * where an empty set of restrictions are created for use in processing query results - see
- * SelectStatement.forSelection
- * * where the restrictions apply to partition keys and not clustering columns e.g.
- * StatementRestrictions.partitionKeyRestrictions
- * * in unit tests (in particular PrimaryKeyRestrictionSetTest which is primarily concerned with the correct
- * generation of bounds when secondary indexes are not used).
- */
- private final CFMetaData cfm;
-
+ public PrimaryKeyRestrictionSet(ClusteringComparator comparator, boolean isPartitionKey)
{
- this(comparator, isPartitionKey, null);
- }
-
- public PrimaryKeyRestrictionSet(ClusteringComparator comparator, boolean isPartitionKey, CFMetaData cfm)
- {
- super(ctype);
+ super(comparator);
+
- if (cfm != null)
- assert !isPartitionKey;
-
- this.cfm = cfm;
this.restrictions = new RestrictionSet();
this.eq = true;
+ this.isPartitionKey = isPartitionKey;
}
private PrimaryKeyRestrictionSet(PrimaryKeyRestrictionSet primaryKeyRestrictions,
Restriction restriction) throws InvalidRequestException
{
- super(primaryKeyRestrictions.ctype);
+ super(primaryKeyRestrictions.comparator);
this.restrictions = primaryKeyRestrictions.restrictions.addRestriction(restriction);
+ this.isPartitionKey = primaryKeyRestrictions.isPartitionKey;
- this.cfm = primaryKeyRestrictions.cfm;
-
- if (!primaryKeyRestrictions.isEmpty() && !hasSupportingIndex(restriction))
- {
- ColumnDefinition lastRestrictionStart = primaryKeyRestrictions.restrictions.lastRestriction().getFirstColumn();
- ColumnDefinition newRestrictionStart = restriction.getFirstColumn();
-
- checkFalse(primaryKeyRestrictions.isSlice() && newRestrictionStart.position() > lastRestrictionStart.position(),
- "Clustering column \"%s\" cannot be restricted (preceding column \"%s\" is restricted by a non-EQ relation)",
- newRestrictionStart.name,
- lastRestrictionStart.name);
-
- if (newRestrictionStart.position() < lastRestrictionStart.position() && restriction.isSlice())
- throw invalidRequest("PRIMARY KEY column \"%s\" cannot be restricted (preceding column \"%s\" is restricted by a non-EQ relation)",
- restrictions.nextColumn(newRestrictionStart).name,
- newRestrictionStart.name);
- }
if (restriction.isSlice() || primaryKeyRestrictions.isSlice())
this.slice = true;
@@@ -141,22 -85,6 +94,15 @@@
this.eq = true;
}
+ private List<ByteBuffer> toByteBuffers(SortedSet<? extends ClusteringPrefix> clusterings)
+ {
+ // It's currently a tad hard to follow that this is only called for partition key so we should fix that
+ List<ByteBuffer> l = new ArrayList<>(clusterings.size());
+ for (ClusteringPrefix clustering : clusterings)
+ l.add(CFMetaData.serializePartitionKey(clustering));
+ return l;
+ }
+
- private boolean hasSupportingIndex(Restriction restriction)
- {
- return cfm != null
- && restriction.hasSupportingIndex(Keyspace.openAndGetStore(cfm).indexManager);
-
- }
-
@Override
public boolean isSlice()
{
@@@ -319,16 -338,22 +265,15 @@@
for (Restriction restriction : restrictions)
{
-- ColumnDefinition columnDef = restriction.getFirstColumn();
-
- // PrimaryKeyRestrictionSet contains only one kind of column, either partition key or clustering columns.
- // Therefore we only need to check the column kind once. All the other columns will be of the same kind.
- if (clusteringColumns == null)
- clusteringColumns = columnDef.isClusteringColumn() ? Boolean.TRUE : Boolean.FALSE;
--
// We ignore all the clustering columns that can be handled by slices.
- if (!isPartitionKey && !restriction.isContains()&& position == columnDef.position())
- if (!clusteringColumns || handleInFilter(restriction, position) || restriction.hasSupportingIndex(indexManager))
++ if (isPartitionKey || handleInFilter(restriction, position) || restriction.hasSupportingIndex(indexManager))
{
- position = restriction.getLastColumn().position() + 1;
- if (!restriction.hasSupportingIndex(indexManager))
- continue;
- restriction.addIndexExpressionTo(expressions, indexManager, options);
++ restriction.addRowFilterTo(filter, indexManager, options);
+ continue;
}
- restriction.addRowFilterTo(filter, indexManager, options);
+
+ if (!restriction.isSlice())
+ position = restriction.getLastColumn().position() + 1;
}
}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/9244531a/src/java/org/apache/cassandra/cql3/restrictions/StatementRestrictions.java
----------------------------------------------------------------------
diff --cc src/java/org/apache/cassandra/cql3/restrictions/StatementRestrictions.java
index ae0c9c4,1547210..647d22f
--- a/src/java/org/apache/cassandra/cql3/restrictions/StatementRestrictions.java
+++ b/src/java/org/apache/cassandra/cql3/restrictions/StatementRestrictions.java
@@@ -27,22 -28,17 +27,20 @@@ import org.apache.cassandra.config.Colu
import org.apache.cassandra.cql3.*;
import org.apache.cassandra.cql3.functions.Function;
import org.apache.cassandra.cql3.statements.Bound;
+import org.apache.cassandra.cql3.statements.StatementType;
import org.apache.cassandra.db.*;
-import org.apache.cassandra.db.composites.Composite;
-import org.apache.cassandra.db.index.SecondaryIndexManager;
+import org.apache.cassandra.db.filter.RowFilter;
+import org.apache.cassandra.db.marshal.AbstractType;
import org.apache.cassandra.dht.*;
import org.apache.cassandra.exceptions.InvalidRequestException;
-import org.apache.cassandra.service.StorageService;
+import org.apache.cassandra.index.Index;
+import org.apache.cassandra.index.SecondaryIndexManager;
+import org.apache.cassandra.net.MessagingService;
import org.apache.cassandra.utils.ByteBufferUtil;
+import org.apache.cassandra.utils.btree.BTreeSet;
-import static org.apache.cassandra.config.ColumnDefinition.toIdentifiers;
import static org.apache.cassandra.cql3.statements.RequestValidations.checkFalse;
import static org.apache.cassandra.cql3.statements.RequestValidations.checkNotNull;
- import static org.apache.cassandra.cql3.statements.RequestValidations.checkTrue;
import static org.apache.cassandra.cql3.statements.RequestValidations.invalidRequest;
/**
@@@ -125,58 -110,28 +123,58 @@@ public final class StatementRestriction
VariableSpecifications boundNames,
boolean selectsOnlyStaticColumns,
boolean selectACollection,
- boolean useFiltering,
- boolean allowFiltering)
++ boolean allowFiltering,
+ boolean forView) throws InvalidRequestException
{
+ this.type = type;
this.cfm = cfm;
- this.partitionKeyRestrictions = new PrimaryKeyRestrictionSet(cfm.getKeyValidatorAsCType());
- this.clusteringColumnsRestrictions = new PrimaryKeyRestrictionSet(cfm.comparator);
+ this.partitionKeyRestrictions = new PrimaryKeyRestrictionSet(cfm.getKeyValidatorAsClusteringComparator(), true);
- this.clusteringColumnsRestrictions = new PrimaryKeyRestrictionSet(cfm.comparator, false, cfm);
++ this.clusteringColumnsRestrictions = new PrimaryKeyRestrictionSet(cfm.comparator, false);
this.nonPrimaryKeyRestrictions = new RestrictionSet();
+ this.notNullColumns = new HashSet<>();
/*
- * WHERE clause. For a given entity, rules are: - EQ relation conflicts with anything else (including a 2nd EQ)
- * - Can't have more than one LT(E) relation (resp. GT(E) relation) - IN relation are restricted to row keys
- * (for now) and conflicts with anything else (we could allow two IN for the same entity but that doesn't seem
- * very useful) - The value_alias cannot be restricted in any way (we don't support wide rows with indexed value
- * in CQL so far)
+ * WHERE clause. For a given entity, rules are:
+ * - EQ relation conflicts with anything else (including a 2nd EQ)
+ * - Can't have more than one LT(E) relation (resp. GT(E) relation)
+ * - IN relation are restricted to row keys (for now) and conflicts with anything else (we could
+ * allow two IN for the same entity but that doesn't seem very useful)
+ * - The value_alias cannot be restricted in any way (we don't support wide rows with indexed value
+ * in CQL so far)
*/
- for (Relation relation : whereClause)
- addRestriction(relation.toRestriction(cfm, boundNames));
+ for (Relation relation : whereClause.relations)
+ {
+ if (relation.operator() == Operator.IS_NOT)
+ {
+ if (!forView)
+ throw new InvalidRequestException("Unsupported restriction: " + relation);
+
+ for (ColumnDefinition def : relation.toRestriction(cfm, boundNames).getColumnDefs())
+ this.notNullColumns.add(def);
+ }
+ else
+ {
+ addRestriction(relation.toRestriction(cfm, boundNames));
+ }
+ }
+
+ boolean hasQueriableClusteringColumnIndex = false;
+ boolean hasQueriableIndex = false;
- SecondaryIndexManager secondaryIndexManager = Keyspace.open(cfm.ksName).getColumnFamilyStore(cfm.cfName).indexManager;
- boolean hasQueriableClusteringColumnIndex = clusteringColumnsRestrictions.hasSupportingIndex(secondaryIndexManager);
- boolean hasQueriableIndex = hasQueriableClusteringColumnIndex
- || partitionKeyRestrictions.hasSupportingIndex(secondaryIndexManager)
- || nonPrimaryKeyRestrictions.hasSupportingIndex(secondaryIndexManager);
+ if (type.allowUseOfSecondaryIndices())
+ {
+ ColumnFamilyStore cfs = Keyspace.open(cfm.ksName).getColumnFamilyStore(cfm.cfName);
+ SecondaryIndexManager secondaryIndexManager = cfs.indexManager;
+
+ if (whereClause.containsCustomExpressions())
+ processCustomIndexExpressions(whereClause.expressions, boundNames, secondaryIndexManager);
+
+ hasQueriableClusteringColumnIndex = clusteringColumnsRestrictions.hasSupportingIndex(secondaryIndexManager);
+ hasQueriableIndex = !indexRestrictions.getCustomIndexExpressions().isEmpty()
+ || hasQueriableClusteringColumnIndex
+ || partitionKeyRestrictions.hasSupportingIndex(secondaryIndexManager)
+ || nonPrimaryKeyRestrictions.hasSupportingIndex(secondaryIndexManager);
+ }
// At this point, the select statement if fully constructed, but we still have a few things to validate
processPartitionKeyRestrictions(hasQueriableIndex);
@@@ -220,19 -159,17 +218,19 @@@
// there is restrictions not covered by the PK.
if (!nonPrimaryKeyRestrictions.isEmpty())
{
- if (!hasQueriableIndex)
+ if (!type.allowNonPrimaryKeyInWhereClause())
{
- // Filtering for non-index query is only supported for thrift static CFs
- if (cfm.comparator.isDense() || cfm.comparator.isCompound())
- throw invalidRequest("Predicates on non-primary-key columns (%s) are not yet supported for non secondary index queries",
- Joiner.on(", ").join(toIdentifiers(nonPrimaryKeyRestrictions.getColumnDefs())));
+ Collection<ColumnIdentifier> nonPrimaryKeyColumns =
+ ColumnDefinition.toIdentifiers(nonPrimaryKeyRestrictions.getColumnDefs());
- if (!allowFiltering)
- throw invalidRequest(REQUIRES_ALLOW_FILTERING_MESSAGE);
+ throw invalidRequest("Non PRIMARY KEY columns found in where clause: %s ",
+ Joiner.on(", ").join(nonPrimaryKeyColumns));
}
- usesSecondaryIndexing = true;
+ if (hasQueriableIndex)
+ usesSecondaryIndexing = true;
- else if (!useFiltering)
++ else if (!allowFiltering)
+ throw invalidRequest(StatementRestrictions.REQUIRES_ALLOW_FILTERING_MESSAGE);
+
indexRestrictions.add(nonPrimaryKeyRestrictions);
}
@@@ -435,60 -299,78 +433,93 @@@
* Processes the clustering column restrictions.
*
* @param hasQueriableIndex <code>true</code> if some of the queried data are indexed, <code>false</code> otherwise
+ * @param selectsOnlyStaticColumns <code>true</code> if the selected or modified columns are all statics,
+ * <code>false</code> otherwise.
* @param selectACollection <code>true</code> if the query should return a collection column
- * @throws InvalidRequestException if the request is invalid
*/
private void processClusteringColumnsRestrictions(boolean hasQueriableIndex,
- boolean selectACollection) throws InvalidRequestException
+ boolean selectsOnlyStaticColumns,
+ boolean selectACollection,
+ boolean forView) throws InvalidRequestException
{
+ validateClusteringRestrictions(hasQueriableIndex);
+
- checkFalse(clusteringColumnsRestrictions.isIN() && selectACollection,
- "Cannot restrict clustering columns by IN relations when a collection is selected by the query");
- checkFalse(clusteringColumnsRestrictions.isContains() && !hasQueriableIndex,
- "Cannot restrict clustering columns by a CONTAINS relation without a secondary index");
+ checkFalse(!type.allowClusteringColumnSlices() && clusteringColumnsRestrictions.isSlice(),
+ "Slice restrictions are not supported on the clustering columns in %s statements", type);
- if (hasClusteringColumnsRestriction() && clusteringRestrictionsNeedFiltering())
+ if (!type.allowClusteringColumnSlices()
+ && (!cfm.isCompactTable() || (cfm.isCompactTable() && !hasClusteringColumnsRestriction())))
{
- if (hasQueriableIndex)
- {
- usesSecondaryIndexing = true;
- return;
- }
-
- List<ColumnDefinition> clusteringColumns = cfm.clusteringColumns();
- List<ColumnDefinition> restrictedColumns = new LinkedList<>(clusteringColumnsRestrictions.getColumnDefs());
+ if (!selectsOnlyStaticColumns && hasUnrestrictedClusteringColumns())
+ throw invalidRequest("Some clustering keys are missing: %s",
+ Joiner.on(", ").join(getUnrestrictedClusteringColumns()));
+ }
+ else
+ {
+ checkFalse(clusteringColumnsRestrictions.isIN() && selectACollection,
+ "Cannot restrict clustering columns by IN relations when a collection is selected by the query");
+ checkFalse(clusteringColumnsRestrictions.isContains() && !hasQueriableIndex,
+ "Cannot restrict clustering columns by a CONTAINS relation without a secondary index");
- for (int i = 0, m = restrictedColumns.size(); i < m; i++)
+ if (hasClusteringColumnsRestriction() && clusteringRestrictionsNeedFiltering())
{
- ColumnDefinition clusteringColumn = clusteringColumns.get(i);
- ColumnDefinition restrictedColumn = restrictedColumns.get(i);
+ if (hasQueriableIndex || forView)
+ {
+ usesSecondaryIndexing = true;
+ return;
+ }
- if (!clusteringColumn.equals(restrictedColumn))
+ List<ColumnDefinition> clusteringColumns = cfm.clusteringColumns();
+ List<ColumnDefinition> restrictedColumns = new LinkedList<>(clusteringColumnsRestrictions.getColumnDefs());
+
+ for (int i = 0, m = restrictedColumns.size(); i < m; i++)
{
- throw invalidRequest(
- "PRIMARY KEY column \"%s\" cannot be restricted as preceding column \"%s\" is not restricted",
- restrictedColumn.name,
- clusteringColumn.name);
+ ColumnDefinition clusteringColumn = clusteringColumns.get(i);
+ ColumnDefinition restrictedColumn = restrictedColumns.get(i);
+
+ if (!clusteringColumn.equals(restrictedColumn))
+ {
+ throw invalidRequest(
+ "PRIMARY KEY column \"%s\" cannot be restricted as preceding column \"%s\" is not restricted",
+ restrictedColumn.name,
+ clusteringColumn.name);
+ }
}
}
}
}
+ /**
+ * Validates whether or not restrictions are allowed for execution when secondary index is not used.
+ */
+ public final void validateClusteringRestrictions(boolean hasQueriableIndex)
+ {
+ assert clusteringColumnsRestrictions instanceof PrimaryKeyRestrictionSet;
+
+ // If there's a queriable index, filtering will take care of clustering restrictions
+ if (hasQueriableIndex)
+ return;
+
- Iterator<Restriction> iter = ((PrimaryKeyRestrictionSet)clusteringColumnsRestrictions).iterator();
++ Iterator<Restriction> iter = ((PrimaryKeyRestrictionSet) clusteringColumnsRestrictions).iterator();
+ Restriction previousRestriction = null;
-
+ while (iter.hasNext())
+ {
+ Restriction restriction = iter.next();
+
+ if (previousRestriction != null)
+ {
+ ColumnDefinition lastRestrictionStart = previousRestriction.getFirstColumn();
+ ColumnDefinition newRestrictionStart = restriction.getFirstColumn();
+
+ if (previousRestriction.isSlice() && newRestrictionStart.position() > lastRestrictionStart.position())
+ throw invalidRequest("Clustering column \"%s\" cannot be restricted (preceding column \"%s\" is restricted by a non-EQ relation)",
+ newRestrictionStart.name,
+ lastRestrictionStart.name);
+ }
+ previousRestriction = restriction;
+ }
+ }
+
public final boolean clusteringRestrictionsNeedFiltering()
{
assert clusteringColumnsRestrictions instanceof PrimaryKeyRestrictionSet;
http://git-wip-us.apache.org/repos/asf/cassandra/blob/9244531a/test/unit/org/apache/cassandra/cql3/validation/operations/SelectMultiColumnRelationTest.java
----------------------------------------------------------------------
diff --cc test/unit/org/apache/cassandra/cql3/validation/operations/SelectMultiColumnRelationTest.java
index 0db0039,0975662..ce74fe2
--- a/test/unit/org/apache/cassandra/cql3/validation/operations/SelectMultiColumnRelationTest.java
+++ b/test/unit/org/apache/cassandra/cql3/validation/operations/SelectMultiColumnRelationTest.java
@@@ -885,19 -874,33 +885,46 @@@ public class SelectMultiColumnRelationT
}
@Test
+ public void testMultiColumnRestrictionsWithIndex() throws Throwable
+ {
+ createTable("CREATE TABLE %s (a int, b int, c int, d int, e int, v int, PRIMARY KEY (a, b, c, d, e))");
+ createIndex("CREATE INDEX ON %s (v)");
+ for (int i = 1; i <= 5; i++)
+ {
+ execute("INSERT INTO %s (a,b,c,d,e,v) VALUES (?,?,?,?,?,?)", 0, i, 0, 0, 0, 0);
+ execute("INSERT INTO %s (a,b,c,d,e,v) VALUES (?,?,?,?,?,?)", 0, i, i, 0, 0, 0);
+ execute("INSERT INTO %s (a,b,c,d,e,v) VALUES (?,?,?,?,?,?)", 0, i, i, i, 0, 0);
+ execute("INSERT INTO %s (a,b,c,d,e,v) VALUES (?,?,?,?,?,?)", 0, i, i, i, i, 0);
+ execute("INSERT INTO %s (a,b,c,d,e,v) VALUES (?,?,?,?,?,?)", 0, i, i, i, i, i);
+ }
+
+ String errorMsg = "Multi-column slice restrictions cannot be used for filtering.";
+ assertInvalidMessage(errorMsg,
+ "SELECT * FROM %s WHERE a = 0 AND (c,d) < (2,2) AND v = 0 ALLOW FILTERING");
+ assertInvalidMessage(errorMsg,
+ "SELECT * FROM %s WHERE a = 0 AND (d,e) < (2,2) AND b = 1 AND v = 0 ALLOW FILTERING");
+ assertInvalidMessage(errorMsg,
+ "SELECT * FROM %s WHERE a = 0 AND b = 1 AND (d,e) < (2,2) AND v = 0 ALLOW FILTERING");
+ assertInvalidMessage(errorMsg,
+ "SELECT * FROM %s WHERE a = 0 AND b > 1 AND (d,e) < (2,2) AND v = 0 ALLOW FILTERING");
+ assertInvalidMessage(errorMsg,
+ "SELECT * FROM %s WHERE a = 0 AND (b,c) > (1,0) AND (d,e) < (2,2) AND v = 0 ALLOW FILTERING");
+ }
+
+ @Test
+ public void testMultipleClusteringWithIndexAndValueOver64K() throws Throwable
+ {
+ createTable("CREATE TABLE %s (a int, b blob, c int, d int, PRIMARY KEY (a, b, c))");
+ createIndex("CREATE INDEX ON %s (b)");
+
+ execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, ByteBufferUtil.bytes(1), 0, 0);
+ execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, ByteBufferUtil.bytes(2), 1, 0);
+
+ assertInvalidMessage("Index expression values may not be larger than 64K",
+ "SELECT * FROM %s WHERE (b, c) = (?, ?) AND d = ? ALLOW FILTERING", TOO_BIG, 1, 2);
+ }
+
+ @Test
public void testMultiplePartitionKeyAndMultiClusteringWithIndex() throws Throwable
{
createTable("CREATE TABLE %s (a int, b int, c int, d int, e int, f int, PRIMARY KEY ((a, b), c, d, e))");
http://git-wip-us.apache.org/repos/asf/cassandra/blob/9244531a/test/unit/org/apache/cassandra/cql3/validation/operations/SelectTest.java
----------------------------------------------------------------------
diff --cc test/unit/org/apache/cassandra/cql3/validation/operations/SelectTest.java
index 65bfb32,c8df4c3..1b6fe9b
--- a/test/unit/org/apache/cassandra/cql3/validation/operations/SelectTest.java
+++ b/test/unit/org/apache/cassandra/cql3/validation/operations/SelectTest.java
@@@ -1534,6 -1450,32 +1534,24 @@@ public class SelectTest extends CQLTest
}
@Test
- public void testFilteringOnStaticColumnWithoutIndices() throws Throwable
++ public void testIndexQueryWithCompositePartitionKey() throws Throwable
+ {
- createTable("CREATE TABLE %s (a int, b int, s int static, c int, PRIMARY KEY (a, b))");
++ createTable("CREATE TABLE %s (p1 int, p2 int, v int, PRIMARY KEY ((p1, p2)))");
++ assertInvalidMessage("Partition key parts: p2 must be restricted as other parts are",
++ "SELECT * FROM %s WHERE p1 = 1 AND v = 3 ALLOW FILTERING");
+
- // Checks filtering
- assertInvalidMessage("Predicates on non-primary-key columns (c, s) are not yet supported for non secondary index queries",
- "SELECT * FROM %s WHERE c = 1 AND s = 2 ALLOW FILTERING");
- assertInvalidMessage("Predicates on non-primary-key columns (s) are not yet supported for non secondary index queries",
- "SELECT * FROM %s WHERE a = 1 AND b = 1 AND s = 2 ALLOW FILTERING");
- assertInvalidMessage("Predicates on non-primary-key columns (s) are not yet supported for non secondary index queries",
- "SELECT * FROM %s WHERE s > 2 ALLOW FILTERING");
++ createIndex("CREATE INDEX ON %s(v)");
+
- // Checks filtering with null
- assertInvalidMessage("Predicates on non-primary-key columns (s) are not yet supported for non secondary index queries",
- "SELECT * FROM %s WHERE s = null ALLOW FILTERING");
- assertInvalidMessage("Predicates on non-primary-key columns (s) are not yet supported for non secondary index queries",
- "SELECT * FROM %s WHERE s > null ALLOW FILTERING");
++ execute("INSERT INTO %s(p1, p2, v) values (?, ?, ?)", 1, 1, 3);
++ execute("INSERT INTO %s(p1, p2, v) values (?, ?, ?)", 1, 2, 3);
++ execute("INSERT INTO %s(p1, p2, v) values (?, ?, ?)", 2, 1, 3);
+
- // Checks filtering with unset
- assertInvalidMessage("Predicates on non-primary-key columns (s) are not yet supported for non secondary index queries",
- "SELECT * FROM %s WHERE s = ? ALLOW FILTERING", unset());
- assertInvalidMessage("Predicates on non-primary-key columns (s) are not yet supported for non secondary index queries",
- "SELECT * FROM %s WHERE s > ? ALLOW FILTERING", unset());
++ assertRows(execute("SELECT * FROM %s WHERE p1 = 1 AND v = 3 ALLOW FILTERING"),
++ row(1, 2, 3),
++ row(1, 1, 3));
+ }
+
+ @Test
public void testFilteringOnCompactTablesWithoutIndices() throws Throwable
{
//----------------------------------------------
@@@ -2515,4 -2250,93 +2533,47 @@@
row("a", 3, 5));
}
}
+
+ @Test
- public void testOverlyLargeSelectPK() throws Throwable
- {
- createTable("CREATE TABLE %s (a text, b text, PRIMARY KEY ((a), b))");
-
- assertInvalidThrow(InvalidRequestException.class,
- "SELECT * FROM %s WHERE a = ?", new String(TOO_BIG.array()));
- }
-
- @Test
- public void testOverlyLargeSelectCK() throws Throwable
- {
- createTable("CREATE TABLE %s (a text, b text, PRIMARY KEY ((a), b))");
-
- assertInvalidThrow(InvalidRequestException.class,
- "SELECT * FROM %s WHERE a = 'foo' AND b = ?", new String(TOO_BIG.array()));
- }
-
- @Test
- public void testOverlyLargeSelectKeyIn() throws Throwable
- {
- createTable("CREATE TABLE %s (a text, b text, c text, d text, PRIMARY KEY ((a, b, c), d))");
-
- assertInvalidThrow(InvalidRequestException.class,
- "SELECT * FROM %s WHERE a = 'foo' AND b= 'bar' AND c IN (?, ?)",
- new String(TOO_BIG.array()), new String(TOO_BIG.array()));
- }
-
- @Test
+ public void testFilteringWithSecondaryIndex() throws Throwable
+ {
+ createTable("CREATE TABLE %s (pk int, " +
+ "c1 int, " +
+ "c2 int, " +
+ "c3 int, " +
+ "v int, " +
+ "PRIMARY KEY (pk, c1, c2, c3))");
+ createIndex("CREATE INDEX v_idx_1 ON %s (v);");
+
+ for (int i = 1; i <= 5; i++)
+ {
+ execute("INSERT INTO %s (pk, c1, c2, c3, v) VALUES (?, ?, ?, ?, ?)", 1, 1, 1, 1, i);
+ execute("INSERT INTO %s (pk, c1, c2, c3, v) VALUES (?, ?, ?, ?, ?)", 1, 1, 1, i, i);
+ execute("INSERT INTO %s (pk, c1, c2, c3, v) VALUES (?, ?, ?, ?, ?)", 1, 1, i, i, i);
+ execute("INSERT INTO %s (pk, c1, c2, c3, v) VALUES (?, ?, ?, ?, ?)", 1, i, i, i, i);
+ }
+
+ assertRows(execute("SELECT * FROM %s WHERE pk = 1 AND c1 > 0 AND c1 < 5 AND c2 = 1 AND v = 3 ALLOW FILTERING;"),
+ row(1, 1, 1, 3, 3));
+
+ assertEmpty(execute("SELECT * FROM %s WHERE pk = 1 AND c1 > 1 AND c1 < 5 AND c2 = 1 AND v = 3 ALLOW FILTERING;"));
+
+ assertRows(execute("SELECT * FROM %s WHERE pk = 1 AND c1 > 1 AND c2 > 2 AND c3 > 2 AND v = 3 ALLOW FILTERING;"),
+ row(1, 3, 3, 3, 3));
+
+ assertRows(execute("SELECT * FROM %s WHERE pk = 1 AND c1 > 1 AND c2 > 2 AND c3 = 3 AND v = 3 ALLOW FILTERING;"),
+ row(1, 3, 3, 3, 3));
+
+ assertRows(execute("SELECT * FROM %s WHERE pk = 1 AND c1 IN(0,1,2) AND c2 = 1 AND v = 3 ALLOW FILTERING;"),
+ row(1, 1, 1, 3, 3));
+
+ assertRows(execute("SELECT * FROM %s WHERE pk = 1 AND c1 IN(0,1,2) AND c2 = 1 AND v = 3"),
+ row(1, 1, 1, 3, 3));
+
+ assertInvalidMessage("Clustering column \"c2\" cannot be restricted (preceding column \"c1\" is restricted by a non-EQ relation)",
+ "SELECT * FROM %s WHERE pk = 1 AND c1 > 0 AND c1 < 5 AND c2 = 1 ALLOW FILTERING;");
+
+ assertInvalidMessage("PRIMARY KEY column \"c2\" cannot be restricted as preceding column \"c1\" is not restricted",
+ "SELECT * FROM %s WHERE pk = 1 AND c2 = 1 ALLOW FILTERING;");
+ }
-
- @Test
- public void testIndexQueryWithCompositePartitionKey() throws Throwable
- {
- createTable("CREATE TABLE %s (p1 int, p2 int, v int, PRIMARY KEY ((p1, p2)))");
- assertInvalidMessage("Partition key parts: p2 must be restricted as other parts are",
- "SELECT * FROM %s WHERE p1 = 1 AND v = 3 ALLOW FILTERING");
-
- createIndex("CREATE INDEX ON %s(v)");
-
- execute("INSERT INTO %s(p1, p2, v) values (?, ?, ?)", 1, 1, 3);
- execute("INSERT INTO %s(p1, p2, v) values (?, ?, ?)", 1, 2, 3);
- execute("INSERT INTO %s(p1, p2, v) values (?, ?, ?)", 2, 1, 3);
-
- assertRows(execute("SELECT * FROM %s WHERE p1 = 1 AND v = 3 ALLOW FILTERING"),
- row(1, 2, 3),
- row(1, 1, 3));
- }
}