select 10, case
test("Test select 10") {
val df = sql("SELECT 10 ")
df.explain(false)
df.show()
df.explain(false)
}
ProjectExec
./sql/core/src/main/scala/org/apache/spark/sql/execution/basicPhysicalOperators.scala
case class ProjectExec(projectList: Seq[NamedExpression], child: SparkPlan)
执行函数
protected override def doExecute(): RDD[InternalRow] = {
child.execute().mapPartitionsWithIndexInternal { (index, iter) =>
val project = UnsafeProjection.create(projectList, child.output)
project.initialize(index)
iter.map(project)
}
}
/**
* Returns an UnsafeProjection for given sequence of Expressions, which will be bound to
* `inputSchema`.
*/
def create(exprs: Seq[Expression], inputSchema: Seq[Attribute]): UnsafeProjection = {
create(bindReferences(exprs, inputSchema))
}
RDDScanExec 饭后的的inputSchema 是空
child.execute().mapPartitionsWithIndexInternal RDDScanExec , 返回只有一个空 row, rowcount 为1
RDDScanExec
./sql/core/src/main/scala/org/apache/spark/sql/execution/ExistingRDD.scala
/** Physical plan node for scanning data from an RDD of InternalRow. */
case class RDDScanExec(
output: Seq[Attribute],
rdd: RDD[InternalRow],
name: String,
override val outputPartitioning: Partitioning = UnknownPartitioning(0),
override val outputOrdering: Seq[SortOrder] = Nil) extends LeafExecNode with InputRDDCodegen {
protected override def doExecute(): RDD[InternalRow] = {
val numOutputRows = longMetric("numOutputRows")
rdd.mapPartitionsWithIndexInternal { (index, iter) =>
val proj = UnsafeProjection.create(schema)
proj.initialize(index)
iter.map { r =>
numOutputRows += 1
proj(r)
}
}
}