class Sequel::SQL::BooleanExpression

Subclass of ComplexExpression where the expression results in a boolean value in SQL.

Public Class Methods

from_value_pairs(pairs, op=:AND, negate=false) click to toggle source

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)
     # File lib/sequel/sql.rb
1079 def self.from_value_pairs(pairs, op=:AND, negate=false)
1080   pairs = pairs.map{|l,r| from_value_pair(l, r)}
1081   pairs.map!{|ce| invert(ce)} if negate
1082   pairs.length == 1 ? pairs[0] : new(op, *pairs)
1083 end
invert(ce) click to toggle source

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"
     # File lib/sequel/sql.rb
1138 def self.invert(ce)
1139   case ce
1140   when BooleanExpression
1141     case op = ce.op
1142     when :AND, :OR
1143       BooleanExpression.new(OPERTATOR_INVERSIONS[op], *ce.args.map{|a| BooleanExpression.invert(a)})
1144     when :IN, :"NOT IN"
1145       BooleanExpression.new(OPERTATOR_INVERSIONS[op], *ce.args.dup)
1146     else
1147       if ce.args.length == 2
1148         case ce.args[1]
1149         when Function, LiteralString, PlaceholderLiteralString
1150           # Special behavior to not push down inversion in this case because doing so
1151           # can result in incorrect behavior for ANY/SOME/ALL operators.
1152           BooleanExpression.new(:NOT, ce)
1153         else
1154           BooleanExpression.new(OPERTATOR_INVERSIONS[op], *ce.args.dup)
1155         end
1156       else
1157         BooleanExpression.new(OPERTATOR_INVERSIONS[op], *ce.args.dup)
1158       end
1159     end
1160   when StringExpression, NumericExpression
1161     raise(Sequel::Error, "cannot invert #{ce.inspect}")
1162   when Constant
1163     CONSTANT_INVERSIONS[ce] || raise(Sequel::Error, "cannot invert #{ce.inspect}")
1164   else
1165     BooleanExpression.new(:NOT, ce)
1166   end
1167 end

Private Class Methods

from_value_pair(l, r) click to toggle source

Return a BooleanExpression based on the right side of the pair.

     # File lib/sequel/sql.rb
1086 def self.from_value_pair(l, r)
1087   case r
1088   when Range
1089     unless r.begin.nil?
1090       begin_expr = new(:>=, l, r.begin)
1091     end
1092     unless r.end.nil?
1093       end_expr = new(r.exclude_end? ? :< : :<=, l, r.end)
1094     end
1095     if begin_expr
1096       if end_expr
1097         new(:AND, begin_expr, end_expr)
1098       else
1099         begin_expr
1100       end
1101     elsif end_expr
1102       end_expr
1103     else
1104       new(:'=', 1, 1)
1105     end
1106   when ::Array
1107     r = r.dup.freeze unless r.frozen?
1108     new(:IN, l, r)
1109   when ::String
1110     r = r.dup.freeze unless r.frozen?
1111     new(:'=', l, r)
1112   when ::Sequel::Dataset
1113     new(:IN, l, r)
1114   when NegativeBooleanConstant
1115     new(:"IS NOT", l, r.constant)
1116   when BooleanConstant
1117     new(:IS, l, r.constant)
1118   when NilClass, TrueClass, FalseClass
1119     new(:IS, l, r)
1120   when Regexp
1121     StringExpression.like(l, r)
1122   when DelayedEvaluation
1123     Sequel.delay{|ds| from_value_pair(l, r.call(ds))}
1124   when Dataset::PlaceholderLiteralizer::Argument
1125     r.transform{|v| from_value_pair(l, v)}
1126   else
1127     new(:'=', l, r)
1128   end
1129 end

Public Instance Methods

&(ce) click to toggle source

Always use an AND operator for & on BooleanExpressions

     # File lib/sequel/sql.rb
1170 def &(ce)
1171   BooleanExpression.new(:AND, self, ce)
1172 end
sql_boolean() click to toggle source

Return self instead of creating a new object to save on memory.

     # File lib/sequel/sql.rb
1180 def sql_boolean
1181   self
1182 end
|(ce) click to toggle source

Always use an OR operator for | on BooleanExpressions

     # File lib/sequel/sql.rb
1175 def |(ce)
1176   BooleanExpression.new(:OR, self, ce)
1177 end