$self->_debug("UNDEF($k) means IS NULL");
push @sqlf, $label . $self->_sqlcase(' is null');
} elsif (ref $v eq 'ARRAY') {
- my @v = @$v;
-
- # multiple elements: multiple options
- $self->_debug("ARRAY($k) means multiple elements: [ @v ]");
-
- # special nesting, like -and, -or, -nest, so shift over
- my $subjoin = $self->_sqlcase('or');
- if ($v[0] =~ /^-(\D+)/) {
- $subjoin = $self->_modlogic($1); # override subjoin
- $self->_debug("OP(-$1) means special logic ($subjoin), shifting...");
- shift @v;
- }
+ if( @$v ) {
+ my @v = @$v;
+ # multiple elements: multiple options
+ $self->_debug("ARRAY($k) means multiple elements: [ @v ]");
+
+ # special nesting, like -and, -or, -nest, so shift over
+ my $subjoin = $self->_sqlcase('or');
+ if ($v[0] =~ /^-(\D+)/) {
+ $subjoin = $self->_modlogic($1); # override subjoin
+ $self->_debug("OP(-$1) means special logic ($subjoin), shifting...");
+ shift @v;
+ }
- # map into an array of hashrefs and recurse
- my @ret = $self->_recurse_where([map { {$k => $_} } @v], $subjoin);
+ # map into an array of hashrefs and recurse
+ my @ret = $self->_recurse_where([map { {$k => $_} } @v], $subjoin);
- # push results into our structure
- push @sqlf, shift @ret;
- push @sqlv, @ret;
+ # push results into our structure
+ push @sqlf, shift @ret;
+ push @sqlv, @ret;
+ } else {
+ $self->_debug("empty ARRAY($k) means 0=1");
+ push @sqlf, '0=1';
+ }
} elsif (ref $v eq 'HASH') {
# modified operator { '!=', 'completed' }
for my $f (sort keys %$v) {
push(@sqlf, ($u =~ /not/i ? "1=1" : "0=1"));
}
push @sqlv, $self->_bindtype($k, @$x);
+ } elsif(@$x) {
+ # multiple elements: multiple options
+ $self->_debug("ARRAY($x) means multiple elements: [ @$x ]");
+ # map into an array of hashrefs and recurse
+ my @ret = $self->_recurse_where([map { {$k => {$f, $_}} } @$x]);
+
+ # push results into our structure
+ push @sqlf, shift @ret;
+ push @sqlv, @ret;
} else {
- # multiple elements: multiple options
- $self->_debug("ARRAY($x) means multiple elements: [ @$x ]");
-
- # map into an array of hashrefs and recurse
- my @ret = $self->_recurse_where([map { {$k => {$f, $_}} } @$x]);
-
- # push results into our structure
- push @sqlf, shift @ret;
- push @sqlv, @ret;
+ #DTRT for $op => []
+ # I feel like <= and >= should resolve to 0=1 but I am not sure.
+ if($f eq '='){
+ push @sqlf, '0=1';
+ } elsif( $f eq '!='){
+ push @sqlf, '1=1';
+ } else {
+ $self->puke("Can not generate SQL for '${f}' comparison of '${k}' using empty array");
+ }
}
} elsif (! defined($x)) {
# undef = NOT null
$stmt = "WHERE user = ? AND ( status = ? OR status = ? OR status = ? )";
@bind = ('nwiger', 'assigned', 'in-progress', 'pending');
+Please note that an empty arrayref will be considered a logical false and
+will generate 0=1.
+
If you want to specify a different type of operator for your comparison,
you can use a hashref for a given column:
status => { '!=', ['assigned', 'in-progress', 'pending'] };
+An empty arrayref will try to Do The Right Thing for the operators '=', '!=',
+'-in' '-not_in', but will throw an exception for everything else.
+
Which would give you:
"WHERE status != ? OR status != ? OR status != ?"
use strict;
use warnings;
use Test::More;
+use Test::Exception;
-plan tests => 24;
+plan tests => 27;
use SQL::Abstract;
bind => [7,8,9,'a','b',100,200,150,160,'zz','yy','30','40'],
},
+ {
+ where => {
+ id => [],
+ bar => {'!=' => []},
+ },
+ stmt => " WHERE ( 1=1 AND 0=1 )",
+ bind => [],
+ },
+
);
-for (@handle_tests) {
- local $" = ', ';
- #print "creating a handle with args ($_->{args}): ";
+for my $case (@handle_tests) {
my $sql = SQL::Abstract->new;
-
- # run twice
- for (my $i=0; $i < 2; $i++) {
- my($stmt, @bind) = $sql->where($_->{where}, $_->{order});
- my $bad = 0;
- for(my $i=0; $i < @{$_->{bind}}; $i++) {
- $bad++ unless $_->{bind}[$i] eq $bind[$i];
- }
-
- ok($stmt eq $_->{stmt} && @bind == @{$_->{bind}} && ! $bad) or
- print "got\n",
- "[$stmt] [@bind]\n",
- "instead of\n",
- "[$_->{stmt}] [@{$_->{bind}}]\n\n";
- }
+ my($stmt, @bind) = $sql->where($case->{where}, $case->{order});
+ is($stmt, $case->{stmt});
+ is_deeply(\@bind, $case->{bind});
}
+dies_ok {
+ my $sql = SQL::Abstract->new;
+ $sql->where({ foo => { '>=' => [] }},);
+}