Return-Path: X-Original-To: apmail-cassandra-commits-archive@www.apache.org Delivered-To: apmail-cassandra-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id AB751E1FB for ; Fri, 23 Nov 2012 09:44:27 +0000 (UTC) Received: (qmail 34569 invoked by uid 500); 23 Nov 2012 09:44:27 -0000 Delivered-To: apmail-cassandra-commits-archive@cassandra.apache.org Received: (qmail 34442 invoked by uid 500); 23 Nov 2012 09:44:27 -0000 Mailing-List: contact commits-help@cassandra.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cassandra.apache.org Delivered-To: mailing list commits@cassandra.apache.org Received: (qmail 34422 invoked by uid 99); 23 Nov 2012 09:44:27 -0000 Received: from tyr.zones.apache.org (HELO tyr.zones.apache.org) (140.211.11.114) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 23 Nov 2012 09:44:27 +0000 Received: by tyr.zones.apache.org (Postfix, from userid 65534) id C61CC319392; Fri, 23 Nov 2012 09:44:26 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: slebresne@apache.org To: commits@cassandra.apache.org X-Mailer: ASF-Git Admin Mailer Subject: [3/5] git commit: Prevent inefficient queries (CQL3) Message-Id: <20121123094426.C61CC319392@tyr.zones.apache.org> Date: Fri, 23 Nov 2012 09:44:26 +0000 (UTC) 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/trunk Commit: 6fb751240013799a13890282e1af1f7dc85d9e8d Parents: 9fb5779 Author: Sylvain Lebresne Authored: Fri Nov 23 10:04:56 2012 +0100 Committer: Sylvain Lebresne 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 orderings = new LinkedHashMap(); + 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.asList(names)); } @@ -1432,12 +1452,14 @@ public class SelectStatement implements CQLStatement private final int limit; private final Map orderings; private final boolean isCount; + private final boolean allowFiltering; - public Parameters(int limit, Map orderings, boolean isCount) + public Parameters(int limit, Map orderings, boolean isCount, boolean allowFiltering) { this.limit = limit; this.orderings = orderings; this.isCount = isCount; + this.allowFiltering = allowFiltering; } }