[SPARK-4485][SQL]Add BroadcastHashOuterJoin

JIRA issue: [SPARK-4485](https://issues.apache.org/jira/browse/SPARK-4485)
We are planning to create a `BroadcastHashouterJoin` to implement the broadcast join for `left outer join` and `right outer join`
In left outer join :
If the size of data from right side is smaller than the user-settable threshold`AUTO_BROADCASTJOIN_THRESHOLD`, 
the planner would mark it as the broadcast relation and mark the other relation as the stream side. The broadcast table will be broadcasted to all of the executors involved in the join, as aorg.apache.spark.broadcast.Broadcast object. It will use joins.BroadcastHashouterJoin.,else it will usejoins.HashOuterJoin.
In right outer join: 
If the size of data from left side is smaller than the user-settable threshold `AUTO_BROADCASTJOIN_THRESHOLD`,the planner would mark it as the broadcast relation and mark the other relation as the stream side. The broadcast table will be broadcasted to all of the executors involved in the join, as `aorg.apache.spark.broadcast.Broadcast` object. It will use `joins.BroadcastHashouterJoin`. else it will use`joins.HashOuterJoin`.

The benchmark suggests these  made the optimized version 7x faster  when `left outer join` and`right outer join`
<pre><code>
Original:
left outer join : 15439 ms 
right outer join : 9707 ms
Optimized:
left outer join : 1992 ms
 right outer join : 1288 ms
</code></pre>
The micro benchmark load `data1/kv3.txt` into a normal Hive table.
Benchmark code:
<pre><code>
 def benchmark(f: => Unit) = {
    val begin = System.currentTimeMillis()
    f
    val end = System.currentTimeMillis()
    end - begin
  }
  val sc = new SparkContext(
    new SparkConf()
      .setMaster("local")
      .setAppName(getClass.getSimpleName.stripSuffix("$")))
  val hiveContext = new HiveContext(sc)
  import hiveContext._
  sql("drop table if exists left_table")
  sql("drop table if exists right_table")
  sql( """create table left_table (key int, value string)
       """.stripMargin)
  sql( s"""load data local inpath "/data1/kv3.txt" into table left_table""")
  sql( """create table right_table (key int, value string)
       """.stripMargin)
  sql(
    """
      |from left_table
      |insert overwrite table right_table
      |select left_table.key, left_table.value
    """.stripMargin)
  val leftOuterJoin = sql(
    """select a.key from left_table a
      | left outer join right_table b on a.key = b.key """.stripMargin)
  val rightOuterJoin = sql(
    """select a.key from left_table a
      |right outer join right_table b on a.key = b.key""".stripMargin)

  val leftOuterJoinDuration = benchmark(leftOuterJoin.count())
  val rightOuterJoinDuration = benchmark(rightOuterJoin.count())
  println(s"left outer join : $leftOuterJoinDuration ms right outer join : $rightOuterJoinDuration ms")
</code></pre>
Looks like we are never planning HashOuterJoin?  We need to make sure we don't lose test coverage here.