(seq dag.Seq, lhs, rhs dag.Expr)
| 39 | } |
| 40 | |
| 41 | func liftFilterIntoJoin(seq dag.Seq, lhs, rhs dag.Expr) bool { |
| 42 | fork, isfork := seq[0].(*dag.ForkOp) |
| 43 | join, isjoin := seq[1].(*dag.JoinOp) |
| 44 | if !isfork || !isjoin { |
| 45 | return false |
| 46 | } |
| 47 | if len(fork.Paths) != 2 { |
| 48 | panic(fork) |
| 49 | } |
| 50 | lhsFirst, lok := firstThisPathComponent(lhs) |
| 51 | rhsFirst, rok := firstThisPathComponent(rhs) |
| 52 | if !lok || !rok { |
| 53 | return false |
| 54 | } |
| 55 | if lhsFirst == rhsFirst { |
| 56 | lhs, rhs = dag.CopyExpr(lhs), dag.CopyExpr(rhs) |
| 57 | stripFirstThisPathComponent(lhs) |
| 58 | stripFirstThisPathComponent(rhs) |
| 59 | if lhsFirst == join.LeftAlias { |
| 60 | return liftFilterIntoJoin(fork.Paths[0], lhs, rhs) |
| 61 | } |
| 62 | if lhsFirst == join.RightAlias { |
| 63 | return liftFilterIntoJoin(fork.Paths[1], lhs, rhs) |
| 64 | } |
| 65 | return false |
| 66 | } |
| 67 | if lhsFirst != join.LeftAlias { |
| 68 | lhsFirst, rhsFirst = rhsFirst, lhsFirst |
| 69 | lhs, rhs = rhs, lhs |
| 70 | } |
| 71 | if lhsFirst != join.LeftAlias || rhsFirst != join.RightAlias { |
| 72 | return false |
| 73 | } |
| 74 | cond := dag.NewBinaryExpr("==", lhs, rhs) |
| 75 | if join.Cond != nil { |
| 76 | cond = dag.NewBinaryExpr("and", join.Cond, cond) |
| 77 | } |
| 78 | join.Cond = cond |
| 79 | return true |
| 80 | } |
| 81 | |
| 82 | func replaceJoinWithHashJoin(seq dag.Seq) { |
| 83 | walkT(reflect.ValueOf(seq), func(op dag.Op) dag.Op { |
no test coverage detected