Multiway join rules

Add rules to compile query to a plan using HyperCube shuffle and multiway join. 
* [x]  add rule to merge left deep join into nary join in logical plan
* [x]  add rule break nary join to hypercube shuffle and local multiway join
* [x]  add rule to instantiate local multiway join (currently we only have leapfrog, but there could be more, so this part is seperated from break break nary join)
* [x]  add rule to place sort before LeapFrogJoin.
* [x]  add unit test
* [x]  add query test
 

`Exception` is generally the wrong type. It's like throwing a `Throwable` in Java -- it's not informative. Also, the message is basically useless. What kind of error is it? Why did it happen?

I might replace this with the above `elif`:

```python
assert isinstance(op.left, algebra.ProjectingJoin), 'Expected ProjectionJoin, not {op}'.format(op=tyope(op.left)
MergeToNaryJoin(op.left, conditions, children)
```