X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=t%2F01generate.t;h=020dfa5f27b73a02d9738d558d3143b721a69a3f;hb=19b6ccce01924e9ff476b4723bbbd2051c69412f;hp=e3737ffd421f3575f4c09075f22656514805f3f3;hpb=904c36212d6024755df9c19a5f32b3e8c290bcd4;p=dbsrgits%2FSQL-Abstract.git diff --git a/t/01generate.t b/t/01generate.t index e3737ff..020dfa5 100644 --- a/t/01generate.t +++ b/t/01generate.t @@ -113,6 +113,13 @@ my @tests = ( bind => ['nwiger'] }, { + func => 'select', + args => [[\'test1', 'test2'], '*', { 'test1.a' => 'boom' } ], + stmt => 'SELECT * FROM test1, test2 WHERE ( test1.a = ? )', + stmt_q => 'SELECT * FROM test1, `test2` WHERE ( `test1`.`a` = ? )', + bind => ['boom'] + }, + { func => 'insert', args => ['test', {a => 1, b => 2, c => 3, d => 4, e => 5}], stmt => 'INSERT INTO test (a, b, c, d, e) VALUES (?, ?, ?, ?, ?)', @@ -121,10 +128,10 @@ my @tests = ( }, { func => 'insert', - args => ['test', [qw/1 2 3 4 5/]], - stmt => 'INSERT INTO test VALUES (?, ?, ?, ?, ?)', - stmt_q => 'INSERT INTO `test` VALUES (?, ?, ?, ?, ?)', - bind => [qw/1 2 3 4 5/], + args => ['test', [1..30]], + stmt => 'INSERT INTO test VALUES ('.join(', ', ('?')x30).')', + stmt_q => 'INSERT INTO `test` VALUES ('.join(', ', ('?')x30).')', + bind => [1..30], }, { func => 'insert', @@ -552,19 +559,61 @@ my @tests = ( bind => [], warns => qr/\QSupplying an undefined argument to 'NOT LIKE' is deprecated/, }, + { + func => 'select', + args => ['`test``table`', ['`test``column`']], + stmt => 'SELECT `test``column` FROM `test``table`', + stmt_q => 'SELECT ```test````column``` FROM ```test````table```', + bind => [], + }, + { + func => 'select', + args => ['`test\\`table`', ['`test`\\column`']], + stmt => 'SELECT `test`\column` FROM `test\`table`', + stmt_q => 'SELECT `\`test\`\\\\column\`` FROM `\`test\\\\\`table\``', + esc => '\\', + bind => [], + }, + { + func => 'update', + args => ['mytable', { foo => 42 }, { baz => 32 }, { returning => 'id' }], + stmt => 'UPDATE mytable SET foo = ? WHERE baz = ? RETURNING id', + stmt_q => 'UPDATE `mytable` SET `foo` = ? WHERE `baz` = ? RETURNING `id`', + bind => [42, 32], + }, + { + func => 'update', + args => ['mytable', { foo => 42 }, { baz => 32 }, { returning => \'*' }], + stmt => 'UPDATE mytable SET foo = ? WHERE baz = ? RETURNING *', + stmt_q => 'UPDATE `mytable` SET `foo` = ? WHERE `baz` = ? RETURNING *', + bind => [42, 32], + }, + { + func => 'update', + args => ['mytable', { foo => 42 }, { baz => 32 }, { returning => ['id','created_at'] }], + stmt => 'UPDATE mytable SET foo = ? WHERE baz = ? RETURNING id, created_at', + stmt_q => 'UPDATE `mytable` SET `foo` = ? WHERE `baz` = ? RETURNING `id`, `created_at`', + bind => [42, 32], + }, ); # check is( not) => undef -for my $op (qw( is is_not), 'is not' ) { +for my $op ( qw(not is is_not), 'is not' ) { (my $sop = uc $op) =~ s/_/ /gi; - push @tests, { - func => 'where', - args => [{ a => { "$_$op" => undef } }], - stmt => "WHERE a $sop NULL", - stmt_q => "WHERE `a` $sop NULL", - bind => [], - } for ('', '-'); # with and without - + $sop = 'IS NOT' if $sop eq 'NOT'; + + for my $uc (0, 1) { + for my $prefix ('', '-') { + push @tests, { + func => 'where', + args => [{ a => { ($prefix . ($uc ? uc $op : lc $op) ) => undef } }], + stmt => "WHERE a $sop NULL", + stmt_q => "WHERE `a` $sop NULL", + bind => [], + }; + } + } } # check single-element inequality ops for no warnings @@ -631,14 +680,139 @@ for my $op ( qw(like rlike not_like not_rlike), 'not like', 'not rlike', 'is lik } for ('', '-'); # with and without - } +# check emtpty-lhs in a hashpair and arraypair +for my $lhs (undef, '') { + no warnings 'uninitialized'; + +## +## hard exceptions - never worked + for my $where_arg ( + ( map { $_, { @$_ } } + [ $lhs => "foo" ], + [ $lhs => { "=" => "bozz" } ], + [ $lhs => { "=" => \"bozz" } ], + [ $lhs => { -max => \"bizz" } ], + ), + [ -and => { $lhs => "baz" }, bizz => "buzz" ], + [ foo => "bar", { $lhs => "baz" }, bizz => "buzz" ], + { foo => "bar", -or => { $lhs => "baz" } }, + + # the hashref forms of these work sadly - check for warnings below + { foo => "bar", -and => [ $lhs => \"baz" ], bizz => "buzz" }, + { foo => "bar", -or => [ $lhs => \"baz" ], bizz => "buzz" }, + [ foo => "bar", [ $lhs => \"baz" ], bizz => "buzz" ], + [ foo => "bar", $lhs => \"baz", bizz => "buzz" ], + [ foo => "bar", $lhs => \["baz"], bizz => "buzz" ], + [ $lhs => \"baz" ], + [ $lhs => \["baz"] ], + + # except for this one, that is automagically arrayified + { foo => "bar", -or => { $lhs => \"baz" }, bizz => "buzz" }, + ) { + push @tests, { + func => 'where', + args => [ $where_arg ], + throws => qr/\QSupplying an empty left hand side argument is not supported/, + }; + } + +## +## deprecations - sorta worked, likely abused by folks + for my $where_arg ( + # the arrayref forms of this never worked and throw above + { foo => "bar", -and => { $lhs => \"baz" }, bizz => "buzz" }, + { foo => "bar", $lhs => \"baz", bizz => "buzz" }, + { foo => "bar", $lhs => \["baz"], bizz => "buzz" }, + ) { + push @tests, { + func => 'where', + args => [ $where_arg ], + stmt => 'WHERE baz AND bizz = ? AND foo = ?', + stmt_q => 'WHERE baz AND `bizz` = ? AND `foo` = ?', + bind => [qw( buzz bar )], + warns => qr/\QHash-pairs consisting of an empty string with a literal are deprecated/, + }; + } + + for my $where_arg ( + { $lhs => \"baz" }, + { $lhs => \["baz"] }, + ) { + push @tests, { + func => 'where', + args => [ $where_arg ], + stmt => 'WHERE baz', + stmt_q => 'WHERE baz', + bind => [], + warns => qr/\QHash-pairs consisting of an empty string with a literal are deprecated/, + } + } +} + +# check false lhs, silly but possible +{ + for my $where_arg ( + [ { 0 => "baz" }, bizz => "buzz", foo => "bar" ], + [ -or => { foo => "bar", -or => { 0 => "baz" }, bizz => "buzz" } ], + ) { + push @tests, { + func => 'where', + args => [ $where_arg ], + stmt => 'WHERE 0 = ? OR bizz = ? OR foo = ?', + stmt_q => 'WHERE `0` = ? OR `bizz` = ? OR `foo` = ?', + bind => [qw( baz buzz bar )], + }; + } + + for my $where_arg ( + { foo => "bar", -and => [ 0 => \"= baz" ], bizz => "buzz" }, + { foo => "bar", -or => [ 0 => \"= baz" ], bizz => "buzz" }, + + { foo => "bar", -and => { 0 => \"= baz" }, bizz => "buzz" }, + { foo => "bar", -or => { 0 => \"= baz" }, bizz => "buzz" }, + + { foo => "bar", 0 => \"= baz", bizz => "buzz" }, + { foo => "bar", 0 => \["= baz"], bizz => "buzz" }, + ) { + push @tests, { + func => 'where', + args => [ $where_arg ], + stmt => 'WHERE 0 = baz AND bizz = ? AND foo = ?', + stmt_q => 'WHERE `0` = baz AND `bizz` = ? AND `foo` = ?', + bind => [qw( buzz bar )], + }; + } + + for my $where_arg ( + [ -and => [ 0 => \"= baz" ], bizz => "buzz", foo => "bar" ], + [ -or => [ 0 => \"= baz" ], bizz => "buzz", foo => "bar" ], + [ 0 => \"= baz", bizz => "buzz", foo => "bar" ], + [ 0 => \["= baz"], bizz => "buzz", foo => "bar" ], + ) { + push @tests, { + func => 'where', + args => [ $where_arg ], + stmt => 'WHERE 0 = baz OR bizz = ? OR foo = ?', + stmt_q => 'WHERE `0` = baz OR `bizz` = ? OR `foo` = ?', + bind => [qw( buzz bar )], + }; + } +} + for my $t (@tests) { my $new = $t->{new} || {}; for my $quoted (0, 1) { - my $maker = SQL::Abstract->new(%$new, $quoted - ? (quote_char => '`', name_sep => '.') - : () + my $maker = SQL::Abstract->new( + %$new, + ($quoted ? ( + quote_char => '`', + name_sep => '.', + ( $t->{esc} ? ( + escape_char => $t->{esc}, + ) : ()) + ) : ()) ); my($stmt, @bind); @@ -655,10 +829,10 @@ for my $t (@tests) { ) || diag dumper ({ args => $t->{args}, result => $stmt }); } else { - warnings_exist( + warnings_like( sub { $cref->() }, $t->{warns} || [], - ); + ) || diag dumper ({ args => $t->{args}, result => $stmt }); is_same_sql_bind( $stmt,