Skip to content

Commit ffca662

Browse files
committed
Added Warning logs when detecting precision less Oracle numbers.
1 parent 198895d commit ffca662

File tree

2 files changed

+32
-1
lines changed

2 files changed

+32
-1
lines changed

oracle-plugin/src/main/java/io/cdap/plugin/oracle/OracleSourceDBRecord.java

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
import io.cdap.plugin.db.ColumnType;
2525
import io.cdap.plugin.db.DBRecord;
2626
import io.cdap.plugin.db.SchemaReader;
27+
import org.slf4j.Logger;
28+
import org.slf4j.LoggerFactory;
2729

2830
import java.io.IOException;
2931
import java.io.InputStream;
@@ -48,6 +50,8 @@
4850
*/
4951
public class OracleSourceDBRecord extends DBRecord {
5052

53+
private static final Logger LOG = LoggerFactory.getLogger(OracleSourceDBRecord.class);
54+
5155
public OracleSourceDBRecord(StructuredRecord record, List<ColumnType> columnTypes) {
5256
this.record = record;
5357
this.columnTypes = columnTypes;
@@ -214,16 +218,31 @@ private void handleOracleSpecificType(ResultSet resultSet, StructuredRecord.Buil
214218
if (Double.class.getTypeName().equals(resultSet.getMetaData().getColumnClassName(columnIndex))) {
215219
recordBuilder.set(field.getName(), resultSet.getDouble(columnIndex));
216220
} else {
221+
int scaleInSchema = getScale(field.getSchema());
222+
if (precision == 0 && scaleInSchema == 0) {
223+
BigDecimal value = BigDecimal.valueOf(resultSet.getDouble(columnIndex));
224+
if (value != null && !containsIntegerValue(value)) {
225+
LOG.warn(String.format("Precision loss detected in the field '%s'. "
226+
+ "Scale in the data='%s' scale present in the schema='%s'.",
227+
field.getName(),
228+
value.scale(),
229+
scaleInSchema));
230+
}
231+
}
217232
// It's required to pass 'scale' parameter since in the case of Oracle, scale of 'BigDecimal' depends on the
218233
// scale set in the logical schema. For example for value '77.12' if the scale set in the logical schema is
219234
// set to 4 then the number will change to '77.1200'. Also if the value is '22.1274' and the logical schema
220235
// scale is set to 2 then the decimal value used will be '22.13' after rounding.
221-
BigDecimal decimal = resultSet.getBigDecimal(columnIndex, getScale(field.getSchema()));
236+
BigDecimal decimal = resultSet.getBigDecimal(columnIndex, scaleInSchema);
222237
recordBuilder.setDecimal(field.getName(), decimal);
223238
}
224239
}
225240
}
226241

242+
private boolean containsIntegerValue(BigDecimal value) {
243+
return value.remainder(BigDecimal.ONE).compareTo(BigDecimal.ZERO) == 0;
244+
}
245+
227246
/**
228247
* Get the scale set in Non-nullable schema associated with the schema
229248
* */

oracle-plugin/src/main/java/io/cdap/plugin/oracle/OracleSourceSchemaReader.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
import com.google.common.collect.ImmutableSet;
2020
import io.cdap.cdap.api.data.schema.Schema;
2121
import io.cdap.plugin.db.CommonSchemaReader;
22+
import org.slf4j.Logger;
23+
import org.slf4j.LoggerFactory;
2224

2325
import java.sql.ResultSetMetaData;
2426
import java.sql.SQLException;
@@ -42,6 +44,11 @@ public class OracleSourceSchemaReader extends CommonSchemaReader {
4244
public static final int LONG = -1;
4345
public static final int LONG_RAW = -4;
4446

47+
/**
48+
* Logger instance for Oracle Schema reader.
49+
*/
50+
private static final Logger LOG = LoggerFactory.getLogger(OracleSourceSchemaReader.class);
51+
4552
public static final Set<Integer> ORACLE_TYPES = ImmutableSet.of(
4653
INTERVAL_DS,
4754
INTERVAL_YM,
@@ -100,6 +107,11 @@ public Schema getSchema(ResultSetMetaData metadata, int index) throws SQLExcepti
100107
// reference : https://docs.oracle.com/cd/B28359_01/server.111/b28318/datatype.htm#CNCPT1832
101108
precision = 38;
102109
scale = 0;
110+
LOG.warn(String.format("%s type with undefined precision and scale is detected, "
111+
+ "there may be a precision loss while running the pipeline. "
112+
+ "Please define an output precision and scale for field '%s' to avoid precision loss.",
113+
metadata.getColumnTypeName(index),
114+
metadata.getColumnName(index)));
103115
}
104116
return Schema.decimalOf(precision, scale);
105117
}

0 commit comments

Comments
 (0)