Skip to content
Snippets Groups Projects
Commit d3a302de authored by Reynold Xin's avatar Reynold Xin
Browse files

[SQL] Fixed expression data type matching.

Also took the chance to improve documentation for various types.

Author: Reynold Xin <rxin@databricks.com>

Closes #5675 from rxin/data-type-matching-expr and squashes the following commits:

0f31856 [Reynold Xin] One more function documentation.
27c1973 [Reynold Xin] Added more documentation.
336a36d [Reynold Xin] [SQL] Fixed expression data type matching.
parent 67bccbda
No related branches found
No related tags found
No related merge requests found
...@@ -279,7 +279,7 @@ abstract class CodeGenerator[InType <: AnyRef, OutType <: AnyRef] extends Loggin ...@@ -279,7 +279,7 @@ abstract class CodeGenerator[InType <: AnyRef, OutType <: AnyRef] extends Loggin
org.apache.spark.sql.types.UTF8String(${eval.primitiveTerm}.toString) org.apache.spark.sql.types.UTF8String(${eval.primitiveTerm}.toString)
""".children """.children
case EqualTo(e1: BinaryType, e2: BinaryType) => case EqualTo(e1 @ BinaryType(), e2 @ BinaryType()) =>
(e1, e2).evaluateAs (BooleanType) { (e1, e2).evaluateAs (BooleanType) {
case (eval1, eval2) => case (eval1, eval2) =>
q""" q"""
......
...@@ -40,32 +40,46 @@ import org.apache.spark.util.Utils ...@@ -40,32 +40,46 @@ import org.apache.spark.util.Utils
*/ */
@DeveloperApi @DeveloperApi
abstract class DataType { abstract class DataType {
/** Matches any expression that evaluates to this DataType */ /**
def unapply(a: Expression): Boolean = a match { * Enables matching against NumericType for expressions:
* {{{
* case Cast(child @ BinaryType(), StringType) =>
* ...
* }}}
*/
private[sql] def unapply(a: Expression): Boolean = a match {
case e: Expression if e.dataType == this => true case e: Expression if e.dataType == this => true
case _ => false case _ => false
} }
/** The default size of a value of this data type. */ /**
* The default size of a value of this data type, used internally for size estimation.
*/
def defaultSize: Int def defaultSize: Int
/** Name of the type used in JSON serialization. */
def typeName: String = this.getClass.getSimpleName.stripSuffix("$").dropRight(4).toLowerCase def typeName: String = this.getClass.getSimpleName.stripSuffix("$").dropRight(4).toLowerCase
private[sql] def jsonValue: JValue = typeName private[sql] def jsonValue: JValue = typeName
/** The compact JSON representation of this data type. */
def json: String = compact(render(jsonValue)) def json: String = compact(render(jsonValue))
/** The pretty (i.e. indented) JSON representation of this data type. */
def prettyJson: String = pretty(render(jsonValue)) def prettyJson: String = pretty(render(jsonValue))
/** Readable string representation for the type. */
def simpleString: String = typeName def simpleString: String = typeName
/** Check if `this` and `other` are the same data type when ignoring nullability /**
* (`StructField.nullable`, `ArrayType.containsNull`, and `MapType.valueContainsNull`). * Check if `this` and `other` are the same data type when ignoring nullability
* (`StructField.nullable`, `ArrayType.containsNull`, and `MapType.valueContainsNull`).
*/ */
private[spark] def sameType(other: DataType): Boolean = private[spark] def sameType(other: DataType): Boolean =
DataType.equalsIgnoreNullability(this, other) DataType.equalsIgnoreNullability(this, other)
/** Returns the same data type but set all nullability fields are true /**
* Returns the same data type but set all nullability fields are true
* (`StructField.nullable`, `ArrayType.containsNull`, and `MapType.valueContainsNull`). * (`StructField.nullable`, `ArrayType.containsNull`, and `MapType.valueContainsNull`).
*/ */
private[spark] def asNullable: DataType private[spark] def asNullable: DataType
...@@ -104,12 +118,25 @@ abstract class NumericType extends AtomicType { ...@@ -104,12 +118,25 @@ abstract class NumericType extends AtomicType {
private[sql] object NumericType { private[sql] object NumericType {
/**
* Enables matching against NumericType for expressions:
* {{{
* case Cast(child @ NumericType(), StringType) =>
* ...
* }}}
*/
def unapply(e: Expression): Boolean = e.dataType.isInstanceOf[NumericType] def unapply(e: Expression): Boolean = e.dataType.isInstanceOf[NumericType]
} }
/** Matcher for any expressions that evaluate to [[IntegralType]]s */
private[sql] object IntegralType { private[sql] object IntegralType {
/**
* Enables matching against IntegralType for expressions:
* {{{
* case Cast(child @ IntegralType(), StringType) =>
* ...
* }}}
*/
def unapply(a: Expression): Boolean = a match { def unapply(a: Expression): Boolean = a match {
case e: Expression if e.dataType.isInstanceOf[IntegralType] => true case e: Expression if e.dataType.isInstanceOf[IntegralType] => true
case _ => false case _ => false
...@@ -122,9 +149,14 @@ private[sql] abstract class IntegralType extends NumericType { ...@@ -122,9 +149,14 @@ private[sql] abstract class IntegralType extends NumericType {
} }
/** Matcher for any expressions that evaluate to [[FractionalType]]s */
private[sql] object FractionalType { private[sql] object FractionalType {
/**
* Enables matching against FractionalType for expressions:
* {{{
* case Cast(child @ FractionalType(), StringType) =>
* ...
* }}}
*/
def unapply(a: Expression): Boolean = a match { def unapply(a: Expression): Boolean = a match {
case e: Expression if e.dataType.isInstanceOf[FractionalType] => true case e: Expression if e.dataType.isInstanceOf[FractionalType] => true
case _ => false case _ => false
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment