fix for SelectStatement start/end key are not set correctly when a key alias is 
involved
patch by Pavel Yaskevich; reviewed by Jonathan Ellis for CASSANDRA-3700


Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/621bc0cc
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/621bc0cc
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/621bc0cc

Branch: refs/heads/trunk
Commit: 621bc0cc7939efdc00d32826f138701349191fe0
Parents: 7ab6cb1
Author: Pavel Yaskevich <[email protected]>
Authored: Fri Jan 6 15:59:40 2012 +0200
Committer: Pavel Yaskevich <[email protected]>
Committed: Sat Jan 7 17:34:54 2012 +0200

----------------------------------------------------------------------
 CHANGES.txt                                        |    2 +
 .../org/apache/cassandra/cql/QueryProcessor.java   |    2 +-
 src/java/org/apache/cassandra/cql/Relation.java    |   23 +----
 src/java/org/apache/cassandra/cql/WhereClause.java |   76 +++++++--------
 4 files changed, 41 insertions(+), 62 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/621bc0cc/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index e17def1..859401a 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -24,6 +24,8 @@ Merged from 0.8:
  * Secondary Indexes should report memory consumption (CASSANDRA-3155)
  * use correct list of replicas for LOCAL_QUORUM reads when read repair
    is disabled (CASSANDRA-3696)
+ * fix for SelectStatement start/end key are not set correctly
+   when a key alias is involved (CASSANDRA-3700)
 
 
 1.0.6

http://git-wip-us.apache.org/repos/asf/cassandra/blob/621bc0cc/src/java/org/apache/cassandra/cql/QueryProcessor.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql/QueryProcessor.java 
b/src/java/org/apache/cassandra/cql/QueryProcessor.java
index f2038ea..8e90e06 100644
--- a/src/java/org/apache/cassandra/cql/QueryProcessor.java
+++ b/src/java/org/apache/cassandra/cql/QueryProcessor.java
@@ -412,7 +412,7 @@ public class QueryProcessor
         assert key.toUpperCase().equals(key); // should always be uppercased 
by caller
         String realKeyAlias = bufferToString(cfm.getKeyName()).toUpperCase();
         if (!realKeyAlias.equals(key))
-            throw new InvalidRequestException(String.format("Expected key '%s' 
to be present in WHERE clause for '%s'", key, cfm.cfName));
+            throw new InvalidRequestException(String.format("Expected key '%s' 
to be present in WHERE clause for '%s'", realKeyAlias, cfm.cfName));
     }
 
     private static void validateColumnNames(Iterable<ByteBuffer> columns)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/621bc0cc/src/java/org/apache/cassandra/cql/Relation.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql/Relation.java 
b/src/java/org/apache/cassandra/cql/Relation.java
index 1e3aecf..eb34080 100644
--- a/src/java/org/apache/cassandra/cql/Relation.java
+++ b/src/java/org/apache/cassandra/cql/Relation.java
@@ -22,12 +22,11 @@ package org.apache.cassandra.cql;
 
 /**
  * Relations encapsulate the relationship between an entity of some kind, and
- * a value (term). For example, KEY > "start" or "colname1" = "somevalue".
+ * a value (term). For example, <key> > "start" or "colname1" = "somevalue".
  *
  */
 public class Relation
 {
-    private EntityType entityType = EntityType.COLUMN;
     private Term entity;
     private RelationType relationType;
     private Term value;
@@ -41,24 +40,11 @@ public class Relation
      */
     public Relation(Term entity, String type, Term value)
     {
-        if (entity.getText().toUpperCase().equals("KEY"))
-            this.entityType = EntityType.KEY;
-        
         this.entity = entity;
         this.relationType = RelationType.forString(type);
         this.value = value;
     }
     
-    public boolean isKey()
-    {
-        return entityType == EntityType.KEY;
-    }
-    
-    public boolean isColumn()
-    {
-        return entityType == EntityType.COLUMN;
-    }
-    
     public RelationType operator()
     {
         return relationType;
@@ -77,15 +63,10 @@ public class Relation
     @Override
     public String toString()
     {
-        return String.format("Relation(%s, %s,nnn %s)", entity, relationType, 
value);
+        return String.format("Relation(%s, %s, %s)", entity, relationType, 
value);
     }
 }
 
-enum EntityType
-{
-    KEY, COLUMN;
-}
-
 enum RelationType
 {
     EQ, LT, LTE, GTE, GT;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/621bc0cc/src/java/org/apache/cassandra/cql/WhereClause.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql/WhereClause.java 
b/src/java/org/apache/cassandra/cql/WhereClause.java
index 5df4512..964aad8 100644
--- a/src/java/org/apache/cassandra/cql/WhereClause.java
+++ b/src/java/org/apache/cassandra/cql/WhereClause.java
@@ -20,27 +20,29 @@ package org.apache.cassandra.cql;
  * 
  */
 
-
-import org.apache.cassandra.config.CFMetaData;
-import org.apache.cassandra.utils.ByteBufferUtil;
-
 import java.nio.ByteBuffer;
 import java.util.ArrayList;
-import java.util.Iterator;
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Set;
 
+import org.apache.cassandra.config.CFMetaData;
+import org.apache.cassandra.utils.ByteBufferUtil;
+
 /**
  * WhereClauses encapsulate all of the predicates of a SELECT query.
  *
  */
 public class WhereClause
 {
-    // added to either by the parser, e.g. from an IN clause, or by 
extractKeysFromColumns
+    // all relations (except for `<key> IN (.., .., ..)` which can be directly 
interpreted) from parser
+    // are stored into this array and are filtered to the keys/columns by 
extractKeysFromColumns(...)
+    private List<Relation> clauseRelations = new ArrayList<Relation>();
+    private List<Relation> columns = new ArrayList<Relation>();
+
+    // added to either by the parser from an IN clause or by 
extractKeysFromColumns
     private Set<Term> keys = new LinkedHashSet<Term>();
     private Term startKey, finishKey;
-    private List<Relation> columns = new ArrayList<Relation>();
     private boolean includeStartKey = false, includeFinishKey = false, 
multiKey = false;
     // set by extractKeysFromColumns
     private String keyAlias = null;
@@ -56,9 +58,7 @@ public class WhereClause
     }
     
     public WhereClause()
-    {
-        
-    }
+    {}
     
     /**
      * Add an additional relation to this WHERE clause.
@@ -67,24 +67,7 @@ public class WhereClause
      */
     public void and(Relation relation)
     {
-        if ((relation != null) && relation.isKey())
-        {
-            if (relation.operator() == RelationType.EQ)
-                keys.add(relation.getValue());
-            else if ((relation.operator() == RelationType.GT) || 
(relation.operator() == RelationType.GTE))
-            {
-                startKey = relation.getValue();
-                includeStartKey = relation.operator() == RelationType.GTE;
-            }
-            else if ((relation.operator() == RelationType.LT) || 
(relation.operator() == RelationType.LTE))
-            {
-                finishKey = relation.getValue();
-                includeFinishKey = relation.operator() == RelationType.LTE;
-            }
-            
-        }
-        else
-            columns.add(relation);
+        clauseRelations.add(relation);
     }
 
     /**
@@ -162,23 +145,36 @@ public class WhereClause
         ByteBuffer realKeyAlias = cfm.getKeyName();
 
         if (!keys.isEmpty())
-            return; // we already have key(s) set
-
-        Iterator<Relation> iter = columns.iterator();
+            return; // we already have key(s) set (<key> IN (.., ...) 
construction used)
 
-        while (iter.hasNext())
+        for (Relation relation : clauseRelations)
         {
-            Relation relation = iter.next();
-
-            ByteBuffer name = 
ByteBufferUtil.bytes(relation.getEntity().getText());
+            String nameText = relation.getEntity().getText();
+            ByteBuffer name = ByteBufferUtil.bytes(nameText);
 
             if (name.equals(realKeyAlias))
             {
-                // setting found key as an alias
-                keyAlias = relation.getEntity().getText().toUpperCase();
-                keys.add(relation.getValue()); // add a key value to the keys 
list
-                iter.remove(); // removing it from the columns
-                break;
+                if (keyAlias == null) // setting found key as an alias
+                    keyAlias = nameText.toUpperCase();
+
+                if (relation.operator() == RelationType.EQ)
+                {
+                    keys.add(relation.getValue());
+                }
+                else if ((relation.operator() == RelationType.GT) || 
(relation.operator() == RelationType.GTE))
+                {
+                    startKey = relation.getValue();
+                    includeStartKey = relation.operator() == RelationType.GTE;
+                }
+                else if ((relation.operator() == RelationType.LT) || 
(relation.operator() == RelationType.LTE))
+                {
+                    finishKey = relation.getValue();
+                    includeFinishKey = relation.operator() == RelationType.LTE;
+                }
+            }
+            else
+            {
+                columns.add(relation);
             }
         }
     }

Reply via email to