class Bmg::Sql::Processor::SemiJoin

Attributes

negate[R]
on[R]
right[R]

Public Class Methods

new(right, on, negate = false, builder) click to toggle source
Calls superclass method Bmg::Sql::Processor::new
# File lib/bmg/sql/processor/semi_join.rb, line 7
def initialize(right, on, negate = false, builder)
  super(builder)
  @right  = right
  @on = on
  @negate = negate
end

Public Instance Methods

call(sexpr) click to toggle source
Calls superclass method
# File lib/bmg/sql/processor/semi_join.rb, line 15
def call(sexpr)
  if sexpr.set_operator?
    call(builder.from_self(sexpr))
  elsif right.set_operator?
    SemiJoin.new(builder.from_self(right), negate, builder).call(sexpr)
  else
    super(sexpr)
  end
end

Private Instance Methods

apply_join_strategy(left, right) click to toggle source
# File lib/bmg/sql/processor/semi_join.rb, line 27
def apply_join_strategy(left, right)
  predicate = build_semijoin_predicate(left, right)
  expand_where_clause(left, negate ? !predicate : predicate)
end
build_semijoin_predicate(left, right) click to toggle source
# File lib/bmg/sql/processor/semi_join.rb, line 32
def build_semijoin_predicate(left, right)
  if right.is_table_dee?
    right.where_clause.predicate
  else
    commons = self.on
    subquery = Clip.new(commons, false, :star, builder).call(right)
    subquery = Requalify.new(builder).call(subquery)
    subquery = All.new(builder).call(subquery)
    if commons.size == 0
      builder.exists(subquery)
    elsif commons.size == 1
      identifier = left.desaliaser(true)[commons.to_a.first]
      Predicate::Factory.in(identifier, Predicate::Factory.opaque(subquery))
    else
      join_pre  = join_predicate(left, subquery, commons)
      subquery  = expand_where_clause(subquery, join_pre)
      subquery  = Star.new(builder).call(subquery)
      builder.exists(subquery)
    end
  end
end
expand_where_clause(sexpr, predicate) click to toggle source
# File lib/bmg/sql/processor/semi_join.rb, line 54
def expand_where_clause(sexpr, predicate)
  Grammar.sexpr \
    [ :select_exp,
      sexpr.set_quantifier,
      sexpr.select_list,
      sexpr.from_clause,
      [ :where_clause, (sexpr.predicate || tautology) & predicate ],
      sexpr.order_by_clause,
      sexpr.limit_clause,
      sexpr.offset_clause ].compact
end