Commit 3fbca58
[SPARK-54473][SQL] Add Avro read and write support for TIME type
### What changes were proposed in this pull request?
This PR adds Avro serialization and deserialization support for Spark's TIME type.
### Why are the changes needed?
TIME type currently lacks Avro support, preventing users from:
- Reading/writing Avro files with TIME columns
- Using TIME with data exchange pipelines (Kafka, streaming)
- Integrating TIME data with Avro-based systems
- Preserving TIME precision in schema evolution
### Does this PR introduce _any_ user-facing change?
Yes. Users can now:
1. Read Avro with TIME columns
```scala
spark.read.format("avro").load("data.avro")
// Returns DataFrame with TIME columns preserved
```
2. Write DataFrames with TIME to Avro
```scala
val df = spark.sql("SELECT TIME'14:30:45.123456' as shift_start")
df.write.format("avro").save("output.avro")
```
3. Use to_avro/from_avro functions with TIME
```scala
import org.apache.spark.sql.avro.functions.{to_avro, from_avro}
// Serialize TIME to Avro binary
val avroDF = df.select(to_avro($"shift_start").as("avro"))
// Deserialize Avro binary back to TIME (with precision metadata)
val schema = """
{
"type": "long",
"logicalType": "time-micros",
"spark.sql.catalyst.type": "time(3)"
}
"""
val timeDF = avroDF.select(from_avro($"avro", schema).as("shift_start"))
```
4. Use TIME in Avro-based streaming
```scala
// Kafka with Avro serialization
df.selectExpr("to_avro(struct(shift_start)) as value")
.write
.format("kafka")
.save()
```
### How was this patch tested?
Added tests in `AvroSuite` and `AvroFunctionsSuite.scala`
Also manually tested using
`spark-shell --packages org.apache.spark:spark-avro_2.13:4.0.0`
```scala
val df = spark.sql("SELECT TIME'14:30:45.123456' as shift_start")
import org.apache.spark.sql.avro.functions.{to_avro, from_avro}
val avroDF = df.select(to_avro($"shift_start").as("avro"))
// Deserialize Avro binary back to TIME (with precision metadata)
val schema = """
{
"type": "long",
"logicalType": "time-micros",
"spark.sql.catalyst.type": "time(3)"
}
"""
val timeDF = avroDF.select(from_avro($"avro", schema).as("shift_start"))
timeDF.show
```
```
+---------------+
| shift_start|
+---------------+
|14:30:45.123456|
+---------------+
```
```scala
timeDF.printSchema
```
```
root
|-- shift_start: time(3) (nullable = true)
```
### Was this patch authored or co-authored using generative AI tooling?
Yes.
Generated-by: Claude 3.5 Sonnet
AI assistance was used for:
- Code pattern analysis and design discussions
- Implementation guidance following Spark conventions
- Test case generation and organization
- Documentation and examples
Closes apache#53189 from vinodkc/br_time_avro_read_write.
Authored-by: vinodkc <vinod.kc.in@gmail.com>
Signed-off-by: Dongjoon Hyun <dongjoon@apache.org>1 parent 5a7d1b5 commit 3fbca58
File tree
6 files changed
+196
-16
lines changed- connector/avro/src/test/scala/org/apache/spark/sql/avro
- sql/core/src/main/scala/org/apache/spark/sql/avro
6 files changed
+196
-16
lines changedLines changed: 78 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
29 | 29 | | |
30 | 30 | | |
31 | 31 | | |
| 32 | + | |
32 | 33 | | |
33 | 34 | | |
34 | 35 | | |
| |||
665 | 666 | | |
666 | 667 | | |
667 | 668 | | |
| 669 | + | |
| 670 | + | |
| 671 | + | |
| 672 | + | |
| 673 | + | |
| 674 | + | |
| 675 | + | |
| 676 | + | |
| 677 | + | |
| 678 | + | |
| 679 | + | |
| 680 | + | |
| 681 | + | |
| 682 | + | |
| 683 | + | |
| 684 | + | |
| 685 | + | |
| 686 | + | |
| 687 | + | |
| 688 | + | |
| 689 | + | |
| 690 | + | |
| 691 | + | |
| 692 | + | |
| 693 | + | |
| 694 | + | |
| 695 | + | |
| 696 | + | |
| 697 | + | |
| 698 | + | |
| 699 | + | |
| 700 | + | |
| 701 | + | |
| 702 | + | |
| 703 | + | |
| 704 | + | |
| 705 | + | |
| 706 | + | |
| 707 | + | |
| 708 | + | |
| 709 | + | |
| 710 | + | |
| 711 | + | |
| 712 | + | |
| 713 | + | |
| 714 | + | |
| 715 | + | |
| 716 | + | |
| 717 | + | |
| 718 | + | |
| 719 | + | |
| 720 | + | |
| 721 | + | |
| 722 | + | |
| 723 | + | |
| 724 | + | |
| 725 | + | |
| 726 | + | |
| 727 | + | |
| 728 | + | |
| 729 | + | |
| 730 | + | |
| 731 | + | |
| 732 | + | |
| 733 | + | |
| 734 | + | |
| 735 | + | |
| 736 | + | |
| 737 | + | |
| 738 | + | |
| 739 | + | |
| 740 | + | |
| 741 | + | |
| 742 | + | |
| 743 | + | |
| 744 | + | |
| 745 | + | |
668 | 746 | | |
Lines changed: 90 additions & 15 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3192 | 3192 | | |
3193 | 3193 | | |
3194 | 3194 | | |
3195 | | - | |
3196 | | - | |
3197 | | - | |
3198 | | - | |
3199 | | - | |
3200 | | - | |
3201 | | - | |
3202 | | - | |
3203 | | - | |
3204 | | - | |
3205 | | - | |
3206 | | - | |
3207 | | - | |
3208 | | - | |
3209 | | - | |
3210 | 3195 | | |
3211 | 3196 | | |
3212 | 3197 | | |
| |||
3407 | 3392 | | |
3408 | 3393 | | |
3409 | 3394 | | |
| 3395 | + | |
| 3396 | + | |
| 3397 | + | |
| 3398 | + | |
| 3399 | + | |
| 3400 | + | |
| 3401 | + | |
| 3402 | + | |
| 3403 | + | |
| 3404 | + | |
| 3405 | + | |
| 3406 | + | |
| 3407 | + | |
| 3408 | + | |
| 3409 | + | |
| 3410 | + | |
| 3411 | + | |
| 3412 | + | |
| 3413 | + | |
| 3414 | + | |
| 3415 | + | |
| 3416 | + | |
| 3417 | + | |
| 3418 | + | |
| 3419 | + | |
| 3420 | + | |
| 3421 | + | |
| 3422 | + | |
| 3423 | + | |
| 3424 | + | |
| 3425 | + | |
| 3426 | + | |
| 3427 | + | |
| 3428 | + | |
| 3429 | + | |
| 3430 | + | |
| 3431 | + | |
| 3432 | + | |
| 3433 | + | |
| 3434 | + | |
| 3435 | + | |
| 3436 | + | |
| 3437 | + | |
| 3438 | + | |
| 3439 | + | |
| 3440 | + | |
| 3441 | + | |
| 3442 | + | |
| 3443 | + | |
| 3444 | + | |
| 3445 | + | |
| 3446 | + | |
| 3447 | + | |
| 3448 | + | |
| 3449 | + | |
| 3450 | + | |
| 3451 | + | |
| 3452 | + | |
| 3453 | + | |
| 3454 | + | |
| 3455 | + | |
| 3456 | + | |
| 3457 | + | |
| 3458 | + | |
| 3459 | + | |
| 3460 | + | |
| 3461 | + | |
| 3462 | + | |
| 3463 | + | |
| 3464 | + | |
| 3465 | + | |
| 3466 | + | |
| 3467 | + | |
| 3468 | + | |
| 3469 | + | |
| 3470 | + | |
| 3471 | + | |
| 3472 | + | |
| 3473 | + | |
| 3474 | + | |
| 3475 | + | |
| 3476 | + | |
| 3477 | + | |
| 3478 | + | |
| 3479 | + | |
| 3480 | + | |
| 3481 | + | |
| 3482 | + | |
| 3483 | + | |
| 3484 | + | |
3410 | 3485 | | |
Lines changed: 8 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
203 | 203 | | |
204 | 204 | | |
205 | 205 | | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
206 | 214 | | |
207 | 215 | | |
208 | 216 | | |
| |||
Lines changed: 6 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
191 | 191 | | |
192 | 192 | | |
193 | 193 | | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
194 | 200 | | |
195 | 201 | | |
196 | 202 | | |
| |||
Lines changed: 0 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
83 | 83 | | |
84 | 84 | | |
85 | 85 | | |
86 | | - | |
87 | 86 | | |
88 | 87 | | |
89 | 88 | | |
| |||
Lines changed: 14 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
131 | 131 | | |
132 | 132 | | |
133 | 133 | | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
134 | 144 | | |
135 | 145 | | |
136 | 146 | | |
| |||
324 | 334 | | |
325 | 335 | | |
326 | 336 | | |
| 337 | + | |
| 338 | + | |
| 339 | + | |
| 340 | + | |
327 | 341 | | |
328 | 342 | | |
329 | 343 | | |
| |||
0 commit comments