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]
