kaqing 2.0.101__py3-none-any.whl → 2.0.104__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.
- adam/batch.py +0 -14
- adam/commands/audit/audit.py +4 -8
- adam/commands/audit/audit_repair_tables.py +13 -35
- adam/commands/audit/audit_run.py +49 -0
- adam/commands/bash.py +60 -2
- adam/commands/cd.py +8 -8
- adam/commands/commands_utils.py +1 -2
- adam/commands/cql/cql_completions.py +4 -4
- adam/commands/cql/cql_utils.py +6 -9
- adam/commands/cql/cqlsh.py +6 -3
- adam/commands/deploy/deploy_pg_agent.py +2 -2
- adam/commands/deploy/undeploy_pg_agent.py +2 -2
- adam/commands/ls.py +12 -12
- adam/commands/nodetool.py +1 -1
- adam/commands/postgres/postgres.py +3 -3
- adam/commands/postgres/{postgres_session.py → postgres_context.py} +26 -27
- adam/commands/postgres/postgres_utils.py +5 -5
- adam/commands/postgres/psql_completions.py +1 -1
- adam/commands/preview_table.py +8 -27
- adam/commands/pwd.py +2 -2
- adam/embedded_params.py +1 -1
- adam/repl.py +5 -5
- adam/repl_commands.py +4 -5
- adam/repl_state.py +2 -2
- adam/sql/sql_completer.py +67 -76
- adam/sql/sql_state_machine.py +518 -0
- adam/sql/term_completer.py +3 -0
- adam/utils_athena.py +68 -1
- adam/utils_k8s/cassandra_clusters.py +4 -4
- adam/utils_k8s/cassandra_nodes.py +2 -2
- adam/utils_k8s/pods.py +12 -6
- adam/utils_k8s/statefulsets.py +2 -2
- adam/version.py +1 -1
- {kaqing-2.0.101.dist-info → kaqing-2.0.104.dist-info}/METADATA +1 -1
- {kaqing-2.0.101.dist-info → kaqing-2.0.104.dist-info}/RECORD +38 -47
- adam/commands/audit/audit_table_completer.py +0 -9
- adam/commands/cql/cql_table_completer.py +0 -8
- adam/commands/describe/__init__.py +0 -0
- adam/commands/describe/describe.py +0 -61
- adam/commands/describe/describe_keyspace.py +0 -58
- adam/commands/describe/describe_keyspaces.py +0 -46
- adam/commands/describe/describe_schema.py +0 -46
- adam/commands/describe/describe_table.py +0 -57
- adam/commands/describe/describe_tables.py +0 -46
- adam/commands/postgres/psql_table_completer.py +0 -11
- adam/sql/state_machine.py +0 -576
- {kaqing-2.0.101.dist-info → kaqing-2.0.104.dist-info}/WHEEL +0 -0
- {kaqing-2.0.101.dist-info → kaqing-2.0.104.dist-info}/entry_points.txt +0 -0
- {kaqing-2.0.101.dist-info → kaqing-2.0.104.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,518 @@
|
|
|
1
|
+
from typing import Callable
|
|
2
|
+
from sqlparse.sql import Token
|
|
3
|
+
from sqlparse import tokens as TOKEN
|
|
4
|
+
|
|
5
|
+
from adam.utils_repl.state_machine import StateMachine, State
|
|
6
|
+
|
|
7
|
+
__all__ = [
|
|
8
|
+
'SqlStateMachine', 'CqlStateMachine', 'AthenaStateMachine'
|
|
9
|
+
]
|
|
10
|
+
|
|
11
|
+
SQL_SPEC = [
|
|
12
|
+
# <select_statement> ::= SELECT <select_list>
|
|
13
|
+
# FROM <table_expression>
|
|
14
|
+
# [WHERE <search_condition>]
|
|
15
|
+
# [<group_by_clause>]
|
|
16
|
+
# [<having_clause>]
|
|
17
|
+
# [<order_by_clause>]
|
|
18
|
+
# [<limit_clause>]
|
|
19
|
+
|
|
20
|
+
# <search_condition> ::= <boolean_term>
|
|
21
|
+
# | <search_condition> OR <boolean_term>
|
|
22
|
+
|
|
23
|
+
# <boolean_term> ::= <boolean_factor>
|
|
24
|
+
# | <boolean_term> AND <boolean_factor>
|
|
25
|
+
|
|
26
|
+
# <boolean_factor> ::= [NOT] <predicate>
|
|
27
|
+
# | ([NOT] <search_condition>)
|
|
28
|
+
|
|
29
|
+
# <predicate> ::= <comparison_predicate>
|
|
30
|
+
# | <between_predicate>
|
|
31
|
+
# | <in_predicate>
|
|
32
|
+
# | <like_predicate>
|
|
33
|
+
# | <null_predicate>
|
|
34
|
+
# | <exists_predicate>
|
|
35
|
+
# | <quantified_predicate>
|
|
36
|
+
# | <unique_predicate>
|
|
37
|
+
# | <match_predicate>
|
|
38
|
+
# | <overlaps_predicate>
|
|
39
|
+
# | <distinct_predicate>
|
|
40
|
+
# | <member_predicate>
|
|
41
|
+
# | <submultiset_predicate>
|
|
42
|
+
# | <set_predicate>
|
|
43
|
+
|
|
44
|
+
# <comparison_predicate> ::= <row_value_expression> <comparison_operator> <row_value_expression>
|
|
45
|
+
# <comparison_operator> ::= '=' | '<>' | '<' | '<=' | '>' | '>='
|
|
46
|
+
|
|
47
|
+
# <row_value_expression> ::= <value_expression>
|
|
48
|
+
# | (<value_expression> [ { <comma> <value_expression> }... ])
|
|
49
|
+
|
|
50
|
+
# <value_expression> ::= <numeric_value_expression>
|
|
51
|
+
# | <string_value_expression>
|
|
52
|
+
# | <datetime_value_expression>
|
|
53
|
+
# | <interval_value_expression>
|
|
54
|
+
# | <boolean_value_expression>
|
|
55
|
+
# | <user_defined_type_value_expression>
|
|
56
|
+
# | <reference_value_expression>
|
|
57
|
+
# | <collection_value_expression>
|
|
58
|
+
# | <row_value_constructor>
|
|
59
|
+
# | <case_expression>
|
|
60
|
+
# | <cast_expression>
|
|
61
|
+
# | <subquery>
|
|
62
|
+
# | NULL
|
|
63
|
+
# | DEFAULT
|
|
64
|
+
# | <identifier>
|
|
65
|
+
# | <literal>
|
|
66
|
+
' > select > select ^ select,insert,update,delete,alter,preview',
|
|
67
|
+
'select_ > name|* > select_a ^ *',
|
|
68
|
+
'select_a > , > select_a_comma_',
|
|
69
|
+
'select_a_comma_ > name|* > select_a ^ *',
|
|
70
|
+
'select_a_ > from > select_from ^ from',
|
|
71
|
+
'select_from_ > name|audit > select_from_x ^ (select,tables',
|
|
72
|
+
'- > ( > select_from_lp_',
|
|
73
|
+
'- < ) > select_from_sq',
|
|
74
|
+
'select_from_lp_ > select > select',
|
|
75
|
+
'select_from_x > , > select_from_x_comma_ ^ (select,tables',
|
|
76
|
+
'select_from_sq_ > as > select_from_x_as ^ as',
|
|
77
|
+
'select_from_x_comma_ > name|audit > select_from_x ^ tables',
|
|
78
|
+
'select_from_x_ ^ as,where,inner join,left outer join,right outer join,full outer join,group by,order by,limit',
|
|
79
|
+
'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',
|
|
80
|
+
'- > as > select_from_x_as',
|
|
81
|
+
'- > where > select_where',
|
|
82
|
+
'- > order > select_order',
|
|
83
|
+
'- > order by > select_order_by',
|
|
84
|
+
'- > limit > select_where_sc_limit',
|
|
85
|
+
'- > group > select_group',
|
|
86
|
+
'- > group by > select_group_by',
|
|
87
|
+
'- > inner > select_from_x_inner',
|
|
88
|
+
'- > inner join > select_join',
|
|
89
|
+
'- > left > select_from_x_left',
|
|
90
|
+
'- > left join > select_join',
|
|
91
|
+
'- > left outer join > select_join',
|
|
92
|
+
'- > right > select_from_x_right',
|
|
93
|
+
'- > right join > select_join',
|
|
94
|
+
'- > right outer join > select_join',
|
|
95
|
+
'- > full > select_from_x_full',
|
|
96
|
+
'- > full outer join > select_join',
|
|
97
|
+
'select_from_x_as_ > name > select_from_x_as_x ^ x,y,z',
|
|
98
|
+
'select_from_x_as_x > , > select_from_x_as_x_comma_',
|
|
99
|
+
'select_from_x_as_x_comma_ > name|audit > select_from_x ^ tables',
|
|
100
|
+
'select_where_ > name > select_where_a ^ columns',
|
|
101
|
+
'select_where_a > name > select_where_a ^ columns,=,<,<=,>,>=,<>',
|
|
102
|
+
'- > comparison > select_where_a_op',
|
|
103
|
+
'select_where_a_ > comparison > select_where_a_op ^ =,<,<=,>,>=,<>,like,not,in',
|
|
104
|
+
'- > not > select_where_a_not',
|
|
105
|
+
'- > in > select_where_a_in',
|
|
106
|
+
'select_where_a_not_ > comparison > select_where_a_not_op ^ like,in',
|
|
107
|
+
'- > in > select_where_a_in',
|
|
108
|
+
'select_where_a_in > ( > select_where_a_in_lp_ ^ (',
|
|
109
|
+
'- < ) > select_where_sc',
|
|
110
|
+
'select_where_a_in_lp_ > name|single|num > select_where_a_in_lp_a ^ single,select',
|
|
111
|
+
'- > select > select_where_a_in_lp_select',
|
|
112
|
+
'select_where_a_in_lp_select_ > name > select_a ^ id',
|
|
113
|
+
'select_where_a_in_lp_a > , > select_where_a_in_lp_a_comma_ ^ comma,)',
|
|
114
|
+
'select_where_a_in_lp_a_comma_ > name|single|num > select_where_a_in_lp_a ^ single',
|
|
115
|
+
'select_where_a_not_op > name|single|num > select_where_sc ^ single',
|
|
116
|
+
'select_where_a_op > name|single|num > select_where_sc ^ single',
|
|
117
|
+
'select_where_sc_ > and|or > select_where ^ and,or,order by,group by,limit',
|
|
118
|
+
'- > group > select_group',
|
|
119
|
+
'- > group by > select_group_by',
|
|
120
|
+
'- > order > select_order',
|
|
121
|
+
'- > order by > select_order_by',
|
|
122
|
+
'- > limit > select_where_sc_limit',
|
|
123
|
+
'select_group_ > by > select_group_by ^ by',
|
|
124
|
+
'select_group_by_ > name > select_group_by_a ^ columns',
|
|
125
|
+
'select_group_by_a > , > select_group_by_a_comma_ ^ columns',
|
|
126
|
+
'select_group_by_a_comma_ > name > select_group_by_a ^ columns',
|
|
127
|
+
'select_group_by_a_ > limit > select_where_sc_limit ^ limit,order by',
|
|
128
|
+
'- > order > select_order',
|
|
129
|
+
'- > order by > select_order_by',
|
|
130
|
+
'select_order_ > by > select_order_by ^ by',
|
|
131
|
+
'select_order_by_ > name > select_order_by_a ^ columns',
|
|
132
|
+
'select_order_by_a > , > select_order_by_a_comma_',
|
|
133
|
+
'select_order_by_a_comma_ > name > select_order_by_a ^ columns',
|
|
134
|
+
'select_order_by_a_ > desc|asc > select_order_by_a_desc ^ desc,asc,limit',
|
|
135
|
+
'- > limit > select_where_sc_limit',
|
|
136
|
+
'select_order_by_a_desc > , > select_order_by_a_comma_',
|
|
137
|
+
'select_order_by_a_desc_ > limit > select_where_sc_limit ^ limit',
|
|
138
|
+
'select_where_sc_limit_ > num > select_where_sc_limit_num ^ 1',
|
|
139
|
+
'select_where_sc_limit_num_rp__ > as > select_from_x_as ^ as',
|
|
140
|
+
'select_where_x_inner_ > join > select_join',
|
|
141
|
+
'select_join_ > name|audit > select_x_join_y ^ tables',
|
|
142
|
+
'select_from_x_left_ > join > select_join ^ outer join',
|
|
143
|
+
'- > outer > select_from_x_left_outer',
|
|
144
|
+
'select_from_x_left_outer_ > join > select_join ^ join',
|
|
145
|
+
'select_from_x_right_ > join > select_join ^ outer join',
|
|
146
|
+
'- > outer > select_from_x_right_outer',
|
|
147
|
+
'select_from_x_right_outer_ > join > select_join ^ join',
|
|
148
|
+
'select_from_x_full_ > join > select_join ^ outer join',
|
|
149
|
+
'- > outer > select_from_x_full_outer',
|
|
150
|
+
'select_from_x_full_outer_ > join > select_join ^ join',
|
|
151
|
+
'select_x_join_y_ > as > select_x_join_y_as ^ as,on',
|
|
152
|
+
'- > on > select_x_join_y_on ^ as,on',
|
|
153
|
+
'select_x_join_y_as_ > name > select_x_join_y_as_y ^ x,y,z',
|
|
154
|
+
'select_x_join_y_as_y_ > on > select_x_join_y_on ^ on',
|
|
155
|
+
'select_x_join_y_on_ > name > select_x_join_y_on_a ^ columns',
|
|
156
|
+
'select_x_join_y_on_a > name > select_x_join_y_on_a ^ columns,=',
|
|
157
|
+
'- > comparison > select_x_join_y_on_a_op',
|
|
158
|
+
'select_x_join_y_on_a_ > comparison > select_x_join_y_on_a_op ^ =',
|
|
159
|
+
'select_x_join_y_on_a_op > name > select_x_join_y_on_a_op_b ^ columns',
|
|
160
|
+
'select_x_join_y_on_a_op_b > _ > select_from_x_as_x_',
|
|
161
|
+
|
|
162
|
+
# <insert_statement> ::= INSERT INTO <table_name> [ ( <column_list> ) ]
|
|
163
|
+
# VALUES ( <value_list> )
|
|
164
|
+
# | INSERT INTO <table_name> [ ( <column_list> ) ]
|
|
165
|
+
# <query_expression>
|
|
166
|
+
|
|
167
|
+
# <table_name> ::= <identifier>
|
|
168
|
+
|
|
169
|
+
# <column_list> ::= <column_name> [ , <column_list> ]
|
|
170
|
+
|
|
171
|
+
# <column_name> ::= <identifier>
|
|
172
|
+
|
|
173
|
+
# <value_list> ::= <expression> [ , <value_list> ]
|
|
174
|
+
|
|
175
|
+
# <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> ]
|
|
176
|
+
' > insert > insert',
|
|
177
|
+
'insert_ > into > insert_into ^ into',
|
|
178
|
+
'insert_into_ > name|audit > insert_into_x ^ tables',
|
|
179
|
+
'insert_into_x > ( > insert_into_x_lp_',
|
|
180
|
+
'insert_into_x_ > ( > insert_into_x_lp_ ^ (,values(',
|
|
181
|
+
'- > values > insert_values',
|
|
182
|
+
'insert_into_x_lp_ > name > insert_into_x_lp_a ^ id',
|
|
183
|
+
'insert_into_x_lp_a > , > insert_into_x_lp_a_comma_',
|
|
184
|
+
'- > ) > insert_into_x_lp_a_rp_',
|
|
185
|
+
'insert_into_x_lp_a_comma_ > name > insert_into_x_lp_a ^ id',
|
|
186
|
+
'insert_into_x_lp_a_rp__ > values > insert_values ^ values(,select',
|
|
187
|
+
'- > select > select',
|
|
188
|
+
'insert_values > ( > insert_values_lp_',
|
|
189
|
+
'insert_values_lp_ > name|single|num > insert_values_lp_v ^ single',
|
|
190
|
+
'insert_values_lp_v > , > insert_values_lp_v_comma_',
|
|
191
|
+
'insert_values_lp_v_comma_ > name|single|num > insert_values_lp_v',
|
|
192
|
+
|
|
193
|
+
# <update_statement> ::= UPDATE <table_name>
|
|
194
|
+
# SET <set_clause_list>
|
|
195
|
+
# [WHERE <search_condition>]
|
|
196
|
+
|
|
197
|
+
# <set_clause_list> ::= <set_clause> { , <set_clause> }
|
|
198
|
+
|
|
199
|
+
# <set_clause> ::= <column_name> = <update_value>
|
|
200
|
+
|
|
201
|
+
# <update_value> ::= <expression> | NULL | DEFAULT
|
|
202
|
+
|
|
203
|
+
# <search_condition> ::= <boolean_expression>
|
|
204
|
+
' > update > update',
|
|
205
|
+
'update_ > name|audit > update_x ^ tables',
|
|
206
|
+
'update_x_ > set > update_set ^ set',
|
|
207
|
+
'update_set_ > name > update_set_a ^ id',
|
|
208
|
+
'update_set_a > comparison > update_set_a_op',
|
|
209
|
+
'update_set_a_op > name|single|num > update_set_sc ^ single',
|
|
210
|
+
'update_set_sc > , > update_set_sc_comma_',
|
|
211
|
+
'update_set_sc_comma_ > name > update_set_a ^ id',
|
|
212
|
+
'update_set_sc_ > , > update_set_sc_comma_ ^ where',
|
|
213
|
+
'- > where > update_where',
|
|
214
|
+
'update_where_ > name > update_where_a ^ id',
|
|
215
|
+
'update_where_a > comparison > update_where_a_op',
|
|
216
|
+
'update_where_a_ > comparison > update_where_a_op ^ =,<,<=,>,>=,<>,like,not,in',
|
|
217
|
+
'- > not > update_where_a_not',
|
|
218
|
+
'- > in > update_where_a_in',
|
|
219
|
+
'update_where_a_not_ > comparison > update_where_a_not_op ^ like,in',
|
|
220
|
+
'- > in > update_where_a_in',
|
|
221
|
+
'update_where_a_in > ( > update_where_a_in_lp_ ^ (',
|
|
222
|
+
'- < ) > update_where_sc',
|
|
223
|
+
'update_where_a_in_lp_ > name|single|num > update_where_a_in_lp_a ^ single,select',
|
|
224
|
+
'- > select > update_where_a_in_lp_select',
|
|
225
|
+
'update_where_a_in_lp_select_ > name > select_a ^ id',
|
|
226
|
+
'update_where_a_in_lp_a > , > update_where_a_in_lp_a_comma_ ^ comma,)',
|
|
227
|
+
'update_where_a_in_lp_a_comma_ > name|single|num > update_where_a_in_lp_a ^ single',
|
|
228
|
+
'update_where_a_not_op > name|single|num > update_where_sc ^ single',
|
|
229
|
+
'update_where_a_op > name|single|num > update_where_sc ^ single',
|
|
230
|
+
'update_where_sc_ > and|or > update_where ^ and,or',
|
|
231
|
+
|
|
232
|
+
# <delete_statement> ::= DELETE FROM <table_name> [ WHERE <search_condition> ]
|
|
233
|
+
|
|
234
|
+
# <table_name> ::= <identifier>
|
|
235
|
+
|
|
236
|
+
# <search_condition> ::= <boolean_expression>
|
|
237
|
+
|
|
238
|
+
# <boolean_expression> ::= <predicate>
|
|
239
|
+
# | <boolean_expression> AND <predicate>
|
|
240
|
+
# | <boolean_expression> OR <predicate>
|
|
241
|
+
# | NOT <predicate>
|
|
242
|
+
# | ( <boolean_expression> )
|
|
243
|
+
|
|
244
|
+
# <predicate> ::= <expression> <comparison_operator> <expression>
|
|
245
|
+
# | <expression> IS NULL
|
|
246
|
+
# | <expression> IS NOT NULL
|
|
247
|
+
# | <expression> LIKE <pattern> [ ESCAPE <escape_character> ]
|
|
248
|
+
# | <expression> IN ( <expression_list> )
|
|
249
|
+
# | EXISTS ( <select_statement> )
|
|
250
|
+
# | ... (other predicates)
|
|
251
|
+
|
|
252
|
+
# <comparison_operator> ::= = | <> | != | > | < | >= | <=
|
|
253
|
+
|
|
254
|
+
# <expression> ::= <literal>
|
|
255
|
+
# | <column_name>
|
|
256
|
+
# | <function_call>
|
|
257
|
+
# | ( <expression> )
|
|
258
|
+
# | <expression> <arithmetic_operator> <expression>
|
|
259
|
+
# | ... (other expressions)
|
|
260
|
+
|
|
261
|
+
# <literal> ::= <numeric_literal> | <string_literal> | <boolean_literal> | <date_literal> | ...
|
|
262
|
+
|
|
263
|
+
# <column_name> ::= <identifier>
|
|
264
|
+
|
|
265
|
+
# <identifier> ::= <letter> { <letter> | <digit> | _ }...
|
|
266
|
+
|
|
267
|
+
# <pattern> ::= <string_literal>
|
|
268
|
+
|
|
269
|
+
# <escape_character> ::= <string_literal> (single character)
|
|
270
|
+
|
|
271
|
+
# <expression_list> ::= <expression> { , <expression> }...
|
|
272
|
+
' > delete > delete',
|
|
273
|
+
'delete_ > from > delete_from ^ from',
|
|
274
|
+
'delete_from_ > name|audit > delete_from_x ^ tables',
|
|
275
|
+
'delete_from_x_ > where > update_where ^ where',
|
|
276
|
+
|
|
277
|
+
# <alter table action> ::=
|
|
278
|
+
# ADD <column definition>
|
|
279
|
+
# | DROP COLUMN <column name>
|
|
280
|
+
# | MODIFY COLUMN <column name> <column modification>
|
|
281
|
+
# | RENAME TO <new table name>
|
|
282
|
+
# | ADD CONSTRAINT <constraint definition>
|
|
283
|
+
# | DROP CONSTRAINT <constraint name>
|
|
284
|
+
# | ... (other actions like adding/dropping indexes, partitions, etc.)
|
|
285
|
+
|
|
286
|
+
# <column definition> ::= <column name> <data type> [ <column constraint> ... ]
|
|
287
|
+
|
|
288
|
+
# <column modification> ::=
|
|
289
|
+
# SET DATA TYPE <data type>
|
|
290
|
+
# | SET DEFAULT <expression>
|
|
291
|
+
# | DROP DEFAULT
|
|
292
|
+
# | SET NOT NULL
|
|
293
|
+
# | DROP NOT NULL
|
|
294
|
+
# | ...
|
|
295
|
+
|
|
296
|
+
# <constraint definition> ::=
|
|
297
|
+
# PRIMARY KEY ( <column name list> )
|
|
298
|
+
# | UNIQUE ( <column name list> )
|
|
299
|
+
# | FOREIGN KEY ( <column name list> ) REFERENCES <referenced table> ( <referenced column list> )
|
|
300
|
+
# | CHECK ( <search condition> )
|
|
301
|
+
|
|
302
|
+
' > alter > alter',
|
|
303
|
+
'alter_ > table > alter_table ^ table',
|
|
304
|
+
'alter_table_ > name|audit > alter_table_t ^ tables',
|
|
305
|
+
'alter_table_t_ > add > alter_table_add ^ add,add constraint,drop column,drop constraint,rename to',
|
|
306
|
+
'- > drop > alter_table_drop',
|
|
307
|
+
|
|
308
|
+
' > preview > preview',
|
|
309
|
+
'preview_ > name|audit > preview_t ^ tables',
|
|
310
|
+
]
|
|
311
|
+
|
|
312
|
+
SQL_KEYWORDS = [
|
|
313
|
+
'select', 'from', 'as', 'not', 'in', 'where',
|
|
314
|
+
'and', 'or', 'group', 'by', 'group by', 'order', 'order by', 'limit', 'asc', 'desc',
|
|
315
|
+
'inner join', 'on', 'left', 'right', 'full', 'outer', 'left outer join',
|
|
316
|
+
'left join', 'right outer join', 'right join', 'full join', 'full outer join',
|
|
317
|
+
'insert', 'into', 'values',
|
|
318
|
+
'update', 'where', 'set',
|
|
319
|
+
'delete',
|
|
320
|
+
'audit',
|
|
321
|
+
'alter', 'table', 'tables', 'add', 'drop', 'with',
|
|
322
|
+
'describe'
|
|
323
|
+
]
|
|
324
|
+
|
|
325
|
+
EXPANDABLE_NAMES = {'tables', 'columns', 'partition-columns', 'table-props', 'table-props-values'}
|
|
326
|
+
|
|
327
|
+
CQL_SPEC = SQL_SPEC + [
|
|
328
|
+
' > select > select ^ select,insert,update,delete,alter,describe,preview',
|
|
329
|
+
|
|
330
|
+
# ALTER TABLE [ <keyspace_name> . ] <table_name>
|
|
331
|
+
# ( ALTER <column_name> TYPE <cql_type>
|
|
332
|
+
# | ADD ( <column_definition_list> )
|
|
333
|
+
# | DROP ( <column_list> )
|
|
334
|
+
# | RENAME <column_name> TO <column_name> [ AND <column_name> TO <column_name> ... ]
|
|
335
|
+
# | WITH <table_properties> );
|
|
336
|
+
|
|
337
|
+
'alter_ > table > alter_table ^ table,`tables`',
|
|
338
|
+
'- > tables > alter_tables',
|
|
339
|
+
'alter_tables_ > with > alter_table_with ^ with',
|
|
340
|
+
'alter_table_t_ > with > alter_table_with ^ with,add,drop',
|
|
341
|
+
'alter_table_with_ > name > alter_table_with_p ^ table-props',
|
|
342
|
+
'alter_table_with_p > comparison > alter_table_with_p_op ^ =',
|
|
343
|
+
'alter_table_with_p_op > name|single|num > alter_table_with_p_op_v ^ table-prop-values',
|
|
344
|
+
'alter_table_with_p_op_v_ > --include-reaper > alter_table_with_p_op_v_$ ^ --include-reaper',
|
|
345
|
+
|
|
346
|
+
' > describe > describe',
|
|
347
|
+
'describe_ > table > desc_table ^ table,`tables`,keyspace,keyspaces,schema',
|
|
348
|
+
'- > tables > desc_tables',
|
|
349
|
+
'- > keyspace > desc_keyspace',
|
|
350
|
+
'- > keyspaces > desc_keyspaces',
|
|
351
|
+
'- > schema > desc_schema',
|
|
352
|
+
'desc_table_ > name > desc_table_t ^ tables',
|
|
353
|
+
'desc_table_t_ > & > desc_table_t_$ ^ &',
|
|
354
|
+
'desc_tables_ > & > desc_tables_$ ^ &',
|
|
355
|
+
'desc_keyspace_ > name > desc_keyspace_k',
|
|
356
|
+
'desc_keyspace_k_ > & > desc_keyspace_k_$ ^ &',
|
|
357
|
+
'desc_schema_ > & > desc_schema_$ ^ &',
|
|
358
|
+
]
|
|
359
|
+
|
|
360
|
+
CQL_KEYWORDS = SQL_KEYWORDS + [
|
|
361
|
+
'schema', 'keyspace', 'keyspaces', 'tables'
|
|
362
|
+
]
|
|
363
|
+
|
|
364
|
+
ATHENA_SPEC = SQL_SPEC + [
|
|
365
|
+
' > select > select ^ select,insert,update,delete,alter,describe,preview',
|
|
366
|
+
|
|
367
|
+
'alter_table_t_ > add > alter_table_add ^ add partition,drop partition',
|
|
368
|
+
'alter_table_add_ > partition > alter_partition ^ partition',
|
|
369
|
+
'alter_table_drop_ > partition > alter_partition ^ partition',
|
|
370
|
+
'alter_partition > ( > alter_partition_lp ^ (',
|
|
371
|
+
'alter_partition_lp > name > alter_partition_lp_a ^ partition-columns',
|
|
372
|
+
'alter_partition_lp_a > comparison > alter_partition_lp_a_op ^ =',
|
|
373
|
+
'alter_partition_lp_a_op > single > alter_partition_lp_a_op_v ^ single',
|
|
374
|
+
'alter_partition_lp_a_op_v > , > alter_partition_lp_sc ^ single',
|
|
375
|
+
'alter_partition_lp_sc > name|) > alter_partition_lp_a ^ partition-columns',
|
|
376
|
+
|
|
377
|
+
' > describe > describe',
|
|
378
|
+
'describe_ > name > desc_t ^ tables',
|
|
379
|
+
'desc_t_ > name > desc_t_',
|
|
380
|
+
|
|
381
|
+
'repair'
|
|
382
|
+
]
|
|
383
|
+
|
|
384
|
+
ATHENA_KEYWORDS = SQL_KEYWORDS + [
|
|
385
|
+
'partition'
|
|
386
|
+
]
|
|
387
|
+
|
|
388
|
+
class SqlStateMachine(StateMachine[Token]):
|
|
389
|
+
def __init__(self, indent=0, push_level = 0, debug = False):
|
|
390
|
+
super().__init__(indent, push_level, debug)
|
|
391
|
+
|
|
392
|
+
def traverse_tokens(self, tokens: list[Token], state: State = State('')):
|
|
393
|
+
def handle_push():
|
|
394
|
+
if f'{state.state} > {it}' in self.states:
|
|
395
|
+
state_test = self.states[f'{state.state} > {it}']
|
|
396
|
+
if state_test.comeback_token:
|
|
397
|
+
self.comebacks[self.push_level] = state_test.comeback_state
|
|
398
|
+
|
|
399
|
+
def handle_pop():
|
|
400
|
+
if self.push_level in self.comebacks:
|
|
401
|
+
try:
|
|
402
|
+
return State(self.comebacks[self.push_level])
|
|
403
|
+
finally:
|
|
404
|
+
del self.comebacks[self.push_level]
|
|
405
|
+
|
|
406
|
+
return None
|
|
407
|
+
|
|
408
|
+
for token in tokens:
|
|
409
|
+
if self.debug:
|
|
410
|
+
if token.ttype == TOKEN.Whitespace:
|
|
411
|
+
print('_ ', end='')
|
|
412
|
+
elif token.ttype in [TOKEN.DML, TOKEN.Wildcard, TOKEN.Punctuation, TOKEN.CTE]:
|
|
413
|
+
print(f'{token.value} ', end='')
|
|
414
|
+
elif token.ttype:
|
|
415
|
+
tks = str(token.ttype).split('.')
|
|
416
|
+
typ = tks[len(tks) - 1]
|
|
417
|
+
if ' ' in token.value:
|
|
418
|
+
print(f'"{token.value}:{typ}" ', end='')
|
|
419
|
+
else:
|
|
420
|
+
print(f'{token.value}:{typ} ', end='')
|
|
421
|
+
# print(" " * self.indent + f"Token: {token.value}, Type: {token.ttype}@{token.ttype.__class__}")
|
|
422
|
+
|
|
423
|
+
last_name = None
|
|
424
|
+
if token.is_group:
|
|
425
|
+
state = self.traverse_tokens(token.tokens, state)
|
|
426
|
+
else:
|
|
427
|
+
comeback_state = None
|
|
428
|
+
|
|
429
|
+
it = ''
|
|
430
|
+
if (t := token.value.lower()) in self.keywords():
|
|
431
|
+
it = t
|
|
432
|
+
elif token.ttype == TOKEN.Text.Whitespace:
|
|
433
|
+
it = '_'
|
|
434
|
+
elif token.ttype == TOKEN.Name:
|
|
435
|
+
it = 'name'
|
|
436
|
+
last_name = token.value
|
|
437
|
+
elif token.ttype == TOKEN.Literal.String.Single:
|
|
438
|
+
it = 'single'
|
|
439
|
+
elif token.ttype in [TOKEN.Literal.Number.Integer, TOKEN.Literal.Number.Float]:
|
|
440
|
+
it = 'num'
|
|
441
|
+
elif token.ttype == TOKEN.Wildcard:
|
|
442
|
+
it = '*'
|
|
443
|
+
elif token.ttype == TOKEN.Punctuation:
|
|
444
|
+
it = token.value
|
|
445
|
+
|
|
446
|
+
if it == '(':
|
|
447
|
+
handle_push()
|
|
448
|
+
self.push_level += 1
|
|
449
|
+
elif it == ')':
|
|
450
|
+
self.push_level -= 1
|
|
451
|
+
comeback_state = handle_pop()
|
|
452
|
+
|
|
453
|
+
elif token.ttype == TOKEN.Operator.Comparison:
|
|
454
|
+
it = 'comparison'
|
|
455
|
+
|
|
456
|
+
try:
|
|
457
|
+
# print(f'\n{state.to_s} > {it} > ', end='')
|
|
458
|
+
if comeback_state:
|
|
459
|
+
state = comeback_state
|
|
460
|
+
else:
|
|
461
|
+
context = state.context
|
|
462
|
+
state = self.states[f'{state.state} > {it}']
|
|
463
|
+
state.context = context
|
|
464
|
+
|
|
465
|
+
if last_name:
|
|
466
|
+
state.context['last_name'] = last_name
|
|
467
|
+
except:
|
|
468
|
+
pass
|
|
469
|
+
|
|
470
|
+
return state
|
|
471
|
+
|
|
472
|
+
def spec(self):
|
|
473
|
+
return SQL_SPEC
|
|
474
|
+
|
|
475
|
+
def keywords(self):
|
|
476
|
+
return SQL_KEYWORDS
|
|
477
|
+
|
|
478
|
+
def expandable_names(self):
|
|
479
|
+
return EXPANDABLE_NAMES
|
|
480
|
+
|
|
481
|
+
def witespace_transition_condition(self, from_s: str, to_s: str):
|
|
482
|
+
return from_s.endswith('_') and not from_s.endswith('_comma_') and not from_s.endswith('_lp_') and not from_s.endswith('_rp_')
|
|
483
|
+
|
|
484
|
+
def incomplete_name_transition_condition(self, from_s: str, token: str, to_s: str, suggestions: str):
|
|
485
|
+
if not suggestions:
|
|
486
|
+
return None
|
|
487
|
+
|
|
488
|
+
tokens = [token]
|
|
489
|
+
if '|' in token:
|
|
490
|
+
tokens = token.split('|')
|
|
491
|
+
|
|
492
|
+
if 'name' not in tokens:
|
|
493
|
+
return None
|
|
494
|
+
|
|
495
|
+
if not self.expandable_names().intersection(set(suggestions.split(','))):
|
|
496
|
+
return None
|
|
497
|
+
|
|
498
|
+
return tokens
|
|
499
|
+
|
|
500
|
+
class CqlStateMachine(SqlStateMachine):
|
|
501
|
+
def __init__(self, indent=0, push_level = 0, debug = False):
|
|
502
|
+
super().__init__(indent, push_level, debug)
|
|
503
|
+
|
|
504
|
+
def spec(self):
|
|
505
|
+
return CQL_SPEC
|
|
506
|
+
|
|
507
|
+
def keywords(self):
|
|
508
|
+
return CQL_KEYWORDS
|
|
509
|
+
|
|
510
|
+
class AthenaStateMachine(SqlStateMachine):
|
|
511
|
+
def __init__(self, indent=0, push_level = 0, debug = False):
|
|
512
|
+
super().__init__(indent, push_level, debug)
|
|
513
|
+
|
|
514
|
+
def spec(self):
|
|
515
|
+
return ATHENA_SPEC
|
|
516
|
+
|
|
517
|
+
def keywords(self):
|
|
518
|
+
return ATHENA_KEYWORDS
|
adam/sql/term_completer.py
CHANGED
|
@@ -22,6 +22,9 @@ class TermCompleter(WordCompleter):
|
|
|
22
22
|
) -> None:
|
|
23
23
|
super().__init__(words, ignore_case, display_dict, meta_dict, WORD, sentence, match_middle, pattern)
|
|
24
24
|
|
|
25
|
+
def __str__(self):
|
|
26
|
+
return ','.join(self.words)
|
|
27
|
+
|
|
25
28
|
def get_completions(
|
|
26
29
|
self, document: Document, complete_event: CompleteEvent
|
|
27
30
|
) -> Iterable[Completion]:
|
adam/utils_athena.py
CHANGED
|
@@ -1,10 +1,77 @@
|
|
|
1
|
+
from datetime import datetime
|
|
1
2
|
import functools
|
|
2
3
|
import time
|
|
3
4
|
import boto3
|
|
5
|
+
import requests
|
|
4
6
|
|
|
5
7
|
from adam.config import Config
|
|
6
8
|
from adam.utils import lines_to_tabular, log, log2
|
|
7
9
|
|
|
10
|
+
class AuditMeta:
|
|
11
|
+
def __init__(self, checked_in: float, cluster_last_checked: float):
|
|
12
|
+
self.checked_in = checked_in
|
|
13
|
+
self.cluster_last_checked = cluster_last_checked
|
|
14
|
+
|
|
15
|
+
def get_meta() -> AuditMeta:
|
|
16
|
+
checked_in = 0.0
|
|
17
|
+
cluster_last_checked = 0.0
|
|
18
|
+
|
|
19
|
+
state, _, rs = audit_query(f'select partitions_last_checked, clusters_last_checked from meta')
|
|
20
|
+
if state == 'SUCCEEDED':
|
|
21
|
+
if len(rs) > 1:
|
|
22
|
+
try:
|
|
23
|
+
row = rs[1]['Data']
|
|
24
|
+
checked_in = float(row[0]['VarCharValue'])
|
|
25
|
+
cluster_last_checked = float(row[1]['VarCharValue'])
|
|
26
|
+
except:
|
|
27
|
+
pass
|
|
28
|
+
|
|
29
|
+
return AuditMeta(checked_in, cluster_last_checked)
|
|
30
|
+
|
|
31
|
+
def find_new_clusters(cluster_last_checked: float) -> list[str]:
|
|
32
|
+
dt_object = datetime.fromtimestamp(cluster_last_checked)
|
|
33
|
+
|
|
34
|
+
y = dt_object.strftime("%Y")
|
|
35
|
+
m = dt_object.strftime("%m")
|
|
36
|
+
d = dt_object.strftime("%d")
|
|
37
|
+
# select distinct c2.name from cluster as c1 right outer join
|
|
38
|
+
# (select distinct c as name from audit where y = '1969' and m = '12' and d >= '31' or y = '1969' and m > '12' or y > '1969') as c2
|
|
39
|
+
# on c1.name = c2.name where c1.name is null
|
|
40
|
+
where = f"y = '{y}' and m = '{m}' and d >= '{d}' or y = '{y}' and m > '{m}' or y > '{y}'"
|
|
41
|
+
query = '\n '.join([
|
|
42
|
+
'select distinct c2.name from cluster as c1 right outer join',
|
|
43
|
+
f'(select distinct c as name from audit where {where}) as c2',
|
|
44
|
+
'on c1.name = c2.name where c1.name is null'])
|
|
45
|
+
log2(query)
|
|
46
|
+
state, _, rs = audit_query(query)
|
|
47
|
+
if state == 'SUCCEEDED':
|
|
48
|
+
if len(rs) > 1:
|
|
49
|
+
try:
|
|
50
|
+
return [r['Data'][0]['VarCharValue'] for r in rs[1:]]
|
|
51
|
+
except:
|
|
52
|
+
pass
|
|
53
|
+
|
|
54
|
+
return []
|
|
55
|
+
|
|
56
|
+
def put_meta(action: str, meta: AuditMeta, clusters: list[str] = None):
|
|
57
|
+
payload = {
|
|
58
|
+
'action': action,
|
|
59
|
+
'partitions-last-checked': meta.checked_in,
|
|
60
|
+
'clusters-last-checked': meta.cluster_last_checked
|
|
61
|
+
}
|
|
62
|
+
if clusters:
|
|
63
|
+
payload['clusters'] = clusters
|
|
64
|
+
|
|
65
|
+
audit_endpoint = Config().get("audit.endpoint", "https://4psvtaxlcb.execute-api.us-west-2.amazonaws.com/prod/")
|
|
66
|
+
try:
|
|
67
|
+
response = requests.post(audit_endpoint, json=payload, timeout=Config().get("audit.timeout", 10))
|
|
68
|
+
if response.status_code in [200, 201]:
|
|
69
|
+
Config().debug(response.text)
|
|
70
|
+
else:
|
|
71
|
+
log2(f"Error: {response.status_code} {response.text}")
|
|
72
|
+
except requests.exceptions.Timeout as e:
|
|
73
|
+
log2(f"Timeout occurred: {e}")
|
|
74
|
+
|
|
8
75
|
@functools.lru_cache()
|
|
9
76
|
def audit_table_names():
|
|
10
77
|
region_name = Config().get('audit.athena.region', 'us-west-2')
|
|
@@ -50,7 +117,7 @@ def run_audit_query(sql: str, database: str = None):
|
|
|
50
117
|
columns = [col.get('VarCharValue') for col in column_info]
|
|
51
118
|
lines = []
|
|
52
119
|
for row in rs[1:]:
|
|
53
|
-
row_data = [col.get('VarCharValue') for col in row['Data']]
|
|
120
|
+
row_data = [col.get('VarCharValue') if col else '' for col in row['Data']]
|
|
54
121
|
lines.append('\t'.join(row_data))
|
|
55
122
|
|
|
56
123
|
log(lines_to_tabular(lines, header='\t'.join(columns), separator='\t'))
|
|
@@ -14,12 +14,12 @@ T = TypeVar('T')
|
|
|
14
14
|
# utility collection on cassandra clusters; methods are all static
|
|
15
15
|
class CassandraClusters:
|
|
16
16
|
def exec(statefulset: str, namespace: str, command: str, action: str = 'action',
|
|
17
|
-
max_workers=0, show_out=True, on_any = False, shell = '/bin/sh') -> list[PodExecResult]:
|
|
17
|
+
max_workers=0, show_out=True, on_any = False, shell = '/bin/sh', background = False) -> list[PodExecResult]:
|
|
18
18
|
def body(executor: ThreadPoolExecutor, pod: str, namespace: str, show_out: bool):
|
|
19
19
|
if executor:
|
|
20
|
-
return executor.submit(CassandraNodes.exec, pod, namespace, command, False, False, shell)
|
|
20
|
+
return executor.submit(CassandraNodes.exec, pod, namespace, command, False, False, shell, background)
|
|
21
21
|
|
|
22
|
-
return CassandraNodes.exec(pod, namespace, command, show_out=show_out)
|
|
22
|
+
return CassandraNodes.exec(pod, namespace, command, show_out=show_out, background=background)
|
|
23
23
|
|
|
24
24
|
def post(result, show_out: bool):
|
|
25
25
|
if KubeContext.show_out(show_out):
|
|
@@ -31,4 +31,4 @@ class CassandraClusters:
|
|
|
31
31
|
|
|
32
32
|
return result
|
|
33
33
|
|
|
34
|
-
return StatefulSets.on_cluster(statefulset, namespace, body, post=post, action=action, max_workers=max_workers, show_out=show_out, on_any=on_any)
|
|
34
|
+
return StatefulSets.on_cluster(statefulset, namespace, body, post=post, action=action, max_workers=max_workers, show_out=show_out, on_any=on_any, background=background)
|
|
@@ -6,8 +6,8 @@ from adam.repl_session import ReplSession
|
|
|
6
6
|
|
|
7
7
|
# utility collection on cassandra nodes; methods are all static
|
|
8
8
|
class CassandraNodes:
|
|
9
|
-
def exec(pod_name: str, namespace: str, command: str, show_out = True, throw_err = False, shell = '/bin/sh') -> PodExecResult:
|
|
10
|
-
r = Pods.exec(pod_name, "cassandra", namespace, command, show_out = show_out, throw_err = throw_err, shell = shell)
|
|
9
|
+
def exec(pod_name: str, namespace: str, command: str, show_out = True, throw_err = False, shell = '/bin/sh', background = False) -> PodExecResult:
|
|
10
|
+
r = Pods.exec(pod_name, "cassandra", namespace, command, show_out = show_out, throw_err = throw_err, shell = shell, background = background)
|
|
11
11
|
|
|
12
12
|
if r and Config().get('repl.history.push-cat-remote-log-file', True):
|
|
13
13
|
if r.log_file:
|