DBZ-6513 Fix the computation of Oracle's negative interval

This commit is contained in:
Vojtech Juranek 2023-06-15 23:40:32 +02:00 committed by Jiri Pechanec
parent 7e6c2ea75d
commit 8172434dda
2 changed files with 34 additions and 12 deletions

View File

@ -746,8 +746,8 @@ private void convertOracleIntervalDaySecond(Object data, ResultReceiver r) {
if (m.matches()) {
final int sign = "-".equals(m.group(1)) ? -1 : 1;
if (intervalHandlingMode == OracleConnectorConfig.IntervalHandlingMode.STRING) {
double seconds = (double) (sign * Integer.parseInt(m.group(5)))
+ (double) Integer.parseInt(Strings.pad(m.group(6), 6, '0')) / 1_000_000D;
double seconds = sign * ((double) (Integer.parseInt(m.group(5)))
+ (double) Integer.parseInt(Strings.pad(m.group(6), 6, '0')) / 1_000_000D);
r.deliver(Interval.toIsoString(
0,
0,

View File

@ -1249,6 +1249,10 @@ public void shouldHandleIntervalTypesAsString() throws Exception {
connection.execute("INSERT INTO debezium.interval (id, intYM, intYM2, intDS, intDS2) "
+ "values (2, INTERVAL '0' YEAR, INTERVAL '0' MONTH, "
+ "INTERVAL '0' DAY, INTERVAL '0' SECOND)");
// DBZ-6513 negative intervals
connection.execute("INSERT INTO debezium.interval (id, intYM, intYM2, intDS, intDS2) "
+ "values (3, INTERVAL '-1' YEAR, INTERVAL '-1' MONTH, "
+ "INTERVAL '-1' DAY, INTERVAL '-7 5:12:10.0123' DAY(1) TO SECOND)");
connection.commit();
final Configuration config = TestHelper.defaultConfig()
@ -1265,12 +1269,12 @@ public void shouldHandleIntervalTypesAsString() throws Exception {
waitForSnapshotToBeCompleted(TestHelper.CONNECTOR_NAME, TestHelper.SERVER_NAME);
// Verify record generated during snapshot
final SourceRecords snapshotRecords = consumeRecordsByTopic(2);
assertThat(snapshotRecords.allRecordsInOrder()).hasSize(2);
final SourceRecords snapshotRecords = consumeRecordsByTopic(3);
assertThat(snapshotRecords.allRecordsInOrder()).hasSize(3);
assertThat(snapshotRecords.topics()).contains("server1.DEBEZIUM.INTERVAL");
List<SourceRecord> records = snapshotRecords.recordsForTopic("server1.DEBEZIUM.INTERVAL");
assertThat(records).hasSize(2);
assertThat(records).hasSize(3);
Struct after = ((Struct) records.get(0).value()).getStruct(AFTER);
assertThat(after.get("ID")).isEqualTo(1);
@ -1286,38 +1290,56 @@ public void shouldHandleIntervalTypesAsString() throws Exception {
assertThat(after.getString("INTDS")).isEqualTo("P0Y0M0DT0H0M0S");
assertThat(after.getString("INTDS2")).isEqualTo("P0Y0M0DT0H0M0S");
after = ((Struct) records.get(2).value()).getStruct(AFTER);
assertThat(after.get("ID")).isEqualTo(3);
assertThat(after.getString("INTYM")).isEqualTo("P-1Y0M0DT0H0M0S");
assertThat(after.getString("INTYM2")).isEqualTo("P0Y-1M0DT0H0M0S");
assertThat(after.getString("INTDS")).isEqualTo("P0Y0M-1DT0H0M0S");
assertThat(after.getString("INTDS2")).isEqualTo("P0Y0M-7DT-5H-12M-10.0123S");
waitForStreamingRunning(TestHelper.CONNECTOR_NAME, TestHelper.SERVER_NAME);
connection.execute("INSERT INTO debezium.interval (id, intYM, intYM2, intDS, intDS2) "
+ "values (3, INTERVAL '2' YEAR, INTERVAL '555-4' YEAR(3) TO MONTH, "
+ "values (4, INTERVAL '2' YEAR, INTERVAL '555-4' YEAR(3) TO MONTH, "
+ "INTERVAL '3' DAY, INTERVAL '111 10:09:08.555444333' DAY(3) TO SECOND(9))");
connection.execute("INSERT INTO debezium.interval (id, intYM, intYM2, intDS, intDS2) "
+ "values (4, INTERVAL '0' YEAR, INTERVAL '0' MONTH, "
+ "values (5, INTERVAL '0' YEAR, INTERVAL '0' MONTH, "
+ "INTERVAL '0' DAY, INTERVAL '0' SECOND)");
// DBZ-6513 negative intervals
connection.execute("INSERT INTO debezium.interval (id, intYM, intYM2, intDS, intDS2) "
+ "values (6, INTERVAL '-1' YEAR, INTERVAL '-1' MONTH, "
+ "INTERVAL '-1' DAY, INTERVAL '-7 5:12:10.0123' DAY(1) TO SECOND)");
connection.commit();
// Verify record generated during streaming
final SourceRecords streamingRecords = consumeRecordsByTopic(2);
assertThat(streamingRecords.allRecordsInOrder()).hasSize(2);
final SourceRecords streamingRecords = consumeRecordsByTopic(3);
assertThat(streamingRecords.allRecordsInOrder()).hasSize(3);
assertThat(streamingRecords.topics()).contains("server1.DEBEZIUM.INTERVAL");
records = streamingRecords.recordsForTopic("server1.DEBEZIUM.INTERVAL");
assertThat(records).hasSize(2);
assertThat(records).hasSize(3);
after = ((Struct) records.get(0).value()).getStruct(AFTER);
assertThat(after.get("ID")).isEqualTo(3);
assertThat(after.get("ID")).isEqualTo(4);
assertThat(after.getString("INTYM")).isEqualTo("P2Y0M0DT0H0M0S");
assertThat(after.getString("INTYM2")).isEqualTo("P555Y4M0DT0H0M0S");
assertThat(after.getString("INTDS")).isEqualTo("P0Y0M3DT0H0M0S");
assertThat(after.getString("INTDS2")).isEqualTo("P0Y0M111DT10H9M563.444333S");
after = ((Struct) records.get(1).value()).getStruct(AFTER);
assertThat(after.get("ID")).isEqualTo(4);
assertThat(after.get("ID")).isEqualTo(5);
assertThat(after.getString("INTYM")).isEqualTo("P0Y0M0DT0H0M0S");
assertThat(after.getString("INTYM2")).isEqualTo("P0Y0M0DT0H0M0S");
assertThat(after.getString("INTDS")).isEqualTo("P0Y0M0DT0H0M0S");
assertThat(after.getString("INTDS2")).isEqualTo("P0Y0M0DT0H0M0S");
after = ((Struct) records.get(2).value()).getStruct(AFTER);
assertThat(after.get("ID")).isEqualTo(6);
assertThat(after.getString("INTYM")).isEqualTo("P-1Y0M0DT0H0M0S");
assertThat(after.getString("INTYM2")).isEqualTo("P0Y-1M0DT0H0M0S");
assertThat(after.getString("INTDS")).isEqualTo("P0Y0M-1DT0H0M0S");
assertThat(after.getString("INTDS2")).isEqualTo("P0Y0M-7DT-5H-12M-10.0123S");
assertNoRecordsToConsume();
}
finally {