Updated Branches:
refs/heads/cassandra-1.2.0 e1ac6e9ff -> 6fb751240
Prevent inefficient queries (CQL3)
patch by slebresne; reviewed by jbellis for CASSANDRA-4915
Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/6fb75124
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/6fb75124
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/6fb75124
Branch: refs/heads/cassandra-1.2.0
Commit: 6fb751240013799a13890282e1af1f7dc85d9e8d
Parents: 9fb5779
Author: Sylvain Lebresne <sylvain@datastax.com>
Authored: Fri Nov 23 10:04:56 2012 +0100
Committer: Sylvain Lebresne <sylvain@datastax.com>
Committed: Fri Nov 23 10:04:56 2012 +0100
----------------------------------------------------------------------
CHANGES.txt | 1 +
src/java/org/apache/cassandra/cql3/Cql.g | 8 ++++-
.../cassandra/cql3/statements/SelectStatement.java | 24 ++++++++++++++-
3 files changed, 31 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cassandra/blob/6fb75124/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 90b6537..4ea42c1 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -21,6 +21,7 @@
* Fix CQL3 LIMIT (CASSANDRA-4877)
* Fix Stress for CQL3 (CASSANDRA-4979)
* Remove cassandra specific exceptions from JMX interface (CASSANDRA-4893)
+ * (CQL3) Force using ALLOW FILTERING on potentially inefficient queries (CASSANDRA-4915)
Merged from 1.1:
* add basic authentication support for Pig CassandraStorage (CASSANDRA-3042)
* fix CQL2 ALTER TABLE compaction_strategy_class altering (CASSANDRA-4965)
http://git-wip-us.apache.org/repos/asf/cassandra/blob/6fb75124/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 9c3f77b..d814434 100644
--- a/src/java/org/apache/cassandra/cql3/Cql.g
+++ b/src/java/org/apache/cassandra/cql3/Cql.g
@@ -190,16 +190,19 @@ selectStatement returns [SelectStatement.RawStatement expr]
boolean isCount = false;
int limit = Integer.MAX_VALUE;
Map<ColumnIdentifier, Boolean> orderings = new LinkedHashMap<ColumnIdentifier,
Boolean>();
+ boolean allowFiltering = false;
}
: K_SELECT ( sclause=selectClause | (K_COUNT '(' sclause=selectCountClause ')' { isCount
= true; }) )
K_FROM cf=columnFamilyName
( K_WHERE wclause=whereClause )?
( K_ORDER K_BY orderByClause[orderings] ( ',' orderByClause[orderings] )* )?
( K_LIMIT rows=INTEGER { limit = Integer.parseInt($rows.text); } )?
+ ( K_ALLOW K_FILTERING { allowFiltering = true; } )?
{
SelectStatement.Parameters params = new SelectStatement.Parameters(limit,
orderings,
- isCount);
+ isCount,
+ allowFiltering);
$expr = new SelectStatement.RawStatement(cf, params, sclause, wclause);
}
;
@@ -754,6 +757,7 @@ unreserved_keyword returns [String str]
| K_WRITETIME
| K_MAP
| K_LIST
+ | K_FILTERING
) { $str = $k.text; }
| t=native_type { $str = t.toString(); }
;
@@ -822,6 +826,8 @@ K_DESCRIBE: D E S C R I B E;
K_FOR: F O R;
K_FULL_ACCESS: F U L L '_' A C C E S S;
K_NO_ACCESS: N O '_' A C C E S S;
+K_ALLOW: A L L O W;
+K_FILTERING: F I L T E R I N G;
K_CLUSTERING: C L U S T E R I N G;
http://git-wip-us.apache.org/repos/asf/cassandra/blob/6fb75124/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 4ae2b55..4e61a7b 100644
--- a/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java
@@ -957,6 +957,16 @@ public class SelectStatement implements CQLStatement
return name.type instanceof ReversedType;
}
+ private boolean columnFilterIsIdentity()
+ {
+ for (Restriction r : columnRestrictions)
+ {
+ if (r != null)
+ return false;
+ }
+ return true;
+ }
+
public static class RawStatement extends CFStatement
{
private final Parameters parameters;
@@ -1247,6 +1257,16 @@ public class SelectStatement implements CQLStatement
stmt.isReversed = isReversed;
}
+ // Make sure this queries is allowed (note: only key range can involve filtering
underneath)
+ if (!parameters.allowFiltering && stmt.isKeyRange)
+ {
+ // We will potentially filter data if either:
+ // - Have more than one IndexExpression
+ // - Have no index expression and the column filter is not the identity
+ if (stmt.metadataRestrictions.size() > 1 || (stmt.metadataRestrictions.isEmpty()
&& !stmt.columnFilterIsIdentity()))
+ throw new InvalidRequestException("Cannot execute this query as it might
involve data filtering and thus may have impredictible performance. "
+ + "If you want to execute this query
despite the performance impredictibility, use ALLOW FILTERING");
+ }
return new ParsedStatement.Prepared(stmt, Arrays.<ColumnSpecification>asList(names));
}
@@ -1432,12 +1452,14 @@ public class SelectStatement implements CQLStatement
private final int limit;
private final Map<ColumnIdentifier, Boolean> orderings;
private final boolean isCount;
+ private final boolean allowFiltering;
- public Parameters(int limit, Map<ColumnIdentifier, Boolean> orderings, boolean
isCount)
+ public Parameters(int limit, Map<ColumnIdentifier, Boolean> orderings, boolean
isCount, boolean allowFiltering)
{
this.limit = limit;
this.orderings = orderings;
this.isCount = isCount;
+ this.allowFiltering = allowFiltering;
}
}
|