[Dbix-class] SQL::Abstract inequality warning

Dagfinn Ilmari Mannsåker ilmari at ilmari.org
Fri Dec 12 17:21:28 GMT 2014


Duncan Garland <duncan.garland at motortrak.com> writes:

> Hi,
>
>
> Can somebody explain why I've started to get this warning when I run the
> statement below.
>
> As far as I can see, I'm doing exactly as asked, and the code works so it
> doesn't evaluate to 1=1.

It doesn't evaluate to literally "1=1", but by default array refs are
ORed, so it evaluates to 'foo != x OR foo != y', which is always true
if x != y.

> SQL::Abstract::belch(): [SQL::Abstract::_where_field_op_ARRAYREF] Warning:
> A multi-element arrayref as an argument to the inequality op '!=' is
> technically equivalent to an always-true 1=1 (you probably wanted to say
> ...{ $inequality_op => [ -and => @values ] }... instead)

Note it says @values, not \@values. [ -and => ... ] and [ -or => ... ]
only override the operator used between the rest of the values in that
same array, not recursively into contained arrays.

>   my @service_contracts = $c->model('DB::Mbfl2ServiceContract')->search(
>     { vehicle_id => $vehicle_id,
>       deleted_yn => 'N',
>       status     => { '!=' => [ '-and' => [ 'T', 'X', 'E' ] ] }

If you run this with DBIC_TRACE=1, you'll see this renders as

     status != ? OR status != ? OR status != ?

If you'd had [ -and => [...], [...] ] you would have seen it more clearly

    (status != ? OR status != ?) AND (status != ? OR status != ?)

What you actually want is:

        status     => { '!=' => [ '-and' => 'T', 'X', 'E' ] }

Which renders as 

    status != ? AND status != ? AND status != ?

Hope this clarifies things.

-- 
"The surreality of the universe tends towards a maximum" -- Skud's Law
"Never formulate a law or axiom that you're not prepared to live with
 the consequences of."                              -- Skud's Meta-Law




More information about the DBIx-Class mailing list