-
Notifications
You must be signed in to change notification settings - Fork 29k
[SPARK-23595][SQL] ValidateExternalType should support interpreted execution #20757
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 1 commit
78de6c8
4bee661
647df9f
9b6b314
8cec382
bede101
7474811
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1672,11 +1672,37 @@ case class ValidateExternalType(child: Expression, expected: DataType) | |
|
|
||
| override def dataType: DataType = RowEncoder.externalDataTypeForInput(expected) | ||
|
|
||
| override def eval(input: InternalRow): Any = | ||
| throw new UnsupportedOperationException("Only code-generated evaluation is supported") | ||
|
|
||
| private val errMsg = s" is not a valid external type for schema of ${expected.simpleString}" | ||
|
|
||
| private lazy val checkType = expected match { | ||
| case _: DecimalType => | ||
| (value: Any) => { | ||
| Seq(classOf[java.math.BigDecimal], classOf[scala.math.BigDecimal], classOf[Decimal]) | ||
|
||
| .exists { x => value.getClass.isAssignableFrom(x) } | ||
| } | ||
| case _: ArrayType => | ||
| (value: Any) => { | ||
| value.getClass.isAssignableFrom(classOf[Seq[_]]) || value.getClass.isArray | ||
|
||
| } | ||
| case _ if ScalaReflection.isNativeType(expected) => | ||
| (value: Any) => { | ||
| value.getClass.isAssignableFrom(ScalaReflection.classForNativeTypeOf(expected)) | ||
|
||
| } | ||
| case _ => | ||
| (value: Any) => { | ||
| value.getClass.isAssignableFrom(dataType.asInstanceOf[ObjectType].cls) | ||
|
||
| } | ||
| } | ||
|
|
||
| override def eval(input: InternalRow): Any = { | ||
| val result = child.eval(input) | ||
| if (checkType(result)) { | ||
| result | ||
| } else { | ||
| throw new RuntimeException(s"${result.getClass.getName}$errMsg") | ||
| } | ||
| } | ||
|
|
||
| override def doGenCode(ctx: CodegenContext, ev: ExprCode): ExprCode = { | ||
| // Use unnamed reference that doesn't create a local field here to reduce the number of fields | ||
| // because errMsgField is used only when the type doesn't match. | ||
|
|
||
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.
Shouldn't this match
CodeGenerator.boxedTypein terms of functionality? See my previous comments, but I am also missing complex types (struct, map & array).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.
IIUC this function would be better to only handles the
nativetypes that have the same format between the Spark SQL internals formats and externals (struct, map, and array have different formats between them). https://github.com/apache/spark/blob/master/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/encoders/RowEncoder.scala#L209 So, this function needs to handle more wider types thanCodeGenerator.boxedType.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.
There is a difference between how we implement an expression and how we use an expression. In this case the implementations should behave the same, and not only in the context in which it is being used.
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.
ok, I'll brush up the code.
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.
@hvanhovell How about the latest commit?