Commit 16dacbb
committed
[SPARK-57463][SQL] Render nanosecond-precision timestamp types in the Thrift server via the Types Framework
### What changes were proposed in this pull request?
This PR makes the nanosecond-capable timestamp types `TIMESTAMP_NTZ(p)` and `TIMESTAMP_LTZ(p)` (`p` in 7-9) usable over the Spark Thrift / JDBC server, reaching parity with the microsecond `TimestampType` / `TimestampNTZType`.
1. Implement the Types Framework `thriftTypeName` hook. `SparkExecuteStatementOperation` resolves a column's Thrift `TTypeId` via `TypeApiOps(typ).flatMap(_.thriftTypeName)`. `TimestampNanosTypeApiOps` did not override it (defaulted to `None`), and the nanos types are not in the `toTTypeIdDefault` fallback, so a nanos column hit `case other => throw new IllegalArgumentException("Unrecognized type name: ...")`. The fix overrides `thriftTypeName` in the abstract base `TimestampNanosTypeApiOps` (inherited by both NTZ and LTZ subclasses) to return `Some("STRING_TYPE")`, mirroring the reference `TimeTypeApiOps`. `STRING_TYPE` is correct because `RowSetUtils` already serializes these values as a string column (`TStringColumn`), rendered at the column precision by `HiveResult.toHiveString`.
2. Enable the nanosecond golden-file tests in `ThriftServerQueryTestSuite` by removing `timestamp-ntz-nanos.sql` and `timestamp-ltz-nanos.sql` from its ignore list (they were skipped only because nanos types were not yet mapped by the Thrift server).
3. Drop the now-unnecessary `cast(... as string)` workarounds for the micros -> nanos widening cases in `cast.sql` (SPARK-57293 section), which existed only because a bare nanos result column was not serializable over JDBC/thrift. They now produce bare `TIMESTAMP_NTZ(9)` / `TIMESTAMP_LTZ(9)` result columns; golden files are regenerated and the output values are unchanged.
No changes were needed in `SparkExecuteStatementOperation` or `RowSetUtils`. Related Hive CLI rendering through the framework is tracked separately by SPARK-57386.
### Why are the changes needed?
To be able to retrieve nanosecond-precision timestamps via the Hive Thrift server. Before this change, with the preview flag enabled, such a query fails:
```
0: jdbc:hive2://localhost:10000/default> SET spark.sql.timestampNanosTypes.enabled=true;
0: jdbc:hive2://localhost:10000/default> SELECT timestamp_ntz'2021-01-01 01:02:03.000000001';
Error: java.lang.IllegalArgumentException: Unrecognized type name: timestamp_ntz(9) (state=,code=0)
```
This is analogous to the ANSI-interval issue fixed by SPARK-35017 (`Unrecognized type name: day-time interval`) and the TIME support added by SPARK-51516.
### Does this PR introduce _any_ user-facing change?
Yes. After the changes, nanosecond timestamp columns are returned over JDBC as strings rendered at the column precision (the nanos types are a preview feature gated by `spark.sql.timestampNanosTypes.enabled`):
```
0: jdbc:hive2://localhost:10000/default> SET spark.sql.timestampNanosTypes.enabled=true;
0: jdbc:hive2://localhost:10000/default> SELECT timestamp_ntz'2021-01-01 01:02:03.000000001' AS ntz9;
+--------------------------------+
| ntz9 |
+--------------------------------+
| 2021-01-01 01:02:03.000000001 |
+--------------------------------+
0: jdbc:hive2://localhost:10000/default> SELECT timestamp_ltz'2021-01-01 01:02:03.123456789' AS ltz9;
+--------------------------------+
| ltz9 |
+--------------------------------+
| 2021-01-01 01:02:03.123456789 |
+--------------------------------+
0: jdbc:hive2://localhost:10000/default> SELECT CAST('2021-01-01 01:02:03.123456789' AS TIMESTAMP_NTZ(7)) AS ntz7;
+------------------------------+
| ntz7 |
+------------------------------+
| 2021-01-01 01:02:03.1234567 |
+------------------------------+
0: jdbc:hive2://localhost:10000/default> SELECT CAST('2021-01-01 01:02:03.123456789' AS TIMESTAMP_LTZ(8)) AS ltz8;
+-------------------------------+
| ltz8 |
+-------------------------------+
| 2021-01-01 01:02:03.12345678 |
+-------------------------------+
```
With the flag off (the production default), a nanos literal continues to degrade to a microsecond timestamp, unchanged by this PR:
```
0: jdbc:hive2://localhost:10000/default> SELECT timestamp_ntz'2021-01-01 01:02:03.000000001' AS ntz;
+------------------------+
| ntz |
+------------------------+
| 2021-01-01 01:02:03.0 |
+------------------------+
```
### How was this patch tested?
1. New tests under `sql/hive-thriftserver`:
- `SparkExecuteStatementOperationSuite`: asserts `toTTableSchema` maps `TimestampNTZNanosType(p)` / `TimestampLTZNanosType(p)` (p in 7-9) to `TTypeId.STRING_TYPE`.
- `HiveThriftBinaryServerSuite`: an end-to-end JDBC test that enables the flag, queries NTZ/LTZ at precisions 7-9, and asserts both the column metadata (`VARCHAR` / `"string"`) and the rendered fractional digits.
2. `ThriftServerQueryTestSuite` now runs `timestamp-ntz-nanos.sql`, `timestamp-ltz-nanos.sql`, and `cast.sql` end-to-end over JDBC (previously the nanos files were ignored).
```
$ build/sbt -Phive -Phive-thriftserver "hive-thriftserver/testOnly *SparkExecuteStatementOperationSuite"
$ build/sbt -Phive -Phive-thriftserver "hive-thriftserver/testOnly *HiveThriftBinaryServerSuite -- -z nanosecond"
$ build/sbt -Phive -Phive-thriftserver "hive-thriftserver/testOnly *ThriftServerQueryTestSuite -- -z nanos"
$ build/sbt -Phive -Phive-thriftserver "hive-thriftserver/testOnly *ThriftServerQueryTestSuite -- -z cast.sql"
```
3. Regenerated `cast.sql` golden files via `SPARK_GENERATE_GOLDEN_FILES=1 build/sbt "sql/testOnly org.apache.spark.sql.SQLQueryTestSuite -- -z cast.sql"`; the output values are unchanged (only the result column type changed from `string` to the nanos type).
4. Manually verified end-to-end against a running Thrift server with `beeline` (the before/after transcripts shown above).
### Was this patch authored or co-authored using generative AI tooling?
Generated-by: Cursor (Claude Opus 4.8)
Closes #56519 from MaxGekk/nanos-thriftserver.
Authored-by: Maxim Gekk <max.gekk@gmail.com>
Signed-off-by: Max Gekk <max.gekk@gmail.com>
(cherry picked from commit a6e3fdd)
Signed-off-by: Max Gekk <max.gekk@gmail.com>1 parent 03c44cc commit 16dacbb
9 files changed
Lines changed: 68 additions & 25 deletions
File tree
- sql
- api/src/main/scala/org/apache/spark/sql/types/ops
- core/src/test/resources/sql-tests
- analyzer-results
- nonansi
- inputs
- results
- nonansi
- hive-thriftserver/src/test/scala/org/apache/spark/sql/hive/thriftserver
Lines changed: 7 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
67 | 67 | | |
68 | 68 | | |
69 | 69 | | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
70 | 77 | | |
71 | 78 | | |
72 | 79 | | |
| |||
Lines changed: 4 additions & 4 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
775 | 775 | | |
776 | 776 | | |
777 | 777 | | |
778 | | - | |
| 778 | + | |
779 | 779 | | |
780 | | - | |
| 780 | + | |
781 | 781 | | |
782 | 782 | | |
783 | 783 | | |
| |||
796 | 796 | | |
797 | 797 | | |
798 | 798 | | |
799 | | - | |
| 799 | + | |
800 | 800 | | |
801 | | - | |
| 801 | + | |
802 | 802 | | |
803 | 803 | | |
804 | 804 | | |
| |||
Lines changed: 4 additions & 4 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
639 | 639 | | |
640 | 640 | | |
641 | 641 | | |
642 | | - | |
| 642 | + | |
643 | 643 | | |
644 | | - | |
| 644 | + | |
645 | 645 | | |
646 | 646 | | |
647 | 647 | | |
| |||
660 | 660 | | |
661 | 661 | | |
662 | 662 | | |
663 | | - | |
| 663 | + | |
664 | 664 | | |
665 | | - | |
| 665 | + | |
666 | 666 | | |
667 | 667 | | |
668 | 668 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
138 | 138 | | |
139 | 139 | | |
140 | 140 | | |
141 | | - | |
142 | | - | |
| 141 | + | |
143 | 142 | | |
144 | | - | |
| 143 | + | |
145 | 144 | | |
146 | 145 | | |
147 | 146 | | |
148 | 147 | | |
149 | 148 | | |
150 | | - | |
| 149 | + | |
151 | 150 | | |
152 | 151 | | |
153 | 152 | | |
| |||
Lines changed: 4 additions & 4 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1475 | 1475 | | |
1476 | 1476 | | |
1477 | 1477 | | |
1478 | | - | |
| 1478 | + | |
1479 | 1479 | | |
1480 | | - | |
| 1480 | + | |
1481 | 1481 | | |
1482 | 1482 | | |
1483 | 1483 | | |
| |||
1499 | 1499 | | |
1500 | 1500 | | |
1501 | 1501 | | |
1502 | | - | |
| 1502 | + | |
1503 | 1503 | | |
1504 | | - | |
| 1504 | + | |
1505 | 1505 | | |
1506 | 1506 | | |
1507 | 1507 | | |
| |||
Lines changed: 4 additions & 4 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
737 | 737 | | |
738 | 738 | | |
739 | 739 | | |
740 | | - | |
| 740 | + | |
741 | 741 | | |
742 | | - | |
| 742 | + | |
743 | 743 | | |
744 | 744 | | |
745 | 745 | | |
| |||
761 | 761 | | |
762 | 762 | | |
763 | 763 | | |
764 | | - | |
| 764 | + | |
765 | 765 | | |
766 | | - | |
| 766 | + | |
767 | 767 | | |
768 | 768 | | |
769 | 769 | | |
| |||
Lines changed: 25 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
244 | 244 | | |
245 | 245 | | |
246 | 246 | | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
| 269 | + | |
| 270 | + | |
| 271 | + | |
247 | 272 | | |
248 | 273 | | |
249 | 274 | | |
| |||
Lines changed: 16 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
32 | 32 | | |
33 | 33 | | |
34 | 34 | | |
35 | | - | |
| 35 | + | |
36 | 36 | | |
37 | 37 | | |
38 | 38 | | |
| |||
76 | 76 | | |
77 | 77 | | |
78 | 78 | | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
79 | 94 | | |
80 | 95 | | |
81 | 96 | | |
| |||
Lines changed: 1 addition & 4 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
118 | 118 | | |
119 | 119 | | |
120 | 120 | | |
121 | | - | |
122 | | - | |
123 | | - | |
124 | | - | |
| 121 | + | |
125 | 122 | | |
126 | 123 | | |
127 | 124 | | |
| |||
0 commit comments