From 6f88549fafffa0bc10515b8c7dd63c554babb53f Mon Sep 17 00:00:00 2001 From: Brian Lindblom Date: Sun, 2 Apr 2017 14:57:01 -0700 Subject: [PATCH] Enable forceSchema option for writer --- .../spark/avro/AvroOutputWriter.scala | 152 ++++++++++-- .../spark/avro/AvroOutputWriterFactory.scala | 19 +- .../databricks/spark/avro/DefaultSource.scala | 11 +- src/test/resources/messy.avro | Bin 0 -> 85855 bytes src/test/resources/messy.avsc | 224 ++++++++++++++++++ .../com/databricks/spark/avro/AvroSuite.scala | 83 +++++++ 6 files changed, 464 insertions(+), 25 deletions(-) create mode 100644 src/test/resources/messy.avro create mode 100644 src/test/resources/messy.avsc diff --git a/src/main/scala/com/databricks/spark/avro/AvroOutputWriter.scala b/src/main/scala/com/databricks/spark/avro/AvroOutputWriter.scala index 297c39d6..cb497e33 100644 --- a/src/main/scala/com/databricks/spark/avro/AvroOutputWriter.scala +++ b/src/main/scala/com/databricks/spark/avro/AvroOutputWriter.scala @@ -20,32 +20,47 @@ import java.io.{IOException, OutputStream} import java.nio.ByteBuffer import java.sql.Timestamp import java.sql.Date +import java.util import java.util.HashMap import org.apache.hadoop.fs.Path -import scala.collection.immutable.Map +import scala.collection.immutable.Map import org.apache.avro.generic.GenericData.Record -import org.apache.avro.generic.GenericRecord +import org.apache.avro.generic.{GenericData, GenericRecord, GenericRecordBuilder} import org.apache.avro.{Schema, SchemaBuilder} import org.apache.avro.mapred.AvroKey import org.apache.avro.mapreduce.AvroKeyOutputFormat import org.apache.hadoop.io.NullWritable import org.apache.hadoop.mapreduce.{RecordWriter, TaskAttemptContext, TaskAttemptID} - +import org.apache.log4j.Logger import org.apache.spark.sql.Row import org.apache.spark.sql.execution.datasources.OutputWriter import org.apache.spark.sql.types._ +import scala.collection.JavaConversions._ +import scala.collection.JavaConverters._ +import scala.collection.mutable.ArrayBuffer + // NOTE: This class is instantiated and used on executor side only, no need to be serializable. private[avro] class AvroOutputWriter( path: String, context: TaskAttemptContext, schema: StructType, recordName: String, - recordNamespace: String) extends OutputWriter { + recordNamespace: String, + forceSchema: String) extends OutputWriter { - private lazy val converter = createConverterToAvro(schema, recordName, recordNamespace) + private val logger = Logger.getLogger(this.getClass) + + private val forceAvroSchema = if (forceSchema.contentEquals("")) { + None + } else { + Option(new Schema.Parser().parse(forceSchema)) + } + private lazy val converter = createConverterToAvro( + schema, recordName, recordNamespace, forceAvroSchema + ) /** * Overrides the couple of methods responsible for generating the output streams / files so @@ -73,6 +88,27 @@ private[avro] class AvroOutputWriter( override def close(): Unit = recordWriter.close(context) + private def resolveStructTypeToAvroUnion(schema:Schema, dataType:String): Schema = { + val allowedAvroTypes = dataType match { + case "boolean" => List(Schema.Type.BOOLEAN) + case "integer" => List(Schema.Type.INT) + case "long" => List(Schema.Type.LONG) + case "float" => List(Schema.Type.FLOAT) + case "double" => List(Schema.Type.DOUBLE) + case "binary" => List(Schema.Type.BYTES, Schema.Type.FIXED) + case "array" => List(Schema.Type.ARRAY) + case "map" => List(Schema.Type.MAP) + case "string" => List(Schema.Type.STRING, Schema.Type.ENUM) + case "struct" => List(Schema.Type.ARRAY, Schema.Type.RECORD) + case default => { + throw new RuntimeException( + s"Cannot map SparkSQL type '$dataType' against Avro schema '$schema'" + ) + } + } + schema.getTypes.find (allowedAvroTypes contains _.getType).get + } + /** * This function constructs converter function for a given sparkSQL datatype. This is used in * writing Avro records out to disk @@ -80,21 +116,51 @@ private[avro] class AvroOutputWriter( private def createConverterToAvro( dataType: DataType, structName: String, - recordNamespace: String): (Any) => Any = { + recordNamespace: String, + forceAvroSchema: Option[Schema]): (Any) => Any = { dataType match { case BinaryType => (item: Any) => item match { case null => null - case bytes: Array[Byte] => ByteBuffer.wrap(bytes) + case bytes: Array[Byte] => if (forceAvroSchema.isDefined) { + // Handle mapping from binary => bytes|fixed w/ forceSchema + forceAvroSchema.get.getType match { + case Schema.Type.BYTES => ByteBuffer.wrap(bytes) + case Schema.Type.FIXED => new GenericData.Fixed( + forceAvroSchema.get, bytes + ) + case default => bytes + } + } else { + ByteBuffer.wrap(bytes) + } } case ByteType | ShortType | IntegerType | LongType | - FloatType | DoubleType | StringType | BooleanType => identity + FloatType | DoubleType | BooleanType => identity + case StringType => (item: Any) => if (forceAvroSchema.isDefined) { + // Handle case when forcing schema where this string should map + // to an ENUM + forceAvroSchema.get.getType match { + case Schema.Type.ENUM => new GenericData.EnumSymbol( + forceAvroSchema.get, item.toString + ) + case default => item + } + } else { + item + } case _: DecimalType => (item: Any) => if (item == null) null else item.toString case TimestampType => (item: Any) => if (item == null) null else item.asInstanceOf[Timestamp].getTime case DateType => (item: Any) => if (item == null) null else item.asInstanceOf[Date].getTime case ArrayType(elementType, _) => - val elementConverter = createConverterToAvro(elementType, structName, recordNamespace) + val elementConverter = if (forceAvroSchema.isDefined) { + createConverterToAvro(elementType, structName, + recordNamespace, Option(forceAvroSchema.get.getElementType)) + } else { + createConverterToAvro(elementType, structName, + recordNamespace, forceAvroSchema) + } (item: Any) => { if (item == null) { null @@ -107,14 +173,20 @@ private[avro] class AvroOutputWriter( targetArray(idx) = elementConverter(sourceArray(idx)) idx += 1 } - targetArray + targetArray.toSeq.asJava } } case MapType(StringType, valueType, _) => - val valueConverter = createConverterToAvro(valueType, structName, recordNamespace) + val valueConverter = if (forceAvroSchema.isDefined) { + createConverterToAvro(valueType, structName, + recordNamespace, Option(forceAvroSchema.get.getValueType)) + } else { + createConverterToAvro(valueType, structName, + recordNamespace, forceAvroSchema) + } (item: Any) => { if (item == null) { - null + if (forceAvroSchema.isDefined) new HashMap[String, Any]() else null } else { val javaMap = new HashMap[String, Any]() item.asInstanceOf[Map[String, Any]].foreach { case (key, value) => @@ -125,10 +197,36 @@ private[avro] class AvroOutputWriter( } case structType: StructType => val builder = SchemaBuilder.record(structName).namespace(recordNamespace) - val schema: Schema = SchemaConverters.convertStructToAvro( - structType, builder, recordNamespace) - val fieldConverters = structType.fields.map(field => - createConverterToAvro(field.dataType, field.name, recordNamespace)) + val schema: Schema = if (!forceAvroSchema.isDefined) { + SchemaConverters.convertStructToAvro( + structType, builder, recordNamespace) + } else { + if (forceAvroSchema.get.getType == Schema.Type.ARRAY) { + forceAvroSchema.get.getElementType + } else { + forceAvroSchema.get + } + } + + val fieldConverters = structType.fields.map ( + field => { + val fieldConvertSchema = if (forceAvroSchema.isDefined) { + val thisFieldSchema = schema.getField(field.name).schema + Option( + thisFieldSchema.getType match { + case Schema.Type.UNION => { + resolveStructTypeToAvroUnion(thisFieldSchema, field.dataType.typeName) + } + case default => thisFieldSchema + } + ) + } else { + forceAvroSchema + } + createConverterToAvro(field.dataType, field.name, recordNamespace, fieldConvertSchema) + } + ) + (item: Any) => { if (item == null) { null @@ -140,9 +238,27 @@ private[avro] class AvroOutputWriter( while (convertersIterator.hasNext) { val converter = convertersIterator.next() - record.put(fieldNamesIterator.next(), converter(rowIterator.next())) + val fieldValue = rowIterator.next() + val fieldName = fieldNamesIterator.next() + try { + record.put(fieldName, converter(fieldValue)) + } catch { + case ex:NullPointerException => { + // This can happen with forceAvroSchema conversion + if (forceAvroSchema.isDefined) { + logger.debug(s"Trying to write field $fieldName which may be null? $fieldValue") + } else { + // Keep previous behavior when forceAvroSchema is not used + throw ex + } + } + } + } + if(forceAvroSchema.isDefined) { + new GenericRecordBuilder(record).build() + } else { + record } - record } } } diff --git a/src/main/scala/com/databricks/spark/avro/AvroOutputWriterFactory.scala b/src/main/scala/com/databricks/spark/avro/AvroOutputWriterFactory.scala index 3f3cbf07..728c4125 100644 --- a/src/main/scala/com/databricks/spark/avro/AvroOutputWriterFactory.scala +++ b/src/main/scala/com/databricks/spark/avro/AvroOutputWriterFactory.scala @@ -16,24 +16,33 @@ package com.databricks.spark.avro +import org.apache.avro.Schema import org.apache.hadoop.mapreduce.TaskAttemptContext - import org.apache.spark.sql.execution.datasources.{OutputWriter, OutputWriterFactory} import org.apache.spark.sql.types.StructType private[avro] class AvroOutputWriterFactory( schema: StructType, recordName: String, - recordNamespace: String) extends OutputWriterFactory { + recordNamespace: String, + forceSchema: String) extends OutputWriterFactory { - override def getFileExtension(context: TaskAttemptContext): String = { + def getFileExtension(context: TaskAttemptContext): String = { ".avro" } - override def newInstance( + def newInstance( + path: String, + bucketId: Option[Int], + dataSchema: StructType, + context: TaskAttemptContext): OutputWriter = { + newInstance(path, dataSchema, context) + } + + def newInstance( path: String, dataSchema: StructType, context: TaskAttemptContext): OutputWriter = { - new AvroOutputWriter(path, context, schema, recordName, recordNamespace) + new AvroOutputWriter(path, context, schema, recordName, recordNamespace, forceSchema) } } diff --git a/src/main/scala/com/databricks/spark/avro/DefaultSource.scala b/src/main/scala/com/databricks/spark/avro/DefaultSource.scala index bfbadd7c..191022ab 100644 --- a/src/main/scala/com/databricks/spark/avro/DefaultSource.scala +++ b/src/main/scala/com/databricks/spark/avro/DefaultSource.scala @@ -112,10 +112,17 @@ private[avro] class DefaultSource extends FileFormat with DataSourceRegister { dataSchema: StructType): OutputWriterFactory = { val recordName = options.getOrElse("recordName", "topLevelRecord") val recordNamespace = options.getOrElse("recordNamespace", "") + val forceAvroSchema = options.getOrElse("forceSchema", "") val build = SchemaBuilder.record(recordName).namespace(recordNamespace) - val outputAvroSchema = SchemaConverters.convertStructToAvro(dataSchema, build, recordNamespace) + val outputAvroSchema = if (forceAvroSchema.contentEquals("")) { + SchemaConverters.convertStructToAvro(dataSchema, build, recordNamespace) + } else { + val parser = new Schema.Parser() + parser.parse(forceAvroSchema) + } AvroJob.setOutputKeySchema(job, outputAvroSchema) + val AVRO_COMPRESSION_CODEC = "spark.sql.avro.compression.codec" val AVRO_DEFLATE_LEVEL = "spark.sql.avro.deflate.level" val COMPRESS_KEY = "mapred.output.compress" @@ -142,7 +149,7 @@ private[avro] class DefaultSource extends FileFormat with DataSourceRegister { log.error(s"unsupported compression codec $unknown") } - new AvroOutputWriterFactory(dataSchema, recordName, recordNamespace) + new AvroOutputWriterFactory(dataSchema, recordName, recordNamespace, forceAvroSchema) } override def buildReader( diff --git a/src/test/resources/messy.avro b/src/test/resources/messy.avro new file mode 100644 index 0000000000000000000000000000000000000000..3dec11c5015ff2f04d7741b055bafdb8c5f0da46 GIT binary patch literal 85855 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 T8H1;aw)w`^>r#0CUpV=H*4pg& literal 0 HcmV?d00001 diff --git a/src/test/resources/messy.avsc b/src/test/resources/messy.avsc new file mode 100644 index 00000000..a0a385c8 --- /dev/null +++ b/src/test/resources/messy.avsc @@ -0,0 +1,224 @@ +{ + "type": "record", + "name": "MessyRecord", + "namespace": "foo.bar.baz", + "doc": "This record encapsulates many failure cases for forceSchema support", + "fields": [ + { + "name": "someEnumField", + "type": { + "type": "enum", + "name": "someEnum", + "symbols": [ + "string1", + "string2", + "string3" + ] + } + }, + { + "name": "someString", + "type": "string" + }, + { + "name": "someNullUnionBool", + "type": [ + "null", + "boolean" + ] + }, + { + "name": "someNullUnionInt", + "type": [ + "null", + "int" + ] + }, + { + "name": "someNullUnionLong", + "type": [ + "null", + "long" + ] + }, + { + "name": "someNullUnionFloat", + "type": [ + "null", + "float" + ] + }, + { + "name": "someNullUnionDouble", + "type": [ + "null", + "double" + ] + }, + { + "name": "someNullUnionBytes", + "type": [ + "null", + "bytes" + ] + }, + { + "name": "someNullUnionString", + "type": [ + "null", + "string" + ] + }, + { + "name": "someNullUnionEnum", + "type": [ + "null", + { + "type": "enum", + "name": "anotherEnum", + "symbols": [ + "string1", + "string2", + "string3" + ] + } + ] + }, + { + "name": "someNullUnionArray", + "type": [ + "null", + { + "type": "array", + "items": "string" + } + ] + }, + { + "name": "someNullUnionMap", + "type": [ + "null", + { + "type": "map", + "values": "long" + } + ], + "order": "ignore", + "default": null + }, + { + "name": "someNullUnionFixed", + "type": [ + "null", + { + "type": "fixed", + "name": "foo", + "size": 8 + } + ] + }, + { + "name": "someRecordField", + "doc": "Field contains a record (or null) with crazy nested stuff", + "type": [ + "null", + { + "type": "record", + "name": "someRecord", + "fields": [ + { + "name": "someSubRecordField", + "type": { + "type": "record", + "name": "someSubRecords", + "fields": [ + { + "name": "someSubRecordsField", + "type": { + "type": "array", + "items": { + "type": "record", + "name": "someSubSubRecords", + "fields": [ + { + "name": "notQuiteDeepEnoughRecordsField", + "type": { + "type": "array", + "items": { + "type": "record", + "name": "notQuiteDeepEnoughRecord", + "fields": [ + { + "name": "notQuiteDeepEnoughRecords", + "type": { + "type": "array", + "items": { + "type": "record", + "name": "okDeepEnoughRecord", + "fields": [ + { + "name": "someReallyDeepString", + "type": "string" + }, + { + "name": "someReallyDeepInt", + "type": "int" + }, + { + "name": "someReallyDeepBooleanWithDefault", + "type": "boolean", + "default": false + } + ] + } + } + } + ] + } + } + } + ] + } + } + } + ] + } + } + ] + } + ], + "default": null + }, + { + "name": "someIntWithDefault", + "type": "int", + "default": 0 + }, + { + "name": "someFloatWithDefault", + "type": "float", + "default": 3.14159 + }, + { + "name": "someLongWithDefault", + "type": "long", + "default": 9999999999999 + }, + { + "name": "someDoubleWithDefault", + "type": "double", + "default": 3.141592654 + }, + { + "name": "someStringMap", + "doc": "This will make sure order: ignore is preseved, null values are defaulted, etc.", + "type": { + "type": "map", + "values": "string" + }, + "order": "ignore", + "default": { + } + } + ] +} diff --git a/src/test/scala/com/databricks/spark/avro/AvroSuite.scala b/src/test/scala/com/databricks/spark/avro/AvroSuite.scala index 4843ad46..c450d47e 100644 --- a/src/test/scala/com/databricks/spark/avro/AvroSuite.scala +++ b/src/test/scala/com/databricks/spark/avro/AvroSuite.scala @@ -34,9 +34,13 @@ import org.apache.spark.sql._ import org.apache.spark.sql.types._ import org.scalatest.{BeforeAndAfterAll, FunSuite} import com.databricks.spark.avro.SchemaConverters.IncompatibleSchemaException +import org.apache.spark.rdd.RDD +import org.apache.spark.sql.catalyst.expressions.GenericRowWithSchema class AvroSuite extends FunSuite with BeforeAndAfterAll { val episodesFile = "src/test/resources/episodes.avro" + val messyFile = "src/test/resources/messy.avro" + val messySchemaFile = "src/test/resources/messy.avsc" val testFile = "src/test/resources/test.avro" private var spark: SparkSession = _ @@ -642,6 +646,85 @@ class AvroSuite extends FunSuite with BeforeAndAfterAll { } } + // Read an avro, write it with converted schema, read it, write it with original forceSchema + // Then, test that data does not change + test("test read original schema, write with converted schema, read, write with original schema") { + // Test if load works as expected + TestUtils.withTempDir { tempDir => + // Let's imagine that + def getSomeSubRecords(df:Dataset[Row]): RDD[GenericRowWithSchema] = { + df.rdd.flatMap { + row => { + val topStruct = row.getAs[GenericRowWithSchema]("someRecordField") + if (topStruct != null){ + val subStruct = topStruct.getAs[GenericRowWithSchema]( + topStruct.fieldIndex("someSubRecordField") + ) + subStruct.getSeq(subStruct.fieldIndex("someSubRecordsField")) + } else { + Array[GenericRowWithSchema]() + } + } + } + } + + def getNotQuiteDeepEnoughRecords(df:Dataset[Row]): RDD[GenericRowWithSchema] = { + getSomeSubRecords(df).flatMap ( + row => row.getSeq(row.fieldIndex("notQuiteDeepEnoughRecordsField")) + ) + } + + def getSumOfReallyDeepInts(df:Dataset[Row]): Long = { + getNotQuiteDeepEnoughRecords(df).flatMap { + row => { + val topLevel:Seq[GenericRowWithSchema] = row + .getSeq(row.fieldIndex("notQuiteDeepEnoughRecords")) + topLevel.map(sub => sub.getInt(sub.fieldIndex("someReallyDeepInt"))) + } + }.reduce((x:Int,y:Int) => x + y) + } + + val forceSchema = scala.io.Source + .fromFile("src/test/resources/messy.avsc") + .getLines() + .mkString("\n") + + val df = spark.read.avro(messyFile) + assert(df.count == 10) + + val tempSaveDir1 = s"$tempDir/save1/" + val tempSaveDir2 = s"$tempDir/save2/" + + df.write.avro(tempSaveDir1) + + val newDf = spark.read.avro(tempSaveDir1) + assert(newDf.count == 10) + + // number of someSubRecords in dataset + val numSomeSubRecords1 = getSomeSubRecords(newDf).collect.length + val notQuiteDeepEnoughRecords1 = getNotQuiteDeepEnoughRecords(newDf).collect.length + val sumOfReallyDeepInts1 = getSumOfReallyDeepInts(newDf) + assert(numSomeSubRecords1 == 33) + assert(notQuiteDeepEnoughRecords1 == 375) + assert(sumOfReallyDeepInts1 == -367812589) + + newDf.write + .option("forceSchema", forceSchema) + .avro(tempSaveDir2) + + val newerDf = spark.read.avro(tempSaveDir2) + assert(newerDf.count == 10) + + // number of someSubRecords in dataset + val numSomeSubRecords2 = getSomeSubRecords(newerDf).collect.length + val notQuiteDeepEnoughRecords2 = getNotQuiteDeepEnoughRecords(newDf).collect.length + val sumOfReallyDeepInts2 = getSumOfReallyDeepInts(newDf) + assert(numSomeSubRecords2 == 33) + assert(notQuiteDeepEnoughRecords2 == 375) + assert(sumOfReallyDeepInts2 == -367812589) + } + } + test("read avro with user defined schema: read partial columns") { val partialColumns = StructType(Seq( StructField("string", StringType, false),