-
Notifications
You must be signed in to change notification settings - Fork 29.3k
[SPARK-32234][SQL] Spark sql commands are failing on selecting the orc tables #29045
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 13 commits
49a2350
195bc23
9b51d67
b9282d0
ff938a5
45be048
c2ca484
f8f7aff
c2d7a21
4469e6d
743ffe3
9de3516
f8ece1f
5b8715e
d0f6b9b
c79794f
cf68729
6150b08
c0f6209
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 |
|---|---|---|
|
|
@@ -160,12 +160,12 @@ class OrcFileFormat | |
| } | ||
|
|
||
| val resultSchema = StructType(requiredSchema.fields ++ partitionSchema.fields) | ||
| val actualSchema = StructType(dataSchema.fields ++ partitionSchema.fields) | ||
| val sqlConf = sparkSession.sessionState.conf | ||
| val enableVectorizedReader = supportBatch(sparkSession, resultSchema) | ||
| val capacity = sqlConf.orcVectorizedReaderBatchSize | ||
|
|
||
| val resultSchemaString = OrcUtils.orcTypeDescriptionString(resultSchema) | ||
| OrcConf.MAPRED_INPUT_SCHEMA.setString(hadoopConf, resultSchemaString) | ||
| var resultSchemaString = OrcUtils.orcTypeDescriptionString(resultSchema) | ||
| OrcConf.IS_SCHEMA_EVOLUTION_CASE_SENSITIVE.setBoolean(hadoopConf, sqlConf.caseSensitiveAnalysis) | ||
|
|
||
| val broadcastedConf = | ||
|
|
@@ -179,12 +179,17 @@ class OrcFileFormat | |
|
|
||
| val fs = filePath.getFileSystem(conf) | ||
| val readerOptions = OrcFile.readerOptions(conf).filesystem(fs) | ||
| val requestedColIdsOrEmptyFile = | ||
| val (requestedColIdsOrEmptyFile, canPruneCols) = | ||
| Utils.tryWithResource(OrcFile.createReader(filePath, readerOptions)) { reader => | ||
| OrcUtils.requestedColumnIds( | ||
| isCaseSensitive, dataSchema, requiredSchema, reader, conf) | ||
| } | ||
|
|
||
| if (!canPruneCols) { | ||
|
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: we can simplify the code a bit Then we don't need to keep the
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. done |
||
| resultSchemaString = OrcUtils.orcTypeDescriptionString(actualSchema) | ||
|
cloud-fan marked this conversation as resolved.
Outdated
|
||
| } | ||
| OrcConf.MAPRED_INPUT_SCHEMA.setString(conf, resultSchemaString) | ||
|
|
||
| if (requestedColIdsOrEmptyFile.isEmpty) { | ||
| Iterator.empty | ||
| } else { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -116,47 +116,53 @@ object OrcUtils extends Logging { | |
| } | ||
|
|
||
| /** | ||
| * Returns the requested column ids from the given ORC file. Column id can be -1, which means the | ||
| * requested column doesn't exist in the ORC file. Returns None if the given ORC file is empty. | ||
| * @return Returns the requested column ids from the given ORC file and Boolean flag to use actual | ||
|
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. can we update the comment a little bit?
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. updated the comment |
||
| * schema or result schema. Column id can be -1, which means the requested column doesn't | ||
| * exist in the ORC file. Returns None if the given ORC file is empty. | ||
|
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. Could you add
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. done |
||
| */ | ||
| def requestedColumnIds( | ||
| isCaseSensitive: Boolean, | ||
| dataSchema: StructType, | ||
| requiredSchema: StructType, | ||
| reader: Reader, | ||
| conf: Configuration): Option[Array[Int]] = { | ||
| conf: Configuration): (Option[Array[Int]], Boolean) = { | ||
|
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 think the return type should be
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. I did similar change by returning the one attribute in the return type. I was asked to make it two attributes to return from this method So I change it after this review comment
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. how about
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. done |
||
| var canPruneCols = true | ||
|
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. do we really need it? We can just use boolean literal in the places that return the value.
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. Removed it |
||
| val orcFieldNames = reader.getSchema.getFieldNames.asScala | ||
|
cloud-fan marked this conversation as resolved.
|
||
| if (orcFieldNames.isEmpty) { | ||
| // SPARK-8501: Some old empty ORC files always have an empty schema stored in their footer. | ||
| None | ||
| (None, canPruneCols) | ||
| } else { | ||
| if (orcFieldNames.forall(_.startsWith("_col"))) { | ||
| // This is a ORC file written by Hive, no field names in the physical schema, assume the | ||
| // physical schema maps to the data scheme by index. | ||
| assert(orcFieldNames.length <= dataSchema.length, "The given data schema " + | ||
| s"${dataSchema.catalogString} has less fields than the actual ORC physical schema, " + | ||
| "no idea which columns were dropped, fail to read.") | ||
| Some(requiredSchema.fieldNames.map { name => | ||
| // for ORC file written by Hive, no field names | ||
| // in the physical schema, there is a need to send the | ||
| // entire dataSchema instead of required schema | ||
| canPruneCols = false | ||
| (Some(requiredSchema.fieldNames.map { name => | ||
| val index = dataSchema.fieldIndex(name) | ||
| if (index < orcFieldNames.length) { | ||
| index | ||
| } else { | ||
| -1 | ||
|
cloud-fan marked this conversation as resolved.
|
||
| } | ||
| }) | ||
| }), canPruneCols) | ||
| } else { | ||
| if (isCaseSensitive) { | ||
| Some(requiredSchema.fieldNames.zipWithIndex.map { case (name, idx) => | ||
| (Some(requiredSchema.fieldNames.zipWithIndex.map { case (name, idx) => | ||
| if (orcFieldNames.indexWhere(caseSensitiveResolution(_, name)) != -1) { | ||
| idx | ||
| } else { | ||
| -1 | ||
| } | ||
| }) | ||
| }), canPruneCols) | ||
| } else { | ||
| // Do case-insensitive resolution only if in case-insensitive mode | ||
| val caseInsensitiveOrcFieldMap = orcFieldNames.groupBy(_.toLowerCase(Locale.ROOT)) | ||
| Some(requiredSchema.fieldNames.zipWithIndex.map { case (requiredFieldName, idx) => | ||
| (Some(requiredSchema.fieldNames.zipWithIndex.map { case (requiredFieldName, idx) => | ||
| caseInsensitiveOrcFieldMap | ||
| .get(requiredFieldName.toLowerCase(Locale.ROOT)) | ||
| .map { matchedOrcFields => | ||
|
|
@@ -170,7 +176,7 @@ object OrcUtils extends Logging { | |
| idx | ||
| } | ||
| }.getOrElse(-1) | ||
| }) | ||
| }), canPruneCols) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -288,4 +288,35 @@ class HiveOrcQuerySuite extends OrcQueryTest with TestHiveSingleton { | |
| } | ||
| } | ||
| } | ||
|
|
||
| test("SPARK-32234: orc data created by the hive tables having _col fields name" + | ||
|
cloud-fan marked this conversation as resolved.
Outdated
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. we can shorten the test name:
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. done |
||
| " for ORC_IMPLEMENTATION") { | ||
| Seq("native", "hive").foreach { orcImpl => | ||
| Seq("false", "true").foreach { vectorized => | ||
| withSQLConf( | ||
| SQLConf.ORC_IMPLEMENTATION.key -> orcImpl, | ||
| SQLConf.ORC_VECTORIZED_READER_ENABLED.key -> vectorized) { | ||
| withTempPath { dir => | ||
|
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: we don't need to provide a custom location. CREATE TABLE without LOCATION clause can also reproduce it.
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. Removed it |
||
| withTable("test_hive_orc_impl") { | ||
| spark.sql( | ||
| s""" | ||
| | CREATE TABLE test_hive_orc_impl | ||
| | (_col1 INT, _col2 STRING, _col3 INT) | ||
|
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. can this test reproduce the bug? the table schema matches the physical file schema.
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. yes this can be reproduce by this also, But I have attached the date_dim tpcds orc data in the jira itself |
||
| | STORED AS ORC LOCATION '$dir' | ||
| """.stripMargin) | ||
| spark.sql( | ||
| """ | ||
| | INSERT INTO | ||
| | test_hive_orc_impl | ||
| | VALUES(9, '12', 2020) | ||
| """.stripMargin) | ||
|
|
||
| val df = spark.sql("SELECT _col2 FROM test_hive_orc_impl") | ||
| checkAnswer(df, Row("12")) | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.