-
Notifications
You must be signed in to change notification settings - Fork 2.5k
[HUDI-3204] Fixing partition-values being derived from partition-path instead of source columns #5364
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
[HUDI-3204] Fixing partition-values being derived from partition-path instead of source columns #5364
Changes from 9 commits
f3cad46
e2c6ce6
49fe4b4
ed396fe
5c7dda4
6aaf861
ceb5add
8f6a7e1
c040d5c
20bf6c9
a94bcce
5d8e15e
3bee902
c1009b9
595a6db
ff25a23
ee7f3ef
27d58e9
3dc0bd1
8a8f18b
d5b99e6
1548335
f4eaa8e
ccc1546
87b30e0
3ffdf87
5a168d6
61dc421
9353c8d
4f6a098
5dab226
d7215bb
dc18eb4
e3cb6f8
e56dcad
f9e166e
64dd7b1
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 |
|---|---|---|
|
|
@@ -114,16 +114,37 @@ class BaseFileOnlyRelation(sqlContext: SQLContext, | |
| * rule; you can find more details in HUDI-3896) | ||
| */ | ||
| def toHadoopFsRelation: HadoopFsRelation = { | ||
| // We're delegating to Spark to append partition values to every row only in cases | ||
| // when these corresponding partition-values are not persisted w/in the data file itself | ||
| val shouldAppendPartitionColumns = omitPartitionColumnsInFile | ||
|
|
||
| val (tableFileFormat, formatClassName) = metaClient.getTableConfig.getBaseFileFormat match { | ||
| case HoodieFileFormat.PARQUET => (new ParquetFileFormat, "parquet") | ||
| case HoodieFileFormat.PARQUET => (sparkAdapter.createHoodieParquetFileFormat(shouldAppendPartitionColumns).get, "hoodie-parquet") | ||
|
Contributor
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. nit: create a constant for "hoodie-parquet" so it can be referenced everywhere. |
||
| case HoodieFileFormat.ORC => (new OrcFileFormat, "orc") | ||
| } | ||
|
|
||
| if (globPaths.isEmpty) { | ||
| // NOTE: There are currently 2 ways partition values could be fetched: | ||
| // - Source columns (producing the values used for physical partitioning) will be read | ||
| // from the data file | ||
| // - Values parsed from the actual partition pat would be appended to the final dataset | ||
|
Contributor
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. typo: "pat"
Contributor
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. Addressed in a follow-up |
||
| // | ||
| // In the former case, we don't need to provide the partition-schema to the relation, | ||
| // therefore we simply stub it w/ empty schema and use full table-schema as the one being | ||
| // read from the data file. | ||
| // | ||
| // In the latter, we have to specify proper partition schema as well as "data"-schema, essentially | ||
| // being a table-schema with all partition columns stripped out | ||
| val (partitionSchema, dataSchema) = if (shouldAppendPartitionColumns) { | ||
| (fileIndex.partitionSchema, fileIndex.dataSchema) | ||
| } else { | ||
| (StructType(Nil), tableStructSchema) | ||
| } | ||
|
|
||
| HadoopFsRelation( | ||
| location = fileIndex, | ||
| partitionSchema = fileIndex.partitionSchema, | ||
| dataSchema = fileIndex.dataSchema, | ||
| partitionSchema = partitionSchema, | ||
| dataSchema = dataSchema, | ||
| bucketSpec = None, | ||
| fileFormat = tableFileFormat, | ||
| optParams)(sparkSession) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -183,7 +183,7 @@ class IncrementalRelation(val sqlContext: SQLContext, | |
| sqlContext.sparkContext.hadoopConfiguration.set(SparkInternalSchemaConverter.HOODIE_TABLE_PATH, metaClient.getBasePath) | ||
| sqlContext.sparkContext.hadoopConfiguration.set(SparkInternalSchemaConverter.HOODIE_VALID_COMMITS_LIST, validCommits) | ||
| val formatClassName = metaClient.getTableConfig.getBaseFileFormat match { | ||
| case HoodieFileFormat.PARQUET => if (!internalSchema.isEmptySchema) "HoodieParquet" else "parquet" | ||
| case HoodieFileFormat.PARQUET => "hoodie-parquet" | ||
|
Contributor
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. same here for constant |
||
| case HoodieFileFormat.ORC => "orc" | ||
| } | ||
| sqlContext.sparkContext.hadoopConfiguration.unset("mapreduce.input.pathFilter.class") | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -28,20 +28,19 @@ import org.apache.spark.sql.types.StructType | |
|
|
||
|
|
||
| class SparkHoodieParquetFileFormat extends ParquetFileFormat with SparkAdapterSupport { | ||
| override def shortName(): String = "HoodieParquet" | ||
| override def shortName(): String = "hoodie-parquet" | ||
|
Contributor
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 assume this is used by Spark to identify the format?
Contributor
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. Correct |
||
|
|
||
| override def toString: String = "HoodieParquet" | ||
| override def toString: String = "Hoodie-Parquet" | ||
|
|
||
| override def buildReaderWithPartitionValues( | ||
| sparkSession: SparkSession, | ||
| dataSchema: StructType, | ||
| partitionSchema: StructType, | ||
| requiredSchema: StructType, | ||
| filters: Seq[Filter], | ||
| options: Map[String, String], | ||
| hadoopConf: Configuration): PartitionedFile => Iterator[InternalRow] = { | ||
| override def buildReaderWithPartitionValues(sparkSession: SparkSession, | ||
| dataSchema: StructType, | ||
| partitionSchema: StructType, | ||
| requiredSchema: StructType, | ||
| filters: Seq[Filter], | ||
| options: Map[String, String], | ||
| hadoopConf: Configuration): PartitionedFile => Iterator[InternalRow] = { | ||
| sparkAdapter | ||
| .createHoodieParquetFileFormat().get | ||
| .createHoodieParquetFileFormat(appendPartitionValues = false).get | ||
| .buildReaderWithPartitionValues(sparkSession, dataSchema, partitionSchema, requiredSchema, filters, options, hadoopConf) | ||
| } | ||
| } | ||
|
|
||
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.
minor. instead of "omitPartitionColumnsInFile" (present tense), may be we can name the variable as "isPartitionColumnPersistedInDataFile" (past tense).
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.
Good call!
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.
@nsivabalan on a second thought -- this flag is actually directing whether we should be omitting partition columns when we persist in data files, so kept it as
omitPartitionColumnsto be aligned with the config value