|
|
@ -16,6 +16,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
package com.ververica.cdc.connectors.oracle.table;
|
|
|
|
package com.ververica.cdc.connectors.oracle.table;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import org.apache.flink.table.data.TimestampData;
|
|
|
|
import org.apache.flink.table.types.logical.LogicalType;
|
|
|
|
import org.apache.flink.table.types.logical.LogicalType;
|
|
|
|
|
|
|
|
|
|
|
|
import com.ververica.cdc.debezium.table.DeserializationRuntimeConverter;
|
|
|
|
import com.ververica.cdc.debezium.table.DeserializationRuntimeConverter;
|
|
|
@ -26,6 +27,7 @@ import org.apache.kafka.connect.data.Schema;
|
|
|
|
import org.apache.kafka.connect.data.Struct;
|
|
|
|
import org.apache.kafka.connect.data.Struct;
|
|
|
|
|
|
|
|
|
|
|
|
import java.math.BigDecimal;
|
|
|
|
import java.math.BigDecimal;
|
|
|
|
|
|
|
|
import java.time.Instant;
|
|
|
|
import java.time.ZoneId;
|
|
|
|
import java.time.ZoneId;
|
|
|
|
import java.util.Optional;
|
|
|
|
import java.util.Optional;
|
|
|
|
|
|
|
|
|
|
|
@ -40,14 +42,14 @@ public class OracleDeserializationConverterFactory {
|
|
|
|
@Override
|
|
|
|
@Override
|
|
|
|
public Optional<DeserializationRuntimeConverter> createUserDefinedConverter(
|
|
|
|
public Optional<DeserializationRuntimeConverter> createUserDefinedConverter(
|
|
|
|
LogicalType logicalType, ZoneId serverTimeZone) {
|
|
|
|
LogicalType logicalType, ZoneId serverTimeZone) {
|
|
|
|
return wrapNumericConverter(createNumericConverter(logicalType));
|
|
|
|
return wrapNumericConverter(createNumericConverter(logicalType, serverTimeZone));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/** Creates a runtime converter which assuming input object is not null. */
|
|
|
|
/** Creates a runtime converter which assuming input object is not null. */
|
|
|
|
private static Optional<DeserializationRuntimeConverter> createNumericConverter(
|
|
|
|
private static Optional<DeserializationRuntimeConverter> createNumericConverter(
|
|
|
|
LogicalType type) {
|
|
|
|
LogicalType type, ZoneId serverTimeZone) {
|
|
|
|
switch (type.getTypeRoot()) {
|
|
|
|
switch (type.getTypeRoot()) {
|
|
|
|
case BOOLEAN:
|
|
|
|
case BOOLEAN:
|
|
|
|
return createBooleanConverter();
|
|
|
|
return createBooleanConverter();
|
|
|
@ -63,12 +65,39 @@ public class OracleDeserializationConverterFactory {
|
|
|
|
return createFloatConverter();
|
|
|
|
return createFloatConverter();
|
|
|
|
case DOUBLE:
|
|
|
|
case DOUBLE:
|
|
|
|
return createDoubleConverter();
|
|
|
|
return createDoubleConverter();
|
|
|
|
|
|
|
|
// Debezium use io.debezium.time.ZonedTimestamp to map Oracle TIMESTAMP WITH LOCAL
|
|
|
|
|
|
|
|
// TIME ZONE type, the value is a string representation of a timestamp in UTC.
|
|
|
|
|
|
|
|
case TIMESTAMP_WITH_LOCAL_TIME_ZONE:
|
|
|
|
|
|
|
|
return convertToLocalTimeZoneTimestamp();
|
|
|
|
default:
|
|
|
|
default:
|
|
|
|
// fallback to default converter
|
|
|
|
// fallback to default converter
|
|
|
|
return Optional.empty();
|
|
|
|
return Optional.empty();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static Optional<DeserializationRuntimeConverter> convertToLocalTimeZoneTimestamp() {
|
|
|
|
|
|
|
|
return Optional.of(
|
|
|
|
|
|
|
|
new DeserializationRuntimeConverter() {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static final long serialVersionUID = 1L;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
|
|
public Object convert(Object dbzObj, Schema schema) {
|
|
|
|
|
|
|
|
if (dbzObj instanceof String) {
|
|
|
|
|
|
|
|
String str = (String) dbzObj;
|
|
|
|
|
|
|
|
// TIMESTAMP_LTZ type is encoded in string type
|
|
|
|
|
|
|
|
Instant instant = Instant.parse(str);
|
|
|
|
|
|
|
|
return TimestampData.fromInstant(instant);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
throw new IllegalArgumentException(
|
|
|
|
|
|
|
|
"Unable to convert to TimestampData from unexpected value '"
|
|
|
|
|
|
|
|
+ dbzObj
|
|
|
|
|
|
|
|
+ "' of type "
|
|
|
|
|
|
|
|
+ dbzObj.getClass().getName());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private static Optional<DeserializationRuntimeConverter> wrapNumericConverter(
|
|
|
|
private static Optional<DeserializationRuntimeConverter> wrapNumericConverter(
|
|
|
|
Optional<DeserializationRuntimeConverter> converterOptional) {
|
|
|
|
Optional<DeserializationRuntimeConverter> converterOptional) {
|
|
|
|
return converterOptional.map(
|
|
|
|
return converterOptional.map(
|
|
|
|