diff --git a/pylib/cqlshlib/cql3handling.py b/pylib/cqlshlib/cql3handling.py index 3697aa4888c2..362e84b27485 100644 --- a/pylib/cqlshlib/cql3handling.py +++ b/pylib/cqlshlib/cql3handling.py @@ -286,6 +286,7 @@ def dequote_value(cqlword): | | | + | | | | @@ -294,6 +295,7 @@ def dequote_value(cqlword): | | | + | | | | @@ -1749,6 +1751,7 @@ def rolename_completer(ctxt, cass): "ON" cf= ; ''' + explain_completion('createTriggerStatement', 'class', '\'fully qualified class name\'') @@ -1765,6 +1768,13 @@ def drop_trigger_completer(ctxt, cass): return list(map(maybe_escape_name, names)) +syntax_rules += r''' + ::= "ADD" "IDENTITY" ("IF" "NOT" "EXISTS")? "TO" "ROLE" + ; + ::= "DROP" "IDENTITY" ("IF" "EXISTS")? + ; +''' + # END SYNTAX/COMPLETION RULE DEFINITIONS CqlRuleSet.append_rules(syntax_rules) diff --git a/pylib/cqlshlib/test/test_cqlsh_completion.py b/pylib/cqlshlib/test/test_cqlsh_completion.py index 80a4def238c1..643f30539006 100644 --- a/pylib/cqlshlib/test/test_cqlsh_completion.py +++ b/pylib/cqlshlib/test/test_cqlsh_completion.py @@ -166,7 +166,7 @@ class TestCqlshCompletion(CqlshCompletionCase): cqlver = '3.1.6' def test_complete_on_empty_string(self): - self.trycompletions('', choices=('?', 'ALTER', 'BEGIN', 'CAPTURE', 'CONSISTENCY', + self.trycompletions('', choices=('?', 'ADD', 'ALTER', 'BEGIN', 'CAPTURE', 'CONSISTENCY', 'COPY', 'CREATE', 'DEBUG', 'DELETE', 'DESC', 'DESCRIBE', 'DROP', 'GRANT', 'HELP', 'INSERT', 'LIST', 'LOGIN', 'PAGING', 'REVOKE', 'SELECT', 'SHOW', 'SOURCE', 'TRACING', 'ELAPSED', 'EXPAND', 'SERIAL', 'TRUNCATE', @@ -288,7 +288,7 @@ def test_complete_in_insert(self): self.trycompletions( ("INSERT INTO twenty_rows_composite_table (a, b, c) " "VALUES ( 'eggs', 'sausage', 'spam');"), - choices=['?', 'ALTER', 'BEGIN', 'CAPTURE', 'CONSISTENCY', 'COPY', + choices=['?', 'ADD', 'ALTER', 'BEGIN', 'CAPTURE', 'CONSISTENCY', 'COPY', 'CREATE', 'DEBUG', 'DELETE', 'DESC', 'DESCRIBE', 'DROP', 'ELAPSED', 'EXPAND', 'GRANT', 'HELP', 'INSERT', 'LIST', 'LOGIN', 'PAGING', 'REVOKE', 'SELECT', 'SHOW', 'SOURCE', 'SERIAL', 'TRACING', @@ -613,7 +613,7 @@ def test_complete_in_string_literals(self): def test_complete_in_drop(self): self.trycompletions('DR', immediate='OP ') self.trycompletions('DROP ', - choices=['AGGREGATE', 'COLUMNFAMILY', 'FUNCTION', + choices=['AGGREGATE', 'COLUMNFAMILY', 'FUNCTION', 'IDENTITY', 'INDEX', 'KEYSPACE', 'ROLE', 'TABLE', 'TRIGGER', 'TYPE', 'USER', 'MATERIALIZED']) @@ -1053,7 +1053,7 @@ def test_complete_in_create_index(self): self.trycompletions('CREATE INDEX example ', immediate='ON ') def test_complete_in_drop_index(self): - self.trycompletions('DROP I', immediate='NDEX ') + self.trycompletions('DROP IN', immediate='DEX ') def test_complete_in_alter_keyspace(self): self.trycompletions('ALTER KEY', 'SPACE ') @@ -1212,6 +1212,38 @@ def test_complete_in_create_user(self): def test_complete_in_drop_role(self): self.trycompletions('DROP ROLE ', choices=['', 'IF', '']) + # IDENTITY checks + def test_complete_in_add_identity(self): + self.trycompletions('A', choices=['ADD', 'ALTER']) + self.trycompletions('AD', immediate='D IDENTITY ') + self.trycompletions('ADD ID', immediate='ENTITY ') + self.trycompletions('ADD IDENTITY IF ', immediate='NOT EXISTS ') + self.trycompletions('ADD IDENTITY IF NOT ', immediate='EXISTS ') + self.trycompletions('ADD IDENTITY ', + choices=['', '', 'IF']) + self.trycompletions("ADD IDENTITY 'testIdentifier' TO R", immediate='OLE ') + self.trycompletions("ADD IDENTITY 'testIdentifier' ", immediate='TO ROLE ') + self.trycompletions("ADD IDENTITY 'testIdentifier' TO ROLE ", + choices=['', ''], other_choices_ok=True) + self.trycompletions("ADD IDENTITY 'testIdentifier' TO ROLE cassandra ", + choices=[';']) + self.trycompletions("ADD IDENTITY IF NOT EXISTS 'stestIdentifier' TO ROLE cassandra ", + choices=[';']) + + def test_complete_in_drop_identity(self): + self.trycompletions('D', choices=['DESCRIBE', 'DEBUG', 'DESC', 'DROP', 'DELETE']) + self.trycompletions('DR', immediate='OP ') + self.trycompletions('DRO', immediate='P ') + self.trycompletions('DROP ID', immediate='ENTITY ') + self.trycompletions('DROP', choices=' ') + self.trycompletions('DROP IDENTITY ', + choices=['', '', 'IF']) + self.trycompletions('DROP IDENTITY IF ', immediate='EXISTS ') + self.trycompletions('DROP IDENTITY IF EXISTS ', + choices=['', '']) + self.trycompletions("DROP IDENTITY 'testIdentifier' ", choices=[';']) + self.trycompletions("DROP IDENTITY IF EXISTS 'testIdentifier' ", choices=[';']) + def test_complete_in_list(self): self.trycompletions('LIST ', choices=['ALL', 'AUTHORIZE', 'DESCRIBE', 'EXECUTE', 'ROLES', 'USERS', 'ALTER',