[ 
https://issues.apache.org/jira/browse/FLINK-41026?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

ASF GitHub Bot updated FLINK-41026:
-----------------------------------
    Labels: pull-request-available  (was: )

> [format/avro] Convert timestamps above precision 3 as microseconds in both 
> directions
> -------------------------------------------------------------------------------------
>
>                 Key: FLINK-41026
>                 URL: https://issues.apache.org/jira/browse/FLINK-41026
>             Project: Flink
>          Issue Type: Bug
>          Components: Formats (JSON, Avro, Parquet, ORC, SequenceFile)
>            Reporter: Pritam Kumar
>            Assignee: Pritam Kumar
>            Priority: Minor
>              Labels: pull-request-available
>
> h2. What
> {{AvroToRowDataConverters}} and {{RowDataToAvroConverters}} now follow the 
> unit {{AvroSchemaConverter}} declares for a timestamp column: microseconds 
> when the mapping is not legacy and the precision is above 3, milliseconds 
> otherwise.
> h2. Why
> For {{TIMESTAMP(4..6)}} and {{TIMESTAMP_LTZ(4..6)}} the schema says 
> {{local-timestamp-micros}} / {{{}timestamp-micros{}}}, but:
>  * the reader took every {{long}} as milliseconds, so a microsecond value was 
> read a thousand times too large;
>  * an {{Instant}} went through {{{}toEpochMilli(){}}}, which drops the 
> sub-millisecond digits;
>  * the writer wrote every timestamp as epoch milliseconds, also into a field 
> declared as microseconds.
> Reading a long as microseconds with a truncating {{/}} and {{%}} would also 
> fail for a negative value that is not a whole millisecond (for example 
> {{{}-86400000001{}}}, 1969-12-30T23:59:59.999999Z): the nanosecond part comes 
> out negative and {{TimestampData.fromEpochMillis}} throws an 
> {{IllegalArgumentException}} without a message. This is how a job reading 
> such a record from Kafka ended up restarting forever; it was found by 
> comparing a Flink sink with a Kafka Connect sink on the same records.
> h2. Change
>  * Reader: a {{long}} is split with {{Math.floorDiv}} / {{Math.floorMod}} 
> when the column is a microsecond one; an {{Instant}} goes through 
> {{TimestampData.fromInstant}} there; milliseconds columns and the legacy 
> mapping are untouched.
>  * Writer: a microsecond column is written as microseconds, computed from the 
> seconds and the (never negative) nanosecond part. 
> {{ChronoUnit.MICROS.between}} is not used because it counts nanoseconds on 
> the way and overflows outside the years 1678 to 2262.
>  * {{{}TIME{}}}: a {{long}} is accepted (a {{time-micros}} that the Avro 
> reader gave without a logical type conversion). {{RowData}} stores a TIME as 
> an int of milliseconds, so the microseconds are dropped there; this is stated 
> in the code.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to