Skip to content

Commit

Permalink
[SPARK-2187] Explain should not run the optimizer twice.
Browse files Browse the repository at this point in the history
  • Loading branch information
rxin committed Jun 19, 2014
1 parent 5ff75c7 commit a9d3ba8
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -250,9 +250,8 @@ private[sql] abstract class SparkStrategies extends QueryPlanner[SparkPlan] {
def apply(plan: LogicalPlan): Seq[SparkPlan] = plan match {
case logical.SetCommand(key, value) =>
Seq(execution.SetCommand(key, value, plan.output)(context))
case logical.ExplainCommand(child) =>
val sparkPlan = context.executePlan(child).sparkPlan
Seq(execution.ExplainCommand(sparkPlan, plan.output)(context))
case logical.ExplainCommand(logicalPlan) =>
Seq(execution.ExplainCommand(logicalPlan, plan.output)(context))
case logical.CacheCommand(tableName, cache) =>
Seq(execution.CacheCommand(tableName, cache)(context))
case _ => Nil
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import org.apache.spark.annotation.DeveloperApi
import org.apache.spark.rdd.RDD
import org.apache.spark.sql.{SQLContext, Row}
import org.apache.spark.sql.catalyst.expressions.{GenericRow, Attribute}
import org.apache.spark.sql.catalyst.plans.logical.LogicalPlan

trait Command {
/**
Expand Down Expand Up @@ -71,16 +72,24 @@ case class SetCommand(
}

/**
* An explain command for users to see how a command will be executed.
*
* Note that this command takes in a logical plan, runs the optimizer on the logical plan
* (but do NOT actually execute it).
*
* :: DeveloperApi ::
*/
@DeveloperApi
case class ExplainCommand(
child: SparkPlan, output: Seq[Attribute])(
logicalPlan: LogicalPlan, output: Seq[Attribute])(
@transient context: SQLContext)
extends UnaryNode with Command {
extends LeafNode with Command {

// Actually "EXPLAIN" command doesn't cause any side effect.
override protected[sql] lazy val sideEffectResult: Seq[String] = this.toString.split("\n")
// Run through the optimizer to generate the physical plan.
// This is really side effect free but we follow the infrastructure anyway...
override protected[sql] lazy val sideEffectResult: Seq[String] = {
context.executePlan(logicalPlan).executedPlan.toString.split("\n")
}

def execute(): RDD[Row] = {
val explanation = sideEffectResult.map(row => new GenericRow(Array[Any](row)))
Expand Down

0 comments on commit a9d3ba8

Please sign in to comment.