class Sequel::SQL::ComplexExpression

  1. lib/sequel/sql.rb
Superclass: Expression

Represents a SQL expression, with a given operator and one or more attributes (which may also be ComplexExpressions, forming a tree). This class is the backbone of Sequel’s ruby expression DSL.

This is an abstract class that is not that useful by itself. The subclasses BooleanExpression, NumericExpression, and StringExpression define the behavior of the DSL via operators.

Methods

Public Class

  1. new

Public Instance

  1. args
  2. op
  3. sql_boolean
  4. sql_number
  5. sql_string

Constants

ASSOCIATIVE_OPERATORS = [:AND, :OR, :'||', :+, :*, :&, :|].freeze  

Operator symbols that are associative

BITWISE_OPERATORS = [:&, :|, :^, :<<, :>>, :%].freeze  

Bitwise mathematical operators used in BitwiseMethods

BOOLEAN_OPERATOR_METHODS = {:& => :AND, :| =>:OR}.freeze  

Hash of ruby operator symbols to SQL operators, used in BooleanMethods

CONSTANT_INVERSIONS = {Constants::TRUE=>Constants::FALSE, Constants::FALSE=>Constants::TRUE, Constants::NULL=>Constants::NOTNULL, Constants::NOTNULL=>Constants::NULL}.freeze  

A hash of the opposite for each constant, used for inverting constants.

CUSTOM_EXPRESSIONS = [:extract].freeze  

Custom expressions that may have different syntax on different databases

EQUALITY_OPERATORS = [:'=', :'!='].freeze  

Operators that check for equality

INEQUALITY_OPERATORS = [:<, :>, :<=, :>=].freeze  

Inequality operators used in InequalityMethods

IN_OPERATORS = [:IN, :'NOT IN'].freeze  

Operators that use IN/NOT IN for inclusion/exclusion

IS_OPERATORS = [:IS, :'IS NOT'].freeze  

Operators that use IS, used for special casing to override literal true/false values

LIKE_OPERATORS = [:LIKE, :'NOT LIKE', :ILIKE, :'NOT ILIKE'].freeze  

Operators that do pattern matching via LIKE

MATHEMATICAL_OPERATORS = [:+, :-, :/, :*, :**].freeze  

Standard mathematical operators used in NumericMethods

N_ARITY_OPERATORS = ([:AND, :OR, :'||'] + MATHEMATICAL_OPERATORS + BITWISE_OPERATORS - [:**]).freeze  

Operator symbols that take one or more arguments

ONE_ARITY_OPERATORS = [:NOT, :NOOP, :'B~'].freeze  

Operator symbols that take only a single argument

OPERATOR_INVERSIONS = {:AND => :OR, :OR => :AND, :< => :>=, :> => :<=, :<= => :>, :>= => :<, :'=' => :'!=' , :'!=' => :'=', :LIKE => :'NOT LIKE', :'NOT LIKE' => :LIKE, :~ => :'!~', :'!~' => :~, :IN => :'NOT IN', :'NOT IN' => :IN, :IS => :'IS NOT', :'IS NOT' => :IS, :'~*' => :'!~*', :'!~*' => :'~*', :NOT => :NOOP, :NOOP => :NOT, :ILIKE => :'NOT ILIKE', :'NOT ILIKE'=>:ILIKE}.freeze  

A hash of the opposite for each operator symbol, used for inverting objects.

OPERTATOR_INVERSIONS = OPERATOR_INVERSIONS  

SEQUEL6: Remove

REGEXP_OPERATORS = [:~, :'!~', :'~*', :'!~*'].freeze  

Operators that do pattern matching via regular expressions

TWO_ARITY_OPERATORS = (EQUALITY_OPERATORS + INEQUALITY_OPERATORS + IS_OPERATORS + IN_OPERATORS + REGEXP_OPERATORS + LIKE_OPERATORS + [:**]).freeze  

Operator symbols that take exactly two arguments

Attributes

args [R]

An array of args for this object

op [R]

The operator symbol for this object

Public Class methods

new(op, *args)

Set the operator symbol and arguments for this object to the ones given. Convert all args that are hashes or arrays of two element arrays to BooleanExpressions, other than the second arg for an IN/NOT IN operator. Raise an Error if the operator doesn’t allow boolean input and a boolean argument is given. Raise an Error if the wrong number of arguments for a given operator is used.

[show source]
    # File lib/sequel/sql.rb
219 def initialize(op, *args)
220   orig_args = args
221   args = args.map{|a| Sequel.condition_specifier?(a) ? SQL::BooleanExpression.from_value_pairs(a) : a}
222   case op
223   when *N_ARITY_OPERATORS
224     raise(Error, "The #{op} operator requires at least 1 argument") unless args.length >= 1
225     args.map!{|a| a.is_a?(self.class) && a.op == :NOOP ? a.args.first : a}
226     if ASSOCIATIVE_OPERATORS.include?(op)
227       old_args = args
228       args = []
229       old_args.each{|a| a.is_a?(self.class) && a.op == op ? args.concat(a.args) : args.push(a)}
230     end
231   when *TWO_ARITY_OPERATORS
232     raise(Error, "The #{op} operator requires precisely 2 arguments") unless args.length == 2
233     # With IN/NOT IN, even if the second argument is an array of two element arrays,
234     # don't convert it into a boolean expression, since it's definitely being used
235     # as a value list.
236     args[1] = orig_args[1] if IN_OPERATORS.include?(op)
237   when *ONE_ARITY_OPERATORS
238     raise(Error, "The #{op} operator requires a single argument") unless args.length == 1
239   when *CUSTOM_EXPRESSIONS
240     # nothing
241   else
242     raise(Error, "Invalid operator #{op}")
243   end
244   @op = op
245   @args = args.freeze
246   freeze
247 end

Public Instance methods

sql_boolean()

Return a BooleanExpression with the same op and args.

[show source]
     # File lib/sequel/sql.rb
1275 def sql_boolean
1276   BooleanExpression.new(op, *args)
1277 end
sql_number()

Return a NumericExpression with the same op and args.

[show source]
     # File lib/sequel/sql.rb
1280 def sql_number
1281   NumericExpression.new(op, *args)
1282 end
sql_string()

Return a StringExpression with the same op and args.

[show source]
     # File lib/sequel/sql.rb
1285 def sql_string
1286   StringExpression.new(op, *args)
1287 end