From: Peter Rabbitson Date: Tue, 22 Sep 2009 08:10:34 +0000 (+0000) Subject: Allow scalarref in IN and open up non-grouping parenthesis around IN arguments (saves... X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=4a1f01a3175d4c88af2adebe6b0482e57ee4c88a;p=scpubgit%2FQ-Branch.git Allow scalarref in IN and open up non-grouping parenthesis around IN arguments (saves sqlite from brain damage) --- diff --git a/lib/SQL/Abstract.pm b/lib/SQL/Abstract.pm index 7740f79..431d428 100644 --- a/lib/SQL/Abstract.pm +++ b/lib/SQL/Abstract.pm @@ -893,20 +893,34 @@ sub _where_field_IN { } }, + SCALARREF => sub { # literal SQL + my $sql = $self->_open_outer_paren ($$vals); + return ("$label $op ( $sql )"); + }, ARRAYREFREF => sub { # literal SQL with bind my ($sql, @bind) = @$$vals; $self->_assert_bindval_matches_bindtype(@bind); + $sql = $self->_open_outer_paren ($sql); return ("$label $op ( $sql )", @bind); }, FALLBACK => sub { - puke "special op 'in' requires an arrayref (or arrayref-ref)"; + puke "special op 'in' requires an arrayref (or scalarref/arrayref-ref)"; }, }); return ($sql, @bind); } +# Some databases (SQLite) treat col IN (1, 2) different from +# col IN ( (1, 2) ). Use this to strip all outer parens while +# adding them back in the corresponding method +sub _open_outer_paren { + my ($self, $sql) = @_; + $sql = $1 while $sql =~ /^ \s* \( (.*) \) \s* $/x; + return $sql; +} + #====================================================================== # ORDER BY diff --git a/t/05between.t b/t/05in_between.t similarity index 80% rename from t/05between.t rename to t/05in_between.t index a155b20..ae6e61c 100644 --- a/t/05between.t +++ b/t/05in_between.t @@ -9,20 +9,6 @@ use SQL::Abstract::Test import => ['is_same_sql_bind']; use Data::Dumper; use SQL::Abstract; -=begin -Test -between and -in - * between - * [scalar, scalar] - * [scalarref, scalar] - * [scalar, scalarref] - * [scalarref, scalarref] - * \[] - * \["? AND ?", scalar, scalar] - * \["1 AND ?", scalar] - * \["? AND 2", scalar] - * \["1 AND 2"] -=cut - my @in_between_tests = ( { where => { x => { -between => [1, 2] } }, @@ -78,6 +64,29 @@ my @in_between_tests = ( bind => [], test => '-between with literal sql with a literal (\"\'this\' AND \'that\'")', }, + + + { + parenthesis_significant => 1, + where => { x => { -in => [ 1 .. 3] } }, + stmt => "WHERE ( x IN (?, ?, ?) )", + bind => [ 1 .. 3], + test => '-in with an array of scalars', + }, + { + parenthesis_significant => 1, + where => { x => { -in => \'( 1,2,lower(y) )' } }, + stmt => "WHERE ( x IN (1, 2, lower(y) ) )", + bind => [], + test => '-in with a literal scalarref', + }, + { + parenthesis_significant => 1, + where => { x => { -in => \['( ( ?,?,lower(y) ) )', 1, 2] } }, + stmt => "WHERE ( x IN (?, ?, lower(y) ) )", + bind => [1, 2], + test => '-in with a literal arrayrefref', + }, ); plan tests => @in_between_tests*4; @@ -85,6 +94,7 @@ plan tests => @in_between_tests*4; for my $case (@in_between_tests) { TODO: { local $TODO = $case->{todo} if $case->{todo}; + local $SQL::Abstract::Test::parenthesis_significant = $case->{parenthesis_significant}; local $Data::Dumper::Terse = 1;