Class: Hotdog::Expression::MultinaryExpressionNode

Inherits:
ExpressionNode show all
Defined in:
lib/hotdog/expression/semantics.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from ExpressionNode

#optimize

Constructor Details

#initialize(op, expressions, options = {}) ⇒ MultinaryExpressionNode

Returns a new instance of MultinaryExpressionNode.



327
328
329
330
331
332
333
334
335
336
337
338
339
# File 'lib/hotdog/expression/semantics.rb', line 327

def initialize(op, expressions, options={})
  case (op || "or").to_s
  when ",", "||", "|", "OR", "or"
    @op = :OR
  else
    raise(SyntaxError.new("unknown multinary operator: #{op.inspect}"))
  end
  if SQLITE_LIMIT_COMPOUND_SELECT < expressions.length
    raise(ArgumentError.new("expressions limit exceeded: #{expressions.length} for #{SQLITE_LIMIT_COMPOUND_SELECT}"))
  end
  @expressions = expressions
  @fallback = options[:fallback]
end

Instance Attribute Details

#expressionsObject (readonly)

Returns the value of attribute expressions.



325
326
327
# File 'lib/hotdog/expression/semantics.rb', line 325

def expressions
  @expressions
end

#opObject (readonly)

Returns the value of attribute op.



325
326
327
# File 'lib/hotdog/expression/semantics.rb', line 325

def op
  @op
end

Instance Method Details

#dump(options = {}) ⇒ Object



382
383
384
# File 'lib/hotdog/expression/semantics.rb', line 382

def dump(options={})
  {multinary_op: @op.to_s, expressions: expressions.map { |expression| expression.dump(options) }}
end

#evaluate(environment, options = {}) ⇒ Object



349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
# File 'lib/hotdog/expression/semantics.rb', line 349

def evaluate(environment, options={})
  case @op
  when :OR
    if expressions.all? { |expression| TagExpressionNode === expression }
      values = expressions.group_by { |expression| expression.class }.values.flat_map { |expressions|
        query_without_condition = expressions.first.maybe_query_without_condition(options)
        if query_without_condition
          condition_length = expressions.map { |expression| expression.condition_values(options).length }.max
          expressions.each_slice(SQLITE_LIMIT_COMPOUND_SELECT / condition_length).flat_map { |expressions|
            q = query_without_condition.sub(/\s*;\s*\z/, "") + " WHERE " + expressions.map { |expression| "( %s )" % expression.condition(options) }.join(" OR ") + ";"
            environment.execute(q, expressions.flat_map { |expression| expression.condition_values(options) }).map { |row| row.first }
          }
        else
          []
        end
      }
    else
      values = []
    end
  else
    values = []
  end
  if values.empty?
    if @fallback
      @fallback.evaluate(environment, options={})
    else
      []
    end
  else
    values
  end
end

#merge(other, options = {}) ⇒ Object



341
342
343
344
345
346
347
# File 'lib/hotdog/expression/semantics.rb', line 341

def merge(other, options={})
  if MultinaryExpressionNode === other and op == other.op
    MultinaryExpressionNode.new(op, expressions + other.expressions, options)
  else
    MultinaryExpressionNode.new(op, expressions + [other], options)
  end
end