[SPARK-2210] cast to boolean on boolean value gets turned into NOT((boolean_condition) = 0)

```
explain select cast(cast(key=0 as boolean) as boolean) aaa from src
```
should be
```
[Physical execution plan:]
[Project [(key#10:0 = 0) AS aaa#7]]
[ HiveTableScan [key#10], (MetastoreRelation default, src, None), None]
```

However, it is currently
```
[Physical execution plan:]
[Project [NOT((key#10=0) = 0) AS aaa#7]]
[ HiveTableScan [key#10], (MetastoreRelation default, src, None), None]
```

Author: Reynold Xin <rxin@apache.org>

Closes #1144 from rxin/booleancast and squashes the following commits:

c4e543d [Reynold Xin] [SPARK-2210] boolean cast on boolean value should be removed.
This commit is contained in:
Reynold Xin 2014-06-19 23:58:23 -07:00
parent f479cf3743
commit 6175640973
2 changed files with 27 additions and 2 deletions

View file

@ -251,7 +251,9 @@ trait HiveTypeCoercion {
def apply(plan: LogicalPlan): LogicalPlan = plan transformAllExpressions {
// Skip nodes who's children have not been resolved yet.
case e if !e.childrenResolved => e
// Skip if the type is boolean type already. Note that this extra cast should be removed
// by optimizer.SimplifyCasts.
case Cast(e, BooleanType) if e.dataType == BooleanType => e
case Cast(e, BooleanType) => Not(Equals(e, Literal(0)))
case Cast(e, dataType) if e.dataType == BooleanType =>
Cast(If(e, Literal(1), Literal(0)), dataType)

View file

@ -17,8 +17,12 @@
package org.apache.spark.sql.hive.execution
import org.apache.spark.sql.catalyst.expressions.{Cast, Equals}
import org.apache.spark.sql.execution.Project
import org.apache.spark.sql.hive.test.TestHive
/**
* A set of tests that validate type promotion rules.
* A set of tests that validate type promotion and coercion rules.
*/
class HiveTypeCoercionSuite extends HiveComparisonTest {
val baseTypes = Seq("1", "1.0", "1L", "1S", "1Y", "'1'")
@ -28,4 +32,23 @@ class HiveTypeCoercionSuite extends HiveComparisonTest {
createQueryTest(s"$i + $j", s"SELECT $i + $j FROM src LIMIT 1")
}
}
test("[SPARK-2210] boolean cast on boolean value should be removed") {
val q = "select cast(cast(key=0 as boolean) as boolean) from src"
val project = TestHive.hql(q).queryExecution.executedPlan.collect { case e: Project => e }.head
// No cast expression introduced
project.transformAllExpressions { case c: Cast =>
assert(false, "unexpected cast " + c)
c
}
// Only one Equals
var numEquals = 0
project.transformAllExpressions { case e: Equals =>
numEquals += 1
e
}
assert(numEquals === 1)
}
}