-
Notifications
You must be signed in to change notification settings - Fork 29.3k
[SPARK-20728][SQL] Make OrcFileFormat configurable between sql/hive and sql/core #19871
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 2 commits
37e240c
e7beb02
8b7e88a
2e498f9
5474a07
2393e1d
8bc420a
e3f6f75
7fac88f
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 |
|---|---|---|
|
|
@@ -363,6 +363,14 @@ object SQLConf { | |
| .checkValues(Set("none", "uncompressed", "snappy", "zlib", "lzo")) | ||
| .createWithDefault("snappy") | ||
|
|
||
| val ORC_USE_NEW_VERSION = buildConf("spark.sql.orc.useNewVersion") | ||
| .doc("When true, use new OrcFileFormat in sql/core module instead of the one in sql/hive. " + | ||
| "Since new OrcFileFormat uses Apache ORC library instead of ORC library Hive 1.2.1, it is " + | ||
| "more stable and faster.") | ||
|
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. tiny nit: let's take out
Member
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. Thank you for review, @HyukjinKwon .
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.
Member
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. Thanks! |
||
| .internal() | ||
| .booleanConf | ||
|
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.
Member
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. Yep. |
||
| .createWithDefault(true) | ||
|
|
||
| val ORC_FILTER_PUSHDOWN_ENABLED = buildConf("spark.sql.orc.filterPushdown") | ||
| .doc("When true, enable filter pushdown for ORC files.") | ||
| .booleanConf | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -36,8 +36,10 @@ import org.apache.spark.sql.catalyst.util.CaseInsensitiveMap | |
| import org.apache.spark.sql.execution.datasources.csv.CSVFileFormat | ||
| import org.apache.spark.sql.execution.datasources.jdbc.JdbcRelationProvider | ||
| import org.apache.spark.sql.execution.datasources.json.JsonFileFormat | ||
| import org.apache.spark.sql.execution.datasources.orc.OrcFileFormat | ||
| import org.apache.spark.sql.execution.datasources.parquet.ParquetFileFormat | ||
| import org.apache.spark.sql.execution.streaming._ | ||
| import org.apache.spark.sql.internal.SQLConf | ||
| import org.apache.spark.sql.sources._ | ||
| import org.apache.spark.sql.streaming.OutputMode | ||
| import org.apache.spark.sql.types.{CalendarIntervalType, StructType} | ||
|
|
@@ -85,7 +87,8 @@ case class DataSource( | |
|
|
||
| case class SourceInfo(name: String, schema: StructType, partitionColumns: Seq[String]) | ||
|
|
||
| lazy val providingClass: Class[_] = DataSource.lookupDataSource(className) | ||
| lazy val providingClass: Class[_] = | ||
| DataSource.lookupDataSource(sparkSession.sessionState.conf, className) | ||
|
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. I'd put this conf as the last argument actually if you wouldn't mind ..
Member
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. Sure! |
||
| lazy val sourceInfo: SourceInfo = sourceSchema() | ||
| private val caseInsensitiveOptions = CaseInsensitiveMap(options) | ||
| private val equality = sparkSession.sessionState.conf.resolver | ||
|
|
@@ -568,8 +571,12 @@ object DataSource extends Logging { | |
| "org.apache.spark.Logging") | ||
|
|
||
| /** Given a provider name, look up the data source class definition. */ | ||
| def lookupDataSource(provider: String): Class[_] = { | ||
| val provider1 = backwardCompatibilityMap.getOrElse(provider, provider) | ||
| def lookupDataSource(conf: SQLConf, provider: String): Class[_] = { | ||
|
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. After more thinking, I think it don't worth to pass the whole SQLConf into this function, we just need to know whether
Member
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. So, are you suggesting |
||
| var provider1 = backwardCompatibilityMap.getOrElse(provider, provider) | ||
|
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. instead of using
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. Also add the maps for new orc format to
Member
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. Thanks. Sure. |
||
| if (Seq("orc").contains(provider1.toLowerCase) && conf.getConf(SQLConf.ORC_USE_NEW_VERSION)) { | ||
|
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. "orc".equalsIgnoreCase(...)
Member
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. Oh. Yep. |
||
| logInfo(s"$provider1 is replaced with ${classOf[OrcFileFormat].getCanonicalName}") | ||
| provider1 = classOf[OrcFileFormat].getCanonicalName | ||
| } | ||
| val provider2 = s"$provider1.DefaultSource" | ||
| val loader = Utils.getContextOrSparkClassLoader | ||
| val serviceLoader = ServiceLoader.load(classOf[DataSourceRegister], loader) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -18,6 +18,7 @@ | |
| package org.apache.spark.sql.sources | ||
|
|
||
| import org.apache.spark.sql.{AnalysisException, SQLContext} | ||
| import org.apache.spark.sql.internal.SQLConf | ||
| import org.apache.spark.sql.test.SharedSQLContext | ||
| import org.apache.spark.sql.types._ | ||
|
|
||
|
|
@@ -54,11 +55,17 @@ class DDLSourceLoadSuite extends DataSourceTest with SharedSQLContext { | |
| .load().schema == StructType(Seq(StructField("stringType", StringType, nullable = false)))) | ||
| } | ||
|
|
||
| test("should fail to load ORC without Hive Support") { | ||
| val e = intercept[AnalysisException] { | ||
| spark.read.format("orc").load() | ||
| test("should fail to load ORC only if spark.sql.orc.enabled=false and without Hive Support") { | ||
|
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 this test is replaced by https://github.com/apache/spark/pull/19871/files#diff-5a2e7f03d14856c8769fd3ddea8742bdR2788
Member
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. Ur, those tests cover different cases.
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. that test also check the exception: https://github.com/apache/spark/pull/19871/files#diff-5a2e7f03d14856c8769fd3ddea8742bdR2790
Member
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. Oh, I confused with SQLQuerySuite.scala in hive. Sorry, I'll remove this. |
||
| Seq( | ||
| (true, "Unable to infer schema for ORC. It must be specified manually"), | ||
| (false, "The ORC data source must be used with Hive support")).foreach { case (value, m) => | ||
| withSQLConf(SQLConf.ORC_USE_NEW_VERSION.key -> s"$value") { | ||
| val e = intercept[AnalysisException] { | ||
| spark.read.format("orc").load() | ||
| } | ||
| assert(e.message.contains(m)) | ||
| } | ||
| } | ||
| assert(e.message.contains("The ORC data source must be used with Hive support enabled")) | ||
| } | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -195,8 +195,18 @@ case class RelationConversions( | |
| .convertToLogicalRelation(relation, options, classOf[ParquetFileFormat], "parquet") | ||
| } else { | ||
| val options = relation.tableMeta.storage.properties | ||
| sessionCatalog.metastoreCatalog | ||
| .convertToLogicalRelation(relation, options, classOf[OrcFileFormat], "orc") | ||
| if (conf.getConf(SQLConf.ORC_USE_NEW_VERSION)) { | ||
| sessionCatalog.metastoreCatalog.convertToLogicalRelation( | ||
| relation, | ||
| options, | ||
| classOf[org.apache.spark.sql.execution.datasources.orc.OrcFileFormat], | ||
| "orc") | ||
| } else { | ||
| sessionCatalog.metastoreCatalog.convertToLogicalRelation( | ||
| relation, | ||
| options, | ||
| classOf[org.apache.spark.sql.hive.orc.OrcFileFormat], "orc") | ||
|
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. indents.
Member
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. |
||
| } | ||
| } | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2153,4 +2153,21 @@ class SQLQuerySuite extends QueryTest with SQLTestUtils with TestHiveSingleton { | |
| } | ||
| } | ||
| } | ||
|
|
||
| test("SPARK-20728 Make ORCFileFormat configurable between sql/hive and sql/core") { | ||
|
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. Move it to
Member
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. Yep. |
||
| Seq( | ||
| (true, classOf[org.apache.spark.sql.execution.datasources.orc.OrcFileFormat]), | ||
| (false, classOf[org.apache.spark.sql.hive.orc.OrcFileFormat])).foreach { case (v, format) => | ||
|
|
||
| withSQLConf(SQLConf.ORC_USE_NEW_VERSION.key -> s"$v") { | ||
| withTable("spark_20728") { | ||
| sql("CREATE TABLE spark_20728(a INT) USING ORC") | ||
| val fileFormat = sql("SELECT * FROM spark_20728").queryExecution.analyzed.collectFirst { | ||
| case l: LogicalRelation => l.relation.asInstanceOf[HadoopFsRelation].fileFormat.getClass | ||
| } | ||
| assert(fileFormat == Some(format)) | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
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.
spark.sql.orc.implThere 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.
No problem to change to it. But, since the name is given by @cloud-fan before, ping @cloud-fan .