Sha256: f83355526a778984da720d05c6587a3542941dffa8b7808c081b84b69dfd989a
Contents?: true
Size: 1.96 KB
Versions: 4
Compression:
Stored size: 1.96 KB
Contents
module Alf module Sql class Processor class SemiJoin < Processor include JoinSupport def initialize(right, negate = false, builder) super(builder) @right = right @negate = negate end attr_reader :right, :negate 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 def apply_join_strategy(left, right) predicate = build_semijoin_predicate(left, right) expand_where_clause(left, negate ? !predicate : predicate) end def build_semijoin_predicate(left, right) if right.is_table_dee? right.where_clause.predicate else commons = left.to_attr_list & right.to_attr_list subquery = Clip.new(commons, :star, builder).call(right) if commons.size == 0 builder.exists(subquery) elsif commons.size == 1 identifier = left.desaliaser[commons.to_a.first] Predicate::Factory.in(identifier, subquery) else join_pre = join_predicate(left, subquery, commons) subquery = expand_where_clause(subquery, join_pre) builder.exists(subquery) end end end 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 end # class SemiJoin end # class Processor end # module Sql end # module Alf
Version data entries
4 entries across 4 versions & 1 rubygems