voonhous opened a new issue, #20538:
URL: https://github.com/apache/hudi/issues/20538

   ### Describe the problem
   
   A column stats expression index on a function that depends on the session 
time zone (for ex, `hour`, `date_format`) stores values rendered in the 
writer's session time zone, and the zone is not recorded anywhere. A query run 
in a different session time zone strips the function off its filter 
(`ExpressionIndexSupport.extractQueryAndLiterals`, 
`ExpressionIndexSupport.scala:445-489`) and compares the literal with those 
stored values. Files holding matching rows are pruned, so the query silently 
returns too few rows.
   
   `git grep -i "timezone\|zoneId"` over `HoodieIndexDefinition`, 
`ExpressionIndexSparkFunctions` and `ExpressionIndexSupport` finds nothing.
   
   ### Repro
   
   ```sql
   SET spark.sql.session.timeZone=UTC;
   
   CREATE TABLE hudi_table_expr_index (
       ts TIMESTAMP, uuid STRING, rider STRING, driver STRING, fare DOUBLE, 
city STRING
   ) USING HUDI
   PARTITIONED BY (city)
   TBLPROPERTIES (
       primaryKey = 'uuid',
       preCombineField = 'ts',
       hoodie.metadata.index.column.stats.column.list = 'fare'
   );
   
   INSERT INTO hudi_table_expr_index VALUES
   (TIMESTAMP'2023-09-19 
23:40:49','334e26e9-8355-45cc-97c6-c31daf0df330','rider-A','driver-K',19.10,'san_francisco'),
   (TIMESTAMP'2023-09-18 
21:45:54','e96c4396-3fad-413a-a942-4cb36106d721','rider-C','driver-M',27.70,'san_francisco'),
   (TIMESTAMP'2023-09-18 
19:14:22','9909a8b1-2d15-4d3d-8ec9-efc48c536a00','rider-D','driver-L',33.90,'san_francisco'),
   (TIMESTAMP'2023-09-21 
16:34:26','1dced545-862b-4ceb-8b43-d2a568f6616b','rider-E','driver-O',93.50,'san_francisco'),
   (TIMESTAMP'2023-09-23 
09:42:17','e3cf430c-889d-4015-bc98-59bdce1e530c','rider-F','driver-P',34.15,'sao_paulo'),
   (TIMESTAMP'2023-09-22 
09:53:40','7a84095f-737f-40bc-b62f-6b69664712d2','rider-G','driver-Q',43.40,'sao_paulo'),
   (TIMESTAMP'2023-09-19 
02:38:07','3eeb61f7-c2b0-4636-99bd-5d7a5a1d2c04','rider-I','driver-S',41.06,'chennai'),
   (TIMESTAMP'2023-09-19 
01:33:19','c8abbe79-8d89-47ea-b4ce-4d224bae5bfa','rider-J','driver-T',17.85,'chennai');
   
   CREATE INDEX ts_hour ON hudi_table_expr_index USING column_stats(ts) 
options(expr='hour');
   
   SET spark.sql.session.timeZone=America/Los_Angeles;
   SELECT city, uuid FROM hudi_table_expr_index WHERE hour(ts) = 18;
   -- returns no rows; chennai c8abbe79 (01:33:19Z, 18:33 PDT) matches
   ```
   
   One base file per partition. Spark 3.5, master `0b696f915b67`, 
`hoodie.enable.data.skipping=true`. Expected = the same filter over an 
unindexed copy of the rows. In UTC every case below is correct.
   
   | index | filter, session zone America/Los_Angeles | rows returned | 
expected |
   | --- | --- | --- | --- |
   | `hour` | `hour(ts) = 18` | none | chennai/c8abbe79 |
   | `hour` | `hour(ts) = 2` | none | sao_paulo/7a84095f, sao_paulo/e3cf430c |
   | `date_format`, `format='yyyy-MM-dd'` | `date_format(ts, 'yyyy-MM-dd') = 
'2023-09-18'` | san_francisco x2 | san_francisco x2, chennai x2 |
   
   The other zone-dependent index functions (`year`, `month`, `day`, 
`from_unixtime`, `unix_timestamp`, `to_date`, `to_timestamp`) take the same 
path; only `hour` and `date_format` were run. Every commit also computes index 
values in its own writer's session time zone, so writers in different zones mix 
zones within one index (from reading the code, not run).
   
   ### Suggested fix
   
   Record the session time zone in the index definition when the index is 
created, and compute index values in that zone on every write. On read, use the 
index only when the query expression's `timeZoneId` resolves to the same zone 
(or to the same fixed offset), and otherwise skip it.
   
   Related: #20537 (same matching step), #20255 / #20256, #20449.
   


-- 
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