bmg 0.18.0 → 0.18.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +1 -0
- data/lib/bmg/algebra.rb +1 -0
- data/lib/bmg/algebra/shortcuts.rb +6 -0
- data/lib/bmg/error.rb +3 -0
- data/lib/bmg/operator/allbut.rb +27 -0
- data/lib/bmg/operator/autosummarize.rb +27 -4
- data/lib/bmg/operator/autowrap.rb +27 -0
- data/lib/bmg/operator/constants.rb +7 -0
- data/lib/bmg/operator/extend.rb +7 -0
- data/lib/bmg/operator/group.rb +1 -0
- data/lib/bmg/operator/image.rb +41 -2
- data/lib/bmg/operator/join.rb +1 -0
- data/lib/bmg/operator/matching.rb +1 -0
- data/lib/bmg/operator/not_matching.rb +1 -0
- data/lib/bmg/operator/page.rb +2 -7
- data/lib/bmg/operator/project.rb +3 -2
- data/lib/bmg/operator/rename.rb +12 -5
- data/lib/bmg/operator/restrict.rb +1 -0
- data/lib/bmg/operator/rxmatch.rb +1 -0
- data/lib/bmg/operator/summarize.rb +2 -17
- data/lib/bmg/operator/transform.rb +39 -1
- data/lib/bmg/operator/union.rb +1 -0
- data/lib/bmg/reader/csv.rb +29 -10
- data/lib/bmg/reader/excel.rb +23 -4
- data/lib/bmg/relation.rb +18 -0
- data/lib/bmg/relation/empty.rb +4 -0
- data/lib/bmg/relation/in_memory.rb +10 -1
- data/lib/bmg/relation/materialized.rb +6 -0
- data/lib/bmg/relation/spied.rb +5 -0
- data/lib/bmg/sequel/relation.rb +5 -0
- data/lib/bmg/sql/relation.rb +2 -3
- data/lib/bmg/summarizer.rb +36 -1
- data/lib/bmg/summarizer/avg.rb +3 -3
- data/lib/bmg/summarizer/by_proc.rb +41 -0
- data/lib/bmg/summarizer/distinct.rb +36 -0
- data/lib/bmg/summarizer/multiple.rb +46 -0
- data/lib/bmg/summarizer/percentile.rb +79 -0
- data/lib/bmg/summarizer/value_by.rb +62 -0
- data/lib/bmg/support.rb +1 -0
- data/lib/bmg/support/ordering.rb +20 -0
- data/lib/bmg/support/tuple_transformer.rb +10 -1
- data/lib/bmg/version.rb +1 -1
- data/lib/bmg/writer.rb +16 -0
- data/lib/bmg/writer/csv.rb +2 -12
- data/lib/bmg/writer/xlsx.rb +68 -0
- metadata +23 -2
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 6569e9038c83dda887da734d97ef58f9ff6e94984c78e8eae993561cde3bbfcc
         | 
| 4 | 
            +
              data.tar.gz: 85d65ca717992a132e94ae17dbdf2cc671a161c495eb5be240c3d4e342e90c3f
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: fbeb5215e5942626dd5115d95c091602daa57128014bc0833c38c3460697ef9dbc59b4ccd7566d4d3604e8d7a8c5e7e4812159a5bb89d3dad477e6a7b75545d8
         | 
| 7 | 
            +
              data.tar.gz: 9e8a9eaaf3699d28890cb15faef5b12360f9bf26c5bb0e9bf42ccedba0b7b5a3c8c2eb627f8b1a4e154c8d992426f47ed82153e9f110634f0ba6aa7ceddd1353
         | 
    
        data/README.md
    CHANGED
    
    | @@ -213,6 +213,7 @@ r.extend(x: ->(t){ ... }, ...)               # add computed attributes | |
| 213 213 | 
             
            r.exclude(predicate)                         # shortcut for restrict(!predicate)
         | 
| 214 214 | 
             
            r.group([:a, :b, ...], :x)                   # relation-valued attribute from attributes
         | 
| 215 215 | 
             
            r.image(right, :x, [:a, :b, ...])            # relation-valued attribute from another relation
         | 
| 216 | 
            +
            r.images({:x => r1, :y => r2}, [:a, ...])    # shortcut over image(r1, :x, ...).image(r2, :y, ...)
         | 
| 216 217 | 
             
            r.join(right, [:a, :b, ...])                 # natural join on a join key
         | 
| 217 218 | 
             
            r.join(right, :a => :x, :b => :y, ...)       # natural join after right reversed renaming
         | 
| 218 219 | 
             
            r.left_join(right, [:a, :b, ...], {...})     # left join with optional default right tuple
         | 
    
        data/lib/bmg/algebra.rb
    CHANGED
    
    | @@ -174,6 +174,7 @@ module Bmg | |
| 174 174 |  | 
| 175 175 | 
             
                def transform(transformation = nil, options = {}, &proc)
         | 
| 176 176 | 
             
                  transformation, options = proc, (transformation || {}) unless proc.nil?
         | 
| 177 | 
            +
                  return self if transformation.is_a?(Hash) && transformation.empty?
         | 
| 177 178 | 
             
                  _transform(self.type.transform(transformation, options), transformation, options)
         | 
| 178 179 | 
             
                end
         | 
| 179 180 |  | 
| @@ -39,6 +39,12 @@ module Bmg | |
| 39 39 | 
             
                    self.image(right.rename(renaming), as, on.keys, options)
         | 
| 40 40 | 
             
                  end
         | 
| 41 41 |  | 
| 42 | 
            +
                  def images(rights, on = [], options = {})
         | 
| 43 | 
            +
                    rights.each_pair.inject(self){|memo,(as,right)|
         | 
| 44 | 
            +
                      memo.image(right, as, on, options)
         | 
| 45 | 
            +
                    }
         | 
| 46 | 
            +
                  end
         | 
| 47 | 
            +
             | 
| 42 48 | 
             
                  def join(right, on = [])
         | 
| 43 49 | 
             
                    return super unless on.is_a?(Hash)
         | 
| 44 50 | 
             
                    renaming = Hash[on.map{|k,v| [v,k] }]
         | 
    
        data/lib/bmg/error.rb
    CHANGED
    
    
    
        data/lib/bmg/operator/allbut.rb
    CHANGED
    
    | @@ -30,6 +30,7 @@ module Bmg | |
| 30 30 | 
             
                public
         | 
| 31 31 |  | 
| 32 32 | 
             
                  def each
         | 
| 33 | 
            +
                    return to_enum unless block_given?
         | 
| 33 34 | 
             
                    seen = {}
         | 
| 34 35 | 
             
                    @operand.each do |tuple|
         | 
| 35 36 | 
             
                      allbuted = tuple_allbut(tuple)
         | 
| @@ -63,12 +64,38 @@ module Bmg | |
| 63 64 |  | 
| 64 65 | 
             
                protected ### optimization
         | 
| 65 66 |  | 
| 67 | 
            +
                  def _allbut(type, butlist)
         | 
| 68 | 
            +
                    operand.allbut(self.butlist|butlist)
         | 
| 69 | 
            +
                  end
         | 
| 70 | 
            +
             | 
| 71 | 
            +
                  def _matching(type, right, on)
         | 
| 72 | 
            +
                    # Always possible to push the matching, since by construction
         | 
| 73 | 
            +
                    # `on` can only use attributes that have not been trown away,
         | 
| 74 | 
            +
                    # hence they exist on `operand` too.
         | 
| 75 | 
            +
                    operand.matching(right, on).allbut(butlist)
         | 
| 76 | 
            +
                  end
         | 
| 77 | 
            +
             | 
| 78 | 
            +
                  def _page(type, ordering, page_index, options)
         | 
| 79 | 
            +
                    return super unless self.preserving_key?
         | 
| 80 | 
            +
                    operand.page(ordering, page_index, options).allbut(butlist)
         | 
| 81 | 
            +
                  end
         | 
| 82 | 
            +
             | 
| 83 | 
            +
                  def _project(type, attrlist)
         | 
| 84 | 
            +
                    operand.project(attrlist)
         | 
| 85 | 
            +
                  end
         | 
| 86 | 
            +
             | 
| 66 87 | 
             
                  def _restrict(type, predicate)
         | 
| 67 88 | 
             
                    operand.restrict(predicate).allbut(butlist)
         | 
| 68 89 | 
             
                  end
         | 
| 69 90 |  | 
| 70 91 | 
             
                protected ### inspect
         | 
| 71 92 |  | 
| 93 | 
            +
                  def preserving_key?
         | 
| 94 | 
            +
                    operand.type.knows_keys? && operand.type.keys.find{|k|
         | 
| 95 | 
            +
                      (k & butlist).empty?
         | 
| 96 | 
            +
                    }
         | 
| 97 | 
            +
                  end
         | 
| 98 | 
            +
             | 
| 72 99 | 
             
                  def args
         | 
| 73 100 | 
             
                    [ butlist ]
         | 
| 74 101 | 
             
                  end
         | 
| @@ -24,7 +24,24 @@ module Bmg | |
| 24 24 |  | 
| 25 25 | 
             
                public
         | 
| 26 26 |  | 
| 27 | 
            +
                  def self.same(*args)
         | 
| 28 | 
            +
                    Same.new(*args)
         | 
| 29 | 
            +
                  end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                  def self.group(*args)
         | 
| 32 | 
            +
                    Group.new(*args)
         | 
| 33 | 
            +
                  end
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                  def self.y_by_x(*args)
         | 
| 36 | 
            +
                    YByX.new(*args)
         | 
| 37 | 
            +
                  end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                  def self.ys_by_x(*args)
         | 
| 40 | 
            +
                    YsByX.new(*args)
         | 
| 41 | 
            +
                  end
         | 
| 42 | 
            +
             | 
| 27 43 | 
             
                  def each(&bl)
         | 
| 44 | 
            +
                    return to_enum unless block_given?
         | 
| 28 45 | 
             
                    h = {}
         | 
| 29 46 | 
             
                    @operand.each do |tuple|
         | 
| 30 47 | 
             
                      key = key(tuple)
         | 
| @@ -41,6 +58,12 @@ module Bmg | |
| 41 58 | 
             
                    [:autosummarize, operand.to_ast, by.dup, sums.dup]
         | 
| 42 59 | 
             
                  end
         | 
| 43 60 |  | 
| 61 | 
            +
                public ### for internal reasons
         | 
| 62 | 
            +
             | 
| 63 | 
            +
                  def _count
         | 
| 64 | 
            +
                    operand._count
         | 
| 65 | 
            +
                  end
         | 
| 66 | 
            +
             | 
| 44 67 | 
             
                protected
         | 
| 45 68 |  | 
| 46 69 | 
             
                  def _restrict(type, predicate)
         | 
| @@ -175,11 +198,11 @@ module Bmg | |
| 175 198 | 
             
                    end
         | 
| 176 199 |  | 
| 177 200 | 
             
                    def init(v)
         | 
| 178 | 
            -
                      [v]
         | 
| 201 | 
            +
                      v.nil? ? [] : [v]
         | 
| 179 202 | 
             
                    end
         | 
| 180 203 |  | 
| 181 204 | 
             
                    def sum(v1, v2)
         | 
| 182 | 
            -
                      v1 << v2
         | 
| 205 | 
            +
                      v2.nil? ? v1 : (v1 << v2)
         | 
| 183 206 | 
             
                    end
         | 
| 184 207 |  | 
| 185 208 | 
             
                    def term(v)
         | 
| @@ -211,11 +234,11 @@ module Bmg | |
| 211 234 | 
             
                    end
         | 
| 212 235 |  | 
| 213 236 | 
             
                    def init(v)
         | 
| 214 | 
            -
                      [v]
         | 
| 237 | 
            +
                      v.nil? ? [] : [v]
         | 
| 215 238 | 
             
                    end
         | 
| 216 239 |  | 
| 217 240 | 
             
                    def sum(v1, v2)
         | 
| 218 | 
            -
                      v1 << v2
         | 
| 241 | 
            +
                      v2.nil? ? v1 : (v1 << v2)
         | 
| 219 242 | 
             
                    end
         | 
| 220 243 |  | 
| 221 244 | 
             
                    def term(v)
         | 
| @@ -43,6 +43,7 @@ module Bmg | |
| 43 43 | 
             
                  end
         | 
| 44 44 |  | 
| 45 45 | 
             
                  def each
         | 
| 46 | 
            +
                    return to_enum unless block_given?
         | 
| 46 47 | 
             
                    @operand.each do |tuple|
         | 
| 47 48 | 
             
                      yield autowrap_tuple(tuple)
         | 
| 48 49 | 
             
                    end
         | 
| @@ -52,6 +53,12 @@ module Bmg | |
| 52 53 | 
             
                    [ :autowrap, operand.to_ast, @original_options.dup ]
         | 
| 53 54 | 
             
                  end
         | 
| 54 55 |  | 
| 56 | 
            +
                public ### for internal reasons
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                  def _count
         | 
| 59 | 
            +
                    operand._count
         | 
| 60 | 
            +
                  end
         | 
| 61 | 
            +
             | 
| 55 62 | 
             
                protected ### optimization
         | 
| 56 63 |  | 
| 57 64 | 
             
                  def _autowrap(type, opts)
         | 
| @@ -86,6 +93,16 @@ module Bmg | |
| 86 93 | 
             
                    false
         | 
| 87 94 | 
             
                  end
         | 
| 88 95 |  | 
| 96 | 
            +
                  def _matching(type, right, on)
         | 
| 97 | 
            +
                    if (wrapped_roots! & on).empty?
         | 
| 98 | 
            +
                      operand.matching(right, on).autowrap(options)
         | 
| 99 | 
            +
                    else
         | 
| 100 | 
            +
                      super
         | 
| 101 | 
            +
                    end
         | 
| 102 | 
            +
                  rescue UnknownAttributesError
         | 
| 103 | 
            +
                    super
         | 
| 104 | 
            +
                  end
         | 
| 105 | 
            +
             | 
| 89 106 | 
             
                  def _page(type, ordering, page_index, opts)
         | 
| 90 107 | 
             
                    attrs = ordering.map{|(a,d)| a }
         | 
| 91 108 | 
             
                    if (wrapped_roots! & attrs).empty?
         | 
| @@ -97,6 +114,16 @@ module Bmg | |
| 97 114 | 
             
                    super
         | 
| 98 115 | 
             
                  end
         | 
| 99 116 |  | 
| 117 | 
            +
                  def _project(type, attrlist)
         | 
| 118 | 
            +
                    if (wrapped_roots! & attrlist).empty?
         | 
| 119 | 
            +
                      operand.project(attrlist).autowrap(options)
         | 
| 120 | 
            +
                    else
         | 
| 121 | 
            +
                      super
         | 
| 122 | 
            +
                    end
         | 
| 123 | 
            +
                  rescue UnknownAttributesError
         | 
| 124 | 
            +
                    super
         | 
| 125 | 
            +
                  end
         | 
| 126 | 
            +
             | 
| 100 127 | 
             
                  def _rename(type, renaming)
         | 
| 101 128 | 
             
                    # 1. Can't optimize if renaming applies to a wrapped one
         | 
| 102 129 | 
             
                    return super unless (wrapped_roots! & renaming.keys).empty?
         | 
| @@ -23,6 +23,7 @@ module Bmg | |
| 23 23 | 
             
                public
         | 
| 24 24 |  | 
| 25 25 | 
             
                  def each
         | 
| 26 | 
            +
                    return to_enum unless block_given?
         | 
| 26 27 | 
             
                    @operand.each do |tuple|
         | 
| 27 28 | 
             
                      yield extend_it(tuple)
         | 
| 28 29 | 
             
                    end
         | 
| @@ -54,6 +55,12 @@ module Bmg | |
| 54 55 | 
             
                    [ :constants, operand.to_ast, constants.dup ]
         | 
| 55 56 | 
             
                  end
         | 
| 56 57 |  | 
| 58 | 
            +
                public ### for internal reasons
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                  def _count
         | 
| 61 | 
            +
                    operand._count
         | 
| 62 | 
            +
                  end
         | 
| 63 | 
            +
             | 
| 57 64 | 
             
                protected ### optimization
         | 
| 58 65 |  | 
| 59 66 | 
             
                  def _page(type, ordering, page_index, options)
         | 
    
        data/lib/bmg/operator/extend.rb
    CHANGED
    
    | @@ -26,6 +26,7 @@ module Bmg | |
| 26 26 | 
             
                public
         | 
| 27 27 |  | 
| 28 28 | 
             
                  def each
         | 
| 29 | 
            +
                    return to_enum unless block_given?
         | 
| 29 30 | 
             
                    @operand.each do |tuple|
         | 
| 30 31 | 
             
                      yield extend_it(tuple)
         | 
| 31 32 | 
             
                    end
         | 
| @@ -53,6 +54,12 @@ module Bmg | |
| 53 54 | 
             
                    [ :extend, operand.to_ast, extension.dup ]
         | 
| 54 55 | 
             
                  end
         | 
| 55 56 |  | 
| 57 | 
            +
                public ### for internal reasons
         | 
| 58 | 
            +
             | 
| 59 | 
            +
                  def _count
         | 
| 60 | 
            +
                    operand._count
         | 
| 61 | 
            +
                  end
         | 
| 62 | 
            +
             | 
| 56 63 | 
             
                protected ### optimization
         | 
| 57 64 |  | 
| 58 65 | 
             
                  def _allbut(type, butlist)
         | 
    
        data/lib/bmg/operator/group.rb
    CHANGED
    
    
    
        data/lib/bmg/operator/image.rb
    CHANGED
    
    | @@ -46,6 +46,7 @@ module Bmg | |
| 46 46 | 
             
                public
         | 
| 47 47 |  | 
| 48 48 | 
             
                  def each(*args, &bl)
         | 
| 49 | 
            +
                    return to_enum unless block_given?
         | 
| 49 50 | 
             
                    (options[:jit_optimized] ? self : jit_optimize)._each(*args, &bl)
         | 
| 50 51 | 
             
                  end
         | 
| 51 52 |  | 
| @@ -99,9 +100,10 @@ module Bmg | |
| 99 100 | 
             
                      key = tuple_project(t, on)
         | 
| 100 101 | 
             
                      index[key].operand << tuple_image(t, on)
         | 
| 101 102 | 
             
                    end
         | 
| 102 | 
            -
                    if options[:array]
         | 
| 103 | 
            +
                    if opt = options[:array]
         | 
| 104 | 
            +
                      sorter = to_sorter(opt)
         | 
| 103 105 | 
             
                      index = index.each_with_object({}) do |(k,v),ix|
         | 
| 104 | 
            -
                        ix[k] = v.to_a
         | 
| 106 | 
            +
                        ix[k] = sorter ? v.to_a.sort(&sorter) : v.to_a
         | 
| 105 107 | 
             
                      end
         | 
| 106 108 | 
             
                    end
         | 
| 107 109 | 
             
                    index
         | 
| @@ -154,8 +156,32 @@ module Bmg | |
| 154 156 | 
             
                    end
         | 
| 155 157 | 
             
                  end
         | 
| 156 158 |  | 
| 159 | 
            +
                public ### for internal reasons
         | 
| 160 | 
            +
             | 
| 161 | 
            +
                  def _count
         | 
| 162 | 
            +
                    left._count
         | 
| 163 | 
            +
                  end
         | 
| 164 | 
            +
             | 
| 157 165 | 
             
                protected ### optimization
         | 
| 158 166 |  | 
| 167 | 
            +
                  def _allbut(type, butlist)
         | 
| 168 | 
            +
                    if butlist.include?(as)
         | 
| 169 | 
            +
                      left.allbut(butlist - [as])
         | 
| 170 | 
            +
                    elsif (butlist & on).empty?
         | 
| 171 | 
            +
                      left.allbut(butlist).image(right, as, on, options)
         | 
| 172 | 
            +
                    else
         | 
| 173 | 
            +
                      super
         | 
| 174 | 
            +
                    end
         | 
| 175 | 
            +
                  end
         | 
| 176 | 
            +
             | 
| 177 | 
            +
                  def _matching(type, m_right, m_on)
         | 
| 178 | 
            +
                    if m_on.include?(as)
         | 
| 179 | 
            +
                      super
         | 
| 180 | 
            +
                    else
         | 
| 181 | 
            +
                      left.matching(m_right, m_on).image(right, as, on, options)
         | 
| 182 | 
            +
                    end
         | 
| 183 | 
            +
                  end
         | 
| 184 | 
            +
             | 
| 159 185 | 
             
                  def _page(type, ordering, page_index, opts)
         | 
| 160 186 | 
             
                    if ordering.map{|(k,v)| k}.include?(as)
         | 
| 161 187 | 
             
                      super
         | 
| @@ -166,6 +192,14 @@ module Bmg | |
| 166 192 | 
             
                    end
         | 
| 167 193 | 
             
                  end
         | 
| 168 194 |  | 
| 195 | 
            +
                  def _project(type, attrlist)
         | 
| 196 | 
            +
                    if attrlist.include?(as)
         | 
| 197 | 
            +
                      super
         | 
| 198 | 
            +
                    else
         | 
| 199 | 
            +
                      left.project(attrlist)
         | 
| 200 | 
            +
                    end
         | 
| 201 | 
            +
                  end
         | 
| 202 | 
            +
             | 
| 169 203 | 
             
                  def _restrict(type, predicate)
         | 
| 170 204 | 
             
                    on_as, rest = predicate.and_split([as])
         | 
| 171 205 | 
             
                    if rest.tautology?
         | 
| @@ -227,6 +261,11 @@ module Bmg | |
| 227 261 | 
             
                    Relation::InMemory.new(image_type, Set.new)
         | 
| 228 262 | 
             
                  end
         | 
| 229 263 |  | 
| 264 | 
            +
                  def to_sorter(opt)
         | 
| 265 | 
            +
                    return nil unless opt.is_a?(Array)
         | 
| 266 | 
            +
                    Ordering.new(opt).comparator
         | 
| 267 | 
            +
                  end
         | 
| 268 | 
            +
             | 
| 230 269 | 
             
                public
         | 
| 231 270 |  | 
| 232 271 | 
             
                  def to_s
         | 
    
        data/lib/bmg/operator/join.rb
    CHANGED
    
    
    
        data/lib/bmg/operator/page.rb
    CHANGED
    
    | @@ -30,6 +30,7 @@ module Bmg | |
| 30 30 | 
             
                public
         | 
| 31 31 |  | 
| 32 32 | 
             
                  def each(&bl)
         | 
| 33 | 
            +
                    return to_enum unless block_given?
         | 
| 33 34 | 
             
                    page_size = options[:page_size]
         | 
| 34 35 | 
             
                    @operand.to_a
         | 
| 35 36 | 
             
                      .sort(&comparator)
         | 
| @@ -45,13 +46,7 @@ module Bmg | |
| 45 46 | 
             
                protected ### inspect
         | 
| 46 47 |  | 
| 47 48 | 
             
                  def comparator
         | 
| 48 | 
            -
                     | 
| 49 | 
            -
                      ordering.each do |(attr,direction)|
         | 
| 50 | 
            -
                        c = t1[attr] <=> t2[attr]
         | 
| 51 | 
            -
                        return (direction == :desc ? -c : c) unless c==0
         | 
| 52 | 
            -
                      end
         | 
| 53 | 
            -
                      0
         | 
| 54 | 
            -
                    }
         | 
| 49 | 
            +
                    Ordering.new(@ordering).comparator
         | 
| 55 50 | 
             
                  end
         | 
| 56 51 |  | 
| 57 52 | 
             
                  def args
         | 
    
        data/lib/bmg/operator/project.rb
    CHANGED
    
    | @@ -29,9 +29,10 @@ module Bmg | |
| 29 29 | 
             
                public
         | 
| 30 30 |  | 
| 31 31 | 
             
                  def each
         | 
| 32 | 
            +
                    return to_enum unless block_given?
         | 
| 32 33 | 
             
                    seen = {}
         | 
| 33 34 | 
             
                    @operand.each do |tuple|
         | 
| 34 | 
            -
                      projected =  | 
| 35 | 
            +
                      projected = tuple_project(tuple)
         | 
| 35 36 | 
             
                      unless seen.has_key?(projected)
         | 
| 36 37 | 
             
                        yield(projected)
         | 
| 37 38 | 
             
                        seen[projected] = true
         | 
| @@ -74,7 +75,7 @@ module Bmg | |
| 74 75 |  | 
| 75 76 | 
             
                private
         | 
| 76 77 |  | 
| 77 | 
            -
                  def  | 
| 78 | 
            +
                  def tuple_project(tuple)
         | 
| 78 79 | 
             
                    tuple.dup.delete_if{|k,_| !@attrlist.include?(k) }
         | 
| 79 80 | 
             
                  end
         | 
| 80 81 |  | 
    
        data/lib/bmg/operator/rename.rb
    CHANGED
    
    | @@ -29,16 +29,17 @@ module Bmg | |
| 29 29 | 
             
                public
         | 
| 30 30 |  | 
| 31 31 | 
             
                  def each
         | 
| 32 | 
            +
                    return to_enum unless block_given?
         | 
| 32 33 | 
             
                    @operand.each do |tuple|
         | 
| 33 | 
            -
                      yield  | 
| 34 | 
            +
                      yield rename_tuple(tuple, renaming)
         | 
| 34 35 | 
             
                    end
         | 
| 35 36 | 
             
                  end
         | 
| 36 37 |  | 
| 37 38 | 
             
                  def insert(arg)
         | 
| 38 39 | 
             
                    case arg
         | 
| 39 | 
            -
                    when Hash       then operand.insert( | 
| 40 | 
            +
                    when Hash       then operand.insert(rename_tuple(arg, reverse_renaming))
         | 
| 40 41 | 
             
                    when Relation   then operand.insert(arg.rename(reverse_renaming))
         | 
| 41 | 
            -
                    when Enumerable then operand.insert(arg.map{|t|  | 
| 42 | 
            +
                    when Enumerable then operand.insert(arg.map{|t| rename_tuple(t, reverse_renaming) })
         | 
| 42 43 | 
             
                    else
         | 
| 43 44 | 
             
                      super
         | 
| 44 45 | 
             
                    end
         | 
| @@ -46,7 +47,7 @@ module Bmg | |
| 46 47 |  | 
| 47 48 | 
             
                  def update(arg)
         | 
| 48 49 | 
             
                    case arg
         | 
| 49 | 
            -
                    when Hash then operand.update( | 
| 50 | 
            +
                    when Hash then operand.update(rename_tuple(arg, reverse_renaming))
         | 
| 50 51 | 
             
                    else
         | 
| 51 52 | 
             
                      super
         | 
| 52 53 | 
             
                    end
         | 
| @@ -60,6 +61,12 @@ module Bmg | |
| 60 61 | 
             
                    [ :rename, operand.to_ast, renaming.dup ]
         | 
| 61 62 | 
             
                  end
         | 
| 62 63 |  | 
| 64 | 
            +
                public ### for internal reasons
         | 
| 65 | 
            +
             | 
| 66 | 
            +
                  def _count
         | 
| 67 | 
            +
                    operand._count
         | 
| 68 | 
            +
                  end
         | 
| 69 | 
            +
             | 
| 63 70 | 
             
                protected ### optimization
         | 
| 64 71 |  | 
| 65 72 | 
             
                  def _page(type, ordering, page_index, options)
         | 
| @@ -82,7 +89,7 @@ module Bmg | |
| 82 89 |  | 
| 83 90 | 
             
                private
         | 
| 84 91 |  | 
| 85 | 
            -
                  def  | 
| 92 | 
            +
                  def rename_tuple(tuple, renaming)
         | 
| 86 93 | 
             
                    tuple.each_with_object({}){|(k,v),h|
         | 
| 87 94 | 
             
                      h[renaming[k] || k] = v
         | 
| 88 95 | 
             
                      h
         |