sql-maker 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +22 -0
  3. data/CHANGELOG.md +3 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +23 -0
  7. data/Rakefile +14 -0
  8. data/lib/sql-maker.rb +5 -0
  9. data/lib/sql/maker.rb +676 -0
  10. data/lib/sql/maker/condition.rb +378 -0
  11. data/lib/sql/maker/error.rb +3 -0
  12. data/lib/sql/maker/helper.rb +22 -0
  13. data/lib/sql/maker/quoting.rb +138 -0
  14. data/lib/sql/maker/select.rb +544 -0
  15. data/lib/sql/maker/select/oracle.rb +30 -0
  16. data/lib/sql/maker/select_set.rb +194 -0
  17. data/lib/sql/maker/util.rb +54 -0
  18. data/lib/sql/query_maker.rb +429 -0
  19. data/scripts/perl2ruby.rb +34 -0
  20. data/spec/maker/bind_param_spec.rb +62 -0
  21. data/spec/maker/condition/add_raw_spec.rb +29 -0
  22. data/spec/maker/condition/compose_empty_spec.rb +72 -0
  23. data/spec/maker/condition/empty_values_spec.rb +25 -0
  24. data/spec/maker/condition/make_term_spec.rb +38 -0
  25. data/spec/maker/condition/where_spec.rb +35 -0
  26. data/spec/maker/delete_spec.rb +116 -0
  27. data/spec/maker/insert_empty_spec.rb +23 -0
  28. data/spec/maker/insert_spec.rb +61 -0
  29. data/spec/maker/new_line_spec.rb +9 -0
  30. data/spec/maker/select/oracle/oracle_spec.rb +16 -0
  31. data/spec/maker/select/pod_select_spec.rb +34 -0
  32. data/spec/maker/select/statement_spec.rb +805 -0
  33. data/spec/maker/select_set_spec.rb +294 -0
  34. data/spec/maker/select_spec.rb +470 -0
  35. data/spec/maker/simple_spec.rb +54 -0
  36. data/spec/maker/strict_spec.rb +45 -0
  37. data/spec/maker/subquery_spec.rb +77 -0
  38. data/spec/maker/update_spec.rb +138 -0
  39. data/spec/maker/util_spec.rb +6 -0
  40. data/spec/maker/where_spec.rb +28 -0
  41. data/spec/query_maker/and_using_hash_spec.rb +13 -0
  42. data/spec/query_maker/cheatsheet_spec.rb +32 -0
  43. data/spec/query_maker/column_bind_spec.rb +55 -0
  44. data/spec/query_maker/refs_in_bind_spec.rb +19 -0
  45. data/spec/spec_helper.rb +15 -0
  46. data/sql-maker.gemspec +25 -0
  47. metadata +185 -0
@@ -0,0 +1,34 @@
1
+ filename = ARGV.first
2
+ body = File.read(filename)
3
+
4
+ body.gsub!(/ eq /, ' == ')
5
+ body.gsub!(/\$([_A-Za-z]\w*)->\{([_A-Za-z]\w*)\}/, '\1.\2') # $self->{var} => self.var
6
+ body.gsub!(/\$([_A-Za-z]\w*)->([_A-Za-z]\w*)/, '\1.\2') # $self->var => self.var
7
+ body.gsub!(/\$([_A-Za-z]\w*)/, '\1') # $var => var
8
+ body.gsub!(/\@([_A-Za-z]\w*)/, '\1') # @var => var
9
+ body.gsub!(/ \. /, ' + ') # str . str => str + str
10
+ body.gsub!(/join\('([^']+)', ([^)]+)\)/, '\2.join(\'\1\')') # join(', ', foo) => foo.join(', ')
11
+ body.gsub!(/subtest '([^']+)' => sub {/, 'it \'\1\' do') # subtest '[]' => sub { => it '[]' do
12
+ body.gsub!(/sub ([_A-Za-z]\w*) {/, 'def \1') # sub sql_op { => def sql_op
13
+ body.gsub!(/([_A-Za-z]\w*) => /, ':\1 => ') # x => [] to :x => []
14
+ body.gsub!(/ +};$/, 'end') # }; => end
15
+ body.gsub!(/}$/, 'end') # } => end
16
+ body.gsub!(/my /, '') # remove my
17
+ body.gsub!(/->/, '.') # foo->var => foo.var
18
+ body.gsub!(/;$/, '')
19
+ body.gsub!(/\\'$/, "'") # \' => '
20
+ body.gsub!(/\\\[$/, "[") # \[ => [
21
+ body.gsub!(/qq{/, '%Q{')
22
+ #body.gsub!(/\[ qw\/([^/]+)\/ \]/, '%w/\1/')
23
+ body.gsub!(/ordered_hashref\(([^)]+)\)/, '{\1}')
24
+ body.gsub!(/use strict/, '')
25
+ body.gsub!(/\(sql, bind\)/, 'sql, bind')
26
+ body.gsub!(/use warnings/, '')
27
+ body.gsub!(/use Test::More/, "require_relative '../spec_helper'")
28
+ body.gsub!(/use SQL::Maker/, "require 'sql/maker'")
29
+ body.gsub!(/use SQL::QueryMaker/, "require 'sql/query_maker'")
30
+ body.gsub!(/done_testing/, '')
31
+ body.gsub!(/is ([^,]+), (.+)$/, 'expect(\1).to be == \2')
32
+ body.gsub!(/is\(([^,]+), (.+)\)$/, 'expect(\1).to be == \2')
33
+ body.gsub!(/is ([^(]+\([^)]+\)), (.+)$/, 'expect(\1).to be == \2') # is foo.join(', '), '1'
34
+ puts body.strip
@@ -0,0 +1,62 @@
1
+ require_relative '../spec_helper'
2
+ require 'sql/maker'
3
+
4
+ describe 'SQL::Maker' do
5
+ context 'auto bind' do
6
+ let(:builder) { SQL::Maker.new(:driver => 'mysql', :auto_bind => true) }
7
+
8
+ it 'delete' do
9
+ sql = builder.delete('foo', {:bar => "t' OR 't' = 't"})
10
+ expect(sql).to be == %q{DELETE FROM `foo` WHERE (`bar` = 't'' OR ''t'' = ''t')}
11
+ end
12
+
13
+ it 'insert' do
14
+ sql = builder.insert('foo', {:bar => "t' OR 't' = 't"})
15
+ expect(sql).to be == %Q{INSERT INTO `foo`\n(`bar`)\nVALUES ('t'' OR ''t'' = ''t')}
16
+ end
17
+
18
+ it 'select' do
19
+ sql = builder.select('foo', ['foo'], { :bar => "t' OR 't' = 't" })
20
+ expect(sql).to be == %Q{SELECT `foo`\nFROM `foo`\nWHERE (`bar` = 't'' OR ''t'' = ''t')}
21
+ end
22
+
23
+ it 'update' do
24
+ sql = builder.update('foo', {:bar => "t' OR 't' = 't"})
25
+ expect(sql).to be == %Q{UPDATE `foo` SET `bar` = 't'' OR ''t'' = ''t'}
26
+ end
27
+ end
28
+
29
+ context '#bind_param' do
30
+ let(:builder) { SQL::Maker.new(:driver => 'mysql', :auto_bind => false) }
31
+
32
+ it 'delete' do
33
+ sql, bind = builder.delete('foo', {:bar => "t' OR 't' = 't"})
34
+ sql = builder.bind_param(sql, bind)
35
+ expect(sql).to be == %q{DELETE FROM `foo` WHERE (`bar` = 't'' OR ''t'' = ''t')}
36
+ end
37
+ end
38
+
39
+ context 'hash arguments' do
40
+ let(:builder) { SQL::Maker.new(:driver => 'mysql', :auto_bind => true) }
41
+
42
+ it 'delete' do
43
+ sql = builder.delete(table: 'foo', where: {:bar => "t' OR 't' = 't"})
44
+ expect(sql).to be == %q{DELETE FROM `foo` WHERE (`bar` = 't'' OR ''t'' = ''t')}
45
+ end
46
+
47
+ it 'insert' do
48
+ sql = builder.insert(table: 'foo', values: {:bar => "t' OR 't' = 't"})
49
+ expect(sql).to be == %Q{INSERT INTO `foo`\n(`bar`)\nVALUES ('t'' OR ''t'' = ''t')}
50
+ end
51
+
52
+ it 'select' do
53
+ sql = builder.select(table: 'foo', fields: ['foo'], where: { :bar => "t' OR 't' = 't" })
54
+ expect(sql).to be == %Q{SELECT `foo`\nFROM `foo`\nWHERE (`bar` = 't'' OR ''t'' = ''t')}
55
+ end
56
+
57
+ it 'update' do
58
+ sql = builder.update(table: 'foo', set: {:bar => "t' OR 't' = 't"})
59
+ expect(sql).to be == %Q{UPDATE `foo` SET `bar` = 't'' OR ''t'' = ''t'}
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,29 @@
1
+ require_relative '../../spec_helper'
2
+ require 'sql/maker/condition'
3
+
4
+ describe 'SQL::Maker::Condition' do
5
+ it 'with values' do
6
+ w1 = SQL::Maker::Condition.new()
7
+ w1.add_raw( 'a = ?' => 1 )
8
+ w1.add_raw( 'b = ?' => 2 )
9
+
10
+ expect(w1.as_sql).to be == '(a = ?) AND (b = ?)'
11
+ expect(w1.bind.join(',')).to be == '1,2'
12
+
13
+ w2 = SQL::Maker::Condition.new()
14
+ w2.add_raw( 'b = IF(c > 0, ?, ?)' => [0, 1] )
15
+ w2.add_raw( 'd = ?' => [2])
16
+
17
+ expect(w2.as_sql).to be == '(b = IF(c > 0, ?, ?)) AND (d = ?)'
18
+ expect(w2.bind.join(',')).to be == '0,1,2'
19
+ end
20
+
21
+ it 'without values' do
22
+ w = SQL::Maker::Condition.new()
23
+ w.add_raw( 'a IS NOT NULL' )
24
+ w.add_raw( 'b IS NULL' )
25
+
26
+ expect(w.as_sql).to be == '(a IS NOT NULL) AND (b IS NULL)'
27
+ expect(w.bind.join(',')).to be == ''
28
+ end
29
+ end
@@ -0,0 +1,72 @@
1
+ require_relative '../../spec_helper'
2
+ require 'sql/maker/condition'
3
+
4
+ describe 'SQL::Maker::Condition' do
5
+ let(:w1) do
6
+ w1 = SQL::Maker::Condition.new()
7
+ w1.add(:x => 1)
8
+ w1.add(:y => 2)
9
+ end
10
+ let(:w2) { SQL::Maker::Condition.new() }
11
+ let(:w3) { SQL::Maker::Condition.new() }
12
+
13
+ it 'and_before' do
14
+ w = (w1 & w2)
15
+ expect(w.as_sql).to be == '((x = ?) AND (y = ?))'
16
+ expect(w.bind.join(', ')).to be == '1, 2'
17
+
18
+ w.add(:z => 99)
19
+ expect(w.as_sql).to be == '((x = ?) AND (y = ?)) AND (z = ?)'
20
+ expect(w.bind.join(', ')).to be == '1, 2, 99'
21
+ end
22
+
23
+ it 'and_after' do
24
+ w = (w2 & w1)
25
+ expect(w.as_sql).to be == '((x = ?) AND (y = ?))'
26
+ expect(w.bind.join(', ')).to be == '1, 2'
27
+
28
+ w.add(:z => 99)
29
+ expect(w.as_sql).to be == '((x = ?) AND (y = ?)) AND (z = ?)'
30
+ expect(w.bind.join(', ')).to be == '1, 2, 99'
31
+ end
32
+
33
+ it 'or_before' do
34
+ w = (w1 | w2)
35
+ expect(w.as_sql).to be == '((x = ?) AND (y = ?))'
36
+ expect(w.bind.join(', ')).to be == '1, 2'
37
+
38
+ w.add(:z => 99)
39
+ expect(w.as_sql).to be == '((x = ?) AND (y = ?)) AND (z = ?)'
40
+ expect(w.bind.join(', ')).to be == '1, 2, 99'
41
+ end
42
+
43
+ it 'or_after' do
44
+ w = (w2 | w1)
45
+ expect(w.as_sql).to be == '((x = ?) AND (y = ?))'
46
+ expect(w.bind.join(', ')).to be == '1, 2'
47
+
48
+ w.add(:z => 99)
49
+ expect(w.as_sql).to be == '((x = ?) AND (y = ?)) AND (z = ?)'
50
+ expect(w.bind.join(', ')).to be == '1, 2, 99'
51
+ end
52
+
53
+ it 'and_both' do
54
+ w = (w2 & w3)
55
+ expect(w.as_sql).to be == ''
56
+ expect(w.bind.join(', ')).to be == ''
57
+
58
+ w.add(:z => 99)
59
+ expect(w.as_sql).to be == '(z = ?)'
60
+ expect(w.bind.join(', ')).to be == '99'
61
+ end
62
+
63
+ it 'or_both' do
64
+ w = (w2 | w3)
65
+ expect(w.as_sql).to be == ''
66
+ expect(w.bind.join(', ')).to be == ''
67
+
68
+ w.add(:z => 99)
69
+ expect(w.as_sql).to be == '(z = ?)'
70
+ expect(w.bind.join(', ')).to be == '99'
71
+ end
72
+ end
@@ -0,0 +1,25 @@
1
+ require_relative '../../spec_helper'
2
+ require 'sql/maker/condition'
3
+
4
+ describe SQL::Maker::Condition do
5
+ it '[]' do
6
+ w = SQL::Maker::Condition.new()
7
+ w.add(:x => [])
8
+ expect(w.as_sql).to be == '(0=1)'
9
+ expect(w.bind.join(', ')).to be == ''
10
+ end
11
+
12
+ it 'in' do
13
+ w = SQL::Maker::Condition.new()
14
+ w.add(:x => { 'IN' => [] })
15
+ expect(w.as_sql).to be == '(0=1)'
16
+ expect(w.bind.join(', ')).to be == ''
17
+ end
18
+
19
+ it 'not in' do
20
+ w2 = SQL::Maker::Condition.new()
21
+ w2.add(:x => { 'NOT IN' => [] })
22
+ expect(w2.as_sql).to be == '(1=1)'
23
+ expect(w2.bind.join(', ')).to be == ''
24
+ end
25
+ end
@@ -0,0 +1,38 @@
1
+ require_relative '../../spec_helper'
2
+ require 'sql/maker/condition'
3
+ require 'sql/maker/helper'
4
+
5
+ include SQL::Maker::Helper
6
+
7
+ def test(input, expected_term, expected_bind)
8
+ describe 'SQL::Maker::Condition' do
9
+ it input do
10
+ source = eval(input, binding)
11
+ cond = SQL::Maker::Condition.new(
12
+ :quote_char => '`',
13
+ :name_sep => '.',
14
+ )
15
+ cond.add(source)
16
+ sql = cond.as_sql
17
+ sql = sql.gsub(/^\(/, '').gsub(/\)$/, '')
18
+ expect(sql).to be == expected_term
19
+ expect(cond.bind).to be == expected_bind
20
+ end
21
+ end
22
+ end
23
+
24
+ begin
25
+ file = File.open("#{ROOT}/lib/sql/maker/condition.rb")
26
+ while line = file.gets
27
+ break if line =~ /=head1 CONDITION CHEAT SHEET/
28
+ end
29
+ while line = file.gets
30
+ next if line =~ /^#/
31
+ src = $1 if line =~ /IN:\s*(.+)\s*$/
32
+ query = eval($1, binding) if line =~ /OUT QUERY:(.+)/
33
+ if line =~ /OUT BIND:(.+)/
34
+ bind = eval($1, binding)
35
+ test(src, query, bind)
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,35 @@
1
+ require_relative '../../spec_helper'
2
+ require 'sql/maker/condition'
3
+
4
+ describe SQL::Maker::Condition do
5
+ let(:w1) do
6
+ w1 = SQL::Maker::Condition.new()
7
+ w1.add(:x => 1)
8
+ w1.add(:y => 2)
9
+ end
10
+ let(:w2) do
11
+ w2 = SQL::Maker::Condition.new()
12
+ w2.add(:a => 3)
13
+ w2.add(:b => 4)
14
+ end
15
+
16
+ it 'and' do
17
+ w = (w1 & w2)
18
+ expect(w.as_sql).to be == '((x = ?) AND (y = ?)) AND ((a = ?) AND (b = ?))'
19
+ expect(w.bind.join(', ')).to be == '1, 2, 3, 4'
20
+
21
+ w.add(:z => 99)
22
+ expect(w.as_sql).to be == '((x = ?) AND (y = ?)) AND ((a = ?) AND (b = ?)) AND (z = ?)'
23
+ expect(w.bind.join(', ')).to be == '1, 2, 3, 4, 99'
24
+ end
25
+
26
+ it 'or' do
27
+ w = (w1 | w2)
28
+ expect(w.as_sql).to be == '(((x = ?) AND (y = ?)) OR ((a = ?) AND (b = ?)))'
29
+ expect(w.bind.join(', ')).to be == '1, 2, 3, 4'
30
+
31
+ w.add(:z => 99)
32
+ expect(w.as_sql).to be == '(((x = ?) AND (y = ?)) OR ((a = ?) AND (b = ?))) AND (z = ?)'
33
+ expect(w.bind.join(', ')).to be == '1, 2, 3, 4, 99'
34
+ end
35
+ end
@@ -0,0 +1,116 @@
1
+ require_relative '../spec_helper'
2
+ require 'sql/maker'
3
+
4
+ describe 'SQL::Maker' do
5
+ context 'driver sqlite' do
6
+ it 'simple where_as_hashref' do
7
+ builder = SQL::Maker.new(:driver => 'sqlite')
8
+ sql, bind = builder.delete('foo', {:bar => 'baz', :john => 'man'})
9
+ expect(sql).to be == %q{DELETE FROM "foo" WHERE ("bar" = ?) AND ("john" = ?)}
10
+ expect(bind.join(',')).to be == 'baz,man'
11
+ end
12
+
13
+ # it 'simple where_as_arrayref' do
14
+
15
+ it 'simple where_as_condition' do
16
+ builder = SQL::Maker.new(:driver => 'sqlite')
17
+ cond = builder.new_condition
18
+ cond.add(:bar => 'baz')
19
+ cond.add(:john => 'man')
20
+ sql, bind = builder.delete('foo', cond)
21
+ expect(sql).to be == %q{DELETE FROM "foo" WHERE ("bar" = ?) AND ("john" = ?)}
22
+ expect(bind.join(',')).to be == 'baz,man'
23
+ end
24
+
25
+ it 'delete all' do
26
+ builder = SQL::Maker.new(:driver => 'sqlite')
27
+ sql, bind = builder.delete('foo')
28
+ expect(sql).to be == %q{DELETE FROM "foo"}
29
+ expect(bind.join(',')).to be == ''
30
+ end
31
+ end
32
+
33
+ context 'driver mysql' do
34
+ it 'simple where_as_hashref' do
35
+ builder = SQL::Maker.new(:driver => 'mysql')
36
+ sql, bind = builder.delete('foo', {:bar => 'baz', :john => 'man'})
37
+ expect(sql).to be == %q{DELETE FROM `foo` WHERE (`bar` = ?) AND (`john` = ?)}
38
+ expect(bind.join(',')).to be == 'baz,man'
39
+ end
40
+
41
+ # it 'simple where_as_arrayref' do
42
+
43
+ it 'simple where_as_condition' do
44
+ builder = SQL::Maker.new(:driver => 'mysql')
45
+ cond = builder.new_condition
46
+ cond.add(:bar => 'baz')
47
+ cond.add(:john => 'man')
48
+ sql, bind = builder.delete('foo', cond)
49
+ expect(sql).to be == %q{DELETE FROM `foo` WHERE (`bar` = ?) AND (`john` = ?)}
50
+ expect(bind.join(',')).to be == 'baz,man'
51
+ end
52
+
53
+ it 'delete all' do
54
+ builder = SQL::Maker.new(:driver => 'mysql')
55
+ sql, bind = builder.delete('foo')
56
+ expect(sql).to be == %q{DELETE FROM `foo`}
57
+ expect(bind.join(',')).to be == ''
58
+ end
59
+
60
+ it 'delete using where_as_hashref' do
61
+ builder = SQL::Maker.new(:driver => 'mysql')
62
+ sql, bind = builder.delete('foo', {:bar => 'baz', :john => 'man'}, {:using => 'bar'})
63
+ expect(sql).to be == %q{DELETE FROM `foo` USING `bar` WHERE (`bar` = ?) AND (`john` = ?)}
64
+ expect(bind.join(',')).to be == 'baz,man'
65
+ end
66
+
67
+ it 'delete using array where_as_hashref' do
68
+ builder = SQL::Maker.new(:driver => 'mysql')
69
+ sql, bind = builder.delete('foo', {:bar => 'baz', :john => 'man'}, {:using => ['bar', 'qux']})
70
+ expect(sql).to be == %q{DELETE FROM `foo` USING `bar`, `qux` WHERE (`bar` = ?) AND (`john` = ?)}
71
+ expect(bind.join(',')).to be == 'baz,man'
72
+ end
73
+ end
74
+
75
+ context 'driver mysql, quote_char: "", new_line: " "' do
76
+ it 'simple where_as_hashref' do
77
+ builder = SQL::Maker.new(:driver => 'mysql', :quote_char => '', :new_line => ' ')
78
+ sql, bind = builder.delete('foo', {:bar => 'baz', :john => 'man'})
79
+ expect(sql).to be == %q{DELETE FROM foo WHERE (bar = ?) AND (john = ?)}
80
+ expect(bind.join(',')).to be == 'baz,man'
81
+ end
82
+
83
+ # it 'simple where_as_arrayref' do
84
+
85
+ it 'simple where_as_condition' do
86
+ builder = SQL::Maker.new(:driver => 'mysql', :quote_char => '', :new_line => ' ')
87
+ cond = builder.new_condition
88
+ cond.add(:bar => 'baz')
89
+ cond.add(:john => 'man')
90
+ sql, bind = builder.delete('foo', cond)
91
+ expect(sql).to be == %q{DELETE FROM foo WHERE (bar = ?) AND (john = ?)}
92
+ expect(bind.join(',')).to be == 'baz,man'
93
+ end
94
+
95
+ it 'delete all' do
96
+ builder = SQL::Maker.new(:driver => 'mysql', :quote_char => '', :new_line => ' ')
97
+ sql, bind = builder.delete('foo')
98
+ expect(sql).to be == %q{DELETE FROM foo}
99
+ expect(bind.join(',')).to be == ''
100
+ end
101
+
102
+ it 'delete using where_as_hashref' do
103
+ builder = SQL::Maker.new(:driver => 'mysql', :quote_char => '', :new_line => ' ')
104
+ sql, bind = builder.delete('foo', {:bar => 'baz', :john => 'man'}, {:using => 'bar'})
105
+ expect(sql).to be == %q{DELETE FROM foo USING bar WHERE (bar = ?) AND (john = ?)}
106
+ expect(bind.join(',')).to be == 'baz,man'
107
+ end
108
+
109
+ it 'delete using array where_as_hashref' do
110
+ builder = SQL::Maker.new(:driver => 'mysql', :quote_char => '', :new_line => ' ')
111
+ sql, bind = builder.delete('foo', {:bar => 'baz', :john => 'man'}, {:using => ['bar', 'qux']})
112
+ expect(sql).to be == %q{DELETE FROM foo USING bar, qux WHERE (bar = ?) AND (john = ?)}
113
+ expect(bind.join(',')).to be == 'baz,man'
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,23 @@
1
+ require_relative '../spec_helper'
2
+ require 'sql/maker'
3
+
4
+ describe 'SQL::Maker#insert' do
5
+ def normalize(sql)
6
+ sql.gsub(/\n/, ' ')
7
+ end
8
+
9
+ # see https://github.com/tokuhirom/SQL-Maker/issues/11
10
+ it 'sqlite' do
11
+ maker = SQL::Maker.new(:driver => 'SQLite')
12
+ sql, bind = maker.insert('foo', {})
13
+ expect(normalize(sql)).to be == 'INSERT INTO "foo" DEFAULT VALUES'
14
+ expect(bind.size).to be == 0
15
+ end
16
+
17
+ it 'mysql' do
18
+ maker = SQL::Maker.new(:driver => 'mysql')
19
+ sql, bind = maker.insert('foo', {})
20
+ expect(normalize(sql)).to be == 'INSERT INTO `foo` () VALUES ()'
21
+ expect(bind.size).to be == 0
22
+ end
23
+ end