This is an automated email from the ASF dual-hosted git repository.
smiklosovic 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 c3089b564a Ignore repetitions of semicolon in CQLSH
c3089b564a is described below
commit c3089b564aad4d8df9a23560371d31060e45d312
Author: Pedro Gordo <[email protected]>
AuthorDate: Sun Jan 19 17:20:42 2025 +0000
Ignore repetitions of semicolon in CQLSH
When grouping the tokens, skip statements composed by a single endtoken.
patch by Pedro Gordo; reviewed by Brad Schoening, Stefan Miklosovic for
CASSANDRA-19956
---
CHANGES.txt | 1 +
pylib/cqlshlib/cqlhandling.py | 29 +++++++++++++++++++++++++++--
pylib/cqlshlib/test/test_cql_parsing.py | 11 +++++++++++
pylib/cqlshlib/util.py | 21 ---------------------
4 files changed, 39 insertions(+), 23 deletions(-)
diff --git a/CHANGES.txt b/CHANGES.txt
index cd2619e4cb..199716afe6 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
5.1
+ * Ignore repetitions of semicolon in CQLSH (CASSANDRA-19956)
* Avoid NPE during cms initialization abort (CASSANDRA-20527)
* Avoid failing queries when epoch changes and replica goes up/down
(CASSANDRA-20489)
* Split out truncation record lock (CASSANDRA-20480)
diff --git a/pylib/cqlshlib/cqlhandling.py b/pylib/cqlshlib/cqlhandling.py
index 504371c16d..2cc49fbee4 100644
--- a/pylib/cqlshlib/cqlhandling.py
+++ b/pylib/cqlshlib/cqlhandling.py
@@ -113,7 +113,9 @@ class CqlParsingRuleSet(pylexotron.ParsingRuleSet):
curstmt.append(t)
if t[0] == 'endtoken':
term_on_nl = False
- output.extend(curstmt)
+ # skip empty statements
+ if len(curstmt) > 1:
+ output.extend(curstmt)
curstmt = []
else:
if len(curstmt) == 1:
@@ -135,7 +137,7 @@ class CqlParsingRuleSet(pylexotron.ParsingRuleSet):
def cql_split_statements(self, text):
tokens = self.lex(text)
tokens = self.cql_massage_tokens(tokens)
- stmts = util.split_list(tokens, lambda t: t[0] == 'endtoken')
+ stmts = self.group_tokens(tokens)
output = []
in_batch = False
in_pg_string = len([st for st in tokens if len(st) > 0 and st[0] ==
'unclosedPgString']) == 1
@@ -151,6 +153,29 @@ class CqlParsingRuleSet(pylexotron.ParsingRuleSet):
in_batch = True
return output, in_batch or in_pg_string
+ def group_tokens(self, items):
+ """
+ Split an iterable into sublists, using 'endtoken' to mark the end of
each sublist.
+ Each sublist accumulates elements until an 'endtoken' is encountered.
If the sublist
+ consists only of a single 'endtoken', it is excluded. An empty list is
added to the
+ result after the last 'endtoken' for cases like autocompletion.
+
+ Parameters:
+ - items (iterable): An iterable of tokens, including 'endtoken'
elements.
+
+ Returns:
+ - list: A list of sublists, with each sublist containing tokens split
by 'endtoken'.
+ """
+
+ thisresult = []
+ results = [thisresult]
+ for i in items:
+ thisresult.append(i)
+ if i[0] == 'endtoken':
+ thisresult = []
+ results.append(thisresult)
+ return results
+
def cql_complete_single(self, text, partial, init_bindings=None,
ignore_case=True,
startsymbol='Start'):
tokens = (self.cql_split_statements(text)[0] or [[]])[-1]
diff --git a/pylib/cqlshlib/test/test_cql_parsing.py
b/pylib/cqlshlib/test/test_cql_parsing.py
index b9eb716a78..7a98c6d88f 100644
--- a/pylib/cqlshlib/test/test_cql_parsing.py
+++ b/pylib/cqlshlib/test/test_cql_parsing.py
@@ -804,6 +804,17 @@ class TestCqlParsing(TestCase):
''')
self.assertRaises(SyntaxError)
+ def test_skip_duplicate_endtokens(self):
+ parsed = parse_cqlsh_statements('SELECT * FROM my_table;;;;')
+ expected_output = [
+ ('SELECT', 'reserved_identifier'),
+ ('*', 'star'),
+ ('FROM', 'reserved_identifier'),
+ ('my_table', 'identifier'),
+ (';', 'endtoken')
+ ]
+ self.assertSequenceEqual(tokens_with_types(parsed), expected_output)
+
def parse_cqlsh_statements(text):
"""
diff --git a/pylib/cqlshlib/util.py b/pylib/cqlshlib/util.py
index 8874be011e..96d9bd272e 100644
--- a/pylib/cqlshlib/util.py
+++ b/pylib/cqlshlib/util.py
@@ -31,27 +31,6 @@ except ImportError:
HAS_LINE_PROFILER = False
-def split_list(items, pred):
- """
- Split up a list (or other iterable) on the elements which satisfy the
- given predicate 'pred'. Elements for which 'pred' returns true start a new
- sublist for subsequent elements, which will accumulate in the new sublist
- until the next satisfying element.
-
- >>> split_list([0, 1, 2, 5, 99, 8], lambda n: (n % 2) == 0)
- [[0], [1, 2], [5, 99, 8], []]
- """
-
- thisresult = []
- results = [thisresult]
- for i in items:
- thisresult.append(i)
- if pred(i):
- thisresult = []
- results.append(thisresult)
- return results
-
-
def find_common_prefix(strs):
"""
Given a list (iterable) of strings, return the longest common prefix.
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]