in core/src/main/java/org/apache/hop/core/row/value/ValueMetaBase.java [5599:5832]
public IValueMeta getMetadataPreview(
IVariables variables, DatabaseMeta databaseMeta, ResultSet rs) throws HopDatabaseException {
try {
// Get some info out of the resultset
final String name = rs.getString("COLUMN_NAME");
int originalColumnType = rs.getInt("DATA_TYPE");
Object dg = rs.getObject("DECIMAL_DIGITS");
int originalScale = dg == null ? 0 : rs.getInt("DECIMAL_DIGITS");
int originalPrecision = rs.getInt("COLUMN_SIZE");
int originalColumnDisplaySize = originalPrecision;
String originalColumnTypeName = rs.getString("TYPE_NAME");
String originalColumnLabel = rs.getString("REMARKS");
int length = -1;
int precision = -1;
int valtype = IValueMeta.TYPE_NONE;
boolean isClob = false;
switch (originalColumnType) {
case Types.CHAR, Types.VARCHAR, Types.NVARCHAR, Types.LONGVARCHAR:
// Character Large Object
valtype = IValueMeta.TYPE_STRING;
length = originalColumnDisplaySize;
break;
case Types.CLOB, Types.NCLOB:
valtype = IValueMeta.TYPE_STRING;
length = DatabaseMeta.CLOB_LENGTH;
isClob = true;
break;
case Types.BIGINT:
// SQL BigInt is equivalent to a Java Long
// And a Java Long is equivalent to an Apache Hop Integer.
valtype = IValueMeta.TYPE_INTEGER;
precision = 0; // Max 9.223.372.036.854.775.807
length = 15;
break;
case Types.INTEGER:
valtype = IValueMeta.TYPE_INTEGER;
precision = 0; // Max 2.147.483.647
length = 9;
break;
case Types.SMALLINT:
valtype = IValueMeta.TYPE_INTEGER;
precision = 0; // Max 32.767
length = 4;
break;
case Types.TINYINT:
valtype = IValueMeta.TYPE_INTEGER;
precision = 0; // Max 127
length = 2;
break;
case Types.DECIMAL, Types.DOUBLE, Types.FLOAT, Types.REAL, Types.NUMERIC:
valtype = IValueMeta.TYPE_NUMBER;
length = originalPrecision;
precision = originalScale;
if (length >= 126) {
length = -1;
}
if (precision >= 126) {
precision = -1;
}
if (originalColumnType == Types.DOUBLE
|| originalColumnType == Types.FLOAT
|| originalColumnType == Types.REAL) {
if (precision == 0) {
precision = -1; // precision is obviously incorrect if the type if
// Double/Float/Real
}
// If we're dealing with PostgreSQL and double precision types
if (databaseMeta.getIDatabase().isPostgresVariant()
&& originalColumnType == Types.DOUBLE
&& precision >= 16
&& length >= 16) {
precision = -1;
length = -1;
}
// MySQL: max resolution is double precision floating point (double)
// The (12,31) that is given back is not correct
if (databaseMeta.isMySqlVariant()) {
if (precision >= length) {
precision = -1;
length = -1;
// MySQL: Double value is giving length of 22,
// that exceeds the maximum length.
} else if (originalColumnType == Types.DOUBLE && length > 15) {
length = -1;
}
}
// if the length or precision needs a BIGNUMBER
if (length > 15 || precision > 15) {
valtype = IValueMeta.TYPE_BIGNUMBER;
}
} else {
if (precision == 0) {
if (length <= 18 && length > 0) { // Among others Oracle is affected
// here.
valtype = IValueMeta.TYPE_INTEGER; // Long can hold up to 18
// significant digits
} else if (length > 18) {
valtype = IValueMeta.TYPE_BIGNUMBER;
}
} else { // we have a precision: keep NUMBER or change to BIGNUMBER?
if (length > 15 || precision > 15) {
valtype = IValueMeta.TYPE_BIGNUMBER;
}
}
}
if (databaseMeta.getIDatabase().isPostgresVariant()
&& originalColumnType == Types.NUMERIC
&& length == 0
&& precision == 0) {
// undefined size => arbitrary precision
valtype = IValueMeta.TYPE_BIGNUMBER;
length = -1;
precision = -1;
}
if (databaseMeta.getIDatabase().isOracleVariant()) {
if (precision == 0 && length == 38) {
valtype =
databaseMeta.getIDatabase().isStrictBigNumberInterpretation()
? TYPE_BIGNUMBER
: TYPE_INTEGER;
}
if (precision <= 0 && length <= 0) {
// undefined size: BIGNUMBER,
// precision on Oracle can be 38, too
// big for a Number type
valtype = IValueMeta.TYPE_BIGNUMBER;
length = -1;
precision = -1;
}
}
break;
case Types.TIMESTAMP:
if (databaseMeta.supportsTimestampDataType()) {
valtype = IValueMeta.TYPE_TIMESTAMP;
length = originalScale;
}
break;
case Types.DATE:
if (databaseMeta.getIDatabase().isTeradataVariant()) {
precision = 1;
}
case Types.TIME:
valtype = IValueMeta.TYPE_DATE;
//
if (databaseMeta.isMySqlVariant()) {
String property =
databaseMeta.getConnectionProperties(variables).getProperty("yearIsDateType");
if (property != null
&& property.equalsIgnoreCase(CONST_FALSE)
&& "YEAR".equalsIgnoreCase(originalColumnTypeName)) {
valtype = IValueMeta.TYPE_INTEGER;
precision = 0;
length = 4;
break;
}
}
break;
case Types.BOOLEAN, Types.BIT:
valtype = IValueMeta.TYPE_BOOLEAN;
break;
case Types.BINARY, Types.BLOB, Types.VARBINARY, Types.LONGVARBINARY:
valtype = IValueMeta.TYPE_BINARY;
IDatabase db = databaseMeta.getIDatabase();
boolean isOracle = db.isOracleVariant();
if (databaseMeta.isDisplaySizeTwiceThePrecision()
&& (2 * originalPrecision) == originalColumnDisplaySize) {
// set the length for "CHAR(X) FOR BIT DATA"
length = originalPrecision;
} else if ((databaseMeta.getIDatabase().isOracleVariant())
&& (originalColumnType == Types.VARBINARY
|| originalColumnType == Types.LONGVARBINARY)) {
// set the length for Oracle "RAW" or "LONGRAW" data types
valtype = IValueMeta.TYPE_STRING;
length = originalColumnDisplaySize;
} else if (databaseMeta.isMySqlVariant()
&& (originalColumnType == Types.VARBINARY
|| originalColumnType == Types.LONGVARBINARY)) {
// don't call 'length = rm.getColumnDisplaySize(index);'
length = -1; // keep the length to -1, e.g. for string functions (e.g.
// CONCAT)
} else if (databaseMeta.getIDatabase().isSqliteVariant()) {
valtype = IValueMeta.TYPE_STRING;
} else {
length = -1;
}
precision = -1;
break;
default:
valtype = IValueMeta.TYPE_STRING;
precision = originalScale;
break;
}
IValueMeta v = ValueMetaFactory.createValueMeta(name, valtype);
v.setLength(length);
v.setPrecision(precision);
v.setLargeTextField(isClob);
// Grab the comment as a description to the field as well.
v.setComments(originalColumnLabel);
v.setOriginalColumnType(originalColumnType);
v.setOriginalColumnTypeName(originalColumnTypeName);
v.setOriginalPrecision(originalPrecision);
v.setOriginalScale(originalScale);
v.setOriginalSigned(originalSigned);
return v;
} catch (Exception e) {
throw new HopDatabaseException(
"Error determining value metadata from SQL resultset metadata", e);
}
}