kaqing 2.0.101__py3-none-any.whl → 2.0.103__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of kaqing might be problematic. Click here for more details.

Files changed (45) hide show
  1. adam/batch.py +0 -14
  2. adam/commands/audit/audit.py +2 -7
  3. adam/commands/cd.py +8 -8
  4. adam/commands/commands_utils.py +1 -2
  5. adam/commands/cql/cql_completions.py +4 -4
  6. adam/commands/cql/cql_utils.py +6 -9
  7. adam/commands/cql/cqlsh.py +6 -3
  8. adam/commands/deploy/deploy_pg_agent.py +2 -2
  9. adam/commands/deploy/undeploy_pg_agent.py +2 -2
  10. adam/commands/ls.py +12 -12
  11. adam/commands/nodetool.py +1 -1
  12. adam/commands/postgres/postgres.py +3 -3
  13. adam/commands/postgres/{postgres_session.py → postgres_context.py} +26 -27
  14. adam/commands/postgres/postgres_utils.py +5 -5
  15. adam/commands/postgres/psql_completions.py +1 -1
  16. adam/commands/preview_table.py +8 -27
  17. adam/commands/pwd.py +2 -2
  18. adam/repl.py +5 -5
  19. adam/repl_commands.py +2 -4
  20. adam/repl_state.py +2 -2
  21. adam/sql/automata_completer.py +63 -0
  22. adam/sql/sql_completer.py +37 -73
  23. adam/sql/sql_state_machine.py +434 -0
  24. adam/sql/state_machine.py +52 -421
  25. adam/sql/term_completer.py +3 -0
  26. adam/utils_k8s/cassandra_clusters.py +4 -4
  27. adam/utils_k8s/cassandra_nodes.py +2 -2
  28. adam/utils_k8s/pods.py +12 -6
  29. adam/utils_k8s/statefulsets.py +2 -2
  30. adam/version.py +1 -1
  31. {kaqing-2.0.101.dist-info → kaqing-2.0.103.dist-info}/METADATA +1 -1
  32. {kaqing-2.0.101.dist-info → kaqing-2.0.103.dist-info}/RECORD +35 -43
  33. adam/commands/audit/audit_table_completer.py +0 -9
  34. adam/commands/cql/cql_table_completer.py +0 -8
  35. adam/commands/describe/__init__.py +0 -0
  36. adam/commands/describe/describe.py +0 -61
  37. adam/commands/describe/describe_keyspace.py +0 -58
  38. adam/commands/describe/describe_keyspaces.py +0 -46
  39. adam/commands/describe/describe_schema.py +0 -46
  40. adam/commands/describe/describe_table.py +0 -57
  41. adam/commands/describe/describe_tables.py +0 -46
  42. adam/commands/postgres/psql_table_completer.py +0 -11
  43. {kaqing-2.0.101.dist-info → kaqing-2.0.103.dist-info}/WHEEL +0 -0
  44. {kaqing-2.0.101.dist-info → kaqing-2.0.103.dist-info}/entry_points.txt +0 -0
  45. {kaqing-2.0.101.dist-info → kaqing-2.0.103.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,63 @@
1
+ from typing import Iterable
2
+ from prompt_toolkit.completion import CompleteEvent, Completer, Completion
3
+ from prompt_toolkit.document import Document
4
+ import sqlparse
5
+ from sqlparse.sql import Statement
6
+
7
+ from adam.sql.state_machine import StateMachine, StateTo
8
+ from adam.sql.term_completer import TermCompleter
9
+
10
+ __all__ = [
11
+ "AutomataCompleter",
12
+ ]
13
+
14
+ def default_columns(_: list[str]):
15
+ return 'id,x.,y.,z.'.split(',')
16
+
17
+ class AutomataCompleter(Completer):
18
+ def __init__(self,
19
+ state_machine: StateMachine,
20
+ first_term: str,
21
+ debug = False):
22
+ super().__init__()
23
+ self.machine = state_machine
24
+ self.first_term = first_term
25
+ self.debug = debug
26
+
27
+ def get_completions(
28
+ self, document: Document, complete_event: CompleteEvent
29
+ ) -> Iterable[Completion]:
30
+ text = document.text_before_cursor.lstrip()
31
+ state = ''
32
+ if self.first_term:
33
+ state = f'{self.first_term}_'
34
+ text = f'{self.first_term} {text}'
35
+
36
+ completer: Completer = None
37
+ tokens = []
38
+ stmts = sqlparse.parse(text)
39
+ if not stmts:
40
+ tokens = []
41
+ else:
42
+ statement: Statement = stmts[0]
43
+ tokens = statement.tokens
44
+
45
+ state: StateTo = self.machine.traverse_tokens(tokens, StateTo(state))
46
+ if self.debug:
47
+ print('\n =>', state.to_s if isinstance(state, StateTo) else '')
48
+
49
+ if state.to_s in self.machine.suggestions:
50
+ terms = []
51
+
52
+ for word in self.machine.suggestions[state.to_s].strip(' ').split(','):
53
+ terms.extend(self.terms(state, word))
54
+
55
+ if terms:
56
+ completer = TermCompleter(terms)
57
+
58
+ if completer:
59
+ for c in completer.get_completions(document, complete_event):
60
+ yield c
61
+
62
+ def terms(self, _: str, word: str) -> list[str]:
63
+ return [word]
adam/sql/sql_completer.py CHANGED
@@ -1,22 +1,16 @@
1
- from typing import Callable, Iterable
2
- from prompt_toolkit.completion import CompleteEvent, Completer, Completion
3
- from prompt_toolkit.document import Document
4
- import sqlparse
5
- from sqlparse.sql import Statement
1
+ from typing import Callable
6
2
 
7
- from adam.sql.state_machine import StateMachine, StateTo
8
- from adam.sql.term_completer import TermCompleter
3
+ from adam.sql.automata_completer import AutomataCompleter
4
+ from adam.sql.sql_state_machine import AthenaStateMachine, CqlStateMachine, SqlStateMachine
9
5
 
10
6
  __all__ = [
11
7
  "SqlCompleter",
12
8
  ]
13
9
 
14
- DML_COMPLETER = TermCompleter(['select', 'insert', 'delete', 'update', 'alter', 'describe'])
15
-
16
10
  def default_columns(tables: list[str]):
17
11
  return 'id,x.,y.,z.'.split(',')
18
12
 
19
- class SqlCompleter(Completer):
13
+ class SqlCompleter(AutomataCompleter):
20
14
  def __init__(self,
21
15
  tables: Callable[[], list[str]],
22
16
  dml: str = None,
@@ -25,78 +19,48 @@ class SqlCompleter(Completer):
25
19
  table_props: Callable[[], dict[str,list[str]]] = lambda: [],
26
20
  variant = 'sql',
27
21
  debug = False):
28
- super().__init__()
29
- self.dml = dml
22
+ machine = SqlStateMachine(debug=debug)
23
+ if variant == 'cql':
24
+ machine = CqlStateMachine(debug=debug)
25
+ elif variant == 'athena':
26
+ machine = AthenaStateMachine(debug=debug)
27
+ super().__init__(machine, dml, debug)
28
+
30
29
  self.tables = tables
31
30
  self.columns = columns
32
31
  self.partition_columns = partition_columns
33
32
  self.table_props = table_props
33
+ self.variant = variant
34
34
  self.debug = debug
35
- self.machine = StateMachine(variant=variant, debug=self.debug)
36
35
 
37
- def get_completions(
38
- self, document: Document, complete_event: CompleteEvent
39
- ) -> Iterable[Completion]:
40
- text = document.text_before_cursor.lstrip()
41
- state = ''
42
- if self.dml:
43
- state = f'{self.dml}_'
44
- text = f'{self.dml} {text}'
36
+ def terms(self, state: str, word: str) -> list[str]:
37
+ terms = []
45
38
 
46
- completer: Completer = None
47
- stmts = sqlparse.parse(text)
48
- if not stmts:
49
- completer = DML_COMPLETER
39
+ if word == 'tables':
40
+ terms.extend(self.tables())
41
+ elif word == '`tables`':
42
+ terms.append('tables')
43
+ elif word == 'columns':
44
+ terms.extend(self.columns([]))
45
+ elif word == 'partition-columns':
46
+ terms.extend(self.partition_columns([]))
47
+ elif word == 'table-props':
48
+ terms.extend(self.table_props().keys())
49
+ elif word == 'table-prop-values':
50
+ if 'last_name' in state.context and state.context['last_name']:
51
+ terms.extend(self.table_props()[state.context['last_name']])
52
+ elif word == 'single':
53
+ terms.append("'")
54
+ elif word == 'comma':
55
+ terms.append(",")
50
56
  else:
51
- statement: Statement = stmts[0]
52
- state: StateTo = self.machine.traverse_tokens(statement.tokens, StateTo(state))
53
- if self.debug:
54
- print('\n =>', state.to_s if isinstance(state, StateTo) else '')
55
-
56
- if not state or not state.to_s:
57
- completer = DML_COMPLETER
58
-
59
- if state and state.to_s in self.machine.suggestions:
60
- terms = []
61
-
62
- for word in self.machine.suggestions[state.to_s].strip(' ').split(','):
63
- if word == 'tables':
64
- terms.extend(self.tables())
65
- elif word == '`tables`':
66
- terms.append('tables')
67
- elif word == 'columns':
68
- terms.extend(self.columns([]))
69
- elif word == 'partition-columns':
70
- terms.extend(self.partition_columns([]))
71
- elif word == 'table-props':
72
- terms.extend(self.table_props().keys())
73
- elif word == 'table-prop-values':
74
- if 'last_name' in state.context and state.context['last_name']:
75
- terms.extend(self.table_props()[state.context['last_name']])
76
- elif word == 'single':
77
- terms.append("'")
78
- elif word == 'comma':
79
- terms.append(",")
80
- else:
81
- terms.append(word)
82
-
83
- if terms:
84
- completer = TermCompleter(terms)
57
+ terms.append(word)
85
58
 
86
- if completer:
87
- for c in completer.get_completions(document, complete_event):
88
- yield c
59
+ return terms
89
60
 
90
- def completions(table_names: Callable[[], list[str]],
91
- columns: Callable[[list[str]], list[str]] = default_columns,
92
- partition_columns: Callable[[list[str]], list[str]] = lambda x: [],
93
- table_props: Callable[[], dict[str, list[str]]] = lambda: [],
94
- variant = 'sql'):
61
+ def completions_for_nesting(self):
95
62
  return {
96
- 'delete': SqlCompleter(table_names, 'delete', columns=columns, partition_columns=partition_columns, table_props=table_props, variant=variant),
97
- 'insert': SqlCompleter(table_names, 'insert', columns=columns, partition_columns=partition_columns, table_props=table_props, variant=variant),
98
- 'select': SqlCompleter(table_names, 'select', columns=columns, partition_columns=partition_columns, table_props=table_props, variant=variant),
99
- 'update': SqlCompleter(table_names, 'update', columns=columns, partition_columns=partition_columns, table_props=table_props, variant=variant),
100
- 'alter': SqlCompleter(table_names, 'alter', columns=columns, partition_columns=partition_columns, table_props=table_props, variant=variant),
101
- 'describe': SqlCompleter(table_names, 'describe', columns=columns, partition_columns=partition_columns, table_props=table_props, variant=variant),
63
+ word : SqlCompleter(self.tables, word, columns=self.columns, partition_columns=self.partition_columns,
64
+ table_props=self.table_props, variant=self.variant)
65
+ for word in self.machine.suggestions[''].strip(' ').split(',')
102
66
  }
@@ -0,0 +1,434 @@
1
+ from adam.sql.state_machine import StateMachine
2
+
3
+ __all__ = [
4
+ 'SqlStateMachine', 'CqlStateMachine', 'AthenaStateMachine'
5
+ ]
6
+
7
+ SQL_SPEC = [
8
+ # <select_statement> ::= SELECT <select_list>
9
+ # FROM <table_expression>
10
+ # [WHERE <search_condition>]
11
+ # [<group_by_clause>]
12
+ # [<having_clause>]
13
+ # [<order_by_clause>]
14
+ # [<limit_clause>]
15
+
16
+ # <search_condition> ::= <boolean_term>
17
+ # | <search_condition> OR <boolean_term>
18
+
19
+ # <boolean_term> ::= <boolean_factor>
20
+ # | <boolean_term> AND <boolean_factor>
21
+
22
+ # <boolean_factor> ::= [NOT] <predicate>
23
+ # | ([NOT] <search_condition>)
24
+
25
+ # <predicate> ::= <comparison_predicate>
26
+ # | <between_predicate>
27
+ # | <in_predicate>
28
+ # | <like_predicate>
29
+ # | <null_predicate>
30
+ # | <exists_predicate>
31
+ # | <quantified_predicate>
32
+ # | <unique_predicate>
33
+ # | <match_predicate>
34
+ # | <overlaps_predicate>
35
+ # | <distinct_predicate>
36
+ # | <member_predicate>
37
+ # | <submultiset_predicate>
38
+ # | <set_predicate>
39
+
40
+ # <comparison_predicate> ::= <row_value_expression> <comparison_operator> <row_value_expression>
41
+ # <comparison_operator> ::= '=' | '<>' | '<' | '<=' | '>' | '>='
42
+
43
+ # <row_value_expression> ::= <value_expression>
44
+ # | (<value_expression> [ { <comma> <value_expression> }... ])
45
+
46
+ # <value_expression> ::= <numeric_value_expression>
47
+ # | <string_value_expression>
48
+ # | <datetime_value_expression>
49
+ # | <interval_value_expression>
50
+ # | <boolean_value_expression>
51
+ # | <user_defined_type_value_expression>
52
+ # | <reference_value_expression>
53
+ # | <collection_value_expression>
54
+ # | <row_value_constructor>
55
+ # | <case_expression>
56
+ # | <cast_expression>
57
+ # | <subquery>
58
+ # | NULL
59
+ # | DEFAULT
60
+ # | <identifier>
61
+ # | <literal>
62
+ ' > select > select ^ select,insert,update,delete,alter,preview',
63
+ 'select_ > name|* > select_a ^ *',
64
+ 'select_a > , > select_a_comma_',
65
+ 'select_a_comma_ > name|* > select_a ^ *',
66
+ 'select_a_ > from > select_from ^ from',
67
+ 'select_from_ > name|audit > select_from_x ^ (select,tables',
68
+ '- > ( > select_from_lp_',
69
+ '- < ) > select_from_sq',
70
+ 'select_from_lp_ > select > select',
71
+ 'select_from_x > , > select_from_x_comma_ ^ (select,tables',
72
+ 'select_from_sq_ > as > select_from_x_as ^ as',
73
+ 'select_from_x_comma_ > name > select_from_x ^ tables',
74
+ 'select_from_x_ ^ as,where,inner join,left outer join,right outer join,full outer join,group by,order by,limit',
75
+ 'select_from_x_as_x_ > , > select_from_x_comma_ ^ where,inner join,left outer join,right outer join,full outer join,group by,order by,limit',
76
+ '- > as > select_from_x_as',
77
+ '- > where > select_where',
78
+ '- > order > select_order',
79
+ '- > order by > select_order_by',
80
+ '- > limit > select_where_sc_limit',
81
+ '- > group > select_group',
82
+ '- > group by > select_group_by',
83
+ '- > inner > select_from_x_inner',
84
+ '- > inner join > select_join',
85
+ '- > left > select_from_x_left',
86
+ '- > left join > select_join',
87
+ '- > left outer join > select_join',
88
+ '- > right > select_from_x_right',
89
+ '- > right join > select_join',
90
+ '- > right outer join > select_join',
91
+ '- > full > select_from_x_full',
92
+ '- > full outer join > select_join',
93
+ 'select_from_x_as_ > name > select_from_x_as_x ^ x,y,z',
94
+ 'select_from_x_as_x > , > select_from_x_as_x_comma_',
95
+ 'select_from_x_as_x_comma_ > name > select_from_x ^ tables',
96
+ 'select_where_ > name > select_where_a ^ columns',
97
+ 'select_where_a > name > select_where_a ^ columns,=,<,<=,>,>=,<>',
98
+ '- > comparison > select_where_a_op',
99
+ 'select_where_a_ > comparison > select_where_a_op ^ =,<,<=,>,>=,<>,like,not,in',
100
+ '- > not > select_where_a_not',
101
+ '- > in > select_where_a_in',
102
+ 'select_where_a_not_ > comparison > select_where_a_not_op ^ like,in',
103
+ '- > in > select_where_a_in',
104
+ 'select_where_a_in > ( > select_where_a_in_lp_ ^ (',
105
+ '- < ) > select_where_sc',
106
+ 'select_where_a_in_lp_ > name|single|num > select_where_a_in_lp_a ^ single,select',
107
+ '- > select > select_where_a_in_lp_select',
108
+ 'select_where_a_in_lp_select_ > name > select_a ^ id',
109
+ 'select_where_a_in_lp_a > , > select_where_a_in_lp_a_comma_ ^ comma,)',
110
+ 'select_where_a_in_lp_a_comma_ > name|single|num > select_where_a_in_lp_a ^ single',
111
+ 'select_where_a_not_op > name|single|num > select_where_sc ^ single',
112
+ 'select_where_a_op > name|single|num > select_where_sc ^ single',
113
+ 'select_where_sc_ > and|or > select_where ^ and,or,order by,group by,limit',
114
+ '- > group > select_group',
115
+ '- > group by > select_group_by',
116
+ '- > order > select_order',
117
+ '- > order by > select_order_by',
118
+ '- > limit > select_where_sc_limit',
119
+ 'select_group_ > by > select_group_by ^ by',
120
+ 'select_group_by_ > name > select_group_by_a ^ columns',
121
+ 'select_group_by_a > , > select_group_by_a_comma_ ^ columns',
122
+ 'select_group_by_a_comma_ > name > select_group_by_a ^ columns',
123
+ 'select_group_by_a_ > limit > select_where_sc_limit ^ limit,order by',
124
+ '- > order > select_order',
125
+ '- > order by > select_order_by',
126
+ 'select_order_ > by > select_order_by ^ by',
127
+ 'select_order_by_ > name > select_order_by_a ^ columns',
128
+ 'select_order_by_a > , > select_order_by_a_comma_',
129
+ 'select_order_by_a_comma_ > name > select_order_by_a ^ columns',
130
+ 'select_order_by_a_ > desc|asc > select_order_by_a_desc ^ desc,asc,limit',
131
+ '- > limit > select_where_sc_limit',
132
+ 'select_order_by_a_desc > , > select_order_by_a_comma_',
133
+ 'select_order_by_a_desc_ > limit > select_where_sc_limit ^ limit',
134
+ 'select_where_sc_limit_ > num > select_where_sc_limit_num ^ 1',
135
+ 'select_where_sc_limit_num_rp__ > as > select_from_x_as ^ as',
136
+ 'select_where_x_inner_ > join > select_join',
137
+ 'select_join_ > name > select_x_join_y ^ tables',
138
+ 'select_from_x_left_ > join > select_join ^ outer join',
139
+ '- > outer > select_from_x_left_outer',
140
+ 'select_from_x_left_outer_ > join > select_join ^ join',
141
+ 'select_from_x_right_ > join > select_join ^ outer join',
142
+ '- > outer > select_from_x_right_outer',
143
+ 'select_from_x_right_outer_ > join > select_join ^ join',
144
+ 'select_from_x_full_ > join > select_join ^ outer join',
145
+ '- > outer > select_from_x_full_outer',
146
+ 'select_from_x_full_outer_ > join > select_join ^ join',
147
+ 'select_x_join_y_ > as > select_x_join_y_as ^ as,on',
148
+ '- > on > select_x_join_y_on ^ as,on',
149
+ 'select_x_join_y_as_ > name > select_x_join_y_as_y ^ x,y,z',
150
+ 'select_x_join_y_as_y_ > on > select_x_join_y_on ^ on',
151
+ 'select_x_join_y_on_ > name > select_x_join_y_on_a ^ columns',
152
+ 'select_x_join_y_on_a > name > select_x_join_y_on_a ^ columns,=',
153
+ '- > comparison > select_x_join_y_on_a_op',
154
+ 'select_x_join_y_on_a_ > comparison > select_x_join_y_on_a_op ^ =',
155
+ 'select_x_join_y_on_a_op > name > select_x_join_y_on_a_op_b ^ columns',
156
+ 'select_x_join_y_on_a_op_b > _ > select_from_x_as_x_',
157
+
158
+ # <insert_statement> ::= INSERT INTO <table_name> [ ( <column_list> ) ]
159
+ # VALUES ( <value_list> )
160
+ # | INSERT INTO <table_name> [ ( <column_list> ) ]
161
+ # <query_expression>
162
+
163
+ # <table_name> ::= <identifier>
164
+
165
+ # <column_list> ::= <column_name> [ , <column_list> ]
166
+
167
+ # <column_name> ::= <identifier>
168
+
169
+ # <value_list> ::= <expression> [ , <value_list> ]
170
+
171
+ # <query_expression> ::= SELECT <select_list> FROM <table_reference_list> [ WHERE <search_condition> ] [ GROUP BY <grouping_column_list> ] [ HAVING <search_condition> ] [ ORDER BY <sort_specification_list> ]
172
+ ' > insert > insert',
173
+ 'insert_ > into > insert_into ^ into',
174
+ 'insert_into_ > name > insert_into_x ^ tables',
175
+ 'insert_into_x > ( > insert_into_x_lp_',
176
+ 'insert_into_x_ > ( > insert_into_x_lp_ ^ (,values(',
177
+ '- > values > insert_values',
178
+ 'insert_into_x_lp_ > name > insert_into_x_lp_a ^ id',
179
+ 'insert_into_x_lp_a > , > insert_into_x_lp_a_comma_',
180
+ '- > ) > insert_into_x_lp_a_rp_',
181
+ 'insert_into_x_lp_a_comma_ > name > insert_into_x_lp_a ^ id',
182
+ 'insert_into_x_lp_a_rp__ > values > insert_values ^ values(,select',
183
+ '- > select > select',
184
+ 'insert_values > ( > insert_values_lp_',
185
+ 'insert_values_lp_ > name|single|num > insert_values_lp_v ^ single',
186
+ 'insert_values_lp_v > , > insert_values_lp_v_comma_',
187
+ 'insert_values_lp_v_comma_ > name|single|num > insert_values_lp_v',
188
+
189
+ # <update_statement> ::= UPDATE <table_name>
190
+ # SET <set_clause_list>
191
+ # [WHERE <search_condition>]
192
+
193
+ # <set_clause_list> ::= <set_clause> { , <set_clause> }
194
+
195
+ # <set_clause> ::= <column_name> = <update_value>
196
+
197
+ # <update_value> ::= <expression> | NULL | DEFAULT
198
+
199
+ # <search_condition> ::= <boolean_expression>
200
+ ' > update > update',
201
+ 'update_ > name > update_x ^ tables',
202
+ 'update_x_ > set > update_set ^ set',
203
+ 'update_set_ > name > update_set_a ^ id',
204
+ 'update_set_a > comparison > update_set_a_op',
205
+ 'update_set_a_op > name|single|num > update_set_sc ^ single',
206
+ 'update_set_sc > , > update_set_sc_comma_',
207
+ 'update_set_sc_comma_ > name > update_set_a ^ id',
208
+ 'update_set_sc_ > , > update_set_sc_comma_ ^ where',
209
+ '- > where > update_where',
210
+ 'update_where_ > name > update_where_a ^ id',
211
+ 'update_where_a > comparison > update_where_a_op',
212
+ 'update_where_a_ > comparison > update_where_a_op ^ =,<,<=,>,>=,<>,like,not,in',
213
+ '- > not > update_where_a_not',
214
+ '- > in > update_where_a_in',
215
+ 'update_where_a_not_ > comparison > update_where_a_not_op ^ like,in',
216
+ '- > in > update_where_a_in',
217
+ 'update_where_a_in > ( > update_where_a_in_lp_ ^ (',
218
+ '- < ) > update_where_sc',
219
+ 'update_where_a_in_lp_ > name|single|num > update_where_a_in_lp_a ^ single,select',
220
+ '- > select > update_where_a_in_lp_select',
221
+ 'update_where_a_in_lp_select_ > name > select_a ^ id',
222
+ 'update_where_a_in_lp_a > , > update_where_a_in_lp_a_comma_ ^ comma,)',
223
+ 'update_where_a_in_lp_a_comma_ > name|single|num > update_where_a_in_lp_a ^ single',
224
+ 'update_where_a_not_op > name|single|num > update_where_sc ^ single',
225
+ 'update_where_a_op > name|single|num > update_where_sc ^ single',
226
+ 'update_where_sc_ > and|or > update_where ^ and,or',
227
+
228
+ # <delete_statement> ::= DELETE FROM <table_name> [ WHERE <search_condition> ]
229
+
230
+ # <table_name> ::= <identifier>
231
+
232
+ # <search_condition> ::= <boolean_expression>
233
+
234
+ # <boolean_expression> ::= <predicate>
235
+ # | <boolean_expression> AND <predicate>
236
+ # | <boolean_expression> OR <predicate>
237
+ # | NOT <predicate>
238
+ # | ( <boolean_expression> )
239
+
240
+ # <predicate> ::= <expression> <comparison_operator> <expression>
241
+ # | <expression> IS NULL
242
+ # | <expression> IS NOT NULL
243
+ # | <expression> LIKE <pattern> [ ESCAPE <escape_character> ]
244
+ # | <expression> IN ( <expression_list> )
245
+ # | EXISTS ( <select_statement> )
246
+ # | ... (other predicates)
247
+
248
+ # <comparison_operator> ::= = | <> | != | > | < | >= | <=
249
+
250
+ # <expression> ::= <literal>
251
+ # | <column_name>
252
+ # | <function_call>
253
+ # | ( <expression> )
254
+ # | <expression> <arithmetic_operator> <expression>
255
+ # | ... (other expressions)
256
+
257
+ # <literal> ::= <numeric_literal> | <string_literal> | <boolean_literal> | <date_literal> | ...
258
+
259
+ # <column_name> ::= <identifier>
260
+
261
+ # <identifier> ::= <letter> { <letter> | <digit> | _ }...
262
+
263
+ # <pattern> ::= <string_literal>
264
+
265
+ # <escape_character> ::= <string_literal> (single character)
266
+
267
+ # <expression_list> ::= <expression> { , <expression> }...
268
+ ' > delete > delete',
269
+ 'delete_ > from > delete_from ^ from',
270
+ 'delete_from_ > name > delete_from_x ^ tables',
271
+ 'delete_from_x_ > where > update_where ^ where',
272
+
273
+ # <alter table action> ::=
274
+ # ADD <column definition>
275
+ # | DROP COLUMN <column name>
276
+ # | MODIFY COLUMN <column name> <column modification>
277
+ # | RENAME TO <new table name>
278
+ # | ADD CONSTRAINT <constraint definition>
279
+ # | DROP CONSTRAINT <constraint name>
280
+ # | ... (other actions like adding/dropping indexes, partitions, etc.)
281
+
282
+ # <column definition> ::= <column name> <data type> [ <column constraint> ... ]
283
+
284
+ # <column modification> ::=
285
+ # SET DATA TYPE <data type>
286
+ # | SET DEFAULT <expression>
287
+ # | DROP DEFAULT
288
+ # | SET NOT NULL
289
+ # | DROP NOT NULL
290
+ # | ...
291
+
292
+ # <constraint definition> ::=
293
+ # PRIMARY KEY ( <column name list> )
294
+ # | UNIQUE ( <column name list> )
295
+ # | FOREIGN KEY ( <column name list> ) REFERENCES <referenced table> ( <referenced column list> )
296
+ # | CHECK ( <search condition> )
297
+
298
+ ' > alter > alter',
299
+ 'alter_ > table > alter_table ^ table',
300
+ 'alter_table_ > name|audit > alter_table_t ^ tables',
301
+ 'alter_table_t_ > add > alter_table_add ^ add,add constraint,drop column,drop constraint,rename to',
302
+ '- > drop > alter_table_drop',
303
+
304
+ ' > preview > preview',
305
+ 'preview_ > name|audit > preview_t ^ tables',
306
+ ]
307
+
308
+ SQL_KEYWORDS = [
309
+ 'select', 'from', 'as', 'not', 'in', 'where',
310
+ 'and', 'or', 'group', 'by', 'group by', 'order', 'order by', 'limit', 'asc', 'desc',
311
+ 'inner join', 'on', 'left', 'right', 'full', 'outer', 'left outer join',
312
+ 'left join', 'right outer join', 'right join', 'full join', 'full outer join',
313
+ 'insert', 'into', 'values',
314
+ 'update', 'where', 'set',
315
+ 'delete',
316
+ 'audit',
317
+ 'alter', 'table', 'tables', 'add', 'drop', 'with',
318
+ 'describe'
319
+ ]
320
+
321
+ EXPANDABLE_NAMES = {'tables', 'columns', 'partition-columns', 'table-props', 'table-props-values'}
322
+
323
+ CQL_SPEC = SQL_SPEC + [
324
+ ' > select > select ^ select,insert,update,delete,alter,describe,preview',
325
+
326
+ # ALTER TABLE [ <keyspace_name> . ] <table_name>
327
+ # ( ALTER <column_name> TYPE <cql_type>
328
+ # | ADD ( <column_definition_list> )
329
+ # | DROP ( <column_list> )
330
+ # | RENAME <column_name> TO <column_name> [ AND <column_name> TO <column_name> ... ]
331
+ # | WITH <table_properties> );
332
+
333
+ 'alter_ > table > alter_table ^ table,`tables`',
334
+ '- > tables > alter_tables',
335
+ 'alter_tables_ > with > alter_table_with ^ with',
336
+ 'alter_table_t_ > with > alter_table_with ^ with,add,drop',
337
+ 'alter_table_with_ > name > alter_table_with_p ^ table-props',
338
+ 'alter_table_with_p > comparison > alter_table_with_p_op ^ =',
339
+ 'alter_table_with_p_op > name|single|num > alter_table_with_p_op_v ^ table-prop-values',
340
+ 'alter_table_with_p_op_v_ > --include-reaper > alter_table_with_p_op_v_$ ^ --include-reaper',
341
+
342
+ ' > describe > describe',
343
+ 'describe_ > table > desc_table ^ table,`tables`,keyspace,keyspaces,schema',
344
+ '- > tables > desc_tables',
345
+ '- > keyspace > desc_keyspace',
346
+ '- > keyspaces > desc_keyspaces',
347
+ '- > schema > desc_schema',
348
+ 'desc_table_ > name > desc_table_t ^ tables',
349
+ 'desc_table_t_ > & > desc_table_t_$ ^ &',
350
+ 'desc_tables_ > & > desc_tables_$ ^ &',
351
+ 'desc_keyspace_ > name > desc_keyspace_k',
352
+ 'desc_keyspace_k_ > & > desc_keyspace_k_$ ^ &',
353
+ 'desc_schema_ > & > desc_schema_$ ^ &',
354
+ ]
355
+
356
+ CQL_KEYWORDS = SQL_KEYWORDS + [
357
+ 'schema', 'keyspace', 'keyspaces', 'tables'
358
+ ]
359
+
360
+ ATHENA_SPEC = SQL_SPEC + [
361
+ ' > select > select ^ select,insert,update,delete,alter,describe,preview',
362
+
363
+ 'alter_table_t_ > add > alter_table_add ^ add partition,drop partition',
364
+ 'alter_table_add_ > partition > alter_partition ^ partition',
365
+ 'alter_table_drop_ > partition > alter_partition ^ partition',
366
+ 'alter_partition > ( > alter_partition_lp ^ (',
367
+ 'alter_partition_lp > name > alter_partition_lp_a ^ partition-columns',
368
+ 'alter_partition_lp_a > comparison > alter_partition_lp_a_op ^ =',
369
+ 'alter_partition_lp_a_op > single > alter_partition_lp_a_op_v ^ single',
370
+ 'alter_partition_lp_a_op_v > , > alter_partition_lp_sc ^ single',
371
+ 'alter_partition_lp_sc > name|) > alter_partition_lp_a ^ partition-columns',
372
+
373
+ ' > describe > describe',
374
+ 'describe_ > name > desc_t ^ tables',
375
+ 'desc_t_ > name > desc_t_',
376
+
377
+ 'repair'
378
+ ]
379
+
380
+ ATHENA_KEYWORDS = SQL_KEYWORDS + [
381
+ 'partition'
382
+ ]
383
+
384
+ class SqlStateMachine(StateMachine):
385
+ def __init__(self, indent=0, push_level = 0, debug = False):
386
+ super().__init__(indent, push_level, debug)
387
+
388
+ def spec(self):
389
+ return SQL_SPEC
390
+
391
+ def keywords(self):
392
+ return SQL_KEYWORDS
393
+
394
+ def expandable_names(self):
395
+ return EXPANDABLE_NAMES
396
+
397
+ def witespace_transition_condition(self, from_s: str, to_s: str):
398
+ return from_s.endswith('_') and not from_s.endswith('_comma_') and not from_s.endswith('_lp_') and not from_s.endswith('_rp_')
399
+
400
+ def incomplete_name_transition_condition(self, from_s: str, token: str, to_s: str, suggestions: str):
401
+ if not suggestions:
402
+ return None
403
+
404
+ tokens = [token]
405
+ if '|' in token:
406
+ tokens = token.split('|')
407
+
408
+ if 'name' not in tokens:
409
+ return None
410
+
411
+ if not self.expandable_names().intersection(set(suggestions.split(','))):
412
+ return None
413
+
414
+ return tokens
415
+
416
+ class CqlStateMachine(SqlStateMachine):
417
+ def __init__(self, indent=0, push_level = 0, debug = False):
418
+ super().__init__(indent, push_level, debug)
419
+
420
+ def spec(self):
421
+ return CQL_SPEC
422
+
423
+ def keywords(self):
424
+ return CQL_KEYWORDS
425
+
426
+ class AthenaStateMachine(SqlStateMachine):
427
+ def __init__(self, indent=0, push_level = 0, debug = False):
428
+ super().__init__(indent, push_level, debug)
429
+
430
+ def spec(self):
431
+ return ATHENA_SPEC
432
+
433
+ def keywords(self):
434
+ return ATHENA_KEYWORDS