mattcasters commented on PR #7820:
URL: https://github.com/apache/hop/pull/7820#issuecomment-5938671304

   Analysis of where a Timestamp becomes a Date, for #5651.
   
   `java.sql.Timestamp` extends `java.util.Date`, and 
`ValueMetaTimestamp.getDate()` returns that same instance. The JDBC 
specification describes this as implementation inheritance: code should not 
view a `Timestamp` as a `Date`. The same note applies to `java.sql.Date`.
   
   Two Hop paths meet that rule in different places.
   
   **Reading a field whose metadata is still Timestamp.** `getDate()` is the 
accessor for that field. `ValueMetaTimestamp.setPreparedStatementValue` writes 
through `getTimestamp()`, so a timestamp column keeps its nanoseconds. 
`OraBulkDataOutput` casts `rowMeta.getDate(...)` to `Timestamp` for a timestamp 
column. Returning `new Date(timestamp.getTime())` from `getDate()` would make 
that cast fail, and every caller that asks a timestamp field for a `Date` would 
lose the nanoseconds.
   
   **Converting into a field whose metadata is Date.** Select Values does this 
with `toMeta.convertData(fromMeta, value)` when the type changes. Stream Lookup 
coerces a key with `convertDataCompatible` when the lookup type differs from 
the input. Both methods returned the source `getDate()` result unchanged, so a 
Timestamp-to-Date conversion changed the metadata and left a `Timestamp` in the 
row. `JdbcDateValues.write` then sees `instanceof Timestamp` and calls 
`setTimestamp` with the original nanoseconds. That is the conversion failure in 
#5651.
   
   `getValueFromResultSet` can also store `ResultSet.getTimestamp()` in a Date 
field when the dialect supports timestamp-to-date conversion. Those rows are 
already Date metadata, so they do not go through 
`ValueMetaTimestamp.getDate()`. `JdbcDateValues` writes the stored object and 
does not call `getDate()`. Whether a Date field may still carry a `Timestamp` 
after a read is separate from this conversion bug. This pull request leaves 
that read path and `JdbcDateValues` as they are.
   
   The normalization is in the two conversion methods, and only when the 
destination type is Date. A `Timestamp` or `java.sql.Date` is copied with `new 
Date(date.getTime())`. A value that is already a plain `java.util.Date` is 
returned as the same instance. `ValueMetaTimestamp.getDate()` and 
`ValueMetaTimestamp.convertData()` are unchanged, so a timestamp field still 
converts as a `Timestamp` and keeps its nanoseconds.
   
   The branch now contains current `main`. The additional commit applies the 
same Date normalization to `convertDataCompatible`. The first patch covered 
`convertData` only.
   


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