You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by al...@apache.org on 2013/01/04 15:15:57 UTC

git commit: cqlsh: Add default limit to SELECT statements; patch by Aleksey Yeschenko, reviewed by Brandon Williams for CASSANDRA-4972

Updated Branches:
  refs/heads/cassandra-1.2 4993d427b -> 0b0a00d24


cqlsh: Add default limit to SELECT statements;
patch by Aleksey Yeschenko, reviewed by Brandon Williams for
CASSANDRA-4972


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

Branch: refs/heads/cassandra-1.2
Commit: 0b0a00d24572ec28c1cd5ea4d5231eabf9604656
Parents: 4993d42
Author: Aleksey Yeschenko <al...@apache.org>
Authored: Fri Jan 4 17:10:29 2013 +0300
Committer: Aleksey Yeschenko <al...@apache.org>
Committed: Fri Jan 4 17:10:29 2013 +0300

----------------------------------------------------------------------
 CHANGES.txt                    |    1 +
 bin/cqlsh                      |   55 ++++++++++++++++++++++------------
 pylib/cqlshlib/cql3handling.py |    2 +-
 pylib/cqlshlib/cqlhandling.py  |    2 +-
 4 files changed, 38 insertions(+), 22 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/0b0a00d2/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 761b68d..41aab18 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -17,6 +17,7 @@
  * Minimize byte array allocation by AbstractData{Input,Output} (CASSANDRA-5090)
  * Add SSL support for the binary protocol (CASSANDRA-5031)
  * Allow non-schema system ks modification for shuffle to work (CASSANDRA-5097)
+ * cqlsh: Add default limit to SELECT statements (CASSANDRA-4972)
 
 
 1.2.0

http://git-wip-us.apache.org/repos/asf/cassandra/blob/0b0a00d2/bin/cqlsh
----------------------------------------------------------------------
diff --git a/bin/cqlsh b/bin/cqlsh
index 5d4ca00..b2e9755 100755
--- a/bin/cqlsh
+++ b/bin/cqlsh
@@ -101,7 +101,7 @@ except ImportError, e:
              'Error: %s\n' % (sys.executable, sys.path, e))
 
 import cql.decoders
-from cql.cursor import _COUNT_DESCRIPTION, _VOID_DESCRIPTION
+from cql.cursor import _VOID_DESCRIPTION
 from cql.cqltypes import (cql_types, cql_typename, lookup_casstype, lookup_cqltype,
                           CassandraType)
 
@@ -127,6 +127,7 @@ DEFAULT_TRANSPORT_FACTORY = 'cqlshlib.tfactory.regular_transport_factory'
 
 DEFAULT_TIME_FORMAT = '%Y-%m-%d %H:%M:%S%z'
 DEFAULT_FLOAT_PRECISION = 5
+DEFAULT_SELECT_LIMIT = 10000
 
 if readline is not None and 'libedit' in readline.__doc__:
     DEFAULT_COMPLETEKEY = '\t'
@@ -969,19 +970,29 @@ class Shell(cmd.Cmd):
             ksname = self.cql_unprotect_name(ksname)
         cfname = self.cql_unprotect_name(parsed.get_binding('cfname'))
         decoder = self.determine_decoder_for(cfname, ksname=ksname)
-        self.perform_statement(parsed.extract_orig(), decoder=decoder)
-
-    def perform_statement(self, statement, decoder=None):
+        statement = parsed.extract_orig()
+        with_default_limit = parsed.get_binding('limit') is None
+        if with_default_limit:
+            statement = "%s LIMIT %d;" % (statement[:-1], DEFAULT_SELECT_LIMIT)
+        self.perform_statement(statement,
+                               decoder=decoder,
+                               with_default_limit=with_default_limit)
+
+    def perform_statement(self, statement, decoder=None, with_default_limit=False):
         if self.tracing_enabled:
             session_id = UUID(bytes=self.trace_next_query())
-            result = self.perform_statement_untraced(statement, decoder=None)
+            result = self.perform_statement_untraced(statement,
+                                                     decoder=decoder,
+                                                     with_default_limit=with_default_limit)
             time.sleep(0.5) # trace writes are async so we wait a little.
             print_trace_session(self, self.cursor, session_id)
             return result
         else:
-            return self.perform_statement_untraced(statement, decoder=decoder)
+            return self.perform_statement_untraced(statement,
+                                                   decoder=decoder,
+                                                   with_default_limit=with_default_limit)
 
-    def perform_statement_untraced(self, statement, decoder=None):
+    def perform_statement_untraced(self, statement, decoder=None, with_default_limit=False):
         if not statement:
             return False
         trynum = 1
@@ -1015,10 +1026,8 @@ class Shell(cmd.Cmd):
                 self.printerr(traceback.format_exc())
                 return False
 
-        if self.cursor.description is _COUNT_DESCRIPTION:
-            self.print_count_result(self.cursor)
-        elif self.cursor.description is not _VOID_DESCRIPTION:
-            self.print_result(self.cursor)
+        if self.cursor.description is not _VOID_DESCRIPTION:
+            self.print_result(self.cursor, with_default_limit)
         self.flush_output()
         return True
 
@@ -1053,14 +1062,6 @@ class Shell(cmd.Cmd):
 
         return cursor.name_info[num][1]
 
-    def print_count_result(self, cursor):
-        if not cursor.result:
-            return
-        self.writeresult('count')
-        self.writeresult('-----')
-        self.writeresult(cursor.result[0])
-        self.writeresult("")
-
     def has_static_result_set(self, cursor):
         if self.cqlver_atleast(3):
             return True  # all cql3 resultsets are static, don't bother scanning
@@ -1073,7 +1074,7 @@ class Shell(cmd.Cmd):
         cursor._reset()
         return True
 
-    def print_result(self, cursor):
+    def print_result(self, cursor, with_default_limit):
         self.decoding_errors = []
 
         self.writeresult("")
@@ -1090,6 +1091,20 @@ class Shell(cmd.Cmd):
                 self.writeresult('%d more decoding errors suppressed.'
                                  % (len(self.decoding_errors) - 2), color=RED)
 
+        if with_default_limit:
+            if (self.is_count_result(cursor) and self.get_count(cursor) == DEFAULT_SELECT_LIMIT) \
+                    or cursor.rowcount == DEFAULT_SELECT_LIMIT:
+                self.writeresult("Default LIMIT of %d was used. "
+                                 "Specify your own LIMIT clause to get more results."
+                                 % DEFAULT_SELECT_LIMIT, color=RED)
+                self.writeresult("")
+
+    def is_count_result(self, cursor):
+        return cursor.description == [(u'count', 'LongType', None, None, None, None, True)]
+
+    def get_count(self, cursor):
+        return lookup_casstype('LongType').deserialize(cursor.result[0][0].value)
+
     def print_static_result(self, cursor):
         colnames = [d[0] for d in cursor.description]
         colnames_t = [(name, self.get_nametype(cursor, n)) for (n, name) in enumerate(colnames)]

http://git-wip-us.apache.org/repos/asf/cassandra/blob/0b0a00d2/pylib/cqlshlib/cql3handling.py
----------------------------------------------------------------------
diff --git a/pylib/cqlshlib/cql3handling.py b/pylib/cqlshlib/cql3handling.py
index 5293857..2c07434 100644
--- a/pylib/cqlshlib/cql3handling.py
+++ b/pylib/cqlshlib/cql3handling.py
@@ -734,7 +734,7 @@ syntax_rules += r'''
                         "FROM" cf=<columnFamilyName>
                           ("WHERE" <whereClause>)?
                           ("ORDER" "BY" <orderByClause> ( "," <orderByClause> )* )?
-                          ("LIMIT" <wholenumber>)?
+                          ("LIMIT" limit=<wholenumber>)?
                     ;
 <whereClause> ::= <relation> ("AND" <relation>)*
                 ;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/0b0a00d2/pylib/cqlshlib/cqlhandling.py
----------------------------------------------------------------------
diff --git a/pylib/cqlshlib/cqlhandling.py b/pylib/cqlshlib/cqlhandling.py
index f755e95..e085df5 100644
--- a/pylib/cqlshlib/cqlhandling.py
+++ b/pylib/cqlshlib/cqlhandling.py
@@ -557,7 +557,7 @@ syntax_rules += r'''
                         "FROM" cf=<columnFamilyName>
                           ("USING" "CONSISTENCY" selcl=<consistencylevel>)?
                           ("WHERE" <selectWhereClause>)?
-                          ("LIMIT" <integer>)?
+                          ("LIMIT" limit=<integer>)?
                     ;
 <selectWhereClause> ::= <relation> ("AND" <relation>)*
                       | keyname=<colname> "IN" "(" <term> ("," <term>)* ")"