Repository navigation
DLPX-99548 Hop 2.x dropped HOP_COMPATIBILITY_DB_IGNORE_TIMEZONE, breaking Teradata batch inserts on nullable TIMESTAMP columns - #18
Merged
srusia-delphix merged 1 commit intoOct 9, 2026
Conversation
srusia-delphix
force-pushed
the
dlpx/pr/srusia-delphix/bf8ef52c-fcc5-43fb-ac33-d8db133174be
branch
from
October 7, 2026 08:10
0c4d5ab to
79d5389
Compare
srusia-delphix
marked this pull request as ready for review
October 7, 2026 09:42
srusia-delphix
requested review from
AnoopKumarDelphix,
abhishekkumardelphix,
ankurs-delphix and
sandeep-delphix
and
a balanced review from Copilot
October 7, 2026 10:06
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Equality handling, JUnit 5 isolation, and converted-date branch coverage remain incomplete.
Review effort: Balanced
Findings: 2
Open (3)
What changed in this PR
Restores the compatibility flag needed to prevent Teradata timestamp batch-insert type conflicts.
Changes:
- Reintroduces
HOP_COMPATIBILITY_DB_IGNORE_TIMEZONE. - Uses non-calendar JDBC date/timestamp overloads when enabled.
- Adds focused tests and environment cleanup.
| File | Description |
|---|---|
Const.java |
Defines and documents the compatibility property. |
ValueMetaBase.java |
Reads and applies the property during JDBC binding. |
ValueMetaBaseSetPreparedStmntValueTest.java |
Tests date and timestamp overload selection. |
RestoreHopEnvironment.java |
Clears the property in JUnit 4 tests. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
…king Teradata batch inserts on nullable TIMESTAMP columns PR URL: https://www.github.com/delphix/hop/pull/18
srusia-delphix
force-pushed
the
dlpx/pr/srusia-delphix/bf8ef52c-fcc5-43fb-ac33-d8db133174be
branch
from
October 7, 2026 11:22
79d5389 to
d7b8b46
Compare
ankurs-delphix
approved these changes
Oct 9, 2026
srusia-delphix
deleted the
dlpx/pr/srusia-delphix/bf8ef52c-fcc5-43fb-ac33-d8db133174be
branch
October 9, 2026 09:36
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


Problem
Jira: DLPX-99548
DLPX-87054 fixed a Teradata masking failure on Kettle/Hop 1.2.0 by adding a
HOP_COMPATIBILITY_DB_IGNORE_TIMEZONEsystem property toValueMetaBase. That flag no longer exists anywhere in this fork'sdelphix/hop-2.17branch (nor in stock Apache Hop 2.10.0 through 2.17.0 — checked directly against the2.10.0-rc1,2.15.0-rc1,2.16.0-rc1and2.17.0-rc1tags), so the original DLPX-87054 failure mode is back on Hop 2.x:The Teradata JDBC driver assigns a different SQL type to a
PreparedStatementtimestamp parameter depending on which overload binds it:setTimestamp(idx, ts, Calendar)→ type 773 (TIMESTAMP WITH TIME ZONE)setTimestamp(idx, ts)/setNull(idx, Types.TIMESTAMP)→ type 675 (plainTIMESTAMP)A batch insert that mixes null and non-null rows for the same nullable TIMESTAMP column binds both types to one parameter, and Teradata rejects the batch outright.
This surfaced during the
dms-core-gateHop 1.2.0 → 2.17 upgrade (DLPX-97999), via PR review on delphix/dms-core-gate#2337 (review comment).dms-core-gatestill sets this flag today for Teradata connectors (RunnerUtil.java, gated onExtendedPlatform::isTeradataConnector), so it silently becomes a no-op the moment the engine takes on this Hop version — until Teradata customers hit the batch-insert failure again.Evaluation
setPreparedStatementValue()'sTYPE_DATEbranch unconditionally uses the Calendar overload whenevergetDateFormatTimeZone() != null.dateFormatTimeZonedefaults toTimeZone.getDefault()in theValueMetaBaseconstructor, so it is essentially never null — meaning every Teradata timestamp binds via the Calendar overload (773) regardless of whether the row's value is null or not, reproducing the exact DLPX-87054 symptom.In Hop 1.2.0, the same method short-circuited the Calendar overload with
if (ignoreTimezone || this.getDateFormatTimeZone() == null), backed by anignoreTimezonefield read once fromHOP_COMPATIBILITY_DB_IGNORE_TIMEZONEin the constructor. Neither the field nor the constant survived the 1.2.0 → 2.x migration — this is an upstream Hop regression, not something a Delphix patch introduced or dropped.Solution
Restore the flag exactly as 1.2.0 had it:
Const.HOP_COMPATIBILITY_DB_IGNORE_TIMEZONE— the system-property name, with a@Variabledoc matching the style of the neighboringHOP_EMPTY_STRING_DIFFERS_FROM_NULL/HOP_LENIENT_STRING_TO_NUMBER_CONVERSIONflags.ValueMetaBase.ignoreTimezone— read once in the constructor, same as the two flags above.setPreparedStatementValue()(setDate, and bothsetTimestampbranches) gated onignoreTimezone || this.getDateFormatTimeZone() == null.Default behavior (property unset) is unchanged — this only takes effect when a caller explicitly sets
HOP_COMPATIBILITY_DB_IGNORE_TIMEZONE=Y, exactly asdms-core-gatealready does for Teradata connectors.Testing Done
ValueMetaBaseSetPreparedStmntValueTestValueMetaBaseTestTwo tests added to
ValueMetaBaseSetPreparedStmntValueTest, mirroring the existingtestDateRegular/testTimestampRegularstyle in that file:testDateWithIgnoreTimezoneSkipsCalendarOverload— with the property set, assertssetDate(idx, date)is called andsetDate(idx, date, Calendar)is not.testTimestampWithIgnoreTimezoneSkipsCalendarOverload— same shape forsetTimestamp.RestoreHopEnvironmentnow also clearsHOP_COMPATIBILITY_DB_IGNORE_TIMEZONEbetween tests, matching how it already clears the two neighboring compatibility flags.Still outstanding. This has not yet been validated against a live or emulated Teradata connection — the tests above confirm the
PreparedStatementcall shape, not an actual Teradata batch insert. Beforedms-core-gatetakes a dependency on this for Teradata masking: publish an updated2.17.0-dlpx1artifact to masking-maven (the one currently published predates this fix), bumpdms-core-gate'shopVersion, and confirm with a real Teradata run.Notes to Reviewers
This is a straight restoration of 1.2.0 behavior, not new design — the diff should read as "put back what upstream removed." The Jira ID in the code comment follows the convention of the other Delphix patches already in this fork (
DLPX-46230/DLPX-82789/DLPX-51415inValueMetaBase).