in repl/src/main/scala/org/apache/livy/repl/AbstractSparkInterpreter.scala [238:297]
private def executeLines(
lines: List[String],
resultFromLastLine: Interpreter.ExecuteResponse): Interpreter.ExecuteResponse = {
lines match {
case Nil => resultFromLastLine
case head :: tail =>
val result = executeLine(head)
result match {
case Interpreter.ExecuteIncomplete() =>
tail match {
case Nil =>
// ExecuteIncomplete could be caused by an actual incomplete statements (e.g. "sc.")
// or statements with just comments.
// To distinguish them, reissue the same statement wrapped in { }.
// If it is an actual incomplete statement, the interpreter will return an error.
// If it is some comment, the interpreter will return success.
executeLine(s"{\n$head\n}") match {
case Interpreter.ExecuteIncomplete() | Interpreter.ExecuteError(_, _, _) =>
// Return the original error so users won't get confusing error message.
result
case _ => resultFromLastLine
}
case next :: nextTail =>
executeLines(head + "\n" + next :: nextTail, resultFromLastLine)
}
case Interpreter.ExecuteError(_, _, _) =>
result
case Interpreter.ExecuteAborted(_) =>
result
case Interpreter.ExecuteSuccess(e) =>
val mergedRet = resultFromLastLine match {
case Interpreter.ExecuteSuccess(s) =>
// Because of SparkMagic related specific logic, so we will only merge text/plain
// result. For any magic related output, still follow the old way.
if (s.values.contains(TEXT_PLAIN) && e.values.contains(TEXT_PLAIN)) {
val lastRet = s.values.getOrElse(TEXT_PLAIN, "").asInstanceOf[String]
val currRet = e.values.getOrElse(TEXT_PLAIN, "").asInstanceOf[String]
if (lastRet.nonEmpty && currRet.nonEmpty) {
Interpreter.ExecuteSuccess(TEXT_PLAIN -> s"$lastRet$currRet")
} else if (lastRet.nonEmpty) {
Interpreter.ExecuteSuccess(TEXT_PLAIN -> lastRet)
} else if (currRet.nonEmpty) {
Interpreter.ExecuteSuccess(TEXT_PLAIN -> currRet)
} else {
result
}
} else {
result
}
case _ => result
}
executeLines(tail, mergedRet)
}
}
}