Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/changes/changes.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
</properties>

<body>
<release version="3.4.0-SNAPSHOT" date="TBD" description="Un-skip and strengthen remaining disabled and no-op tests: implement DefaultPrepAndExpectedTestCaseTest stubs, convert ForwardOnlyDataSetTest no-ops to assertThrows, implement ExcludeTableFilterTest reverse-order tests, relocate ToStringViewTest's package-blocked cases, restore commented-out unit tests in CsvParserTest/FlatXmlTableTest/BiDirectionalEdgesDepthFirstSearchTest, implement ReplacementTableTest.testGetMissingValue, add assertions to applyColumnFilters tests, fix DatabaseTestCase tear-down exceptions obscuring test failures, rewrite obsolete DbUnitTaskIT queryset test, delete two dead commented-out test fragments, stop swallowing failures in PostgreSQL xtest* methods, add CachingConnectionProvider for opt-in IDatabaseConnection reuse across test methods, reduce DefaultPrepAndExpectedTestCase's per-test connection churn, fix DefaultPrepAndExpectedTestCase.runTest() losing a test failure to a cleanup exception, fix DefaultPrepAndExpectedTestCase column-name matching under non-English default locales, harmonize DefaultPrepAndExpectedTestCase's null-databaseTester handling on IllegalStateException, apply code-quality cleanups to DefaultPrepAndExpectedTestCase, pin remaining identifier case folding to Locale.ENGLISH for Turkish-family default locales, fix NullPointerException exporting NO_VALUE cells to flat XML and YAML dumping the raw sentinel, fix SQLHelper's schema-correction notice being silently dropped by a guard/call level mismatch, close BytesDataType file/URL streams and read them in chunks, fail fast on invalid BytesDataType [text]/[base64] values instead of silently storing garbage or NULL, fix QualifiedTableName escaping a single-character segment before a dot as part of the next segment, fix the Ant export step rejecting an uppercase CSV format and leaving an empty output file for unsupported formats, preserve the verify failure as suppressed when DefaultPrepAndExpectedTestCase.postTest's cleanup also fails, fix InsertOperation binding NULL into NOT NULL DEFAULT columns depending on row order, round-trip supplementary characters and replace unrepresentable control characters with U+FFFD in XML export, fix TimestampDataType mis-encoding pre-epoch fractional-second timestamps with a timezone suffix, roll back TransactionOperation on Error instead of implicitly committing, fix XlsTable negative row count and missing-row NullPointerException, pin YAML/DTD/OracleXMLType writer charsets to UTF-8 matching their readers, skip a redundant per-table metadata query in DatabaseDataSet.getTableMetaData, guard or remove per-cell debug logging in the datatype package, fix a data race that could mask the real producer failure in StreamingIterator, fix CsvParser duplicating the continuation line on a short multi-line parse, use DatabaseConfig.getFeature for the qualified-table-names check in DatabaseDataSet, fix FileHelper.copyFile leaking the source stream when the destination cannot be opened, keep DefaultPrepAndExpectedTestCase.configureTest's connection open for the test lifecycle instead of closing and immediately reacquiring it, remove a dead field and harden the close path in RefreshOperation, route Base64's stderr diagnostics through slf4j, remove XmlWriter's dead setEncoding(String) overload, fix CsvProducer truncating table names containing .csv before the final suffix, remove unused duplicate slf4jVersion/snakeYamlVersion pom properties, fix SQLHelper.logDebugIfValueChanged brace indentation, centralize duplicated Turkish-locale test setup into a shared @TurkishDefaultLocale JUnit 5 extension">
<release version="3.4.0-SNAPSHOT" date="TBD" description="Un-skip and strengthen remaining disabled and no-op tests: implement DefaultPrepAndExpectedTestCaseTest stubs, convert ForwardOnlyDataSetTest no-ops to assertThrows, implement ExcludeTableFilterTest reverse-order tests, relocate ToStringViewTest's package-blocked cases, restore commented-out unit tests in CsvParserTest/FlatXmlTableTest/BiDirectionalEdgesDepthFirstSearchTest, implement ReplacementTableTest.testGetMissingValue, add assertions to applyColumnFilters tests, fix DatabaseTestCase tear-down exceptions obscuring test failures, rewrite obsolete DbUnitTaskIT queryset test, delete two dead commented-out test fragments, stop swallowing failures in PostgreSQL xtest* methods, add CachingConnectionProvider for opt-in IDatabaseConnection reuse across test methods, reduce DefaultPrepAndExpectedTestCase's per-test connection churn, fix DefaultPrepAndExpectedTestCase.runTest() losing a test failure to a cleanup exception, fix DefaultPrepAndExpectedTestCase column-name matching under non-English default locales, harmonize DefaultPrepAndExpectedTestCase's null-databaseTester handling on IllegalStateException, apply code-quality cleanups to DefaultPrepAndExpectedTestCase, pin remaining identifier case folding to Locale.ENGLISH for Turkish-family default locales, fix NullPointerException exporting NO_VALUE cells to flat XML and YAML dumping the raw sentinel, fix SQLHelper's schema-correction notice being silently dropped by a guard/call level mismatch, close BytesDataType file/URL streams and read them in chunks, fail fast on invalid BytesDataType [text]/[base64] values instead of silently storing garbage or NULL, fix QualifiedTableName escaping a single-character segment before a dot as part of the next segment, fix the Ant export step rejecting an uppercase CSV format and leaving an empty output file for unsupported formats, preserve the verify failure as suppressed when DefaultPrepAndExpectedTestCase.postTest's cleanup also fails, fix InsertOperation binding NULL into NOT NULL DEFAULT columns depending on row order, round-trip supplementary characters and replace unrepresentable control characters with U+FFFD in XML export, fix TimestampDataType mis-encoding pre-epoch fractional-second timestamps with a timezone suffix, roll back TransactionOperation on Error instead of implicitly committing, fix XlsTable negative row count and missing-row NullPointerException, pin YAML/DTD/OracleXMLType writer charsets to UTF-8 matching their readers, skip a redundant per-table metadata query in DatabaseDataSet.getTableMetaData, guard or remove per-cell debug logging in the datatype package, fix a data race that could mask the real producer failure in StreamingIterator, fix CsvParser duplicating the continuation line on a short multi-line parse, use DatabaseConfig.getFeature for the qualified-table-names check in DatabaseDataSet, fix FileHelper.copyFile leaking the source stream when the destination cannot be opened, keep DefaultPrepAndExpectedTestCase.configureTest's connection open for the test lifecycle instead of closing and immediately reacquiring it, remove a dead field and harden the close path in RefreshOperation, route Base64's stderr diagnostics through slf4j, remove XmlWriter's dead setEncoding(String) overload, fix CsvProducer truncating table names containing .csv before the final suffix, remove unused duplicate slf4jVersion/snakeYamlVersion pom properties, fix SQLHelper.logDebugIfValueChanged brace indentation, centralize duplicated Turkish-locale test setup into a shared @TurkishDefaultLocale JUnit 5 extension, fix TimestampDataType writing the wrong instant to TIMESTAMP WITH TIME ZONE columns when some JDBC drivers tag the value with the JVM's default time zone instead of the dataset's own time zone">
<action dev="jeffjensen" type="test" issue="797" system="github" due-to="jeffjensen">
Implement the 8 empty, @Disabled DefaultPrepAndExpectedTestCaseTest stub methods covering preTest, postTest, setupData, verifyData, cleanupData, and makeCompositeDataSet, using the class's existing Mockito-based connection harness. Move the test fixture's databaseTester/tc construction from field initializers to a @BeforeEach method so @Mock injection (MockitoExtension) completes before they are built.
</action>
Expand Down Expand Up @@ -152,6 +152,9 @@
<action dev="jeffjensen" type="test" issue="833" system="github" due-to="jeffjensen">
Centralize the duplicated Turkish-locale save/mutate/restore boilerplate across 13 test classes into a shared @TurkishDefaultLocale JUnit 5 extension.
</action>
<action dev="jeffjensen" type="fix" issue="831" system="github" due-to="yoshida16729438">
Fix TimestampDataType writing the wrong instant to TIMESTAMP WITH TIME ZONE columns: the issue #711 fix's Calendar-based setTimestamp(Timestamp, Calendar) call let some JDBC drivers tag the stored value with the JVM's default time zone instead of the dataset's own time zone, silently discarding it. Detect such columns via PreparedStatement.getParameterMetaData() and write them with setObject(OffsetDateTime) instead, which drivers supporting the SQL type map unambiguously; columns without a time zone keep the existing Calendar-based behavior from #711 unchanged.
</action>
</release>
<release version="3.3.0" date="Jul 22, 2026" description="Performance improvements and fixes: speed up column index lookups, suppress RowOutOfBoundsException stack traces, buffer XML, CSV, DTD, and YAML output, cache DecimalFormat in XlsTable, restore DepthFirstSearch tests, fix DepthFirstSearch depth limit, cache DatabaseSequenceFilter dependency edges, topological sort in DatabaseSequenceFilter, single column-metadata fetch in ResultSetTableMetaData, precompute sort keys in SortedTable, reduce assertion loop overhead, reduce ReplacementTable scanning, flatten CompositeDataSet table merging, detect columns without exception flow in FlatXmlProducer, fix PrimaryKeyFilter result set leak, fix XlsDataSetWriter memory leak, skip timezone regex for plain timestamps, guard hot-path debug logging, fix SQLHelper result set leak, reuse query metadata in QueryTableIterator, fix XlsDataSet file stream leak, release consumed CSV rows early, lookup map for OrderedTableNameMap original names, primitive row index storage in RowFilterTable, set-based membership in Columns.mergeColumnsByName, extend ResultSetTableMetaData column-metadata cache to MySqlMetadataHandler and Db2MetadataHandler, fix XlsDataSetWriter StringIndexOutOfBoundsException for BigDecimal scale greater than 52, restore execution of 45 test methods silenced by missing @Test annotations, fix corrupted assertion in HandlersTest">
<!-- dependabot:dep=actions/checkout:new=7:pr=756 -->
Expand Down
55 changes: 54 additions & 1 deletion src/main/java/org/dbunit/dataset/datatype/TimestampDataType.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,15 @@
package org.dbunit.dataset.datatype;

import java.math.BigInteger;
import java.sql.ParameterMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.sql.Types;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeParseException;
import java.util.Calendar;
import java.util.TimeZone;
Expand Down Expand Up @@ -270,13 +273,63 @@ private void setSqlValueFromString(final String value, final int column,
if (timezoneMatcher.matches() && timezoneMatcher.group(2) != null)
{
final Calendar cal = makeCalendar(timezoneMatcher);
statement.setTimestamp(column, ts, cal);
if (isTimestampWithTimeZoneColumn(column, statement))
{
final ZoneId zoneId = cal.getTimeZone().toZoneId();
final OffsetDateTime offsetDateTime =
OffsetDateTime.ofInstant(ts.toInstant(), zoneId);
statement.setObject(column, offsetDateTime);
} else
{
statement.setTimestamp(column, ts, cal);
}
} else
{
statement.setTimestamp(column, ts);
}
}

/**
* Determines whether a prepared-statement parameter targets a column of
* SQL type {@code TIMESTAMP WITH TIME ZONE}.
* <p>
* {@link PreparedStatement#setTimestamp(int, Timestamp, Calendar)} only
* changes the wall-clock digits sent to the database. Some drivers write
* those digits into a time-zone-aware column tagged with the JVM's
* default time zone rather than the given calendar's zone, which
* silently discards the dataset's own time zone. Columns of this type
* must instead be written with
* {@link PreparedStatement#setObject(int, Object)} using an
* {@link OffsetDateTime}, which drivers supporting this SQL type map
* unambiguously.
* @param column The one-based parameter index.
* @param statement The statement the parameter belongs to.
* @return {@code true} if the parameter's declared SQL type is
* {@link Types#TIMESTAMP_WITH_TIMEZONE}, {@code false} if it is
* not, or if that could not be determined.
*/
private boolean isTimestampWithTimeZoneColumn(final int column,
final PreparedStatement statement)
{
try
{
final ParameterMetaData parameterMetaData =
statement.getParameterMetaData();
final int parameterType =
parameterMetaData.getParameterType(column);
return parameterType == Types.TIMESTAMP_WITH_TIMEZONE;
} catch (final Exception e)
{
// Driver support for ParameterMetaData is inconsistent; treat any
// failure as "unknown" and fall back to the safe, existing
// behavior instead of failing the whole operation.
logger.debug(
"Could not determine parameter type for column {}, assuming no timezone.",
column, e);
return false;
}
}

private Calendar makeCalendar(final Matcher timezoneMatcher)
{
final String zoneValue = timezoneMatcher.group(2);
Expand Down
4 changes: 4 additions & 0 deletions src/site/asciidoc/integrationtests.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,10 @@ The valid feature names, their descriptions, and the databases that do not suppo
|`XML_TYPE`
|Oracle `XMLTYPE` column type; tests inserting and updating XML_TYPE_TABLE rows.
|DB2, Derby, H2, HSQLDB, MySQL, MSSQL, PostgreSQL

|`TIMESTAMP_WITH_TIMEZONE`
|`TIMESTAMP WITH TIME ZONE` column type; tests `TimestampDataType` preserving the dataset's own offset instead of the JVM's default time zone.
|DB2, Derby, MySQL, MSSQL, Oracle
|===

== Running Integration Tests with IDEs
Expand Down
2 changes: 2 additions & 0 deletions src/test/java/org/dbunit/TestFeature.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ public class TestFeature
public static final TestFeature SDO_GEOMETRY =
new TestFeature("SDO_GEOMETRY");
public static final TestFeature XML_TYPE = new TestFeature("XML_TYPE");
public static final TestFeature TIMESTAMP_WITH_TIMEZONE =
new TestFeature("TIMESTAMP_WITH_TIMEZONE");

private final String _name;

Expand Down
Loading
Loading