Repository: cassandra Updated Branches: refs/heads/trunk 479e8aff1 -> bc8e878ec
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/trunk Commit: af6bd1b3f0852242736f27e4782cb3483888eac9 Parents: 6b1bd17 Author: Michael Edge <[email protected]> Authored: Thu Feb 11 15:29:31 2016 -0600 Committer: Tyler Hobbs <[email protected]> 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; +
