module Sequel::SQL::BooleanExpression::ClassMethods

  1. lib/sequel/sql.rb

Methods

Public Instance

  1. from_value_pairs
  2. invert

Public Instance methods

from_value_pairs(pairs, op=:AND, negate=false)

Take pairs of values (e.g. a hash or array of two element arrays) and converts it to a BooleanExpression. The operator and args used depends on the case of the right (2nd) argument:

0..10

left >= 0 AND left <= 10

1,2

left IN (1,2)

nil

left IS NULL

true

left IS TRUE

false

left IS FALSE

/as/

left ~ ‘as’

:blah

left = blah

‘blah’

left = ‘blah’

If multiple arguments are given, they are joined with the op given (AND by default, OR possible). If negate is set to true, all subexpressions are inverted before used. Therefore, the following expressions are equivalent:

~from_value_pairs(hash)
from_value_pairs(hash, :OR, true)
[show source]
     # File lib/sequel/sql.rb
1085 def from_value_pairs(pairs, op=:AND, negate=false)
1086   pairs = pairs.map{|l,r| from_value_pair(l, r)}
1087   pairs.map!{|ce| invert(ce)} if negate
1088   pairs.length == 1 ? pairs[0] : new(op, *pairs)
1089 end
invert(ce)

Invert the expression, if possible. If the expression cannot be inverted, raise an error. An inverted expression should match everything that the uninverted expression did not match, and vice-versa, except for possible issues with SQL NULL (i.e. 1 == NULL is NULL and 1 != NULL is also NULL).

BooleanExpression.invert(:a) # NOT "a"
[show source]
     # File lib/sequel/sql.rb
1150 def invert(ce)
1151   case ce
1152   when BooleanExpression
1153     case op = ce.op
1154     when :AND, :OR
1155       BooleanExpression.new(ComplexExpression::OPERATOR_INVERSIONS[op], *ce.args.map{|a| BooleanExpression.invert(a)})
1156     when :IN, :"NOT IN"
1157       BooleanExpression.new(ComplexExpression::OPERATOR_INVERSIONS[op], *ce.args.dup)
1158     else
1159       if ce.args.length == 2
1160         case ce.args[1]
1161         when Function, LiteralString, PlaceholderLiteralString
1162           # Special behavior to not push down inversion in this case because doing so
1163           # can result in incorrect behavior for ANY/SOME/ALL operators.
1164           BooleanExpression.new(:NOT, ce)
1165         else
1166           BooleanExpression.new(ComplexExpression::OPERATOR_INVERSIONS[op], *ce.args.dup)
1167         end
1168       else
1169         BooleanExpression.new(ComplexExpression::OPERATOR_INVERSIONS[op], *ce.args.dup)
1170       end
1171     end
1172   when StringExpression, NumericExpression
1173     raise(Sequel::Error, "cannot invert #{ce.inspect}")
1174   when Constant
1175     ComplexExpression::CONSTANT_INVERSIONS[ce] || raise(Sequel::Error, "cannot invert #{ce.inspect}")
1176   else
1177     BooleanExpression.new(:NOT, ce)
1178   end
1179 end