flydata 0.2.7 → 0.2.8
Sign up to get free protection for your applications and to get access to all the features.
- 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
|