[SPARK-28637][SQL] Thriftserver support interval type
## What changes were proposed in this pull request?
`bin/spark-shell` support query interval value:
```scala
scala> spark.sql("SELECT interval 3 months 1 hours AS i").show(false)
+-------------------------+
|i |
+-------------------------+
|interval 3 months 1 hours|
+-------------------------+
```
But `sbin/start-thriftserver.sh` can't support query interval value:
```sql
0: jdbc:hive2://localhost:10000/default> SELECT interval 3 months 1 hours AS i;
Error: java.lang.IllegalArgumentException: Unrecognized type name: interval (state=,code=0)
```
This PR maps `CalendarIntervalType` to `StringType` for `TableSchema` to make Thriftserver support query interval value because we do not support `INTERVAL_YEAR_MONTH` type and `INTERVAL_DAY_TIME`:
02c33694c8/sql/hive-thriftserver/v1.2.1/src/main/java/org/apache/hive/service/cli/Type.java (L73-L78)
[SPARK-27791](https://issues.apache.org/jira/browse/SPARK-27791): Support SQL year-month INTERVAL type
[SPARK-27793](https://issues.apache.org/jira/browse/SPARK-27793): Support SQL day-time INTERVAL type
## How was this patch tested?
unit tests
Closes #25277 from wangyum/Thriftserver-support-interval-type.
Authored-by: Yuming Wang <yumwang@ebay.com>
Signed-off-by: Xiao Li <gatorsmile@gmail.com>
This commit is contained in:
parent
d4eca7c99d
commit
4a3a6b66be
|
@ -39,6 +39,7 @@ import org.apache.spark.sql.execution.HiveResult
|
|||
import org.apache.spark.sql.execution.command.SetCommand
|
||||
import org.apache.spark.sql.internal.SQLConf
|
||||
import org.apache.spark.sql.types._
|
||||
import org.apache.spark.unsafe.types.CalendarInterval
|
||||
import org.apache.spark.util.{Utils => SparkUtils}
|
||||
|
||||
private[hive] class SparkExecuteStatementOperation(
|
||||
|
@ -103,6 +104,8 @@ private[hive] class SparkExecuteStatementOperation(
|
|||
to += from.getAs[Timestamp](ordinal)
|
||||
case BinaryType =>
|
||||
to += from.getAs[Array[Byte]](ordinal)
|
||||
case CalendarIntervalType =>
|
||||
to += HiveResult.toHiveString((from.getAs[CalendarInterval](ordinal), CalendarIntervalType))
|
||||
case _: ArrayType | _: StructType | _: MapType | _: UserDefinedType[_] =>
|
||||
val hiveString = HiveResult.toHiveString((from.get(ordinal), dataTypes(ordinal)))
|
||||
to += hiveString
|
||||
|
@ -331,7 +334,11 @@ private[hive] class SparkExecuteStatementOperation(
|
|||
object SparkExecuteStatementOperation {
|
||||
def getTableSchema(structType: StructType): TableSchema = {
|
||||
val schema = structType.map { field =>
|
||||
val attrTypeString = if (field.dataType == NullType) "void" else field.dataType.catalogString
|
||||
val attrTypeString = field.dataType match {
|
||||
case NullType => "void"
|
||||
case CalendarIntervalType => StringType.catalogString
|
||||
case other => other.catalogString
|
||||
}
|
||||
new FieldSchema(field.name, attrTypeString, field.getComment.getOrElse(""))
|
||||
}
|
||||
new TableSchema(schema.asJava)
|
||||
|
|
|
@ -662,6 +662,21 @@ class HiveThriftBinaryServerSuite extends HiveThriftJdbcTest {
|
|||
assert(rs.getBigDecimal(1) === new java.math.BigDecimal("1.000000000000000000"))
|
||||
}
|
||||
}
|
||||
|
||||
test("Support interval type") {
|
||||
withJdbcStatement() { statement =>
|
||||
val rs = statement.executeQuery("SELECT interval 3 months 1 hours")
|
||||
assert(rs.next())
|
||||
assert(rs.getString(1) === "interval 3 months 1 hours")
|
||||
}
|
||||
// Invalid interval value
|
||||
withJdbcStatement() { statement =>
|
||||
val e = intercept[SQLException] {
|
||||
statement.executeQuery("SELECT interval 3 months 1 hou")
|
||||
}
|
||||
assert(e.getMessage.contains("org.apache.spark.sql.catalyst.parser.ParseException"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class SingleSessionSuite extends HiveThriftJdbcTest {
|
||||
|
|
|
@ -261,10 +261,10 @@ class SparkThriftServerProtocolVersionsSuite extends HiveThriftJdbcTest {
|
|||
}
|
||||
}
|
||||
|
||||
// We do not fully support interval type
|
||||
ignore(s"$version get interval type") {
|
||||
test(s"$version get interval type") {
|
||||
testExecuteStatementWithProtocolVersion(version, "SELECT interval '1' year '2' day") { rs =>
|
||||
assert(rs.next())
|
||||
assert(rs.getString(1) === "interval 1 years 2 days")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue