lib/bmg/operator/join.rb in bmg-0.17.2 vs lib/bmg/operator/join.rb in bmg-0.17.3

- old
+ new

@@ -6,20 +6,23 @@ # Natural join, following relational algebra # class Join include Operator::Binary - def initialize(type, left, right, on) + DEFAULT_OPTIONS = {} + + def initialize(type, left, right, on, options = {}) @type = type @left = left @right = right @on = on + @options = DEFAULT_OPTIONS.merge(options) end private - attr_reader :on + attr_reader :on, :options public def each index = Hash.new @@ -32,18 +35,30 @@ key = tuple_project(tuple, on) if to_join = index[key] to_join.each do |right| yield right.merge(tuple) end + elsif left_join? + yield(tuple.merge(default_right_tuple)) end end end def to_ast - [ :join, left.to_ast, right.to_ast, on ] + [ :join, left.to_ast, right.to_ast, on, extra_opts ].compact end + protected + + def left_join? + options[:variant] == :left + end + + def default_right_tuple + options[:default_right_tuple] + end + protected ### optimization def _autowrap(type, options) u_left, left_replaced = _unautowrap(left, options) u_right, right_replaced = _unautowrap(right, options) @@ -61,11 +76,16 @@ end private :_unautowrap protected ### inspect + def extra_opts + extra = options.dup.delete_if{|k,v| DEFAULT_OPTIONS[k] == v } + extra.empty? ? nil : extra + end + def args - [ on ] + [ on, extra_opts ].compact end private def tuple_project(tuple, on)