[SPARK-31910][SQL] Enable Java 8 time API in Thrift server
### What changes were proposed in this pull request? Set `spark.sql.datetime.java8API.enabled` to `true` in: 1. `SparkSQLEnv.init()` of Thrift server, and 2. `SparkSQLSessionManager.openSession()` ### Why are the changes needed? 1. Date and timestamp string literals are parsed by using Java 8 time API and Spark's session time zone. Before the changes, date/timestamp values were collected as legacy types `java.sql.Date`/`java.sql.Timestamp`, and the value of such types didn't respect the config `spark.sql.session.timeZone`. To have consistent view, users had to keep JVM time zone and Spark's session time zone in sync. 2. After the changes, formatting of date values doesn't depend on JVM time zone. 3. While returning dates/timestamps of Java 8 type, we can avoid dates/timestamps rebasing from Proleptic Gregorian calendar to the hybrid calendar (Julian + Gregorian), and the issues related to calendar switching. 4. Properly handle negative years (BCE). 5. Consistent conversion of date/timestamp strings to/from internal Catalyst types in both direction to and from Spark. ### Does this PR introduce any user-facing change? Yes. Before: ```sql spark-sql> select make_date(-44, 3, 15); 0045-03-15 ``` After: ```sql spark-sql> select make_date(-44, 3, 15); -0044-03-15 ``` ### How was this patch tested? Manually via `bin/spark-sql`. Closes #28729 from MaxGekk/enable-java8-time-api-in-thrift-server. Lead-authored-by: Max Gekk <max.gekk@gmail.com> Co-authored-by: Maxim Gekk <max.gekk@gmail.com> Signed-off-by: Wenchen Fan <wenchen@databricks.com>
This commit is contained in:
parent
ea010138e9
commit
2c9988eaf3
|
@ -24,6 +24,7 @@ import org.apache.spark.{SparkConf, SparkContext}
|
|||
import org.apache.spark.internal.Logging
|
||||
import org.apache.spark.sql.{SparkSession, SQLContext}
|
||||
import org.apache.spark.sql.hive.{HiveExternalCatalog, HiveUtils}
|
||||
import org.apache.spark.sql.internal.SQLConf
|
||||
import org.apache.spark.util.Utils
|
||||
|
||||
/** A singleton object for the master program. The slaves should not access this. */
|
||||
|
@ -45,6 +46,8 @@ private[hive] object SparkSQLEnv extends Logging {
|
|||
|
||||
sparkConf
|
||||
.setAppName(maybeAppName.getOrElse(s"SparkSQL::${Utils.localHostName()}"))
|
||||
.set(SQLConf.DATETIME_JAVA8API_ENABLED, true)
|
||||
|
||||
|
||||
val sparkSession = SparkSession.builder.config(sparkConf).enableHiveSupport().getOrCreate()
|
||||
sparkContext = sparkSession.sparkContext
|
||||
|
|
|
@ -30,6 +30,7 @@ import org.apache.spark.sql.SQLContext
|
|||
import org.apache.spark.sql.hive.HiveUtils
|
||||
import org.apache.spark.sql.hive.thriftserver.ReflectionUtils._
|
||||
import org.apache.spark.sql.hive.thriftserver.server.SparkSQLOperationManager
|
||||
import org.apache.spark.sql.internal.SQLConf
|
||||
|
||||
|
||||
private[hive] class SparkSQLSessionManager(hiveServer: HiveServer2, sqlContext: SQLContext)
|
||||
|
@ -63,6 +64,7 @@ private[hive] class SparkSQLSessionManager(hiveServer: HiveServer2, sqlContext:
|
|||
sqlContext.newSession()
|
||||
}
|
||||
ctx.setConf(HiveUtils.FAKE_HIVE_VERSION.key, HiveUtils.builtinHiveVersion)
|
||||
ctx.setConf(SQLConf.DATETIME_JAVA8API_ENABLED, true)
|
||||
val hiveSessionState = session.getSessionState
|
||||
setConfMap(ctx, hiveSessionState.getOverriddenConfigurations)
|
||||
setConfMap(ctx, hiveSessionState.getHiveVariables)
|
||||
|
|
|
@ -551,4 +551,10 @@ class CliSuite extends SparkFunSuite with BeforeAndAfterAll with Logging {
|
|||
errorResponses = Seq("AnalysisException"))(
|
||||
("", "Error in query: The second argument of 'date_sub' function needs to be an integer."))
|
||||
}
|
||||
|
||||
test("SPARK-30808: use Java 8 time API in Thrift SQL CLI by default") {
|
||||
// If Java 8 time API is enabled via the SQL config `spark.sql.datetime.java8API.enabled`,
|
||||
// the date formatter for `java.sql.LocalDate` must output negative years with sign.
|
||||
runCliWithin(1.minute)("SELECT MAKE_DATE(-44, 3, 15);" -> "-0044-03-15")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -862,6 +862,18 @@ class HiveThriftBinaryServerSuite extends HiveThriftJdbcTest {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
test("SPARK-30808: use Java 8 time API and Proleptic Gregorian calendar by default") {
|
||||
withJdbcStatement() { st =>
|
||||
// Proleptic Gregorian calendar has no gap in the range 1582-10-04..1582-10-15
|
||||
val date = "1582-10-10"
|
||||
val rs = st.executeQuery(s"select date '$date'")
|
||||
rs.next()
|
||||
val expected = java.sql.Date.valueOf(date)
|
||||
assert(rs.getDate(1) === expected)
|
||||
assert(rs.getString(1) === expected.toString)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class SingleSessionSuite extends HiveThriftJdbcTest {
|
||||
|
|
Loading…
Reference in a new issue