flydata 0.2.7 → 0.2.8
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.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/flydata.gemspec +3 -3
- data/lib/flydata/command/base.rb +7 -1
- data/lib/flydata/command/sync.rb +9 -0
- data/lib/flydata/fluent-plugins/mysql/alter_table_query_handler.rb +4 -2
- data/lib/flydata/fluent-plugins/mysql/binlog_record_handler.rb +3 -2
- data/lib/flydata/fluent-plugins/mysql/dml_record_handler.rb +1 -1
- data/lib/flydata/parser/mysql/mysql_alter_table.treetop +461 -22
- data/lib/flydata/util/encryptor.rb +1 -1
- data/spec/flydata/fluent-plugins/in_mysql_binlog_flydata_spec.rb +26 -2
- data/spec/flydata/fluent-plugins/mysql/alter_table_query_handler_spec.rb +1 -1
- data/spec/flydata/parser/mysql/alter_table_parser_spec.rb +499 -81
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c5fda2fb95c38692e1a0995b3ee7430ea706ec09
|
4
|
+
data.tar.gz: 5028033ad26d7399e7bcb091257540f1fb4ab46a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dbcb9055ead8575095ef96d378d2817743f0c03cb629d6d7ef5d46bc99f04fd22e420f2c8011c28a97a3c5041ec683ed57045d59bd86c31fdb6ec680dbb81769
|
7
|
+
data.tar.gz: 1e77c0720dd22cad760cd00f11eef55514bb768937acb5b6970027f352d5cf97d9f2177b6d904aeb74c8716ab6f9f374757f3ce09780e3c166f79ad3b6a7360d
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.2.
|
1
|
+
0.2.8
|
data/flydata.gemspec
CHANGED
@@ -2,16 +2,16 @@
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
3
|
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
-
# stub: flydata 0.2.
|
5
|
+
# stub: flydata 0.2.8 ruby lib
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "flydata"
|
9
|
-
s.version = "0.2.
|
9
|
+
s.version = "0.2.8"
|
10
10
|
|
11
11
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
12
12
|
s.require_paths = ["lib"]
|
13
13
|
s.authors = ["Koichi Fujikawa", "Masashi Miyazaki", "Matthew Luu", "Mak Inada", "Sriram NS"]
|
14
|
-
s.date = "2014-10-
|
14
|
+
s.date = "2014-10-15"
|
15
15
|
s.description = "FlyData Agent"
|
16
16
|
s.email = "sysadmin@flydata.com"
|
17
17
|
s.executables = ["fdmysqldump", "flydata", "serverinfo"]
|
data/lib/flydata/command/base.rb
CHANGED
@@ -35,8 +35,14 @@ module Flydata
|
|
35
35
|
end
|
36
36
|
def ask_yes_no(message, default_yes=true)
|
37
37
|
suffix = default_yes ? "(Y/n)" : "(y/n)"
|
38
|
+
prompt = "#{message} #{suffix}: "
|
39
|
+
if opts && opts.yes? # Yes option
|
40
|
+
puts "#{prompt}Yes"
|
41
|
+
return true
|
42
|
+
end
|
43
|
+
|
38
44
|
loop do
|
39
|
-
ans = ask(
|
45
|
+
ans = ask(prompt)
|
40
46
|
return true if default_yes and ans == ''
|
41
47
|
if ans.size > 0
|
42
48
|
case ans[0].downcase
|
data/lib/flydata/command/sync.rb
CHANGED
@@ -21,6 +21,7 @@ module Flydata
|
|
21
21
|
def self.slop
|
22
22
|
Slop.new do
|
23
23
|
on 'c', 'skip-cleanup', 'Skip server cleanup'
|
24
|
+
on 'y', 'yes', 'Skip command prompt assuming yes to all questions. Use this for batch operation.'
|
24
25
|
end
|
25
26
|
end
|
26
27
|
|
@@ -42,6 +43,12 @@ module Flydata
|
|
42
43
|
sync_mysql_to_redshift(de)
|
43
44
|
end
|
44
45
|
|
46
|
+
def self.slop_flush
|
47
|
+
Slop.new do
|
48
|
+
on 'y', 'yes', 'Skip command prompt assuming yes to all questions. Use this for batch operation.'
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
45
52
|
def flush
|
46
53
|
flush_buffer_and_stop
|
47
54
|
puts "Buffers have been flushed and the sender process has been stopped."
|
@@ -50,6 +57,7 @@ module Flydata
|
|
50
57
|
def self.slop_reset
|
51
58
|
Slop.new do
|
52
59
|
on 'c', 'client', 'Resets client only.'
|
60
|
+
on 'y', 'yes', 'Skip command prompt assuming yes to all questions. Use this for batch operation.'
|
53
61
|
end
|
54
62
|
end
|
55
63
|
|
@@ -134,6 +142,7 @@ module Flydata
|
|
134
142
|
def self.slop_generate_table_ddl
|
135
143
|
Slop.new do
|
136
144
|
on 'c', 'ctl-only', 'Only generate FlyData Control definitions'
|
145
|
+
on 'y', 'yes', 'Skip command prompt assuming yes to all questions. Use this for batch operation.'
|
137
146
|
end
|
138
147
|
end
|
139
148
|
|
@@ -14,14 +14,16 @@ module Mysql
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def process(record, normalized_query)
|
17
|
-
emit_record(:alter_table, record
|
17
|
+
emit_record(:alter_table, record) do |opt|
|
18
18
|
ret = nil
|
19
19
|
begin
|
20
20
|
result = ParserProvider.parser(:mysql, :mysql_alter_table).new.parse(record['query'])
|
21
21
|
if result.nil?
|
22
|
-
$log.
|
22
|
+
$log.error("Received unsupported alter table query. query:'#{record['query']}'")
|
23
23
|
else
|
24
24
|
ret = result.tree
|
25
|
+
breaking_query = ret[:actions].any?{|action| !action.has_key?(:support_level) || action[:support_level] != :nonbreaking}
|
26
|
+
opt[:increment_table_rev] = true if breaking_query
|
25
27
|
end
|
26
28
|
rescue => e
|
27
29
|
msg = <<EOS
|
@@ -54,13 +54,14 @@ module Mysql
|
|
54
54
|
@context.omit_events[table].nil? || !@context.omit_events[table].include?(type)
|
55
55
|
end
|
56
56
|
|
57
|
-
def emit_record(type, record
|
57
|
+
def emit_record(type, record)
|
58
58
|
return unless acceptable_db?(record)
|
59
59
|
return unless record["table_name"].nil? or acceptable_table?(record, record["table_name"])
|
60
60
|
|
61
61
|
check_empty_binlog
|
62
62
|
|
63
|
-
|
63
|
+
opt = {}
|
64
|
+
records = yield(opt) # The block may set options as necessary
|
64
65
|
return if records.nil? # skip
|
65
66
|
records = [records] unless records.kind_of?(Array)
|
66
67
|
|
@@ -41,7 +41,7 @@ module Mysql
|
|
41
41
|
end
|
42
42
|
|
43
43
|
def emit_rows(type, record)
|
44
|
-
emit_record(type, record) do |
|
44
|
+
emit_record(type, record) do |opt|
|
45
45
|
records = record["rows"].collect do |row|
|
46
46
|
row = yield(row) if block_given? # Give the caller a chance to generate the correct row
|
47
47
|
{ ROW => convert_to_flydata_row_format(row) }
|
@@ -20,10 +20,10 @@ grammar MysqlAlterTable
|
|
20
20
|
def tree
|
21
21
|
value = {
|
22
22
|
type: :alter_table,
|
23
|
-
table_name: tbl_name.table_part.
|
23
|
+
table_name: tbl_name.table_part.value,
|
24
24
|
actions: alter_specs.actions
|
25
25
|
}
|
26
|
-
value[:schema_name] = tbl_name.schema_part.
|
26
|
+
value[:schema_name] = tbl_name.schema_part.value if tbl_name.has_schema?
|
27
27
|
value
|
28
28
|
end
|
29
29
|
}
|
@@ -41,27 +41,34 @@ grammar MysqlAlterTable
|
|
41
41
|
alter_spec ( comma alter_spec )* {
|
42
42
|
def actions
|
43
43
|
ret = []
|
44
|
-
|
44
|
+
ret.concat(actions_with_query(alter_spec))
|
45
45
|
0.upto(elements[1].elements.size - 1) do |i|
|
46
|
-
|
47
|
-
concat_action!(ret, action)
|
46
|
+
ret.concat(actions_with_query(elements[1].elements[i].elements[1]))
|
48
47
|
end
|
49
48
|
ret
|
50
49
|
end
|
51
50
|
|
52
|
-
def
|
51
|
+
def actions_with_query(alter_spec)
|
52
|
+
action = alter_spec.action
|
53
53
|
if action.kind_of?(Array)
|
54
54
|
actions = action
|
55
55
|
else
|
56
56
|
actions = [action]
|
57
57
|
end
|
58
|
-
|
58
|
+
actions.each {|a| a[:query] = alter_spec.text_value }
|
59
|
+
actions
|
59
60
|
end
|
60
61
|
}
|
61
62
|
end
|
62
63
|
|
63
64
|
rule alter_spec
|
64
|
-
add_key
|
65
|
+
add_key sp key_def {
|
66
|
+
def action
|
67
|
+
action_hash = key_def.action
|
68
|
+
action_hash
|
69
|
+
end
|
70
|
+
}
|
71
|
+
/ add_key (sp col_key)? sp col_name_def ( sp pos_def )? {
|
65
72
|
def action
|
66
73
|
ret = { action: :add_column }
|
67
74
|
ret.merge!(col_name_def.column_def)
|
@@ -71,7 +78,7 @@ grammar MysqlAlterTable
|
|
71
78
|
ret
|
72
79
|
end
|
73
80
|
}
|
74
|
-
/ add_key (sp col_key)?
|
81
|
+
/ add_key (sp col_key)? nsp '(' nsp col_name_def ( comma col_name_def )* nsp ')' {
|
75
82
|
def action
|
76
83
|
ret = [col_name_def.column_def]
|
77
84
|
ret += 0.upto(elements[6].elements.count - 1).collect do |i|
|
@@ -80,19 +87,423 @@ grammar MysqlAlterTable
|
|
80
87
|
ret.collect{|v| {action: :add_column}.merge(v) }
|
81
88
|
end
|
82
89
|
}
|
90
|
+
/ drop_key sp primary_sym sp key_sym {
|
91
|
+
def action
|
92
|
+
{ action: :drop_primary_key }
|
93
|
+
end
|
94
|
+
}
|
95
|
+
/ drop_key sp foreign_sym sp key_sym sp field_ident {
|
96
|
+
def action
|
97
|
+
{ action: :drop_foreign_key,
|
98
|
+
support_level: :nonbreaking
|
99
|
+
}
|
100
|
+
end
|
101
|
+
}
|
102
|
+
/ drop_key sp key_or_index sp field_ident {
|
103
|
+
def action
|
104
|
+
{ action: "drop_#{key_or_index.text_value.downcase}".to_sym,
|
105
|
+
support_level: :nonbreaking
|
106
|
+
}
|
107
|
+
end
|
108
|
+
}
|
83
109
|
/ drop_key (sp col_key)? sp col_name {
|
84
110
|
def action
|
85
111
|
{ action: :drop_column,
|
86
|
-
column: col_name.
|
112
|
+
column: col_name.value, }
|
113
|
+
end
|
114
|
+
}
|
115
|
+
/ enable_sym sp keys_sym {
|
116
|
+
def action
|
117
|
+
{ action: :enable_keys,
|
118
|
+
support_level: :nonbreaking,
|
119
|
+
}
|
120
|
+
end
|
121
|
+
}
|
122
|
+
/ [^,]+ {
|
123
|
+
def action
|
124
|
+
raise "unsupported ALTER TABLE query. Contact FlyData Support"
|
87
125
|
end
|
88
126
|
}
|
89
|
-
|
127
|
+
end
|
128
|
+
|
129
|
+
rule key_def
|
130
|
+
normal_key_type key_alg nsp '(' key_list ')' normal_key_options {
|
131
|
+
def action
|
132
|
+
{ action: :add_index,
|
133
|
+
support_level: :nonbreaking,
|
134
|
+
}
|
135
|
+
end
|
136
|
+
}
|
137
|
+
/ normal_key_type opt_ident key_alg nsp '(' key_list ')' normal_key_options {
|
138
|
+
def action
|
139
|
+
{ action: :add_index,
|
140
|
+
support_level: :nonbreaking,
|
141
|
+
}
|
142
|
+
end
|
143
|
+
}
|
144
|
+
/ fulltext opt_key_or_index opt_ident init_key_options nsp '(' key_list ')' fulltext_key_options {
|
145
|
+
def action
|
146
|
+
{ action: :add_index,
|
147
|
+
support_level: :nonbreaking,
|
148
|
+
}
|
149
|
+
end
|
150
|
+
}
|
151
|
+
/ spatial opt_key_or_index opt_ident init_key_options nsp '(' key_list ')' spatial_key_options {
|
152
|
+
def action
|
153
|
+
{ action: :add_index,
|
154
|
+
support_level: :nonbreaking,
|
155
|
+
}
|
156
|
+
end
|
157
|
+
}
|
158
|
+
/ constraint_sym sp constraint_key_type key_alg nsp '(' key_list ')' normal_key_options {
|
159
|
+
def action
|
160
|
+
case constraint_key_type.value
|
161
|
+
when :unique
|
162
|
+
{ action: :add_unique_constraint,
|
163
|
+
support_level: :nonbreaking
|
164
|
+
}
|
165
|
+
when :primary_key
|
166
|
+
{ action: :add_primary_key_constraint,
|
167
|
+
keys: key_list.value
|
168
|
+
}
|
169
|
+
else
|
170
|
+
raise "Unsupported constraint key type `#{constraint_key_type.value}"
|
171
|
+
end
|
172
|
+
end
|
173
|
+
}
|
174
|
+
/ constraint_sym sp constraint_key_type opt_ident key_alg nsp '(' key_list ')' normal_key_options {
|
175
|
+
def action
|
176
|
+
case constraint_key_type.value
|
177
|
+
when :unique
|
178
|
+
{ action: :add_unique_constraint,
|
179
|
+
support_level: :nonbreaking
|
180
|
+
}
|
181
|
+
when :primary_key
|
182
|
+
{ action: :add_primary_key_constraint,
|
183
|
+
keys: key_list.value
|
184
|
+
}
|
185
|
+
else
|
186
|
+
raise "Unsupported constraint key type `#{constraint_key_type.value}"
|
187
|
+
end
|
188
|
+
end
|
189
|
+
}
|
190
|
+
/ opt_constraint constraint_key_type key_alg nsp '(' key_list ')' normal_key_options {
|
191
|
+
def action
|
192
|
+
case constraint_key_type.value
|
193
|
+
when :unique
|
194
|
+
{ action: :add_unique_constraint,
|
195
|
+
support_level: :nonbreaking
|
196
|
+
}
|
197
|
+
when :primary_key
|
198
|
+
{ action: :add_primary_key_constraint,
|
199
|
+
keys: key_list.value
|
200
|
+
}
|
201
|
+
else
|
202
|
+
raise "Unsupported constraint key type `#{constraint_key_type.value}"
|
203
|
+
end
|
204
|
+
end
|
205
|
+
}
|
206
|
+
/ opt_constraint constraint_key_type opt_ident key_alg nsp '(' key_list ')' normal_key_options {
|
207
|
+
def action
|
208
|
+
case constraint_key_type.value
|
209
|
+
when :unique
|
210
|
+
{ action: :add_unique_constraint,
|
211
|
+
support_level: :nonbreaking
|
212
|
+
}
|
213
|
+
when :primary_key
|
214
|
+
{ action: :add_primary_key_constraint,
|
215
|
+
keys: key_list.value
|
216
|
+
}
|
217
|
+
else
|
218
|
+
raise "Unsupported constraint key type `#{constraint_key_type.value}"
|
219
|
+
end
|
220
|
+
end
|
221
|
+
}
|
222
|
+
/ opt_constraint 'foreign'i key_sym opt_ident nsp '(' key_list ')' sp references
|
223
|
+
/ constraint_sym sp check_constraint {
|
224
|
+
def action
|
225
|
+
{ action: :add_check_constraint,
|
226
|
+
support_level: :nonbreaking,
|
227
|
+
}
|
228
|
+
end
|
229
|
+
}
|
230
|
+
/ opt_constraint check_constraint {
|
231
|
+
def action
|
232
|
+
{ action: :add_check_constraint,
|
233
|
+
support_level: :nonbreaking,
|
234
|
+
}
|
235
|
+
end
|
236
|
+
}
|
237
|
+
end
|
238
|
+
|
239
|
+
rule check_constraint
|
240
|
+
'check'i nsp '(' nsp expr nsp ')'
|
241
|
+
end
|
242
|
+
|
243
|
+
rule expr
|
244
|
+
( !')' . )+
|
245
|
+
end
|
246
|
+
|
247
|
+
rule references
|
248
|
+
'references'i sp table_ident opt_ref_list opt_match_clause opt_on_update_delete
|
249
|
+
end
|
250
|
+
|
251
|
+
rule table_ident
|
252
|
+
ident '.' ident
|
253
|
+
/ '.' ident
|
254
|
+
/ ident
|
255
|
+
end
|
256
|
+
|
257
|
+
rule opt_ref_list
|
258
|
+
( nsp '(' nsp ref_list nsp ')' )?
|
259
|
+
end
|
260
|
+
|
261
|
+
rule ref_list
|
262
|
+
ident comma ref_list
|
263
|
+
/ ident
|
264
|
+
end
|
265
|
+
|
266
|
+
rule opt_match_clause
|
267
|
+
( sp ( 'match'i sp 'full'i / 'match'i sp 'partial'i / 'match'i sp 'simple'i ) )?
|
268
|
+
end
|
269
|
+
|
270
|
+
rule opt_on_update_delete
|
271
|
+
( sp (
|
272
|
+
'on'i sp 'update'i delete_option sp 'on'i sp 'delete'i sp delete_option
|
273
|
+
/ 'on'i sp 'delete'i delete_option sp 'on'i sp 'update'i sp delete_option
|
274
|
+
/ 'on'i sp 'update'i sp delete_option
|
275
|
+
/ 'on'i sp 'delete'i sp delete_option
|
276
|
+
)
|
277
|
+
)?
|
278
|
+
end
|
279
|
+
|
280
|
+
rule delete_option
|
281
|
+
'restrict'i
|
282
|
+
/ 'cascade'i
|
283
|
+
/ 'set'i sp 'null'i
|
284
|
+
/ 'no'i sp 'action'i
|
285
|
+
/ 'set'i sp 'default'i
|
286
|
+
end
|
287
|
+
|
288
|
+
rule opt_constraint
|
289
|
+
( constraint sp )?
|
290
|
+
end
|
291
|
+
|
292
|
+
rule constraint
|
293
|
+
constraint_sym opt_ident
|
294
|
+
end
|
295
|
+
|
296
|
+
rule constraint_sym
|
297
|
+
'constraint'i
|
298
|
+
end
|
299
|
+
|
300
|
+
rule constraint_key_type
|
301
|
+
primary_sym sp key_sym {
|
302
|
+
# #value returns a normalized value of the element while #text_value
|
303
|
+
# returns its text as is
|
304
|
+
def value
|
305
|
+
:primary_key
|
306
|
+
end
|
307
|
+
}
|
308
|
+
/ unique_sym opt_key_or_index {
|
309
|
+
def value
|
310
|
+
:unique
|
311
|
+
end
|
312
|
+
}
|
313
|
+
end
|
314
|
+
|
315
|
+
rule primary_sym
|
316
|
+
'primary'i
|
317
|
+
end
|
318
|
+
|
319
|
+
rule key_sym
|
320
|
+
'key'i
|
321
|
+
end
|
322
|
+
|
323
|
+
rule keys_sym
|
324
|
+
'keys'i
|
325
|
+
end
|
326
|
+
|
327
|
+
rule unique_sym
|
328
|
+
'unique'i
|
329
|
+
end
|
330
|
+
|
331
|
+
rule index_sym
|
332
|
+
'index'i
|
333
|
+
end
|
334
|
+
|
335
|
+
rule enable_sym
|
336
|
+
'enable'i
|
337
|
+
end
|
338
|
+
|
339
|
+
rule foreign_sym
|
340
|
+
'foreign'i
|
341
|
+
end
|
342
|
+
|
343
|
+
rule fulltext
|
344
|
+
'fulltext'i
|
345
|
+
end
|
346
|
+
|
347
|
+
rule fulltext_key_options
|
348
|
+
( sp fulltext_key_opts )?
|
349
|
+
end
|
350
|
+
|
351
|
+
rule fulltext_key_opts
|
352
|
+
fulltext_key_opt sp fulltext_key_opts
|
353
|
+
/ fulltext_key_opt
|
354
|
+
end
|
355
|
+
|
356
|
+
rule fulltext_key_opt
|
357
|
+
all_key_opt
|
358
|
+
/ 'with parser'i sp ident_sys
|
359
|
+
end
|
360
|
+
|
361
|
+
rule spatial
|
362
|
+
'spatial'i
|
363
|
+
end
|
364
|
+
|
365
|
+
rule spatial_key_options
|
366
|
+
( sp spatial_key_opts )?
|
367
|
+
end
|
368
|
+
|
369
|
+
rule spatial_key_opts
|
370
|
+
spatial_key_opt sp spatial_key_opts
|
371
|
+
/ spatial_key_opt
|
372
|
+
end
|
373
|
+
|
374
|
+
rule spatial_key_opt
|
375
|
+
all_key_opt
|
376
|
+
end
|
377
|
+
|
378
|
+
rule opt_key_or_index
|
379
|
+
( sp key_or_index )?
|
380
|
+
end
|
381
|
+
|
382
|
+
rule normal_key_type
|
383
|
+
key_or_index
|
384
|
+
end
|
385
|
+
|
386
|
+
rule key_or_index
|
387
|
+
key_sym / index_sym
|
388
|
+
end
|
389
|
+
|
390
|
+
rule opt_ident
|
391
|
+
( sp field_ident )?
|
392
|
+
end
|
393
|
+
|
394
|
+
rule field_ident
|
395
|
+
ident '.' ident '.' ident
|
396
|
+
/ ident '.' ident
|
397
|
+
/ '.' ident
|
398
|
+
/ ident
|
399
|
+
end
|
400
|
+
|
401
|
+
rule key_alg
|
402
|
+
sp init_key_options key_using_alg
|
403
|
+
/ init_key_options
|
404
|
+
end
|
405
|
+
|
406
|
+
rule init_key_options
|
407
|
+
'' # In original, this is doing some initialization
|
408
|
+
end
|
409
|
+
|
410
|
+
rule key_using_alg
|
411
|
+
'using'i sp btree_or_rtree
|
412
|
+
/ type_sym sp btree_or_rtree
|
413
|
+
end
|
414
|
+
|
415
|
+
rule btree_or_rtree
|
416
|
+
'btree'i / 'rtree'i / 'hash'i
|
417
|
+
end
|
418
|
+
|
419
|
+
rule type_sym
|
420
|
+
'type'i
|
421
|
+
end
|
422
|
+
|
423
|
+
rule key_list
|
424
|
+
nsp key_part order_dir nsp ',' nsp key_list nsp {
|
425
|
+
# #value returns a normalized value of the element while #text_value
|
426
|
+
# returns its text as is
|
427
|
+
def value
|
428
|
+
order_dir_value = order_dir.value
|
429
|
+
if order_dir_value && !order_dir_value.empty?
|
430
|
+
order_dir_value = " " + order_dir_value
|
431
|
+
end
|
432
|
+
[ "#{key_part.value}#{order_dir_value}" ] + key_list.value
|
433
|
+
end
|
434
|
+
}
|
435
|
+
/ nsp key_part order_dir nsp {
|
436
|
+
def value
|
437
|
+
order_dir_value = order_dir.value
|
438
|
+
if order_dir_value && !order_dir_value.empty?
|
439
|
+
order_dir_value = " " + order_dir_value
|
440
|
+
end
|
441
|
+
[ "#{key_part.value}#{order_dir_value}" ]
|
442
|
+
end
|
443
|
+
}
|
444
|
+
end
|
445
|
+
|
446
|
+
rule key_part
|
447
|
+
ident nsp '(' nsp num nsp ')' {
|
448
|
+
# #value returns a normalized value of the element while #text_value
|
449
|
+
# returns its text as is
|
450
|
+
def value
|
451
|
+
"#{ident.value}(#{num.text_value})"
|
452
|
+
end
|
453
|
+
}
|
454
|
+
/ ident
|
455
|
+
end
|
456
|
+
|
457
|
+
rule order_dir
|
458
|
+
# Treetop creates an empty SyntaxNode if the rule results in "match none"
|
459
|
+
# The SyntaxNode instance does not have a custom method as deinfed here,
|
460
|
+
# so it causes an issue to other nodes expecting the method.
|
461
|
+
# 1..1 is a magic trick to force Treetop creating a SyntaxNode with
|
462
|
+
# the custom method.
|
463
|
+
(( sp ('asc'i / 'desc'i) )?) 1..1 {
|
464
|
+
def value
|
465
|
+
text_value.strip.downcase
|
466
|
+
end
|
467
|
+
}
|
468
|
+
end
|
469
|
+
|
470
|
+
rule normal_key_options
|
471
|
+
( sp normal_key_opts )?
|
472
|
+
end
|
473
|
+
|
474
|
+
rule normal_key_opts
|
475
|
+
normal_key_opt sp normal_key_opts
|
476
|
+
/ normal_key_opt
|
477
|
+
end
|
478
|
+
|
479
|
+
rule normal_key_opt
|
480
|
+
all_key_opt
|
481
|
+
/ key_using_alg
|
482
|
+
end
|
483
|
+
|
484
|
+
rule all_key_opt
|
485
|
+
key_block_size nsp equal nsp ulong_num
|
486
|
+
/ key_block_size sp ulong_num
|
487
|
+
/ comment_opt
|
488
|
+
end
|
489
|
+
|
490
|
+
rule opt_equal
|
491
|
+
( nsp equal )?
|
492
|
+
end
|
493
|
+
|
494
|
+
rule equal
|
495
|
+
'='
|
496
|
+
/ ':='
|
497
|
+
end
|
498
|
+
|
499
|
+
rule key_block_size
|
500
|
+
'key_block_size'i
|
90
501
|
end
|
91
502
|
|
92
503
|
rule col_name_def
|
93
504
|
col_name sp col_def {
|
94
505
|
def column_def
|
95
|
-
{column: col_name.
|
506
|
+
{column: col_name.value}.merge(col_def.column_def)
|
96
507
|
end
|
97
508
|
}
|
98
509
|
end
|
@@ -105,7 +516,7 @@ grammar MysqlAlterTable
|
|
105
516
|
}
|
106
517
|
/ 'after'i sp col_name {
|
107
518
|
def pos_def_option
|
108
|
-
{ after: col_name.
|
519
|
+
{ after: col_name.value, }
|
109
520
|
end
|
110
521
|
}
|
111
522
|
end
|
@@ -158,7 +569,7 @@ grammar MysqlAlterTable
|
|
158
569
|
end
|
159
570
|
|
160
571
|
rule data_type_name
|
161
|
-
|
572
|
+
ident_sym ''
|
162
573
|
end
|
163
574
|
|
164
575
|
rule meta_text
|
@@ -248,6 +659,14 @@ grammar MysqlAlterTable
|
|
248
659
|
[0-9]* '.' [0-9]+ { def text_value; v = super; v.start_with?('.') ? "0#{v}" : v; end }
|
249
660
|
/ [0-9]+
|
250
661
|
end
|
662
|
+
rule num
|
663
|
+
[0-9]+
|
664
|
+
end
|
665
|
+
|
666
|
+
rule ulong_num
|
667
|
+
[0-9]+ # TODO May not be the correct definition
|
668
|
+
end
|
669
|
+
|
251
670
|
rule auto_increment_opt
|
252
671
|
'auto_increment'i
|
253
672
|
end
|
@@ -325,7 +744,7 @@ grammar MysqlAlterTable
|
|
325
744
|
|
326
745
|
rule value
|
327
746
|
quoted_value { def raw_value; text_raw_value; end }
|
328
|
-
/
|
747
|
+
/ ident_sym { def raw_value; text_value; end }
|
329
748
|
end
|
330
749
|
|
331
750
|
rule quoted_value
|
@@ -333,21 +752,41 @@ grammar MysqlAlterTable
|
|
333
752
|
end
|
334
753
|
|
335
754
|
rule text
|
336
|
-
("\\\\" / "\\'" / !"'" .)*
|
755
|
+
("\\\\" / "\\'" / !"'" . )*
|
756
|
+
end
|
757
|
+
|
758
|
+
rule ident
|
759
|
+
ident_sys / keyword
|
760
|
+
end
|
761
|
+
|
762
|
+
rule keyword
|
763
|
+
([a-zA-Z_]+) 1..1 { # TODO list all keywords
|
764
|
+
def value
|
765
|
+
text_value
|
766
|
+
end
|
767
|
+
}
|
337
768
|
end
|
338
769
|
|
339
770
|
rule ident_sys
|
340
|
-
|
771
|
+
ident_sym / ident_quoted
|
341
772
|
end
|
342
773
|
|
343
|
-
rule
|
344
|
-
|
774
|
+
rule ident_sym
|
775
|
+
# 1..1 prevents Treetop from embedding the SyntaxNode to an upper node
|
776
|
+
# without the custom method.
|
777
|
+
([0-9a-zA-Z_]+) 1..1 {
|
778
|
+
def value
|
779
|
+
text_value
|
780
|
+
end
|
781
|
+
}
|
345
782
|
end
|
346
783
|
|
347
784
|
rule ident_quoted
|
348
|
-
'`'
|
349
|
-
|
350
|
-
|
785
|
+
'`' ident_sym '`' {
|
786
|
+
# #value returns a normalized value of the element while #text_value
|
787
|
+
# returns its text as is
|
788
|
+
def value
|
789
|
+
ident_sym.value
|
351
790
|
end
|
352
791
|
}
|
353
792
|
end
|