SEPURI-SAI-KRISHNA opened a new issue, #19651:
URL: https://github.com/apache/hudi/issues/19651

   ### Bug Description
   
   **What happened:**
   
   A table partitioned by a `date` column whose partition path does not line up 
one-to-one with the
   partition columns is written successfully but **cannot be read at all**. 
Every query against it —
   including an unfiltered `select *` — fails with:
   
   ```
   java.lang.ClassCastException: class org.apache.spark.unsafe.types.UTF8String
   cannot be cast to class java.lang.Integer
   ```
   
   When the partition fragments do not line up with the partition columns,
   `HoodieSparkUtils#doParsePartitionColumnValues` falls back onto 
`castStringToType` to recover the
   partition values. That method returns values in their *external* 
representation rather than
   Catalyst's *internal* one:
   
   ```scala
   case _: DecimalType => new java.math.BigDecimal(value)   // Catalyst expects 
Decimal
   case StringType     => UTF8String.fromString(value)
   case _: TimestampType => UTF8String.fromString(value)    // Catalyst expects 
Long (micros)
   case _: DateType      => UTF8String.fromString(value)    // Catalyst expects 
Int (epoch days)
   ```
   
   Those values go straight into the `InternalRow` of partition values that 
partition pruning
   (`SparkHoodieTableFileIndex`) and the file index (`HoodieFileIndex`) 
evaluate against, so Spark
   reads a `UTF8String` through `InternalRow#getInt` and throws.
   
   Five distinct problems in that one method, all verified:
   
   | input | expected | actual |
   |---|---|---|
   | `"2023-03-01"` as `DateType` | `Int` 19417 (epoch days) | `UTF8String` 
`2023-03-01` |
   | `"2023-03-01 01:02:03"` as `TimestampType` | `Long` micros | `UTF8String` |
   | `"1.50"` as `DecimalType(10,2)` | `org.apache.spark.sql.types.Decimal` | 
`java.math.BigDecimal` |
   | `"__HIVE_DEFAULT_PARTITION__"` as any type | `null` | the literal sentinel 
string |
   | `"a%3Db"` as `StringType` | `a=b` | `a%3Db` (never unescaped) |
   
   The default-partition and unescaping cases also diverge from the 
non-fallback path: when the
   fragments *do* line up, parsing goes through Spark's partition parser, which 
maps the default
   partition to `null` and unescapes values. So the same table yields different 
partition values
   depending on which branch parses the path.
   
   **What you expected:**
   
   Partition values recovered from the partition path should be in Catalyst's 
internal representation
   and should match what the aligned path produces, so the table is readable 
and partition pruning
   works.
   
   **Steps to reproduce:**
   
   ```sql
   create table date_part_repro (
     id int,
     name string,
     ts long,
     grass_date date
   ) using hudi
   tblproperties (
     primaryKey = 'id',
     type = 'cow',
     orderingFields = 'ts',
     'hoodie.datasource.write.slash.separated.date.partitioning' = 'true'
   )
   partitioned by (grass_date);
   
   insert into date_part_repro values(1, 'a1', 1000, date'2023-02-27');
   insert into date_part_repro values(2, 'a2', 1000, date'2023-03-01');
   
   -- writes fine; partition directories 2023/02/27 and 2023/03/01 are created
   
   select * from date_part_repro;   -- ClassCastException
   ```
   
   The write succeeds and the data is on disk; only reads fail. The same 
failure reproduces without
   that config whenever the fragments do not line up — for example a hive-style 
table
   `partitioned by (dt date, city string)` where a `city` value contains an 
unencoded `/`, giving
   `dt=2023-03-01/city=san/francisco` (three fragments, two columns).
   
   It also reproduces as a plain unit test with no Spark job:
   
   ```scala
   HoodieSparkUtils.castStringToType("2023-03-01", DateType)
   // => UTF8String "2023-03-01", where Catalyst requires an Int
   ```
   
   ### Environment
   
   **Hudi version:** 1.2.0 and master (1.3.0-SNAPSHOT)
   **Query engine:** Spark (verified on Spark 3.5 / Scala 2.12)
   **Relevant configs:** any table whose partition path fragments do not line 
up with the partition
   columns and that has a `date`, `timestamp` or `decimal` partition column, 
e.g.
   `hoodie.datasource.write.slash.separated.date.partitioning=true` with a 
single `date` partition
   column.
   
   ### Logs and Stack Trace
   
   ```
   org.apache.spark.SparkException: Job aborted due to stage failure: Task 0 in 
stage 45.0 failed 1
   times, most recent failure: Lost task 0.0 in stage 45.0: 
java.lang.ClassCastException: class
   org.apache.spark.unsafe.types.UTF8String cannot be cast to class 
java.lang.Integer
   (org.apache.spark.unsafe.types.UTF8String is in unnamed module of loader 
'app'; java.lang.Integer
   is in module java.base of loader 'bootstrap')
   ```
   
   I have a fix and will open a PR referencing this issue.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to