# GLOBALS
#======================================================================
-our $VERSION = '1.63';
+our $VERSION = '1.63_01';
# This would confuse some packagers
#$VERSION = eval $VERSION; # numify for warning-free dev releases
# default comparison is "=", but can be overridden
$opt{cmp} ||= '=';
- # generic SQL comparison operators
- my $anchored_cmp_ops = join ('|', map { '^' . $_ . '$' } (
- '(?:is \s+)? (?:not \s+)? i? like',
- 'is',
- (map { quotemeta($_) } (qw/ < > != <> = <= >= /) ),
- ));
- $opt{cmp_ops} = qr/$anchored_cmp_ops/ix;
-
# try to recognize which are the 'equality' and 'unequality' ops
# (temporary quickfix, should go through a more seasoned API)
$opt{equality_op} = qr/^(\Q$opt{cmp}\E|is|(is\s+)?like)$/i;
# dispatch on appropriate method according to refkind of $where
my $method = $self->_METHOD_FOR_refkind("_where", $where);
-
my ($sql, @bind) = $self->$method($where, $logic);
# DBIx::Class directly calls _recurse_where in scalar context, so
}
else {
$self->debug("Generic unary OP: $k - recursing as function");
- $self->_where_func_generic ($op, $v);
+ my ($sql, @bind) = $self->_where_func_generic ($op, $v);
+ $sql = "($sql)" unless $self->{_nested_func_lhs} eq $k; # top level vs nested
+ ($sql, @bind);
}
}
else {
},
});
- $sql = sprintf ('%s%s',
+ $sql = sprintf ('%s %s',
$self->_sqlcase($op),
- ($op =~ $self->{cmp_ops}) ? " $sql" : "( $sql )",
+ $sql,
);
return ($sql, @bind);
FALLBACK => sub { # CASE: col => {op/func => $stuff}
- # if we are starting to nest and the first func is not a cmp op
- # assume equality
- my $prefix;
- unless ($self->{_nested_func_lhs}) {
- $self->{_nested_func_lhs} = $k;
- $prefix = $self->{cmp} unless $op =~ $self->{cmp_ops};
- }
+ # retain for proper column type bind
+ $self->{_nested_func_lhs} ||= $k;
($sql, @bind) = $self->_where_func_generic ($op, $val);
- $sql = join ' ', $self->_convert($self->_quote($k)), $prefix||(), $sql;
+
+ $sql = join (' ',
+ $self->_convert($self->_quote($k)),
+ $self->{_nested_func_lhs} eq $k ? $sql : "($sql)", # top level vs nested
+ );
},
});
}
{
func => 'select',
new => {bindtype => 'columns'},
- args => ['test', '*', [ Y => { -max => { -LENGTH => { -min => 'x' } } } ] ],
- stmt => 'SELECT * FROM test WHERE ( Y = MAX( LENGTH( MIN( ? ) ) ) )',
- stmt_q => 'SELECT * FROM `test` WHERE ( `Y` = MAX( LENGTH( MIN( ? ) ) ) )',
+ args => ['test', '*', [ Y => { '=' => { -max => { -LENGTH => { -min => 'x' } } } } ] ],
+ stmt => 'SELECT * FROM test WHERE ( Y = ( MAX( LENGTH( MIN ? ) ) ) )',
+ stmt_q => 'SELECT * FROM `test` WHERE ( `Y` = ( MAX( LENGTH( MIN ? ) ) ) )',
bind => [[Y => 'x']],
},
);
# Op against random functions (these two are oracle-specific)
{
- where => { timestamp => { '!=' => { -trunc => \'sysdate' } } },
- stmt => " WHERE ( timestamp != TRUNC(sysdate) )",
+ where => { timestamp => { '!=' => { -trunc => { -year => \'sysdate' } } } },
+ stmt => " WHERE ( timestamp != TRUNC (YEAR sysdate) )",
bind => [],
},
{
where => { timestamp => { '>=' => { -TO_DATE => '2009-12-21 00:00:00' } } },
- stmt => " WHERE ( timestamp >= TO DATE(?) )",
+ stmt => " WHERE ( timestamp >= TO DATE ? )",
bind => ['2009-12-21 00:00:00'],
},
+# Legacy function specs
+ {
+ where => { ip => {'<<=' => '127.0.0.1/32' } },
+ stmt => "WHERE ( ip <<= ? )",
+ bind => ['127.0.0.1/32'],
+ },
+ {
+ where => { foo => { 'GLOB' => '*str*' } },
+ stmt => " WHERE foo GLOB ? ",
+ bind => [ '*str*' ],
+ },
+ {
+ where => { foo => { 'REGEXP' => 'bar|baz' } },
+ stmt => " WHERE foo REGEXP ? ",
+ bind => [ 'bar|baz' ],
+ },
);
plan tests => ( @handle_tests * 2 ) + 1;