This is an automated email from the ASF dual-hosted git repository.
frankgh pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/cassandra.git
The following commit(s) were added to refs/heads/trunk by this push:
new accdaaebdd Add cqlsh autocompletion for the identity mapping feature
accdaaebdd is described below
commit accdaaebdd42634f0a4dea50482dfcb96b9d4501
Author: Shalni Sundram <[email protected]>
AuthorDate: Thu Oct 2 10:39:30 2025 -0700
Add cqlsh autocompletion for the identity mapping feature
Patch by Shalni Sundram; reviewed by Francisco Guerrero, Bernardo Botella
for CASSANDRA-20021
---
CHANGES.txt | 1 +
pylib/cqlshlib/cql3handling.py | 10 +++++++
pylib/cqlshlib/test/test_cqlsh_completion.py | 40 +++++++++++++++++++++++++---
3 files changed, 47 insertions(+), 4 deletions(-)
diff --git a/CHANGES.txt b/CHANGES.txt
index f5c4a1fc74..b1290e1fe8 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
5.1
+ * Add cqlsh autocompletion for the identity mapping feature (CASSANDRA-20021)
* Add DDL Guardrail enabling administrators to disallow creation/modification
of keyspaces with durable_writes = false (CASSANDRA-20913)
* Optimize Counter, Meter and Histogram metrics using thread local counters
(CASSANDRA-20250)
* Update snakeyaml to 2.4 (CASSANDRA-20928)
diff --git a/pylib/cqlshlib/cql3handling.py b/pylib/cqlshlib/cql3handling.py
index 3697aa4888..362e84b274 100644
--- a/pylib/cqlshlib/cql3handling.py
+++ b/pylib/cqlshlib/cql3handling.py
@@ -286,6 +286,7 @@ JUNK ::= /([
\t\r\f\v]+|(--|[/][/])[^\n\r]*([\n\r]|$)|[/][*].*?[*][/])/ ;
| <createFunctionStatement>
| <createAggregateStatement>
| <createTriggerStatement>
+ | <addIdentityStatement>
| <dropKeyspaceStatement>
| <dropColumnFamilyStatement>
| <dropIndexStatement>
@@ -294,6 +295,7 @@ JUNK ::= /([
\t\r\f\v]+|(--|[/][/])[^\n\r]*([\n\r]|$)|[/][*].*?[*][/])/ ;
| <dropFunctionStatement>
| <dropAggregateStatement>
| <dropTriggerStatement>
+ | <dropIdentityStatement>
| <alterTableStatement>
| <alterKeyspaceStatement>
| <alterUserTypeStatement>
@@ -1749,6 +1751,7 @@ syntax_rules += r'''
"ON" cf=<columnFamilyName>
;
'''
+
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'''
+<addIdentityStatement> ::= "ADD" "IDENTITY" ("IF" "NOT" "EXISTS")?
<stringLiteral> "TO" "ROLE" <rolename>
+ ;
+<dropIdentityStatement> ::= "DROP" "IDENTITY" ("IF" "EXISTS")? <stringLiteral>
+ ;
+'''
+
# 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 80a4def238..643f305390 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 @@ class TestCqlshCompletion(CqlshCompletionCase):
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 @@ class TestCqlshCompletion(CqlshCompletionCase):
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 @@ class TestCqlshCompletion(CqlshCompletionCase):
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 @@ class TestCqlshCompletion(CqlshCompletionCase):
def test_complete_in_drop_role(self):
self.trycompletions('DROP ROLE ', choices=['<identifier>', 'IF',
'<quotedName>'])
+ # 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=['<pgStringLiteral>', '<quotedStringLiteral>', '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=['<identifier>', '<quotedName>'],
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=['<pgStringLiteral>',
'<quotedStringLiteral>', 'IF'])
+ self.trycompletions('DROP IDENTITY IF ', immediate='EXISTS ')
+ self.trycompletions('DROP IDENTITY IF EXISTS ',
+ choices=['<pgStringLiteral>',
'<quotedStringLiteral>'])
+ 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',
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]