Github user rxin commented on a diff in the pull request:
https://github.com/apache/spark/pull/10734#discussion_r49557719
--- Diff:
sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/conditionalExpressions.scala
---
@@ -81,44 +81,39 @@ case class If(predicate: Expression, trueValue:
Expression, falseValue: Expressi
/**
* Case statements of the form "CASE WHEN a THEN b [WHEN c THEN d]* [ELSE
e] END".
* When a = true, returns b; when c = true, returns d; else returns e.
+ *
+ * @param branches seq of (branch condition, branch value)
+ * @param elseValue optional value for the else branch
*/
-case class CaseWhen(branches: Seq[Expression]) extends Expression {
-
- // Use private[this] Array to speed up evaluation.
- @transient private[this] lazy val branchesArr = branches.toArray
-
- override def children: Seq[Expression] = branches
-
- @transient lazy val whenList =
- branches.sliding(2, 2).collect { case Seq(whenExpr, _) => whenExpr
}.toSeq
-
- @transient lazy val thenList =
- branches.sliding(2, 2).collect { case Seq(_, thenExpr) => thenExpr
}.toSeq
+case class CaseWhen(branches: Seq[(Expression, Expression)], elseValue:
Option[Expression] = None)
+ extends Expression {
- val elseValue = if (branches.length % 2 == 0) None else
Option(branches.last)
+ override def children: Seq[Expression] = branches.flatMap(b => b._1 ::
b._2 :: Nil) ++ elseValue
// both then and else expressions should be considered.
- def valueTypes: Seq[DataType] = (thenList ++ elseValue).map(_.dataType)
+ def valueTypes: Seq[DataType] = branches.map(_._2.dataType) ++
elseValue.map(_.dataType)
+
def valueTypesEqual: Boolean = valueTypes.size <= 1 ||
valueTypes.sliding(2, 1).forall {
case Seq(dt1, dt2) => dt1.sameType(dt2)
}
- override def dataType: DataType = thenList.head.dataType
+ override def dataType: DataType = branches.head._2.dataType
override def nullable: Boolean = {
- // If no value is nullable and no elseValue is provided, the whole
statement defaults to null.
- thenList.exists(_.nullable) ||
elseValue.map(_.nullable).getOrElse(true)
+ // Result is nullable if any of the branch is nullable, or if the else
value is nullable
+ branches.exists(_._2.nullable) ||
elseValue.map(_.nullable).getOrElse(true)
--- End diff --
While the two are semantically equivalent (and IntelliJ suggests this),
"exists" actually makes it less explicit.
---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at [email protected] or file a JIRA ticket
with INFRA.
---
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]