Skip to content

Commit

Permalink
performing in memory joins
Browse files Browse the repository at this point in the history
  • Loading branch information
Nick Kallen authored and brynary committed May 17, 2009
1 parent b7f58db commit 2fe5853
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 4 deletions.
8 changes: 4 additions & 4 deletions doc/TODO
@@ -1,16 +1,13 @@
todo:
- reorganize memory tests
- implement joins in memory
- result sets should be array relations
- deal with table tests in algebra
- cross-engine joins
- blocks for joins
- implement mnesia adapter
- fix grouping
- fix AR
- rename externalize to derived.

- result sets to attr correlation too
- fix grouping
- audit unit coverage of algebra
- data objects
- remove all explicit aliasing
Expand Down Expand Up @@ -92,6 +89,9 @@ done:
- clean up block_given stuff
- reorganize sql tests
- recursive memory operations
- reorganize memory tests
- result sets to attr correlation too
- implement joins in memory

icebox:
- #bind in Attribute and Expression should be doing a descend?
Expand Down
4 changes: 4 additions & 0 deletions lib/arel/algebra/relations/row.rb
Expand Up @@ -17,5 +17,9 @@ def slice(*attributes)
def bind(relation)
Row.new(relation, tuple)
end

def combine(other, relation)
Row.new(relation, tuple + other.tuple)
end
end
end
21 changes: 21 additions & 0 deletions lib/arel/engines/memory/relations/operations.rb
Expand Up @@ -37,4 +37,25 @@ def eval
raise NotImplementedError
end
end

class Alias < Compound
def eval
unoperated_rows
end
end

class Join < Relation
def eval
result = []
relation1.eval.each do |row1|
relation2.eval.each do |row2|
combined_row = row1.combine(row2, self)
if predicates.all? { |p| p.eval(combined_row) }
result << combined_row
end
end
end
result
end
end
end
32 changes: 32 additions & 0 deletions spec/arel/engines/memory/unit/relations/join_spec.rb
@@ -0,0 +1,32 @@
require File.join(File.dirname(__FILE__), '..', '..', '..', '..', '..', 'spec_helper')

module Arel
describe Join do
before do
@relation1 = Array.new([
[1, 'duck' ],
[2, 'duck' ],
[3, 'goose']
], [:id, :name])
@relation2 = @relation1.alias
@relation3 = @relation1.alias
end

describe InnerJoin do
describe '#call' do
it 'combines the two tables where the predicate obtains' do
@relation1 \
.join(@relation2) \
.on(@relation1[:id].eq(@relation2[:id])) \
.let do |relation|
relation.call.should == [
Row.new(relation, [1, 'duck', 1, 'duck' ]),
Row.new(relation, [2, 'duck', 2, 'duck' ]),
Row.new(relation, [3, 'goose', 3, 'goose'])
]
end
end
end
end
end
end

0 comments on commit 2fe5853

Please sign in to comment.