You are viewing a plain text version of this content. The canonical link for it is here.
Posted to reviews@spark.apache.org by GitBox <gi...@apache.org> on 2023/01/11 20:33:55 UTC
[GitHub] [spark] hvanhovell opened a new pull request, #39517: [SPARK-41993][SQL] Move RowEncoder to AgnosticEncoders
hvanhovell opened a new pull request, #39517:
URL: https://github.com/apache/spark/pull/39517
### What changes were proposed in this pull request?
This PR makes `RowEncoder` produce an `AgnosticEncoder`. The expression generation for these encoders is moved to `ScalaReflection` (this will be moved out in a subsequent PR).
The generated serializer and deserializer expressions will slightly change for both schema and type based encoders. These are not semantically different from the old expressions. Concretely the following changes have been introduced:
- There is more type validation in maps/arrays/seqs for type based encoders. This should be a positive change, since it disallows users to pass wrong data through erasure hackd.
- Array/Seq serialization is a bit more strict. In the old scenario it was possible to pass in sequences/arrays with the wrong type and/or nullability.
### Why are the changes needed?
For the Spark Connect Scala Client we also want to be able to use `Row` based results.
### Does this PR introduce _any_ user-facing change?
No
### How was this patch tested?
This is a refactoring, existing tests should be sufficient.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org
[GitHub] [spark] cloud-fan closed pull request #39517: [SPARK-41993][SQL] Move RowEncoder to AgnosticEncoders
Posted by GitBox <gi...@apache.org>.
cloud-fan closed pull request #39517: [SPARK-41993][SQL] Move RowEncoder to AgnosticEncoders
URL: https://github.com/apache/spark/pull/39517
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org
[GitHub] [spark] hvanhovell commented on a diff in pull request #39517: [SPARK-41993][SQL] Move RowEncoder to AgnosticEncoders
Posted by GitBox <gi...@apache.org>.
hvanhovell commented on code in PR #39517:
URL: https://github.com/apache/spark/pull/39517#discussion_r1068888785
##########
sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/encoders/AgnosticEncoder.scala:
##########
@@ -46,35 +46,42 @@ object AgnosticEncoders {
override val clsTag: ClassTag[Option[E]] = ClassTag(classOf[Option[E]])
}
- case class ArrayEncoder[E](element: AgnosticEncoder[E])
+ case class ArrayEncoder[E](element: AgnosticEncoder[E], containsNull: Boolean)
extends AgnosticEncoder[Array[E]] {
override def isPrimitive: Boolean = false
- override def dataType: DataType = ArrayType(element.dataType, element.nullable)
+ override def dataType: DataType = ArrayType(element.dataType, containsNull)
override val clsTag: ClassTag[Array[E]] = element.clsTag.wrap
}
- case class IterableEncoder[C <: Iterable[E], E](
+ case class IterableEncoder[C, E](
override val clsTag: ClassTag[C],
- element: AgnosticEncoder[E])
+ element: AgnosticEncoder[E],
+ containsNull: Boolean,
+ override val lenientSerialization: Boolean)
Review Comment:
It means we allow a Seq, a generic Array, or a primitive array as input for serialization
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org
[GitHub] [spark] cloud-fan commented on pull request #39517: [SPARK-41993][SQL] Move RowEncoder to AgnosticEncoders
Posted by GitBox <gi...@apache.org>.
cloud-fan commented on PR #39517:
URL: https://github.com/apache/spark/pull/39517#issuecomment-1383789142
Only 2 minor comments, thanks, merging to master!
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org
[GitHub] [spark] hvanhovell commented on pull request #39517: [SPARK-41993][SQL] Move RowEncoder to AgnosticEncoders
Posted by GitBox <gi...@apache.org>.
hvanhovell commented on PR #39517:
URL: https://github.com/apache/spark/pull/39517#issuecomment-1384708819
@dongjoon-hyun I am looking at it now. I am not sure if massive is the qualification I would use; all of these are likely to be caused by the same thing. Feel free to revert if you have too.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org
[GitHub] [spark] dongjoon-hyun commented on pull request #39517: [SPARK-41993][SQL] Move RowEncoder to AgnosticEncoders
Posted by GitBox <gi...@apache.org>.
dongjoon-hyun commented on PR #39517:
URL: https://github.com/apache/spark/pull/39517#issuecomment-1384709452
Thank you, @hvanhovell .
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org
[GitHub] [spark] hvanhovell commented on pull request #39517: [SPARK-41993][SQL] Move RowEncoder to AgnosticEncoders
Posted by GitBox <gi...@apache.org>.
hvanhovell commented on PR #39517:
URL: https://github.com/apache/spark/pull/39517#issuecomment-1379452378
@cloud-fan can you take a look?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org
[GitHub] [spark] hvanhovell commented on a diff in pull request #39517: [SPARK-41993][SQL] Move RowEncoder to AgnosticEncoders
Posted by GitBox <gi...@apache.org>.
hvanhovell commented on code in PR #39517:
URL: https://github.com/apache/spark/pull/39517#discussion_r1067435036
##########
sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/ScalaReflection.scala:
##########
@@ -377,27 +408,96 @@ object ScalaReflection extends ScalaReflection {
val getter = Invoke(
KnownNotNull(input),
field.name,
- dataTypeFor(field.enc),
- returnNullable = field.enc.nullable)
+ externalDataTypeFor(field.enc),
+ returnNullable = field.nullable)
field.name -> serializerFor(field.enc, getter)
}
createSerializerForObject(input, serializedFields)
+
+ case RowEncoder(fields) =>
+ val serializedFields = fields.zipWithIndex.map { case (field, index) =>
+ val fieldValue = serializerFor(
+ field.enc,
+ ValidateExternalType(
+ GetExternalRowField(input, index, field.name),
+ field.enc.dataType,
+ lenientExternalDataTypeFor(field.enc)))
+
+ val convertedField = if (field.nullable) {
+ exprs.If(
+ Invoke(input, "isNullAt", BooleanType, exprs.Literal(index) :: Nil),
+ // Because we strip UDTs, `field.dataType` can be different from `fieldValue.dataType`.
+ // We should use `fieldValue.dataType` here.
+ exprs.Literal.create(null, fieldValue.dataType),
+ fieldValue
+ )
+ } else {
+ AssertNotNull(fieldValue)
+ }
+ field.name -> convertedField
+ }
+ createSerializerForObject(input, serializedFields)
}
private def serializerForArray(
- isArray: Boolean,
elementEnc: AgnosticEncoder[_],
- input: Expression): Expression = {
- dataTypeFor(elementEnc) match {
- case dt: ObjectType =>
- createSerializerForMapObjects(input, dt, serializerFor(elementEnc, _))
- case dt if isArray && elementEnc.isPrimitive =>
- createSerializerForPrimitiveArray(input, dt)
- case dt =>
- createSerializerForGenericArray(input, dt, elementEnc.nullable)
+ elementNullable: Boolean,
+ input: Expression,
+ lenientSerialization: Boolean): Expression = {
+ // Default serializer for Seq and generic Arrays. This does not work for primitive arrays.
+ val genericSerializer = createSerializerForMapObjects(
+ input,
+ ObjectType(classOf[AnyRef]),
+ validateAndSerializeElement(elementEnc, elementNullable))
+
+ // Check if it is possible the user can pass a primitive array. This is the only case when it
+ // is safe to directly convert to an array (for generic arrays and Seqs the type and the
+ // nullability can be violated). If the user has passed a primitive array we create a special
+ // code path to deal with these.
+ val primitiveEncoderOption = elementEnc match {
+ case _ if !lenientSerialization => None
+ case enc: PrimitiveLeafEncoder[_] => Option(enc)
+ case enc: BoxedLeafEncoder[_, _] => Option(enc.primitive)
+ case _ => None
+ }
+ primitiveEncoderOption match {
+ case Some(primitiveEncoder) =>
+ val primitiveArrayClass = primitiveEncoder.clsTag.wrap.runtimeClass
+ val check = Invoke(
+ targetObject = exprs.Literal.fromObject(primitiveArrayClass),
+ functionName = "isInstance",
+ BooleanType,
+ arguments = input :: Nil,
+ propagateNull = false,
+ returnNullable = false)
+ exprs.If(
+ check,
Review Comment:
We can widen this to arrays where the element is allowed to be null. In that case we do need to make sure the element type is sound.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org
[GitHub] [spark] cloud-fan commented on a diff in pull request #39517: [SPARK-41993][SQL] Move RowEncoder to AgnosticEncoders
Posted by GitBox <gi...@apache.org>.
cloud-fan commented on code in PR #39517:
URL: https://github.com/apache/spark/pull/39517#discussion_r1071046887
##########
sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/ScalaReflectionSuite.scala:
##########
@@ -388,11 +388,10 @@ class ScalaReflectionSuite extends SparkFunSuite {
}
test("SPARK-15062: Get correct serializer for List[_]") {
- val list = List(1, 2, 3)
val serializer = serializerFor[List[Int]]
- assert(serializer.isInstanceOf[NewInstance])
- assert(serializer.asInstanceOf[NewInstance]
- .cls.isAssignableFrom(classOf[org.apache.spark.sql.catalyst.util.GenericArrayData]))
+ assert(serializer.isInstanceOf[MapObjects])
Review Comment:
is `MapObjects` better than `NewInstance` for creating `List[Int]`?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org
[GitHub] [spark] hvanhovell commented on a diff in pull request #39517: [SPARK-41993][SQL] Move RowEncoder to AgnosticEncoders
Posted by GitBox <gi...@apache.org>.
hvanhovell commented on code in PR #39517:
URL: https://github.com/apache/spark/pull/39517#discussion_r1069354107
##########
sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/encoders/AgnosticEncoder.scala:
##########
@@ -46,35 +46,42 @@ object AgnosticEncoders {
override val clsTag: ClassTag[Option[E]] = ClassTag(classOf[Option[E]])
}
- case class ArrayEncoder[E](element: AgnosticEncoder[E])
+ case class ArrayEncoder[E](element: AgnosticEncoder[E], containsNull: Boolean)
extends AgnosticEncoder[Array[E]] {
override def isPrimitive: Boolean = false
- override def dataType: DataType = ArrayType(element.dataType, element.nullable)
+ override def dataType: DataType = ArrayType(element.dataType, containsNull)
override val clsTag: ClassTag[Array[E]] = element.clsTag.wrap
}
- case class IterableEncoder[C <: Iterable[E], E](
+ case class IterableEncoder[C, E](
override val clsTag: ClassTag[C],
- element: AgnosticEncoder[E])
+ element: AgnosticEncoder[E],
+ containsNull: Boolean,
+ override val lenientSerialization: Boolean)
Review Comment:
yeah will do. TBH I was quite surprised by it.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org
[GitHub] [spark] cloud-fan commented on a diff in pull request #39517: [SPARK-41993][SQL] Move RowEncoder to AgnosticEncoders
Posted by GitBox <gi...@apache.org>.
cloud-fan commented on code in PR #39517:
URL: https://github.com/apache/spark/pull/39517#discussion_r1067668533
##########
sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/encoders/AgnosticEncoder.scala:
##########
@@ -46,35 +46,42 @@ object AgnosticEncoders {
override val clsTag: ClassTag[Option[E]] = ClassTag(classOf[Option[E]])
}
- case class ArrayEncoder[E](element: AgnosticEncoder[E])
+ case class ArrayEncoder[E](element: AgnosticEncoder[E], containsNull: Boolean)
extends AgnosticEncoder[Array[E]] {
override def isPrimitive: Boolean = false
- override def dataType: DataType = ArrayType(element.dataType, element.nullable)
+ override def dataType: DataType = ArrayType(element.dataType, containsNull)
override val clsTag: ClassTag[Array[E]] = element.clsTag.wrap
}
- case class IterableEncoder[C <: Iterable[E], E](
+ case class IterableEncoder[C, E](
override val clsTag: ClassTag[C],
- element: AgnosticEncoder[E])
+ element: AgnosticEncoder[E],
+ containsNull: Boolean,
+ override val lenientSerialization: Boolean)
Review Comment:
what does lenient mean for a `IterableEncoder`?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org
[GitHub] [spark] cloud-fan commented on a diff in pull request #39517: [SPARK-41993][SQL] Move RowEncoder to AgnosticEncoders
Posted by GitBox <gi...@apache.org>.
cloud-fan commented on code in PR #39517:
URL: https://github.com/apache/spark/pull/39517#discussion_r1067656569
##########
sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/encoders/RowEncoderSuite.scala:
##########
@@ -125,7 +125,7 @@ class RowEncoderSuite extends CodegenInterpretedPlanTest {
new StructType()
.add("mapOfIntAndString", MapType(IntegerType, StringType))
.add("mapOfStringAndArray", MapType(StringType, arrayOfString))
- .add("mapOfArrayAndInt", MapType(arrayOfString, IntegerType))
Review Comment:
`arrayOfString` doesn't work anymore inside map?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org
[GitHub] [spark] hvanhovell commented on a diff in pull request #39517: [SPARK-41993][SQL] Move RowEncoder to AgnosticEncoders
Posted by GitBox <gi...@apache.org>.
hvanhovell commented on code in PR #39517:
URL: https://github.com/apache/spark/pull/39517#discussion_r1068889994
##########
sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/ScalaReflection.scala:
##########
@@ -155,11 +169,19 @@ object ScalaReflection extends ScalaReflection {
val walkedTypePath = WalkedTypePath().recordRoot(enc.clsTag.runtimeClass.getName)
// Assumes we are deserializing the first column of a row.
val input = GetColumnByOrdinal(0, enc.dataType)
- val deserializer = deserializerFor(
- enc,
- upCastToExpectedType(input, enc.dataType, walkedTypePath),
- walkedTypePath)
- expressionWithNullSafety(deserializer, enc.nullable, walkedTypePath)
+ enc match {
+ case RowEncoder(fields) =>
Review Comment:
We create one with null checks. This one does not need them because we always return a Row.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org
[GitHub] [spark] cloud-fan commented on a diff in pull request #39517: [SPARK-41993][SQL] Move RowEncoder to AgnosticEncoders
Posted by GitBox <gi...@apache.org>.
cloud-fan commented on code in PR #39517:
URL: https://github.com/apache/spark/pull/39517#discussion_r1071007920
##########
sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/ScalaReflection.scala:
##########
@@ -82,12 +84,24 @@ object ScalaReflection extends ScalaReflection {
}
}
- // TODO this name is slightly misleading. This returns the input
- // data type we expect to see during serialization.
- private[catalyst] def dataTypeFor(enc: AgnosticEncoder[_]): DataType = {
+ /**
+ * Return the data type we expect to see when deserializing a value with encoder `enc`.
+ */
+ private[catalyst] def externalDataTypeFor(enc: AgnosticEncoder[_]): DataType = {
+ externalDataTypeFor(enc, lenientSerialization = false)
+ }
+
+ private[catalyst] def lenientExternalDataTypeFor(enc: AgnosticEncoder[_]): DataType =
Review Comment:
```suggestion
private[catalyst] def lenientExternalDataTypeFor(enc: AgnosticEncoder[_]): DataType =
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org
[GitHub] [spark] cloud-fan commented on a diff in pull request #39517: [SPARK-41993][SQL] Move RowEncoder to AgnosticEncoders
Posted by GitBox <gi...@apache.org>.
cloud-fan commented on code in PR #39517:
URL: https://github.com/apache/spark/pull/39517#discussion_r1067657414
##########
sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/ScalaReflection.scala:
##########
@@ -377,27 +408,96 @@ object ScalaReflection extends ScalaReflection {
val getter = Invoke(
KnownNotNull(input),
field.name,
- dataTypeFor(field.enc),
- returnNullable = field.enc.nullable)
+ externalDataTypeFor(field.enc),
+ returnNullable = field.nullable)
field.name -> serializerFor(field.enc, getter)
}
createSerializerForObject(input, serializedFields)
+
+ case RowEncoder(fields) =>
+ val serializedFields = fields.zipWithIndex.map { case (field, index) =>
+ val fieldValue = serializerFor(
+ field.enc,
+ ValidateExternalType(
+ GetExternalRowField(input, index, field.name),
+ field.enc.dataType,
+ lenientExternalDataTypeFor(field.enc)))
+
+ val convertedField = if (field.nullable) {
+ exprs.If(
+ Invoke(input, "isNullAt", BooleanType, exprs.Literal(index) :: Nil),
+ // Because we strip UDTs, `field.dataType` can be different from `fieldValue.dataType`.
+ // We should use `fieldValue.dataType` here.
+ exprs.Literal.create(null, fieldValue.dataType),
+ fieldValue
+ )
+ } else {
+ AssertNotNull(fieldValue)
+ }
+ field.name -> convertedField
+ }
+ createSerializerForObject(input, serializedFields)
}
private def serializerForArray(
- isArray: Boolean,
elementEnc: AgnosticEncoder[_],
- input: Expression): Expression = {
- dataTypeFor(elementEnc) match {
- case dt: ObjectType =>
- createSerializerForMapObjects(input, dt, serializerFor(elementEnc, _))
- case dt if isArray && elementEnc.isPrimitive =>
- createSerializerForPrimitiveArray(input, dt)
- case dt =>
- createSerializerForGenericArray(input, dt, elementEnc.nullable)
+ elementNullable: Boolean,
+ input: Expression,
+ lenientSerialization: Boolean): Expression = {
+ // Default serializer for Seq and generic Arrays. This does not work for primitive arrays.
Review Comment:
hmm, why the name is `createSerializerForMapObjects`?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org
[GitHub] [spark] hvanhovell commented on a diff in pull request #39517: [SPARK-41993][SQL] Move RowEncoder to AgnosticEncoders
Posted by GitBox <gi...@apache.org>.
hvanhovell commented on code in PR #39517:
URL: https://github.com/apache/spark/pull/39517#discussion_r1068885292
##########
sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/encoders/RowEncoderSuite.scala:
##########
@@ -125,7 +125,7 @@ class RowEncoderSuite extends CodegenInterpretedPlanTest {
new StructType()
.add("mapOfIntAndString", MapType(IntegerType, StringType))
.add("mapOfStringAndArray", MapType(StringType, arrayOfString))
- .add("mapOfArrayAndInt", MapType(arrayOfString, IntegerType))
Review Comment:
That is a mistake. My bad :)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org
[GitHub] [spark] hvanhovell commented on a diff in pull request #39517: [SPARK-41993][SQL] Move RowEncoder to AgnosticEncoders
Posted by GitBox <gi...@apache.org>.
hvanhovell commented on code in PR #39517:
URL: https://github.com/apache/spark/pull/39517#discussion_r1067433716
##########
sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/ScalaReflection.scala:
##########
@@ -306,7 +330,7 @@ object ScalaReflection extends ScalaReflection {
* input object is located at ordinal 0 of a row, i.e., `BoundReference(0, _)`.
*/
def serializerFor(enc: AgnosticEncoder[_]): Expression = {
Review Comment:
TODO check the generated code for boxed primitives. We might be doing double conversions there.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org
[GitHub] [spark] hvanhovell commented on pull request #39517: [SPARK-41993][SQL] Move RowEncoder to AgnosticEncoders
Posted by GitBox <gi...@apache.org>.
hvanhovell commented on PR #39517:
URL: https://github.com/apache/spark/pull/39517#issuecomment-1379453290
A note for the reviewers. I know that Catalyst tests pass. I have not run other tests, so there might still be a few things to iron out.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org
[GitHub] [spark] cloud-fan commented on a diff in pull request #39517: [SPARK-41993][SQL] Move RowEncoder to AgnosticEncoders
Posted by GitBox <gi...@apache.org>.
cloud-fan commented on code in PR #39517:
URL: https://github.com/apache/spark/pull/39517#discussion_r1067657104
##########
sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/ScalaReflection.scala:
##########
@@ -155,11 +169,19 @@ object ScalaReflection extends ScalaReflection {
val walkedTypePath = WalkedTypePath().recordRoot(enc.clsTag.runtimeClass.getName)
// Assumes we are deserializing the first column of a row.
val input = GetColumnByOrdinal(0, enc.dataType)
- val deserializer = deserializerFor(
- enc,
- upCastToExpectedType(input, enc.dataType, walkedTypePath),
- walkedTypePath)
- expressionWithNullSafety(deserializer, enc.nullable, walkedTypePath)
+ enc match {
+ case RowEncoder(fields) =>
Review Comment:
what encoder do we create for inner struct? how is it different from the root `RowEncoder`?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org
[GitHub] [spark] cloud-fan commented on a diff in pull request #39517: [SPARK-41993][SQL] Move RowEncoder to AgnosticEncoders
Posted by GitBox <gi...@apache.org>.
cloud-fan commented on code in PR #39517:
URL: https://github.com/apache/spark/pull/39517#discussion_r1068892182
##########
sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/encoders/AgnosticEncoder.scala:
##########
@@ -46,35 +46,42 @@ object AgnosticEncoders {
override val clsTag: ClassTag[Option[E]] = ClassTag(classOf[Option[E]])
}
- case class ArrayEncoder[E](element: AgnosticEncoder[E])
+ case class ArrayEncoder[E](element: AgnosticEncoder[E], containsNull: Boolean)
extends AgnosticEncoder[Array[E]] {
override def isPrimitive: Boolean = false
- override def dataType: DataType = ArrayType(element.dataType, element.nullable)
+ override def dataType: DataType = ArrayType(element.dataType, containsNull)
override val clsTag: ClassTag[Array[E]] = element.clsTag.wrap
}
- case class IterableEncoder[C <: Iterable[E], E](
+ case class IterableEncoder[C, E](
override val clsTag: ClassTag[C],
- element: AgnosticEncoder[E])
+ element: AgnosticEncoder[E],
+ containsNull: Boolean,
+ override val lenientSerialization: Boolean)
Review Comment:
Can we leave a code comment to mention it? It's not that obvious compared to `DateEncoder`.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org
[GitHub] [spark] hvanhovell commented on a diff in pull request #39517: [SPARK-41993][SQL] Move RowEncoder to AgnosticEncoders
Posted by GitBox <gi...@apache.org>.
hvanhovell commented on code in PR #39517:
URL: https://github.com/apache/spark/pull/39517#discussion_r1068889994
##########
sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/ScalaReflection.scala:
##########
@@ -155,11 +169,19 @@ object ScalaReflection extends ScalaReflection {
val walkedTypePath = WalkedTypePath().recordRoot(enc.clsTag.runtimeClass.getName)
// Assumes we are deserializing the first column of a row.
val input = GetColumnByOrdinal(0, enc.dataType)
- val deserializer = deserializerFor(
- enc,
- upCastToExpectedType(input, enc.dataType, walkedTypePath),
- walkedTypePath)
- expressionWithNullSafety(deserializer, enc.nullable, walkedTypePath)
+ enc match {
+ case RowEncoder(fields) =>
Review Comment:
We create one with null checks. This one does not need them because we always return a Row (the toplevel row always exists).
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org
[GitHub] [spark] hvanhovell commented on a diff in pull request #39517: [SPARK-41993][SQL] Move RowEncoder to AgnosticEncoders
Posted by GitBox <gi...@apache.org>.
hvanhovell commented on code in PR #39517:
URL: https://github.com/apache/spark/pull/39517#discussion_r1068884900
##########
sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/ScalaReflection.scala:
##########
@@ -377,27 +408,96 @@ object ScalaReflection extends ScalaReflection {
val getter = Invoke(
KnownNotNull(input),
field.name,
- dataTypeFor(field.enc),
- returnNullable = field.enc.nullable)
+ externalDataTypeFor(field.enc),
+ returnNullable = field.nullable)
field.name -> serializerFor(field.enc, getter)
}
createSerializerForObject(input, serializedFields)
+
+ case RowEncoder(fields) =>
+ val serializedFields = fields.zipWithIndex.map { case (field, index) =>
+ val fieldValue = serializerFor(
+ field.enc,
+ ValidateExternalType(
+ GetExternalRowField(input, index, field.name),
+ field.enc.dataType,
+ lenientExternalDataTypeFor(field.enc)))
+
+ val convertedField = if (field.nullable) {
+ exprs.If(
+ Invoke(input, "isNullAt", BooleanType, exprs.Literal(index) :: Nil),
+ // Because we strip UDTs, `field.dataType` can be different from `fieldValue.dataType`.
+ // We should use `fieldValue.dataType` here.
+ exprs.Literal.create(null, fieldValue.dataType),
+ fieldValue
+ )
+ } else {
+ AssertNotNull(fieldValue)
+ }
+ field.name -> convertedField
+ }
+ createSerializerForObject(input, serializedFields)
}
private def serializerForArray(
- isArray: Boolean,
elementEnc: AgnosticEncoder[_],
- input: Expression): Expression = {
- dataTypeFor(elementEnc) match {
- case dt: ObjectType =>
- createSerializerForMapObjects(input, dt, serializerFor(elementEnc, _))
- case dt if isArray && elementEnc.isPrimitive =>
- createSerializerForPrimitiveArray(input, dt)
- case dt =>
- createSerializerForGenericArray(input, dt, elementEnc.nullable)
+ elementNullable: Boolean,
+ input: Expression,
+ lenientSerialization: Boolean): Expression = {
+ // Default serializer for Seq and generic Arrays. This does not work for primitive arrays.
Review Comment:
I don't know. It was like that before this.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org