You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by ty...@apache.org on 2016/02/11 22:31:25 UTC

cassandra git commit: cqlsh: Fix inconsistencies in auto-completion

Repository: cassandra
Updated Branches:
  refs/heads/cassandra-2.2 6b1bd1745 -> af6bd1b3f


cqlsh: Fix inconsistencies in auto-completion

Patch by Michael Edge; reviewed by Tyler Hobbs for CASSANDRA-10733


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

Branch: refs/heads/cassandra-2.2
Commit: af6bd1b3f0852242736f27e4782cb3483888eac9
Parents: 6b1bd17
Author: Michael Edge <ed...@gmail.com>
Authored: Thu Feb 11 15:29:31 2016 -0600
Committer: Tyler Hobbs <ty...@gmail.com>
Committed: Thu Feb 11 15:29:31 2016 -0600

----------------------------------------------------------------------
 CHANGES.txt                                  |   1 +
 pylib/cqlshlib/cql3handling.py               |   3 +-
 pylib/cqlshlib/cqlhandling.py                |   2 +-
 pylib/cqlshlib/test/test_cqlsh_completion.py | 143 +++++++++++++++++++---
 pylib/cqlshlib/test/test_keyspace_init.cql   |  35 ++++++
 5 files changed, 164 insertions(+), 20 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/af6bd1b3/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 3aca720..1a4717d 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
 2.2.6
+ * (cqlsh) Fix inconsistent auto-complete (CASSANDRA-10733)
  * Make SELECT JSON and toJson() threadsafe (CASSANDRA-11048)
  * Fix SELECT on tuple relations for mixed ASC/DESC clustering order (CASSANDRA-7281)
  * (cqlsh) Support utf-8/cp65001 encoding on Windows (CASSANDRA-11030)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/af6bd1b3/pylib/cqlshlib/cql3handling.py
----------------------------------------------------------------------
diff --git a/pylib/cqlshlib/cql3handling.py b/pylib/cqlshlib/cql3handling.py
index 9509f01..81e13c9 100644
--- a/pylib/cqlshlib/cql3handling.py
+++ b/pylib/cqlshlib/cql3handling.py
@@ -504,6 +504,7 @@ def cf_prop_val_mapkey_completer(ctxt, cass):
             opts.add('max_sstable_age_days')
             opts.add('min_threshold')
             opts.add('max_window_size_seconds')
+            opts.add('timestamp_resolution')
         return map(escape_value, opts)
     return ()
 
@@ -732,7 +733,7 @@ completer_for('userFunctionName', 'ksname')(cf_ks_name_completer)
 completer_for('userFunctionName', 'dot')(cf_ks_dot_completer)
 completer_for('userFunctionName', 'udfname')(udf_name_completer)
 completer_for('refUserFunctionName', 'udfname')(ref_udf_name_completer)
-completer_for('userAggregateName', 'ksname')(cf_ks_dot_completer)
+completer_for('userAggregateName', 'ksname')(cf_ks_name_completer)
 completer_for('userAggregateName', 'dot')(cf_ks_dot_completer)
 completer_for('userAggregateName', 'udaname')(uda_name_completer)
 

http://git-wip-us.apache.org/repos/asf/cassandra/blob/af6bd1b3/pylib/cqlshlib/cqlhandling.py
----------------------------------------------------------------------
diff --git a/pylib/cqlshlib/cqlhandling.py b/pylib/cqlshlib/cqlhandling.py
index fb2dfab..c17dc6b 100644
--- a/pylib/cqlshlib/cqlhandling.py
+++ b/pylib/cqlshlib/cqlhandling.py
@@ -306,7 +306,7 @@ class CqlParsingRuleSet(pylexotron.ParsingRuleSet):
                 first = first[:-1]
             if debug:
                 print "** Got a partial completion: %r." % (common_prefix,)
-            first += common_prefix
+            return first + common_prefix
         if debug:
             print "** New total completion: %r. Checking for further matches...\n" % (first,)
         return self.cql_complete_multiple(text, first, init_bindings, startsymbol=startsymbol)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/af6bd1b3/pylib/cqlshlib/test/test_cqlsh_completion.py
----------------------------------------------------------------------
diff --git a/pylib/cqlshlib/test/test_cqlsh_completion.py b/pylib/cqlshlib/test/test_cqlsh_completion.py
index e67fefe..19bd092 100644
--- a/pylib/cqlshlib/test/test_cqlsh_completion.py
+++ b/pylib/cqlshlib/test/test_cqlsh_completion.py
@@ -88,7 +88,7 @@ class CqlshCompletionCase(BaseTestCase):
 
         if split_completed_lines:
             completed_lines = map(set, (completion_separation_re.split(line.strip())
-                               for line in choice_lines))
+                                  for line in choice_lines))
 
             if not completed_lines:
                 return set()
@@ -113,7 +113,7 @@ class CqlshCompletionCase(BaseTestCase):
         match the items in 'choices' (order is not important, but case is).
         """
         completed = self._get_completions(inputstring,
-                                         split_completed_lines=split_completed_lines)
+                                          split_completed_lines=split_completed_lines)
 
         if immediate:
             msg = 'cqlsh completed %r, but we expected %r' % (completed, immediate)
@@ -482,34 +482,34 @@ class TestCqlshCompletion(CqlshCompletionCase):
                             choices=self.strategies())
         # ttl is an "unreserved keyword". should work
         self.trycompletions("create keySPACE ttl with replication ="
-                               "{ 'class' : 'SimpleStrategy'", ", 'replication_factor': ")
+                            "{ 'class' : 'SimpleStrategy'", ", 'replication_factor': ")
         self.trycompletions("create   keyspace ttl with replication ="
-                               "{'class':'SimpleStrategy',", " 'replication_factor': ")
+                            "{'class':'SimpleStrategy',", " 'replication_factor': ")
         self.trycompletions("create keyspace \"ttl\" with replication ="
-                               "{'class': 'SimpleStrategy', ", "'replication_factor': ")
+                            "{'class': 'SimpleStrategy', ", "'replication_factor': ")
         self.trycompletions("create keyspace \"ttl\" with replication ="
-                               "{'class': 'SimpleStrategy', 'repl", "ication_factor'")
+                            "{'class': 'SimpleStrategy', 'repl", "ication_factor'")
         self.trycompletions("create keyspace foo with replication ="
-                               "{'class': 'SimpleStrategy', 'replication_factor': ", '',
+                            "{'class': 'SimpleStrategy', 'replication_factor': ", '',
                             choices=('<term>',))
         self.trycompletions("create keyspace foo with replication ="
-                               "{'class': 'SimpleStrategy', 'replication_factor': 1", '',
+                            "{'class': 'SimpleStrategy', 'replication_factor': 1", '',
                             choices=('<term>',))
         self.trycompletions("create keyspace foo with replication ="
-                               "{'class': 'SimpleStrategy', 'replication_factor': 1 ", '}')
+                            "{'class': 'SimpleStrategy', 'replication_factor': 1 ", '}')
         self.trycompletions("create keyspace foo with replication ="
-                               "{'class': 'SimpleStrategy', 'replication_factor': 1, ",
+                            "{'class': 'SimpleStrategy', 'replication_factor': 1, ",
                             '', choices=())
         self.trycompletions("create keyspace foo with replication ="
-                               "{'class': 'SimpleStrategy', 'replication_factor': 1} ",
+                            "{'class': 'SimpleStrategy', 'replication_factor': 1} ",
                             '', choices=('AND', ';'))
         self.trycompletions("create keyspace foo with replication ="
-                               "{'class': 'NetworkTopologyStrategy', ", '',
+                            "{'class': 'NetworkTopologyStrategy', ", '',
                             choices=('<dc_name>',))
         self.trycompletions("create keyspace \"PB and J\" with replication={"
-                               "'class': 'NetworkTopologyStrategy'", ', ')
+                            "'class': 'NetworkTopologyStrategy'", ', ')
         self.trycompletions("create keyspace PBJ with replication={"
-                               "'class': 'NetworkTopologyStrategy'} and ",
+                            "'class': 'NetworkTopologyStrategy'} and ",
                             "durable_writes = '")
 
     def test_complete_in_string_literals(self):
@@ -655,10 +655,10 @@ class TestCqlshCompletion(CqlshCompletionCase):
         self.trycompletions(prefix + " new_table (col_a int PRIMARY KEY) WITH compaction = "
                             + "{'class': 'DateTieredCompactionStrategy', '",
                             choices=['base_time_seconds', 'max_sstable_age_days',
-                                    'timestamp_resolution', 'min_threshold', 'class', 'max_threshold',
-                                    'tombstone_compaction_interval', 'tombstone_threshold',
-                                    'enabled', 'unchecked_tombstone_compaction',
-                                    'max_window_size_seconds'])
+                                     'timestamp_resolution', 'min_threshold', 'class', 'max_threshold',
+                                     'tombstone_compaction_interval', 'tombstone_threshold',
+                                     'enabled', 'unchecked_tombstone_compaction',
+                                     'max_window_size_seconds'])
 
     def test_complete_in_create_columnfamily(self):
         self.trycompletions('CREATE C', choices=['COLUMNFAMILY', 'CUSTOM'])
@@ -670,6 +670,113 @@ class TestCqlshCompletion(CqlshCompletionCase):
         self.trycompletions('CREATE TA', immediate='BLE ')
         self.create_columnfamily_table_template('TABLE')
 
+    def test_complete_in_describe(self):
+        """
+        Tests for Cassandra-10733
+        """
+        self.trycompletions('DES', immediate='C')
+        # quoted_keyspace = '"' + self.cqlsh.keyspace + '"'
+        self.trycompletions('DESCR', immediate='IBE ')
+        self.trycompletions('DESC TABLE ',
+                            choices=['twenty_rows_table',
+                                     'ascii_with_special_chars', 'users',
+                                     'has_all_types', 'system.',
+                                     'empty_composite_table', 'empty_table',
+                                     'system_auth.', 'undefined_values_table',
+                                     'dynamic_columns',
+                                     'twenty_rows_composite_table',
+                                     'utf8_with_special_chars',
+                                     'system_traces.', 'songs',
+                                     'system_distributed.',
+                                     '"' + self.cqlsh.keyspace + '".'],
+                            other_choices_ok=True)
+
+        self.trycompletions('DESC TYPE ',
+                            choices=['system.',
+                                     'system_auth.',
+                                     'system_traces.',
+                                     'system_distributed.',
+                                     'address',
+                                     'phone_number',
+                                     'band_info_type',
+                                     'tags'],
+                            other_choices_ok=True)
+
+        self.trycompletions('DESC FUNCTION ',
+                            choices=['system.',
+                                     'system_auth.',
+                                     'system_traces.',
+                                     'system_distributed.',
+                                     'fbestband',
+                                     'fbestsong',
+                                     'fmax',
+                                     'fmin',
+                                     '"' + self.cqlsh.keyspace + '".'],
+                            other_choices_ok=True)
+
+        self.trycompletions('DESC AGGREGATE ',
+                            choices=['system.',
+                                     'system_auth.',
+                                     'system_traces.',
+                                     'system_distributed.',
+                                     'aggmin',
+                                     'aggmax',
+                                     '"' + self.cqlsh.keyspace + '".'],
+                            other_choices_ok=True)
+
+        # Unfortunately these commented tests will not work. This is due to the keyspace name containing quotes;
+        # cqlsh auto-completes a DESC differently when the keyspace contains quotes. I'll leave the
+        # test here though in case we ever change this script to test using keyspace names without
+        # quotes
+
+        # self.trycompletions('DESC TABLE ' + '"' + self.cqlsh.keyspace + '"', immediate='.')
+
+        self.trycompletions('DESC TABLE ' + '"' + self.cqlsh.keyspace + '".',
+                            choices=['twenty_rows_table',
+                                     'ascii_with_special_chars',
+                                     'users',
+                                     'has_all_types',
+                                     'empty_composite_table',
+                                     'empty_table',
+                                     'undefined_values_table',
+                                     'dynamic_columns',
+                                     'twenty_rows_composite_table',
+                                     'utf8_with_special_chars',
+                                     'songs'],
+                            other_choices_ok=True)
+
+        # See comment above for DESC TABLE
+        # self.trycompletions('DESC TYPE ' + '"' + self.cqlsh.keyspace + '"', immediate='.')
+
+        self.trycompletions('DESC TYPE ' + '"' + self.cqlsh.keyspace + '".',
+                            choices=['address',
+                                     'phone_number',
+                                     'band_info_type',
+                                     'tags'],
+                            other_choices_ok=True)
+
+        # See comment above for DESC TABLE
+        # self.trycompletions('DESC FUNCTION ' + '"' + self.cqlsh.keyspace + '"', immediate='.f')
+
+        self.trycompletions('DESC FUNCTION ' + '"' + self.cqlsh.keyspace + '".', immediate='f')
+
+        self.trycompletions('DESC FUNCTION ' + '"' + self.cqlsh.keyspace + '".f',
+                            choices=['fbestband',
+                                     'fbestsong',
+                                     'fmax',
+                                     'fmin'],
+                            other_choices_ok=True)
+
+        # See comment above for DESC TABLE
+        # self.trycompletions('DESC AGGREGATE ' + '"' + self.cqlsh.keyspace + '"', immediate='.aggm')
+
+        self.trycompletions('DESC AGGREGATE ' + '"' + self.cqlsh.keyspace + '".', immediate='aggm')
+
+        self.trycompletions('DESC AGGREGATE ' + '"' + self.cqlsh.keyspace + '".aggm',
+                            choices=['aggmin',
+                                     'aggmax'],
+                            other_choices_ok=True)
+
     def test_complete_in_drop_columnfamily(self):
         pass
 

http://git-wip-us.apache.org/repos/asf/cassandra/blob/af6bd1b3/pylib/cqlshlib/test/test_keyspace_init.cql
----------------------------------------------------------------------
diff --git a/pylib/cqlshlib/test/test_keyspace_init.cql b/pylib/cqlshlib/test/test_keyspace_init.cql
index 6082dc7..c64163a 100644
--- a/pylib/cqlshlib/test/test_keyspace_init.cql
+++ b/pylib/cqlshlib/test/test_keyspace_init.cql
@@ -258,3 +258,38 @@ values (
             'origin':'england'
         }
     });
+
+CREATE FUNCTION fBestband ( input double )
+    RETURNS NULL ON NULL INPUT
+    RETURNS text 
+    LANGUAGE java
+    AS 'return "Iron Maiden";';
+
+CREATE FUNCTION fBestsong ( input double )
+    RETURNS NULL ON NULL INPUT
+    RETURNS text 
+    LANGUAGE java
+    AS 'return "Revelations";';
+
+CREATE FUNCTION fMax(current int, candidate int)
+    CALLED ON NULL INPUT
+    RETURNS int 
+    LANGUAGE java 
+    AS 'if (current == null) return candidate; else return Math.max(current, candidate);' ;
+
+CREATE FUNCTION fMin(current int, candidate int)
+    CALLED ON NULL INPUT
+    RETURNS int
+    LANGUAGE java 
+    AS 'if (current == null) return candidate; else return Math.min(current, candidate);' ;
+
+CREATE AGGREGATE aggMax(int)
+    SFUNC fMax
+    STYPE int
+    INITCOND null;
+
+CREATE AGGREGATE aggMin(int)
+    SFUNC fMin
+    STYPE int
+    INITCOND null;
+