flydata 0.2.10 → 0.2.11
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/Gemfile +1 -0
- data/Gemfile.lock +7 -0
- data/VERSION +1 -1
- data/benchmark/benchmark_helper.rb +4 -0
- data/benchmark/data/insert_parser_test_data.sql.gz +0 -0
- data/benchmark/data/insert_parser_test_data_num_only.sql.gz +0 -0
- data/benchmark/insert_parser_bench.rb +28 -0
- data/benchmark/insert_parser_prof.rb +24 -0
- data/flydata.gemspec +12 -5
- data/lib/flydata/fluent-plugins/in_mysql_binlog_flydata.rb +1 -1
- data/lib/flydata/parser/mysql/dump_parser.rb +33 -36
- data/lib/flydata/parser/mysql/mysql_alter_table.treetop +290 -10
- data/lib/flydata/table_def/redshift_table_def.rb +44 -4
- data/spec/flydata/fluent-plugins/in_mysql_binlog_flydata_spec.rb +2 -0
- data/spec/flydata/parser/mysql/alter_table_parser_spec.rb +195 -0
- data/spec/flydata/table_def/redshift_table_def_spec.rb +39 -4
- metadata +22 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1cf10dc736cbd2f2712294f21cf074728aab1be8
|
|
4
|
+
data.tar.gz: aba35db4a5431b33a673f4f1708601eeeaa46507
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 90939617163c3050e124607859340cc0390242a4984451bfcfb383581a8acca374853263b8358c95f5297548984fa0c15fa4bb06a70f171aed0f99e2eca7fa37
|
|
7
|
+
data.tar.gz: f69a0c50a94ba780577fcc5877e10d4d2059f6de3ffaed1145b6509ca11b21500a7ea5a36cab7f47c559023e4b23ed25612c50c31c6ca7e3ed29c7262fd0c472
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
|
@@ -20,6 +20,7 @@ GEM
|
|
|
20
20
|
addressable (2.3.6)
|
|
21
21
|
arel (4.0.2)
|
|
22
22
|
builder (3.1.4)
|
|
23
|
+
coderay (1.1.0)
|
|
23
24
|
cool.io (1.2.4)
|
|
24
25
|
diff-lcs (1.2.5)
|
|
25
26
|
faraday (0.8.9)
|
|
@@ -60,6 +61,7 @@ GEM
|
|
|
60
61
|
jwt (1.0.0)
|
|
61
62
|
kodama (0.1.1)
|
|
62
63
|
ruby-binlog (>= 0.1.9)
|
|
64
|
+
method_source (0.8.2)
|
|
63
65
|
mime-types (2.3)
|
|
64
66
|
minitest (4.7.5)
|
|
65
67
|
msgpack (0.5.8)
|
|
@@ -78,6 +80,10 @@ GEM
|
|
|
78
80
|
polyglot (0.3.5)
|
|
79
81
|
protected_attributes (1.0.8)
|
|
80
82
|
activemodel (>= 4.0.1, < 5.0)
|
|
83
|
+
pry (0.10.1)
|
|
84
|
+
coderay (~> 1.1.0)
|
|
85
|
+
method_source (~> 0.8.1)
|
|
86
|
+
slop (~> 3.4)
|
|
81
87
|
rack (1.5.2)
|
|
82
88
|
rake (10.3.2)
|
|
83
89
|
rdoc (4.1.1)
|
|
@@ -124,6 +130,7 @@ DEPENDENCIES
|
|
|
124
130
|
json (~> 1.8, >= 1.8.0)
|
|
125
131
|
mysql2 (~> 0.3, >= 0.3.11)
|
|
126
132
|
protected_attributes (~> 1.0, >= 1.0.8)
|
|
133
|
+
pry
|
|
127
134
|
rest-client (~> 1.6, >= 1.6.7)
|
|
128
135
|
rspec (~> 3.0)
|
|
129
136
|
ruby-binlog (~> 1.0, >= 1.0.1)
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.2.
|
|
1
|
+
0.2.11
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
require_relative 'benchmark_helper'
|
|
2
|
+
require 'flydata/parser/mysql/dump_parser'
|
|
3
|
+
require 'zlib'
|
|
4
|
+
|
|
5
|
+
INSERT_TEST_FILE_NAME = case ARGV[0]
|
|
6
|
+
when 'num'
|
|
7
|
+
'insert_parser_test_data_num_only.sql.gz'
|
|
8
|
+
else
|
|
9
|
+
'insert_parser_test_data.sql.gz'
|
|
10
|
+
end
|
|
11
|
+
INSERT_TEST_FILE_PATH = File.realpath("data/#{INSERT_TEST_FILE_NAME}", File.dirname(__FILE__))
|
|
12
|
+
def readline_gz_file(gz_file_path = INSERT_TEST_FILE_PATH)
|
|
13
|
+
Zlib::GzipReader.open(gz_file_path) {|f| return f.readline}
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
@test_line = readline_gz_file
|
|
17
|
+
|
|
18
|
+
def subject
|
|
19
|
+
Flydata::Parser::Mysql::MysqlDumpParser::InsertParser.new.parse(@test_line)
|
|
20
|
+
Flydata::Parser::Mysql::MysqlDumpParser::InsertParser.new.parse(@test_line)
|
|
21
|
+
Flydata::Parser::Mysql::MysqlDumpParser::InsertParser.new.parse(@test_line)
|
|
22
|
+
Flydata::Parser::Mysql::MysqlDumpParser::InsertParser.new.parse(@test_line)
|
|
23
|
+
Flydata::Parser::Mysql::MysqlDumpParser::InsertParser.new.parse(@test_line)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
Benchmark.bm do |x|
|
|
27
|
+
x.report { 10.times{ subject } }
|
|
28
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
require_relative 'benchmark_helper'
|
|
2
|
+
require 'flydata/parser/mysql/dump_parser'
|
|
3
|
+
require 'zlib'
|
|
4
|
+
require 'ruby-prof'
|
|
5
|
+
|
|
6
|
+
INSERT_TEST_FILE_NAME = case ARGV[0]
|
|
7
|
+
when 'num'
|
|
8
|
+
'insert_parser_test_data_num_only.sql.gz'
|
|
9
|
+
else
|
|
10
|
+
'insert_parser_test_data.sql.gz'
|
|
11
|
+
end
|
|
12
|
+
INSERT_TEST_FILE_PATH = File.realpath("data/#{INSERT_TEST_FILE_NAME}", File.dirname(__FILE__))
|
|
13
|
+
|
|
14
|
+
def readline_gz_file(gz_file_path = INSERT_TEST_FILE_PATH)
|
|
15
|
+
Zlib::GzipReader.open(gz_file_path) {|f| return f.readline}
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
@test_line = readline_gz_file
|
|
19
|
+
|
|
20
|
+
def subject
|
|
21
|
+
Flydata::Parser::Mysql::MysqlDumpParser::InsertParser.new.parse(@test_line)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
subject
|
data/flydata.gemspec
CHANGED
|
@@ -2,16 +2,14 @@
|
|
|
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.10 ruby lib
|
|
6
5
|
|
|
7
6
|
Gem::Specification.new do |s|
|
|
8
7
|
s.name = "flydata"
|
|
9
|
-
s.version = "0.2.
|
|
8
|
+
s.version = "0.2.11"
|
|
10
9
|
|
|
11
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
|
12
|
-
s.require_paths = ["lib"]
|
|
13
11
|
s.authors = ["Koichi Fujikawa", "Masashi Miyazaki", "Matthew Luu", "Mak Inada", "Sriram NS"]
|
|
14
|
-
s.date = "2014-10-
|
|
12
|
+
s.date = "2014-10-31"
|
|
15
13
|
s.description = "FlyData Agent"
|
|
16
14
|
s.email = "sysadmin@flydata.com"
|
|
17
15
|
s.executables = ["fdmysqldump", "flydata", "serverinfo"]
|
|
@@ -22,6 +20,11 @@ Gem::Specification.new do |s|
|
|
|
22
20
|
"Gemfile.lock",
|
|
23
21
|
"Rakefile",
|
|
24
22
|
"VERSION",
|
|
23
|
+
"benchmark/benchmark_helper.rb",
|
|
24
|
+
"benchmark/data/insert_parser_test_data.sql.gz",
|
|
25
|
+
"benchmark/data/insert_parser_test_data_num_only.sql.gz",
|
|
26
|
+
"benchmark/insert_parser_bench.rb",
|
|
27
|
+
"benchmark/insert_parser_prof.rb",
|
|
25
28
|
"bin/fdmysqldump",
|
|
26
29
|
"bin/flydata",
|
|
27
30
|
"bin/serverinfo",
|
|
@@ -115,7 +118,8 @@ Gem::Specification.new do |s|
|
|
|
115
118
|
]
|
|
116
119
|
s.homepage = "http://flydata.com/"
|
|
117
120
|
s.licenses = ["All right reserved."]
|
|
118
|
-
s.
|
|
121
|
+
s.require_paths = ["lib"]
|
|
122
|
+
s.rubygems_version = "2.0.14"
|
|
119
123
|
s.summary = "FlyData Agent"
|
|
120
124
|
|
|
121
125
|
if s.respond_to? :specification_version then
|
|
@@ -141,6 +145,7 @@ Gem::Specification.new do |s|
|
|
|
141
145
|
s.add_development_dependency(%q<activemodel>, [">= 4.0.0", "~> 4.0"])
|
|
142
146
|
s.add_development_dependency(%q<activerecord>, [">= 4.0.0", "~> 4.0"])
|
|
143
147
|
s.add_development_dependency(%q<protected_attributes>, [">= 1.0.8", "~> 1.0"])
|
|
148
|
+
s.add_development_dependency(%q<pry>, [">= 0"])
|
|
144
149
|
else
|
|
145
150
|
s.add_dependency(%q<rest-client>, [">= 1.6.7", "~> 1.6"])
|
|
146
151
|
s.add_dependency(%q<i18n>, [">= 0.6.5", "~> 0.6"])
|
|
@@ -161,6 +166,7 @@ Gem::Specification.new do |s|
|
|
|
161
166
|
s.add_dependency(%q<activemodel>, [">= 4.0.0", "~> 4.0"])
|
|
162
167
|
s.add_dependency(%q<activerecord>, [">= 4.0.0", "~> 4.0"])
|
|
163
168
|
s.add_dependency(%q<protected_attributes>, [">= 1.0.8", "~> 1.0"])
|
|
169
|
+
s.add_dependency(%q<pry>, [">= 0"])
|
|
164
170
|
end
|
|
165
171
|
else
|
|
166
172
|
s.add_dependency(%q<rest-client>, [">= 1.6.7", "~> 1.6"])
|
|
@@ -182,6 +188,7 @@ Gem::Specification.new do |s|
|
|
|
182
188
|
s.add_dependency(%q<activemodel>, [">= 4.0.0", "~> 4.0"])
|
|
183
189
|
s.add_dependency(%q<activerecord>, [">= 4.0.0", "~> 4.0"])
|
|
184
190
|
s.add_dependency(%q<protected_attributes>, [">= 1.0.8", "~> 1.0"])
|
|
191
|
+
s.add_dependency(%q<pry>, [">= 0"])
|
|
185
192
|
end
|
|
186
193
|
end
|
|
187
194
|
|
|
@@ -58,7 +58,7 @@ class MysqlBinlogFlydataInput < MysqlBinlogInput
|
|
|
58
58
|
load_custom_conf
|
|
59
59
|
$log.info "mysql host:\"#{@host}\" port:\"#{@port}\" username:\"#{@username}\" database:\"#{@database}\" tables:\"#{@tables}\" tables_append_only:\"#{tables_append_only}\""
|
|
60
60
|
$log.info "mysql client version: #{`mysql -V`}"
|
|
61
|
-
server_version = `echo 'select version();' | mysql -h #{@host} --port #{@port} -u #{@username}
|
|
61
|
+
server_version = `echo 'select version();' | MYSQL_PWD="#{@password}" mysql -h #{@host} --port #{@port} -u #{@username} 2>/dev/null`
|
|
62
62
|
$log.info "mysql server version: #{server_version}"
|
|
63
63
|
|
|
64
64
|
@tables = @tables.split(/,\s*/)
|
|
@@ -428,15 +428,6 @@ EOS
|
|
|
428
428
|
# ex) INSERT INTO `data_entries` VALUES (2,2,'access_log'), (2,3,'access_log2');
|
|
429
429
|
class InsertParser
|
|
430
430
|
#INSERT INTO `data_entries` VALUES (2,2,'access_log'), (2,3,'access_log2');
|
|
431
|
-
module State
|
|
432
|
-
IN_VALUE = 'IN_VALUE'
|
|
433
|
-
NEXT_VALUES = 'NEXT_VALUES'
|
|
434
|
-
end
|
|
435
|
-
|
|
436
|
-
def initialize
|
|
437
|
-
@values = []
|
|
438
|
-
@values_set = []
|
|
439
|
-
end
|
|
440
431
|
|
|
441
432
|
def start_ruby_prof
|
|
442
433
|
RubyProf.start if defined?(RubyProf) and not RubyProf.running?
|
|
@@ -466,6 +457,9 @@ EOS
|
|
|
466
457
|
private
|
|
467
458
|
|
|
468
459
|
def _parse(target_line)
|
|
460
|
+
values = []
|
|
461
|
+
values_set = []
|
|
462
|
+
|
|
469
463
|
target_line = target_line.strip
|
|
470
464
|
start_index = target_line.index('(')
|
|
471
465
|
target_line = target_line[start_index..-2]
|
|
@@ -477,48 +471,49 @@ EOS
|
|
|
477
471
|
# 'String#each_char' is twice as slow as the current storategy.
|
|
478
472
|
items = target_line.split(',')
|
|
479
473
|
index = 0
|
|
480
|
-
cur_state =
|
|
474
|
+
cur_state = :next_values
|
|
481
475
|
|
|
482
476
|
loop do
|
|
483
477
|
case cur_state
|
|
484
|
-
when
|
|
478
|
+
when :next_values
|
|
485
479
|
chars = items[index]
|
|
486
480
|
break unless chars
|
|
487
481
|
items[index] = chars[1..-1]
|
|
488
|
-
cur_state =
|
|
489
|
-
when
|
|
482
|
+
cur_state = :in_value
|
|
483
|
+
when :in_value
|
|
490
484
|
chars = items[index]
|
|
491
485
|
index += 1
|
|
492
486
|
if chars.start_with?("'")
|
|
487
|
+
chars_size = chars.size
|
|
493
488
|
# single item (not last item)
|
|
494
489
|
# size check added below otherwise end_with? matches the single quote which was also used by start_with?
|
|
495
|
-
if
|
|
496
|
-
|
|
490
|
+
if chars_size > 1 and chars.end_with?("'") and !(chars.end_with?("\\'") and last_char_escaped?(chars))
|
|
491
|
+
values << (chars[1..-2]).gsub(ESCAPE_REGEXP, ESCAPE_HASH_TABLE)
|
|
497
492
|
# single item (last item)
|
|
498
493
|
# size check added below otherwise end_with? matches the single quote which was also used by start_with?
|
|
499
|
-
elsif
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
cur_state =
|
|
494
|
+
elsif chars_size > 2 and chars.end_with?("')") and !(chars[0..-2].end_with?("\\'") and last_char_escaped?(chars[0..-2]))
|
|
495
|
+
values << (chars[1..-3]).gsub(ESCAPE_REGEXP, ESCAPE_HASH_TABLE)
|
|
496
|
+
values_set << values
|
|
497
|
+
values = []
|
|
498
|
+
cur_state = :next_values
|
|
504
499
|
# multi items
|
|
505
500
|
else
|
|
506
501
|
cur_value = chars[1..-1]
|
|
507
502
|
loop do
|
|
508
503
|
next_chars = items[index]
|
|
509
504
|
index += 1
|
|
510
|
-
if next_chars.end_with?('\'') and !last_char_escaped?(next_chars)
|
|
505
|
+
if next_chars.end_with?('\'') and !(next_chars.end_with?("\\'") and last_char_escaped?(next_chars))
|
|
511
506
|
cur_value << ','
|
|
512
507
|
cur_value << next_chars[0..-2]
|
|
513
|
-
|
|
508
|
+
values << (cur_value).gsub(ESCAPE_REGEXP, ESCAPE_HASH_TABLE)
|
|
514
509
|
break
|
|
515
|
-
elsif next_chars.end_with?("')") and !last_char_escaped?(next_chars[0..-2])
|
|
510
|
+
elsif next_chars.end_with?("')") and !(next_chars[0..-2].end_with?("\\'") and last_char_escaped?(next_chars[0..-2]))
|
|
516
511
|
cur_value << ','
|
|
517
512
|
cur_value << next_chars[0..-3]
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
cur_state =
|
|
513
|
+
values << (cur_value).gsub(ESCAPE_REGEXP, ESCAPE_HASH_TABLE)
|
|
514
|
+
values_set << values
|
|
515
|
+
values = []
|
|
516
|
+
cur_state = :next_values
|
|
522
517
|
break
|
|
523
518
|
else
|
|
524
519
|
cur_value << ','
|
|
@@ -529,26 +524,28 @@ EOS
|
|
|
529
524
|
else
|
|
530
525
|
if chars.end_with?(')')
|
|
531
526
|
chars = chars[0..-2]
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
cur_state =
|
|
527
|
+
values << (chars == 'NULL' ? nil : remove_leading_zeros(chars))
|
|
528
|
+
values_set << values
|
|
529
|
+
values = []
|
|
530
|
+
cur_state = :next_values
|
|
536
531
|
else
|
|
537
|
-
|
|
532
|
+
values << (chars == 'NULL' ? nil : remove_leading_zeros(chars))
|
|
538
533
|
end
|
|
539
534
|
end
|
|
540
535
|
else
|
|
541
536
|
raise "Invalid state: #{cur_state}"
|
|
542
537
|
end
|
|
543
538
|
end
|
|
544
|
-
return
|
|
539
|
+
return values_set
|
|
545
540
|
end
|
|
546
541
|
|
|
542
|
+
ESCAPE_REGEXP = /\\\\|\\'|\\"|\\n|\\r/
|
|
547
543
|
ESCAPE_HASH_TABLE = {"\\\\" => "\\", "\\'" => "'", "\\\"" => "\"", "\\n" => "\n", "\\r" => "\r"}
|
|
548
544
|
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
545
|
+
# For the peformance, this function is put inline.
|
|
546
|
+
#def replace_escape_char(original)
|
|
547
|
+
# original.gsub(ESCAPE_REGEXP, ESCAPE_HASH_TABLE)
|
|
548
|
+
#end
|
|
552
549
|
|
|
553
550
|
# This method assume that the last character is '(single quotation)
|
|
554
551
|
# abcd\' -> true
|
|
@@ -54,39 +54,46 @@ grammar MysqlAlterTable
|
|
|
54
54
|
}]
|
|
55
55
|
end
|
|
56
56
|
}
|
|
57
|
-
/
|
|
58
|
-
alter_specs (sp partition_opts)? {
|
|
57
|
+
/ ( partition_rules ) 1..1 { # This does not exist in sql_yacc.yy
|
|
59
58
|
def actions
|
|
60
|
-
|
|
59
|
+
action = elements[0].action
|
|
60
|
+
action[:query] = text_value
|
|
61
|
+
action[:support_level] = :nonbreaking
|
|
62
|
+
[action]
|
|
63
|
+
end
|
|
64
|
+
}
|
|
65
|
+
/ alter_list (sp partition_opts)? {
|
|
66
|
+
def actions
|
|
67
|
+
alter_list.actions
|
|
61
68
|
end
|
|
62
69
|
}
|
|
63
70
|
end
|
|
64
71
|
|
|
65
|
-
rule
|
|
66
|
-
|
|
72
|
+
rule alter_list
|
|
73
|
+
alter_list_item ( comma alter_list_item )* {
|
|
67
74
|
def actions
|
|
68
75
|
ret = []
|
|
69
|
-
ret.concat(actions_with_query(
|
|
76
|
+
ret.concat(actions_with_query(alter_list_item))
|
|
70
77
|
0.upto(elements[1].elements.size - 1) do |i|
|
|
71
78
|
ret.concat(actions_with_query(elements[1].elements[i].elements[1]))
|
|
72
79
|
end
|
|
73
80
|
ret
|
|
74
81
|
end
|
|
75
82
|
|
|
76
|
-
def actions_with_query(
|
|
77
|
-
action =
|
|
83
|
+
def actions_with_query(alter_list_item)
|
|
84
|
+
action = alter_list_item.action
|
|
78
85
|
if action.kind_of?(Array)
|
|
79
86
|
actions = action
|
|
80
87
|
else
|
|
81
88
|
actions = [action]
|
|
82
89
|
end
|
|
83
|
-
actions.each {|a| a[:query] =
|
|
90
|
+
actions.each {|a| a[:query] = alter_list_item.text_value }
|
|
84
91
|
actions
|
|
85
92
|
end
|
|
86
93
|
}
|
|
87
94
|
end
|
|
88
95
|
|
|
89
|
-
rule
|
|
96
|
+
rule alter_list_item
|
|
90
97
|
add_key sp key_def {
|
|
91
98
|
def action
|
|
92
99
|
action_hash = key_def.action
|
|
@@ -730,6 +737,10 @@ grammar MysqlAlterTable
|
|
|
730
737
|
[0-9]+ # TODO May not be the correct definition
|
|
731
738
|
end
|
|
732
739
|
|
|
740
|
+
rule real_ulong_num
|
|
741
|
+
[0-9]+ # TODO - May have to expand later
|
|
742
|
+
end
|
|
743
|
+
|
|
733
744
|
rule auto_increment_opt
|
|
734
745
|
'auto_increment'i
|
|
735
746
|
end
|
|
@@ -1018,4 +1029,273 @@ grammar MysqlAlterTable
|
|
|
1018
1029
|
rule dot
|
|
1019
1030
|
'.'
|
|
1020
1031
|
end
|
|
1032
|
+
|
|
1033
|
+
## Partition related rules
|
|
1034
|
+
|
|
1035
|
+
rule partition_rules
|
|
1036
|
+
add_partition_rule {
|
|
1037
|
+
def action
|
|
1038
|
+
{ action: :add_partition }
|
|
1039
|
+
end
|
|
1040
|
+
}
|
|
1041
|
+
/ drop_sym sp partition_sym sp alt_part_name_list {
|
|
1042
|
+
def action
|
|
1043
|
+
{ action: :drop_partition }
|
|
1044
|
+
end
|
|
1045
|
+
}
|
|
1046
|
+
/ rebuild_sym sp partition_sym opt_no_write_to_binlog sp all_or_alt_part_name_list {
|
|
1047
|
+
def action
|
|
1048
|
+
{ action: :rebuild_partition }
|
|
1049
|
+
end
|
|
1050
|
+
}
|
|
1051
|
+
/ optimize_sym sp partition_sym opt_no_write_to_binlog sp all_or_alt_part_name_list {
|
|
1052
|
+
def action
|
|
1053
|
+
{ action: :optimize_partition }
|
|
1054
|
+
end
|
|
1055
|
+
}
|
|
1056
|
+
/ analyze_sym sp partition_sym opt_no_write_to_binlog sp all_or_alt_part_name_list {
|
|
1057
|
+
def action
|
|
1058
|
+
{ action: :analyze_partition }
|
|
1059
|
+
end
|
|
1060
|
+
}
|
|
1061
|
+
/ check_sym sp partition_sym sp all_or_alt_part_name_list opt_mi_check_type {
|
|
1062
|
+
def action
|
|
1063
|
+
{ action: :check_partition }
|
|
1064
|
+
end
|
|
1065
|
+
}
|
|
1066
|
+
/ repair_sym sp partition_sym opt_no_write_to_binlog sp all_or_alt_part_name_list opt_mi_repair_type {
|
|
1067
|
+
def action
|
|
1068
|
+
{ action: :repair_partition }
|
|
1069
|
+
end
|
|
1070
|
+
}
|
|
1071
|
+
/ coalesce_sym sp partition_sym opt_no_write_to_binlog sp real_ulong_num {
|
|
1072
|
+
def action
|
|
1073
|
+
{ action: :coalesce_partition }
|
|
1074
|
+
end
|
|
1075
|
+
}
|
|
1076
|
+
/ truncate_sym sp partition_sym sp all_or_alt_part_name_list {
|
|
1077
|
+
def action
|
|
1078
|
+
{ action: :truncate_partition }
|
|
1079
|
+
end
|
|
1080
|
+
}
|
|
1081
|
+
/ reorg_partition_rule {
|
|
1082
|
+
def action
|
|
1083
|
+
{ action: :reorganize_partition }
|
|
1084
|
+
end
|
|
1085
|
+
}
|
|
1086
|
+
/ exchange_sym sp partition_sym sp alt_part_name_item sp
|
|
1087
|
+
with_sym sp table_sym sp table_ident opt_validation {
|
|
1088
|
+
def action
|
|
1089
|
+
{ action: :exchange_partition }
|
|
1090
|
+
end
|
|
1091
|
+
}
|
|
1092
|
+
/ discard_sym sp partition_sym sp all_or_alt_part_name_list sp tablespace_sym {
|
|
1093
|
+
def action
|
|
1094
|
+
{ action: :discard_partition_tablespace }
|
|
1095
|
+
end
|
|
1096
|
+
}
|
|
1097
|
+
/ import_sym sp partition_sym sp all_or_alt_part_name_list sp tablespace_sym {
|
|
1098
|
+
def action
|
|
1099
|
+
{ action: :import_partition_tablespace }
|
|
1100
|
+
end
|
|
1101
|
+
}
|
|
1102
|
+
/ remove_partitioning {
|
|
1103
|
+
def action
|
|
1104
|
+
{ action: :remove_partitioning }
|
|
1105
|
+
end
|
|
1106
|
+
}
|
|
1107
|
+
end
|
|
1108
|
+
|
|
1109
|
+
rule remove_partitioning
|
|
1110
|
+
remove_sym sp partitioning_sym
|
|
1111
|
+
end
|
|
1112
|
+
|
|
1113
|
+
rule add_partition_rule
|
|
1114
|
+
add_sym sp partition_sym opt_no_write_to_binlog nsp add_part_extra
|
|
1115
|
+
end
|
|
1116
|
+
|
|
1117
|
+
rule reorg_partition_rule
|
|
1118
|
+
reorganize_sym sp partition_sym opt_no_write_to_binlog nsp reorg_parts_rule
|
|
1119
|
+
end
|
|
1120
|
+
|
|
1121
|
+
rule opt_validation
|
|
1122
|
+
( sp (with_sym / without_sym) sp validation_sym )?
|
|
1123
|
+
end
|
|
1124
|
+
|
|
1125
|
+
rule remove_sym
|
|
1126
|
+
'remove'i ![A-Za-z0-9_]
|
|
1127
|
+
end
|
|
1128
|
+
|
|
1129
|
+
rule all_sym
|
|
1130
|
+
'all'i ![A-Za-z0-9_]
|
|
1131
|
+
end
|
|
1132
|
+
|
|
1133
|
+
rule check_sym
|
|
1134
|
+
'check'i ![A-Za-z0-9_]
|
|
1135
|
+
end
|
|
1136
|
+
|
|
1137
|
+
rule table_sym
|
|
1138
|
+
'table'i ![A-Za-z0-9_]
|
|
1139
|
+
end
|
|
1140
|
+
|
|
1141
|
+
rule with_sym
|
|
1142
|
+
'with'i ![A-Za-z0-9_]
|
|
1143
|
+
end
|
|
1144
|
+
|
|
1145
|
+
rule without_sym
|
|
1146
|
+
'without'i ![A-Za-z0-9_]
|
|
1147
|
+
end
|
|
1148
|
+
|
|
1149
|
+
rule validation_sym
|
|
1150
|
+
'validation'i ![A-Za-z0-9_]
|
|
1151
|
+
end
|
|
1152
|
+
|
|
1153
|
+
rule exchange_sym
|
|
1154
|
+
'exchange'i ![A-Za-z0-9_]
|
|
1155
|
+
end
|
|
1156
|
+
|
|
1157
|
+
rule reorganize_sym
|
|
1158
|
+
'reorganize'i ![A-Za-z0-9_]
|
|
1159
|
+
end
|
|
1160
|
+
|
|
1161
|
+
rule truncate_sym
|
|
1162
|
+
'truncate'i ![A-Za-z0-9_]
|
|
1163
|
+
end
|
|
1164
|
+
|
|
1165
|
+
rule coalesce_sym
|
|
1166
|
+
'coalesce'i ![A-Za-z0-9_]
|
|
1167
|
+
end
|
|
1168
|
+
|
|
1169
|
+
rule repair_sym
|
|
1170
|
+
'repair'i ![A-Za-z0-9_]
|
|
1171
|
+
end
|
|
1172
|
+
|
|
1173
|
+
rule analyze_sym
|
|
1174
|
+
'analyze'i ![A-Za-z0-9_]
|
|
1175
|
+
end
|
|
1176
|
+
|
|
1177
|
+
rule optimize_sym
|
|
1178
|
+
'optimize'i ![A-Za-z0-9_]
|
|
1179
|
+
end
|
|
1180
|
+
|
|
1181
|
+
rule rebuild_sym
|
|
1182
|
+
'rebuild'i ![A-Za-z0-9_]
|
|
1183
|
+
end
|
|
1184
|
+
|
|
1185
|
+
rule drop_sym
|
|
1186
|
+
'drop'i ![A-Za-z0-9_]
|
|
1187
|
+
end
|
|
1188
|
+
|
|
1189
|
+
rule add_sym
|
|
1190
|
+
'add'i ![A-Za-z0-9_]
|
|
1191
|
+
end
|
|
1192
|
+
|
|
1193
|
+
rule partition_sym
|
|
1194
|
+
'partition'i ![A-Za-z0-9_]
|
|
1195
|
+
end
|
|
1196
|
+
|
|
1197
|
+
rule partitioning_sym
|
|
1198
|
+
'partitioning'i ![A-Za-z0-9_]
|
|
1199
|
+
end
|
|
1200
|
+
|
|
1201
|
+
rule local_sym
|
|
1202
|
+
'local'i ![A-Za-z0-9_]
|
|
1203
|
+
end
|
|
1204
|
+
|
|
1205
|
+
rule for_sym
|
|
1206
|
+
'for'i ![A-Za-z0-9_]
|
|
1207
|
+
end
|
|
1208
|
+
|
|
1209
|
+
rule upgrade_sym
|
|
1210
|
+
'upgrade'i ![A-Za-z0-9_]
|
|
1211
|
+
end
|
|
1212
|
+
|
|
1213
|
+
rule changed_sym
|
|
1214
|
+
'changed'i ![A-Za-z0-9_]
|
|
1215
|
+
end
|
|
1216
|
+
|
|
1217
|
+
rule extended_sym
|
|
1218
|
+
'extended'i ![A-Za-z0-9_]
|
|
1219
|
+
end
|
|
1220
|
+
|
|
1221
|
+
rule medium_sym
|
|
1222
|
+
'medium'i ![A-Za-z0-9_]
|
|
1223
|
+
end
|
|
1224
|
+
|
|
1225
|
+
rule fast_sym
|
|
1226
|
+
'fast'i ![A-Za-z0-9_]
|
|
1227
|
+
end
|
|
1228
|
+
|
|
1229
|
+
rule quick_sym
|
|
1230
|
+
'quick'i ![A-Za-z0-9_]
|
|
1231
|
+
end
|
|
1232
|
+
|
|
1233
|
+
rule use_frm_sym
|
|
1234
|
+
'use_frm'i ![A-Za-z0-9_]
|
|
1235
|
+
end
|
|
1236
|
+
|
|
1237
|
+
# query we parse may never have this, including for the sake of completeness
|
|
1238
|
+
rule no_write_to_binlog_sym
|
|
1239
|
+
'no_write_to_binlog'i ![A-Za-z0-9_]
|
|
1240
|
+
end
|
|
1241
|
+
|
|
1242
|
+
rule opt_no_write_to_binlog
|
|
1243
|
+
( sp (no_write_to_binlog_sym / local_sym) )?
|
|
1244
|
+
end
|
|
1245
|
+
|
|
1246
|
+
# Generic implementation(matches anything). Should be modified when required
|
|
1247
|
+
rule add_part_extra
|
|
1248
|
+
.*
|
|
1249
|
+
end
|
|
1250
|
+
|
|
1251
|
+
# Generic implementation (matches anything). Should be modified when required
|
|
1252
|
+
rule reorg_parts_rule
|
|
1253
|
+
.*
|
|
1254
|
+
end
|
|
1255
|
+
|
|
1256
|
+
rule all_or_alt_part_name_list
|
|
1257
|
+
all_sym / alt_part_name_list
|
|
1258
|
+
end
|
|
1259
|
+
|
|
1260
|
+
rule alt_part_name_list
|
|
1261
|
+
alt_part_name_item comma alt_part_name_list
|
|
1262
|
+
/ alt_part_name_item
|
|
1263
|
+
end
|
|
1264
|
+
|
|
1265
|
+
rule alt_part_name_item
|
|
1266
|
+
ident
|
|
1267
|
+
end
|
|
1268
|
+
|
|
1269
|
+
rule opt_mi_check_type
|
|
1270
|
+
( sp mi_check_types )?
|
|
1271
|
+
end
|
|
1272
|
+
|
|
1273
|
+
rule mi_check_types
|
|
1274
|
+
mi_check_type sp mi_check_types
|
|
1275
|
+
/ mi_check_type
|
|
1276
|
+
end
|
|
1277
|
+
|
|
1278
|
+
rule mi_check_type
|
|
1279
|
+
quick_sym
|
|
1280
|
+
/ fast_sym
|
|
1281
|
+
/ medium_sym
|
|
1282
|
+
/ extended_sym
|
|
1283
|
+
/ changed_sym
|
|
1284
|
+
/ for_sym sp upgrade_sym
|
|
1285
|
+
end
|
|
1286
|
+
|
|
1287
|
+
rule opt_mi_repair_type
|
|
1288
|
+
( sp mi_repair_types )?
|
|
1289
|
+
end
|
|
1290
|
+
|
|
1291
|
+
rule mi_repair_types
|
|
1292
|
+
mi_repair_type sp mi_repair_types
|
|
1293
|
+
/ mi_repair_type
|
|
1294
|
+
end
|
|
1295
|
+
|
|
1296
|
+
rule mi_repair_type
|
|
1297
|
+
quick_sym
|
|
1298
|
+
/ extended_sym
|
|
1299
|
+
/ use_frm_sym
|
|
1300
|
+
end
|
|
1021
1301
|
end
|
|
@@ -119,13 +119,21 @@ EOS
|
|
|
119
119
|
line
|
|
120
120
|
end
|
|
121
121
|
|
|
122
|
+
NULL_STR = "NULL"
|
|
123
|
+
|
|
122
124
|
def self.replace_default_value(type, default_value)
|
|
123
|
-
|
|
125
|
+
return NULL_STR if default_value.nil?
|
|
124
126
|
case type
|
|
125
127
|
when 'timestamp'
|
|
126
|
-
|
|
128
|
+
if default_value.upcase == "CURRENT_TIMESTAMP"
|
|
129
|
+
'SYSDATE'
|
|
130
|
+
else
|
|
131
|
+
"'#{self.parse_timestamp(default_value)}'"
|
|
132
|
+
end
|
|
133
|
+
when 'date'
|
|
134
|
+
"'#{self.parse_date(default_value)}'"
|
|
127
135
|
else
|
|
128
|
-
|
|
136
|
+
"'#{default_value}'"
|
|
129
137
|
end
|
|
130
138
|
end
|
|
131
139
|
|
|
@@ -165,7 +173,7 @@ EOS
|
|
|
165
173
|
def self.escape(text)
|
|
166
174
|
text.gsub("'", "\\\\'")
|
|
167
175
|
end
|
|
168
|
-
|
|
176
|
+
|
|
169
177
|
def self.check_and_replace_max(params, max_size_a)
|
|
170
178
|
final_params = []
|
|
171
179
|
params.split(",").each_with_index do |param, i|
|
|
@@ -174,6 +182,38 @@ EOS
|
|
|
174
182
|
end
|
|
175
183
|
final_params.join(",")
|
|
176
184
|
end
|
|
185
|
+
|
|
186
|
+
APACHE_TIMESTAMP_REGEXP = Regexp.new('^(?<apache_time_format>\[[0-3]\d\/\D{3}\/[1-2]\d{3}:[0-2]\d:[0-5]\d:[0-5]\d ?[\+\-]\d{2}:?\d{2}\])$')
|
|
187
|
+
|
|
188
|
+
def self.parse_timestamp(value)
|
|
189
|
+
if value.kind_of?(Integer) or /^\d+$/ === value
|
|
190
|
+
# Unix epoch in UTC
|
|
191
|
+
t = DateTime.strptime(value.to_s, '%s')
|
|
192
|
+
elsif APACHE_TIMESTAMP_REGEXP.match(value)
|
|
193
|
+
# apache time format
|
|
194
|
+
t = DateTime.strptime(value, "[%d/%b/%Y:%H:%M:%S %Z]")
|
|
195
|
+
else
|
|
196
|
+
t = DateTime.parse(value)
|
|
197
|
+
end
|
|
198
|
+
t = t.new_offset(0) # Redshift Plug-in uses UTC
|
|
199
|
+
t.strftime('%Y-%m-%d %H:%M:%S.%6N')
|
|
200
|
+
rescue ArgumentError => ae
|
|
201
|
+
# '0000-00-00 00:00:00' is valid for mysql datetime column
|
|
202
|
+
if value.start_with?('0000-00-00 00:00:00')
|
|
203
|
+
return '0001-01-01 00:00:00.000000'
|
|
204
|
+
else
|
|
205
|
+
raise ae
|
|
206
|
+
end
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
def self.parse_date(value)
|
|
210
|
+
dt = Date.parse(value)
|
|
211
|
+
dt.strftime('%Y-%m-%d')
|
|
212
|
+
rescue ArgumentError => ae
|
|
213
|
+
# '0000-00-00' is valid for mysql date column
|
|
214
|
+
return '0001-01-01' if value == '0000-00-00'
|
|
215
|
+
raise ae
|
|
216
|
+
end
|
|
177
217
|
end
|
|
178
218
|
|
|
179
219
|
end
|
|
@@ -225,6 +225,8 @@ EOT
|
|
|
225
225
|
setup_initial_flydata_files
|
|
226
226
|
allow(MysqlBinlogInput::BinlogUtil).to receive(:to_hash) {|e| e}
|
|
227
227
|
allow(Mysql::BinLogPositionFile).to receive(:new).with(TEST_POSITION_FILE).and_return(binlog_position_file)
|
|
228
|
+
allow(plugin).to receive(:`).with("mysql -V").and_return("mysql Ver 14.14 Distrib 5.5.40")
|
|
229
|
+
allow(plugin).to receive(:`).with(/^echo 'select version\(\);'/).and_return("version()\n5.5.40-0ubuntu0.12.04.1-log")
|
|
228
230
|
Timecop.freeze(now)
|
|
229
231
|
end
|
|
230
232
|
|
|
@@ -860,6 +860,90 @@ describe 'MysqlAlterTableParser' do
|
|
|
860
860
|
end
|
|
861
861
|
end
|
|
862
862
|
end
|
|
863
|
+
shared_examples "test optional no_write_to_binlog" do |*examples|
|
|
864
|
+
context "with no_write_to_binlog" do
|
|
865
|
+
it_behaves_like *examples do
|
|
866
|
+
let(:no_write_to_binlog){" no_write_to_binlog"}
|
|
867
|
+
end
|
|
868
|
+
end
|
|
869
|
+
context "with local" do
|
|
870
|
+
it_behaves_like *examples do
|
|
871
|
+
let(:no_write_to_binlog){" LOCAL"}
|
|
872
|
+
end
|
|
873
|
+
end
|
|
874
|
+
context "without local or no_write_to_binlog flag" do
|
|
875
|
+
it_behaves_like *examples do
|
|
876
|
+
let(:no_write_to_binlog){""}
|
|
877
|
+
end
|
|
878
|
+
end
|
|
879
|
+
end
|
|
880
|
+
shared_examples "test partition names" do |*examples|
|
|
881
|
+
context "ALL" do
|
|
882
|
+
it_behaves_like *examples do
|
|
883
|
+
let(:partition_names){"ALL"}
|
|
884
|
+
end
|
|
885
|
+
end
|
|
886
|
+
context "ALL lower case" do
|
|
887
|
+
it_behaves_like *examples do
|
|
888
|
+
let(:partition_names){"all"}
|
|
889
|
+
end
|
|
890
|
+
end
|
|
891
|
+
context "single partition" do
|
|
892
|
+
it_behaves_like *examples do
|
|
893
|
+
let(:partition_names){"p0"}
|
|
894
|
+
end
|
|
895
|
+
end
|
|
896
|
+
context "multiple partitions" do
|
|
897
|
+
it_behaves_like *examples do
|
|
898
|
+
let(:partition_names){"p0,P1, p2"}
|
|
899
|
+
end
|
|
900
|
+
end
|
|
901
|
+
end
|
|
902
|
+
shared_examples "test check types" do |*examples|
|
|
903
|
+
["quick", "FAST", "medium", "EXTENDED", "CHANGED", "for upgrade"].each do |check_type|
|
|
904
|
+
context "check_type is #{check_type}" do
|
|
905
|
+
it_behaves_like *examples do
|
|
906
|
+
let(:check_type) {check_type}
|
|
907
|
+
end
|
|
908
|
+
end
|
|
909
|
+
end
|
|
910
|
+
context "multiple check types" do
|
|
911
|
+
it_behaves_like *examples do
|
|
912
|
+
let(:check_type) {"fast for upgrade"}
|
|
913
|
+
end
|
|
914
|
+
end
|
|
915
|
+
end
|
|
916
|
+
shared_examples "test repair types" do |*examples|
|
|
917
|
+
["quick", "EXTENDED", "use_frm"].each do |repair_type|
|
|
918
|
+
context "repair_type is #{repair_type}" do
|
|
919
|
+
it_behaves_like *examples do
|
|
920
|
+
let(:repair_type) {repair_type}
|
|
921
|
+
end
|
|
922
|
+
end
|
|
923
|
+
end
|
|
924
|
+
context "multiple repair types" do
|
|
925
|
+
it_behaves_like *examples do
|
|
926
|
+
let(:repair_type) {"quick USE_FRM"}
|
|
927
|
+
end
|
|
928
|
+
end
|
|
929
|
+
end
|
|
930
|
+
shared_examples "test optional validation" do |*examples|
|
|
931
|
+
context "with validation" do
|
|
932
|
+
it_behaves_like *examples do
|
|
933
|
+
let(:validation){" with validation"}
|
|
934
|
+
end
|
|
935
|
+
end
|
|
936
|
+
context "without validation" do
|
|
937
|
+
it_behaves_like *examples do
|
|
938
|
+
let(:validation){" WITHOUT VALIDATION"}
|
|
939
|
+
end
|
|
940
|
+
end
|
|
941
|
+
context "none" do
|
|
942
|
+
it_behaves_like *examples do
|
|
943
|
+
let(:validation){""}
|
|
944
|
+
end
|
|
945
|
+
end
|
|
946
|
+
end
|
|
863
947
|
context 'add index' do
|
|
864
948
|
let(:action) { :add_index }
|
|
865
949
|
context "with a simple add index" do
|
|
@@ -1138,5 +1222,116 @@ describe 'MysqlAlterTableParser' do
|
|
|
1138
1222
|
let(:action) { :import_tablespace }
|
|
1139
1223
|
it_behaves_like "a parser parsing a breaking query"
|
|
1140
1224
|
end
|
|
1225
|
+
context "add partition" do
|
|
1226
|
+
let(:action) { :add_partition }
|
|
1227
|
+
context "simple definition with spaces" do
|
|
1228
|
+
let(:alter_table_action) { "add partition#{no_write_to_binlog} (PARTITION p2)" }
|
|
1229
|
+
it_behaves_like "test optional no_write_to_binlog", "a parser parsing a nonbreaking query"
|
|
1230
|
+
end
|
|
1231
|
+
context "complex partition definition without spaces" do
|
|
1232
|
+
let(:alter_table_action) { "ADD partition#{no_write_to_binlog}(PARTITION p2 VALUES LESS THAN (800))" }
|
|
1233
|
+
it_behaves_like "test optional no_write_to_binlog", "a parser parsing a nonbreaking query"
|
|
1234
|
+
end
|
|
1235
|
+
end
|
|
1236
|
+
context "drop partition" do
|
|
1237
|
+
let(:action) { :drop_partition }
|
|
1238
|
+
context "drop single partition" do
|
|
1239
|
+
let(:alter_table_action) { "DROP partition p0" }
|
|
1240
|
+
it_behaves_like "a parser parsing a nonbreaking query"
|
|
1241
|
+
end
|
|
1242
|
+
context "drop multiple partitions" do
|
|
1243
|
+
context "upcase and spaces between partition names" do
|
|
1244
|
+
let(:alter_table_action) { "DROP PARTITION p0, p1" }
|
|
1245
|
+
it_behaves_like "a parser parsing a nonbreaking query"
|
|
1246
|
+
end
|
|
1247
|
+
context "lowercase and no spaces between partition names" do
|
|
1248
|
+
let(:alter_table_action) { "drop partition p0,p1,p2" }
|
|
1249
|
+
it_behaves_like "a parser parsing a nonbreaking query"
|
|
1250
|
+
end
|
|
1251
|
+
end
|
|
1252
|
+
end
|
|
1253
|
+
context "rebuild, optimize, analyze partitions" do
|
|
1254
|
+
["rebuild", "optimize", "analyze"].each do |op|
|
|
1255
|
+
context "#{op} partition" do
|
|
1256
|
+
let(:action) { "#{op}_partition".to_sym }
|
|
1257
|
+
context "with upcase op" do
|
|
1258
|
+
let(:alter_table_action) { "#{op.upcase} PARTITION#{no_write_to_binlog} #{partition_names}" }
|
|
1259
|
+
it_behaves_like "test partition names", "test optional no_write_to_binlog", "a parser parsing a nonbreaking query"
|
|
1260
|
+
end
|
|
1261
|
+
context "with lowercase op" do
|
|
1262
|
+
let(:alter_table_action) { "#{op} partition#{no_write_to_binlog} #{partition_names}" }
|
|
1263
|
+
it_behaves_like "test partition names", "test optional no_write_to_binlog", "a parser parsing a nonbreaking query"
|
|
1264
|
+
end
|
|
1265
|
+
end
|
|
1266
|
+
end
|
|
1267
|
+
end
|
|
1268
|
+
context "check partition" do
|
|
1269
|
+
let(:action) { :check_partition }
|
|
1270
|
+
context "without check_type" do
|
|
1271
|
+
let(:alter_table_action) { "CHECK PARTITION #{partition_names}" }
|
|
1272
|
+
it_behaves_like "test partition names", "a parser parsing a nonbreaking query"
|
|
1273
|
+
end
|
|
1274
|
+
context "with check type" do
|
|
1275
|
+
let(:alter_table_action) { "check partition #{partition_names} #{check_type}" }
|
|
1276
|
+
it_behaves_like "test check types", "test partition names", "a parser parsing a nonbreaking query"
|
|
1277
|
+
end
|
|
1278
|
+
end
|
|
1279
|
+
context "repair partition" do
|
|
1280
|
+
let(:action) { :repair_partition }
|
|
1281
|
+
context "without repair_type" do
|
|
1282
|
+
let(:alter_table_action) { "REPAIR PARTITION#{no_write_to_binlog} #{partition_names}" }
|
|
1283
|
+
it_behaves_like "test partition names", "test optional no_write_to_binlog", "a parser parsing a nonbreaking query"
|
|
1284
|
+
end
|
|
1285
|
+
context "with repair type" do
|
|
1286
|
+
let(:alter_table_action) { "repair partition#{no_write_to_binlog} #{partition_names} #{repair_type}" }
|
|
1287
|
+
it_behaves_like "test repair types", "test partition names", "test optional no_write_to_binlog", "a parser parsing a nonbreaking query"
|
|
1288
|
+
end
|
|
1289
|
+
end
|
|
1290
|
+
context "coalesce partition" do
|
|
1291
|
+
let(:action) { :coalesce_partition }
|
|
1292
|
+
context "single digit partition number" do
|
|
1293
|
+
let(:alter_table_action) { "coalesce partition#{no_write_to_binlog} 1" }
|
|
1294
|
+
it_behaves_like "test optional no_write_to_binlog", "a parser parsing a nonbreaking query"
|
|
1295
|
+
end
|
|
1296
|
+
context "double digit partition number" do
|
|
1297
|
+
let(:alter_table_action) { "COALESCE PARTITION#{no_write_to_binlog} 22" }
|
|
1298
|
+
it_behaves_like "test optional no_write_to_binlog", "a parser parsing a nonbreaking query"
|
|
1299
|
+
end
|
|
1300
|
+
end
|
|
1301
|
+
context "truncate partition" do
|
|
1302
|
+
let(:action) { :truncate_partition }
|
|
1303
|
+
let(:alter_table_action) { "TRUNCATE PARTITION #{partition_names}" }
|
|
1304
|
+
it_behaves_like "test partition names", "a parser parsing a nonbreaking query"
|
|
1305
|
+
end
|
|
1306
|
+
context "reorganize partition" do
|
|
1307
|
+
let(:action) { :reorganize_partition }
|
|
1308
|
+
context "simple definition without partition names and partition definition" do
|
|
1309
|
+
let(:alter_table_action) { "reorganize partition#{no_write_to_binlog}" }
|
|
1310
|
+
it_behaves_like "test optional no_write_to_binlog", "a parser parsing a nonbreaking query"
|
|
1311
|
+
end
|
|
1312
|
+
context "complex partition definition" do
|
|
1313
|
+
let(:alter_table_action) { "REORGANIZE PARTITION#{no_write_to_binlog} p0 INTO (PARTITION n0 VALUES LESS THAN (1960))" }
|
|
1314
|
+
it_behaves_like "test optional no_write_to_binlog", "a parser parsing a nonbreaking query"
|
|
1315
|
+
end
|
|
1316
|
+
end
|
|
1317
|
+
context "exchange partition" do
|
|
1318
|
+
let(:action) { :exchange_partition }
|
|
1319
|
+
let(:alter_table_action) { "EXCHANGE PARTITION #{ident} with table#{identifier}#{validation}" }
|
|
1320
|
+
it_behaves_like "test table identifier", "test optional validation", "a parser parsing a nonbreaking query"
|
|
1321
|
+
end
|
|
1322
|
+
context "discard and import partition tablespace" do
|
|
1323
|
+
["discard", "import"].each do |op|
|
|
1324
|
+
context "#{op}" do
|
|
1325
|
+
let(:action) {"#{op}_partition_tablespace".to_sym}
|
|
1326
|
+
let(:alter_table_action) {"#{op} PARTITION #{partition_names} TABLESPACE"}
|
|
1327
|
+
it_behaves_like "test partition names", "a parser parsing a nonbreaking query"
|
|
1328
|
+
end
|
|
1329
|
+
end
|
|
1330
|
+
end
|
|
1331
|
+
context "remove partitioning" do
|
|
1332
|
+
let(:action) {:remove_partitioning}
|
|
1333
|
+
let(:alter_table_action) { "REMOVE PARTITIONING" }
|
|
1334
|
+
it_behaves_like "a parser parsing a nonbreaking query"
|
|
1335
|
+
end
|
|
1141
1336
|
end
|
|
1142
1337
|
end
|
|
@@ -262,17 +262,52 @@ EOT
|
|
|
262
262
|
it_behaves_like *examples
|
|
263
263
|
end
|
|
264
264
|
|
|
265
|
-
context 'with
|
|
266
|
-
|
|
267
|
-
|
|
265
|
+
context 'with date column def' do
|
|
266
|
+
before do
|
|
267
|
+
column[:column] = "value_date"
|
|
268
|
+
column[:type] = "date"
|
|
269
|
+
end
|
|
270
|
+
let(:type_sql) { %Q|"value_date" date| }
|
|
268
271
|
let(:not_null_default_sql) { " DEFAULT '0000-01-01'" }
|
|
272
|
+
|
|
273
|
+
context 'when default_value is normal' do
|
|
274
|
+
let(:default_value) { '2014-10-17' }
|
|
275
|
+
let(:default_value_sql) { "'#{default_value}'" }
|
|
276
|
+
it_behaves_like *examples
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
context 'when default_value is 0000-00-00' do
|
|
280
|
+
let(:default_value) { '0000-00-00' }
|
|
281
|
+
let(:default_value_sql) { "'0001-01-01'" }
|
|
282
|
+
it_behaves_like *examples
|
|
283
|
+
end
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
context 'with datetime column def' do
|
|
269
287
|
before do
|
|
270
288
|
column[:column] = "value_datetime"
|
|
271
289
|
column[:type] = "datetime"
|
|
272
290
|
end
|
|
273
291
|
let(:type_sql) { %Q|"value_datetime" timestamp| }
|
|
292
|
+
let(:not_null_default_sql) { " DEFAULT '0000-01-01'" }
|
|
274
293
|
|
|
275
|
-
|
|
294
|
+
context 'when default_value is normal' do
|
|
295
|
+
let(:default_value) { '2014-10-17 22:22:22' }
|
|
296
|
+
let(:default_value_sql) { "'#{default_value}.000000'" }
|
|
297
|
+
it_behaves_like *examples
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
context 'when default_value is CURRENT_TIMESTAMP' do
|
|
301
|
+
let(:default_value) { 'CURRENT_TIMESTAMP' }
|
|
302
|
+
let(:default_value_sql) { "SYSDATE" }
|
|
303
|
+
it_behaves_like *examples
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
context 'when default_value is 0000-00-00 00:00:00' do
|
|
307
|
+
let(:default_value) { '0000-00-00 00:00:00' }
|
|
308
|
+
let(:default_value_sql) { "'0001-01-01 00:00:00.000000'" }
|
|
309
|
+
it_behaves_like *examples
|
|
310
|
+
end
|
|
276
311
|
end
|
|
277
312
|
|
|
278
313
|
context 'with decimal column def' do
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: flydata
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
4
|
+
version: 0.2.11
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Koichi Fujikawa
|
|
@@ -12,7 +12,7 @@ authors:
|
|
|
12
12
|
autorequire:
|
|
13
13
|
bindir: bin
|
|
14
14
|
cert_chain: []
|
|
15
|
-
date: 2014-10-
|
|
15
|
+
date: 2014-10-31 00:00:00.000000000 Z
|
|
16
16
|
dependencies:
|
|
17
17
|
- !ruby/object:Gem::Dependency
|
|
18
18
|
name: rest-client
|
|
@@ -376,6 +376,20 @@ dependencies:
|
|
|
376
376
|
- - ~>
|
|
377
377
|
- !ruby/object:Gem::Version
|
|
378
378
|
version: '1.0'
|
|
379
|
+
- !ruby/object:Gem::Dependency
|
|
380
|
+
name: pry
|
|
381
|
+
requirement: !ruby/object:Gem::Requirement
|
|
382
|
+
requirements:
|
|
383
|
+
- - '>='
|
|
384
|
+
- !ruby/object:Gem::Version
|
|
385
|
+
version: '0'
|
|
386
|
+
type: :development
|
|
387
|
+
prerelease: false
|
|
388
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
389
|
+
requirements:
|
|
390
|
+
- - '>='
|
|
391
|
+
- !ruby/object:Gem::Version
|
|
392
|
+
version: '0'
|
|
379
393
|
description: FlyData Agent
|
|
380
394
|
email: sysadmin@flydata.com
|
|
381
395
|
executables:
|
|
@@ -391,6 +405,11 @@ files:
|
|
|
391
405
|
- Gemfile.lock
|
|
392
406
|
- Rakefile
|
|
393
407
|
- VERSION
|
|
408
|
+
- benchmark/benchmark_helper.rb
|
|
409
|
+
- benchmark/data/insert_parser_test_data.sql.gz
|
|
410
|
+
- benchmark/data/insert_parser_test_data_num_only.sql.gz
|
|
411
|
+
- benchmark/insert_parser_bench.rb
|
|
412
|
+
- benchmark/insert_parser_prof.rb
|
|
394
413
|
- bin/fdmysqldump
|
|
395
414
|
- bin/flydata
|
|
396
415
|
- bin/serverinfo
|
|
@@ -501,7 +520,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
501
520
|
version: '0'
|
|
502
521
|
requirements: []
|
|
503
522
|
rubyforge_project:
|
|
504
|
-
rubygems_version: 2.
|
|
523
|
+
rubygems_version: 2.0.14
|
|
505
524
|
signing_key:
|
|
506
525
|
specification_version: 4
|
|
507
526
|
summary: FlyData Agent
|