Class: Sequel::SQL::ComplexExpression

Inherits:
Expression show all
Includes:
AliasMethods, CastMethods, OrderMethods, SubscriptMethods
Defined in:
lib/sequel/sql.rb,
lib/sequel/sql.rb,
lib/sequel/sql.rb

Overview

Represents a complex 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.

Constant Summary collapse

OPERTATOR_INVERSIONS =

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

{: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}
MATHEMATICAL_OPERATORS =

Standard mathematical operators used in NumericMethods

[:+, :-, :/, :*]
BITWISE_OPERATORS =

Bitwise mathematical operators used in NumericMethods

[:&, :|, :^, :<<, :>>]
INEQUALITY_OPERATORS =

Inequality operators used in InequalityMethods

[:<, :>, :<=, :>=]
BOOLEAN_OPERATOR_METHODS =

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

{:& => :AND, :| =>:OR}
IN_OPERATORS =

Operators that use IN/NOT IN for inclusion/exclusion

[:IN, :'NOT IN']
IS_OPERATORS =

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

[:IS, :'IS NOT']
TWO_ARITY_OPERATORS =

Operator symbols that take exactly two arguments

[:'=', :'!=', :LIKE, :'NOT LIKE', \
:~, :'!~', :'~*', :'!~*', :ILIKE, :'NOT ILIKE'] + \
INEQUALITY_OPERATORS + BITWISE_OPERATORS + IS_OPERATORS + IN_OPERATORS
N_ARITY_OPERATORS =

Operator symbols that take one or more arguments

[:AND, :OR, :'||'] + MATHEMATICAL_OPERATORS
ONE_ARITY_OPERATORS =

Operator symbols that take only a single argument

[:NOT, :NOOP, :'B~']
CONSTANT_INVERSIONS =

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

{Constants::TRUE=>Constants::FALSE, Constants::FALSE=>Constants::TRUE,
Constants::NULL=>Constants::NOTNULL, Constants::NOTNULL=>Constants::NULL}

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from SubscriptMethods

#sql_subscript

Methods included from OrderMethods

#asc, #desc

Methods included from CastMethods

#cast, #cast_numeric, #cast_string

Methods included from AliasMethods

#as

Methods inherited from Expression

#==, attr_reader, comparison_attrs, #eql?, #hash, #inspect, #lit, #sql_literal

Constructor Details

#initialize(op, *args) ⇒ ComplexExpression

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.



171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
# File 'lib/sequel/sql.rb', line 171

def initialize(op, *args)
  orig_args = args
  args = args.map{|a| Sequel.condition_specifier?(a) ? SQL::BooleanExpression.from_value_pairs(a) : a}
  case op
  when *N_ARITY_OPERATORS
    raise(Error, "The #{op} operator requires at least 1 argument") unless args.length >= 1
    old_args = args
    args = []
    old_args.each{|a| a.is_a?(self.class) && a.op == op ? args.concat(a.args) : args.push(a)}
  when *TWO_ARITY_OPERATORS
    raise(Error, "The #{op} operator requires precisely 2 arguments") unless args.length == 2
    # With IN/NOT IN, even if the second argument is an array of two element arrays,
    # don't convert it into a boolean expression, since it's definitely being used
    # as a value list.
    args[1] = orig_args[1] if IN_OPERATORS.include?(op)
  when *ONE_ARITY_OPERATORS
    raise(Error, "The #{op} operator requires a single argument") unless args.length == 1
  else
    raise(Error, "Invalid operator #{op}")
  end
  @op = op
  @args = args
end

Instance Attribute Details

#argsObject (readonly)

An array of args for this object



161
162
163
# File 'lib/sequel/sql.rb', line 161

def args
  @args
end

#opObject (readonly)

The operator symbol for this object



164
165
166
# File 'lib/sequel/sql.rb', line 164

def op
  @op
end