Raviston Thanasekar created ORC-2236:
----------------------------------------

             Summary: Predicate push down skips row groups with TIMESTAMP 
values in the repeated hour at the end of daylight saving time
                 Key: ORC-2236
                 URL: https://issues.apache.org/jira/browse/ORC-2236
             Project: ORC
          Issue Type: Bug
          Components: Java
    Affects Versions: 2.3.1
            Reporter: Raviston Thanasekar
         Attachments: OrcDstRepro.java

With useUTCTimestamp=false (the default), a SearchArgument on a TIMESTAMP 
column skips a row group whose values match, when a value is in the first 
occurrence of the hour that repeats at the end of daylight saving time in the 
JVM default time zone. With orc-core 2.3.1, the attached OrcDstRepro.java 
writes one value per file with the Java API and reads it back with and without 
{{t = value}}:

{noformat}
JVM time zone America/Los_Angeles
2020-11-01T01:30:00-07:00: value 2020-11-01 01:30:00.0 (1604219400000), file 
min 2020-11-01 01:30:00.0 (1604223000000), rows 1, rows with t = value: 0   <-- 
row group skipped
2020-11-01T01:30:00-08:00: value 2020-11-01 01:30:00.0 (1604223000000), file 
min 2020-11-01 01:30:00.0 (1604223000000), rows 1, rows with t = value: 1
2020-07-01T12:00:00-07:00: value 2020-07-01 12:00:00.0 (1593630000000), file 
min 2020-07-01 12:00:00.0 (1593630000000), rows 1, rows with t = value: 1
JVM time zone Europe/Berlin
2024-10-27T02:30:00+02:00: value 2024-10-27 02:30:00.0 (1729989000000), file 
min 2024-10-27 02:30:00.0 (1729992600000), rows 1, rows with t = value: 0   <-- 
row group skipped
2024-10-27T02:30:00+01:00: value 2024-10-27 02:30:00.0 (1729992600000), file 
min 2024-10-27 02:30:00.0 (1729992600000), rows 1, rows with t = value: 1
JVM time zone Europe/Madrid
1900-01-01T00:00:00-00:14:44: value 1900-01-01 00:00:00.0 (-2208987916000), 
file min 1900-01-01 00:00:00.0 (-2208992400000), rows 1, rows with t = value: 0 
  <-- row group skipped
1900-01-02T00:00:00-00:14:44: value 1900-01-02 00:00:00.0 (-2208901516000), 
file min 1900-01-02 00:00:00.0 (-2208901516000), rows 1, rows with t = value: 1
{noformat}

The writer stores the statistic as the wall clock of the value, millis + offset 
({{SerializationUtils.convertToUtc}} in {{TimestampTreeWriter}}). 
{{TimestampStatisticsImpl.getMinimum()}} and {{getMaximum()}} convert it back 
with {{SerializationUtils.convertFromUtc}}, which looks up the offset at {{time 
- rawOffset}}:

{code:java}
public static long convertFromUtc(TimeZone local, long time) {
  int offset = local.getOffset(time - local.getRawOffset());
  return time - offset;
}
{code}

That isn't the offset of the value when the offset at that instant differs from 
the current raw offset:
* A wall clock in the repeated hour belongs to two instants. {{convertFromUtc}} 
always returns the second one, so the minimum and maximum of a row group with a 
value in the first one are one hour later than the value.
* Before 1900, {{java.util.TimeZone}} returns the current raw offset instead of 
the historical one. A wall clock near 1900-01-01 00:00 is then converted with a 
different offset than it was written with, in time zones such as Europe/Madrid, 
CET, Europe/Brussels, Africa/Ceuta, Antarctica/Casey and Pacific/Kiritimati.

As the wall clock alone can't tell the two instants apart, a fix probably needs 
the minimum to use the earliest instant with that wall clock and the maximum 
the latest one, so that the range still covers the values.

This was found through Spark, where it makes queries on ORC tables return fewer 
rows with filter push down on: SPARK-61463. ORC-451 looks related.



--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

Reply via email to