-
Notifications
You must be signed in to change notification settings - Fork 29k
[SPARK-17683][SQL] Support ArrayType in Literal.apply #15257
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
c46e14c
e495ff5
c026826
c9cdd29
c843840
41b9276
ebee7e4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -17,14 +17,25 @@ | |
|
|
||
| package org.apache.spark.sql.catalyst.expressions | ||
|
|
||
| import java.lang.{Boolean => JavaBoolean} | ||
| import java.lang.{Byte => JavaByte} | ||
| import java.lang.{Double => JavaDouble} | ||
| import java.lang.{Float => JavaFloat} | ||
| import java.lang.{Integer => JavaInteger} | ||
| import java.lang.{Long => JavaLong} | ||
| import java.lang.{Short => JavaShort} | ||
| import java.math.{BigDecimal => JavaBigDecimal} | ||
| import java.nio.charset.StandardCharsets | ||
| import java.sql.{Date, Timestamp} | ||
| import java.util | ||
| import java.util.Objects | ||
| import javax.xml.bind.DatatypeConverter | ||
|
|
||
| import scala.math.{BigDecimal, BigInt} | ||
|
|
||
| import org.json4s.JsonAST._ | ||
|
|
||
| import org.apache.spark.sql.AnalysisException | ||
| import org.apache.spark.sql.catalyst.{CatalystTypeConverters, InternalRow} | ||
| import org.apache.spark.sql.catalyst.expressions.codegen._ | ||
| import org.apache.spark.sql.catalyst.util.DateTimeUtils | ||
|
|
@@ -46,19 +57,63 @@ object Literal { | |
| case s: String => Literal(UTF8String.fromString(s), StringType) | ||
| case b: Boolean => Literal(b, BooleanType) | ||
| case d: BigDecimal => Literal(Decimal(d), DecimalType(Math.max(d.precision, d.scale), d.scale)) | ||
| case d: java.math.BigDecimal => | ||
| case d: JavaBigDecimal => | ||
| Literal(Decimal(d), DecimalType(Math.max(d.precision, d.scale), d.scale())) | ||
| case d: Decimal => Literal(d, DecimalType(Math.max(d.precision, d.scale), d.scale)) | ||
| case t: Timestamp => Literal(DateTimeUtils.fromJavaTimestamp(t), TimestampType) | ||
| case d: Date => Literal(DateTimeUtils.fromJavaDate(d), DateType) | ||
| case a: Array[Byte] => Literal(a, BinaryType) | ||
| case a: Array[_] => | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we use
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yea, I tried though, I couldn't use it here because scala
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I may not understand your point. Where it will be mapped to java type? You use
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry for my bad explanation. And, then run this code; IIUC,
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This seems work:
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If it holds This certainly works.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @maropu ya, we will get a generic type back and
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @maropu, I tested my solution in a shell and it worked. To fix the compilation error, simply make the overloaded method
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @jodersky Can you check the returned
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. oh, you're right. I didn't realize you specifically wanted an ArrayType |
||
| val elementType = componentTypeToDataType(a.getClass.getComponentType()) | ||
| val dataType = ArrayType(elementType) | ||
| val convert = CatalystTypeConverters.createToCatalystConverter(dataType) | ||
| Literal(convert(a), dataType) | ||
| case i: CalendarInterval => Literal(i, CalendarIntervalType) | ||
| case null => Literal(null, NullType) | ||
| case v: Literal => v | ||
| case _ => | ||
| throw new RuntimeException("Unsupported literal type " + v.getClass + " " + v) | ||
| } | ||
|
|
||
| /** | ||
| * Returns the Spark SQL DataType for a given class object. Since this type needs to be resolved | ||
| * in runtime, we use match-case idioms for class objects here. However, there are similar | ||
| * functions in other files (e.g., HiveInspectors), so these functions need to merged into one. | ||
| */ | ||
| private[this] def componentTypeToDataType(clz: Class[_]): DataType = clz match { | ||
| // primitive types | ||
| case JavaShort.TYPE => ShortType | ||
| case JavaInteger.TYPE => IntegerType | ||
| case JavaLong.TYPE => LongType | ||
| case JavaDouble.TYPE => DoubleType | ||
| case JavaByte.TYPE => ByteType | ||
| case JavaFloat.TYPE => FloatType | ||
| case JavaBoolean.TYPE => BooleanType | ||
|
|
||
| // java classes | ||
| case _ if clz == classOf[Date] => DateType | ||
| case _ if clz == classOf[Timestamp] => TimestampType | ||
| case _ if clz == classOf[JavaBigDecimal] => DecimalType.SYSTEM_DEFAULT | ||
| case _ if clz == classOf[Array[Byte]] => BinaryType | ||
| case _ if clz == classOf[JavaShort] => ShortType | ||
| case _ if clz == classOf[JavaInteger] => IntegerType | ||
| case _ if clz == classOf[JavaLong] => LongType | ||
| case _ if clz == classOf[JavaDouble] => DoubleType | ||
| case _ if clz == classOf[JavaByte] => ByteType | ||
| case _ if clz == classOf[JavaFloat] => FloatType | ||
| case _ if clz == classOf[JavaBoolean] => BooleanType | ||
|
|
||
| // other scala classes | ||
| case _ if clz == classOf[String] => StringType | ||
| case _ if clz == classOf[BigInt] => DecimalType.SYSTEM_DEFAULT | ||
| case _ if clz == classOf[BigDecimal] => DecimalType.SYSTEM_DEFAULT | ||
| case _ if clz == classOf[CalendarInterval] => CalendarIntervalType | ||
|
|
||
| case _ if clz.isArray => ArrayType(componentTypeToDataType(clz.getComponentType)) | ||
|
|
||
| case _ => throw new AnalysisException(s"Unsupported component type $clz in arrays") | ||
| } | ||
|
|
||
| /** | ||
| * Constructs a [[Literal]] of [[ObjectType]], for example when you need to pass an object | ||
| * into code generation. | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I personally think it is more clear to just say java.lang.Boolean in the code, but this is fine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have conventionally used JLong etc rather than JavaLong when doing this kind of rename.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just named these along with other classes such as
https://github.com/apache/spark/blob/master/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/CatalystTypeConverters.scala#L20. Nitpicking though, should we fix these name, too (e.g.,JavaDecimal=>JDecimal)?