SQL: test coverage for JdbcResultSet (#32813)

* Tests for JdbcResultSet
* Added VARCHAR conversion for different types
* Made error messages consistent: they now contain both the type that fails to be converted and the value itself
This commit is contained in:
Andrei Stefan 2018-08-31 16:12:01 +03:00 committed by GitHub
parent f6a570880c
commit 0c4b3162be
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 1621 additions and 108 deletions

View File

@ -133,72 +133,37 @@ class JdbcResultSet implements ResultSet, JdbcWrapper {
@Override @Override
public boolean getBoolean(int columnIndex) throws SQLException { public boolean getBoolean(int columnIndex) throws SQLException {
Object val = column(columnIndex); return column(columnIndex) != null ? getObject(columnIndex, Boolean.class) : false;
try {
return val != null ? (Boolean) val : false;
} catch (ClassCastException cce) {
throw new SQLException("unable to convert column " + columnIndex + " to a boolean", cce);
}
} }
@Override @Override
public byte getByte(int columnIndex) throws SQLException { public byte getByte(int columnIndex) throws SQLException {
Object val = column(columnIndex); return column(columnIndex) != null ? getObject(columnIndex, Byte.class) : 0;
try {
return val != null ? ((Number) val).byteValue() : 0;
} catch (ClassCastException cce) {
throw new SQLException("unable to convert column " + columnIndex + " to a byte", cce);
}
} }
@Override @Override
public short getShort(int columnIndex) throws SQLException { public short getShort(int columnIndex) throws SQLException {
Object val = column(columnIndex); return column(columnIndex) != null ? getObject(columnIndex, Short.class) : 0;
try {
return val != null ? ((Number) val).shortValue() : 0;
} catch (ClassCastException cce) {
throw new SQLException("unable to convert column " + columnIndex + " to a short", cce);
}
} }
@Override @Override
public int getInt(int columnIndex) throws SQLException { public int getInt(int columnIndex) throws SQLException {
Object val = column(columnIndex); return column(columnIndex) != null ? getObject(columnIndex, Integer.class) : 0;
try {
return val != null ? ((Number) val).intValue() : 0;
} catch (ClassCastException cce) {
throw new SQLException("unable to convert column " + columnIndex + " to an int", cce);
}
} }
@Override @Override
public long getLong(int columnIndex) throws SQLException { public long getLong(int columnIndex) throws SQLException {
Object val = column(columnIndex); return column(columnIndex) != null ? getObject(columnIndex, Long.class) : 0;
try {
return val != null ? ((Number) val).longValue() : 0;
} catch (ClassCastException cce) {
throw new SQLException("unable to convert column " + columnIndex + " to a long", cce);
}
} }
@Override @Override
public float getFloat(int columnIndex) throws SQLException { public float getFloat(int columnIndex) throws SQLException {
Object val = column(columnIndex); return column(columnIndex) != null ? getObject(columnIndex, Float.class) : 0;
try {
return val != null ? ((Number) val).floatValue() : 0;
} catch (ClassCastException cce) {
throw new SQLException("unable to convert column " + columnIndex + " to a float", cce);
}
} }
@Override @Override
public double getDouble(int columnIndex) throws SQLException { public double getDouble(int columnIndex) throws SQLException {
Object val = column(columnIndex); return column(columnIndex) != null ? getObject(columnIndex, Double.class) : 0;
try {
return val != null ? ((Number) val).doubleValue() : 0;
} catch (ClassCastException cce) {
throw new SQLException("unable to convert column " + columnIndex + " to a double", cce);
}
} }
@Override @Override
@ -272,15 +237,29 @@ class JdbcResultSet implements ResultSet, JdbcWrapper {
@Override @Override
public Date getDate(String columnLabel) throws SQLException { public Date getDate(String columnLabel) throws SQLException {
// TODO: the error message in case the value in the column cannot be converted to a Date refers to a column index
// (for example - "unable to convert column 4 to a long") and not to the column name, which is a bit confusing.
// Should we reconsider this? Maybe by catching the exception here and rethrowing it with the columnLabel instead.
return getDate(column(columnLabel)); return getDate(column(columnLabel));
} }
private Long dateTime(int columnIndex) throws SQLException { private Long dateTime(int columnIndex) throws SQLException {
Object val = column(columnIndex); Object val = column(columnIndex);
JDBCType type = cursor.columns().get(columnIndex - 1).type;
try { try {
// TODO: the B6 appendix of the jdbc spec does mention CHAR, VARCHAR, LONGVARCHAR, DATE, TIMESTAMP as supported
// jdbc types that should be handled by getDate and getTime methods. From all of those we support VARCHAR and
// TIMESTAMP. Should we consider the VARCHAR conversion as a later enhancement?
if (JDBCType.TIMESTAMP.equals(type)) {
// the cursor can return an Integer if the date-since-epoch is small enough, XContentParser (Jackson) will
// return the "smallest" data type for numbers when parsing
// TODO: this should probably be handled server side
return val == null ? null : ((Number) val).longValue();
};
return val == null ? null : (Long) val; return val == null ? null : (Long) val;
} catch (ClassCastException cce) { } catch (ClassCastException cce) {
throw new SQLException("unable to convert column " + columnIndex + " to a long", cce); throw new SQLException(
format(Locale.ROOT, "Unable to convert value [%.128s] of type [%s] to a Long", val, type.getName()), cce);
} }
} }

View File

@ -10,7 +10,6 @@ import org.elasticsearch.xpack.sql.type.DataType;
import java.sql.Date; import java.sql.Date;
import java.sql.JDBCType; import java.sql.JDBCType;
import java.sql.SQLDataException;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException; import java.sql.SQLFeatureNotSupportedException;
import java.sql.Time; import java.sql.Time;
@ -56,9 +55,10 @@ final class TypeConverter {
} }
private static final long DAY_IN_MILLIS = 60 * 60 * 24; private static final long DAY_IN_MILLIS = 60 * 60 * 24 * 1000;
private static final Map<Class<?>, JDBCType> javaToJDBC; private static final Map<Class<?>, JDBCType> javaToJDBC;
static { static {
Map<Class<?>, JDBCType> aMap = Arrays.stream(DataType.values()) Map<Class<?>, JDBCType> aMap = Arrays.stream(DataType.values())
.filter(dataType -> dataType.javaClass() != null .filter(dataType -> dataType.javaClass() != null
@ -120,6 +120,7 @@ final class TypeConverter {
} }
} }
static long convertFromCalendarToUTC(long value, Calendar cal) { static long convertFromCalendarToUTC(long value, Calendar cal) {
if (cal == null) { if (cal == null) {
return value; return value;
@ -143,11 +144,15 @@ final class TypeConverter {
return (T) convert(val, columnType); return (T) convert(val, columnType);
} }
if (type.isInstance(val)) { // converting a Long to a Timestamp shouldn't be possible according to the spec,
// it feels a little brittle to check this scenario here and I don't particularly like it
// TODO: can we do any better or should we go over the spec and allow getLong(date) to be valid?
if (!(type == Long.class && columnType == JDBCType.TIMESTAMP) && type.isInstance(val)) {
try { try {
return type.cast(val); return type.cast(val);
} catch (ClassCastException cce) { } catch (ClassCastException cce) {
throw new SQLDataException("Unable to convert " + val.getClass().getName() + " to " + columnType, cce); throw new SQLException(format(Locale.ROOT, "Unable to convert value [%.128s] of type [%s] to a %s", val,
columnType.getName(), type.getName()), cce);
} }
} }
@ -205,7 +210,8 @@ final class TypeConverter {
if (type == OffsetDateTime.class) { if (type == OffsetDateTime.class) {
return (T) asOffsetDateTime(val, columnType); return (T) asOffsetDateTime(val, columnType);
} }
throw new SQLException("Conversion from type [" + columnType + "] to [" + type.getName() + "] not supported"); throw new SQLException(format(Locale.ROOT, "Unable to convert value [%.128s] of type [%s] to a %s", val,
columnType.getName(), type.getName()));
} }
/** /**
@ -336,8 +342,11 @@ final class TypeConverter {
case FLOAT: case FLOAT:
case DOUBLE: case DOUBLE:
return Boolean.valueOf(Integer.signum(((Number) val).intValue()) != 0); return Boolean.valueOf(Integer.signum(((Number) val).intValue()) != 0);
case VARCHAR:
return Boolean.valueOf((String) val);
default: default:
throw new SQLException("Conversion from type [" + columnType + "] to [Boolean] not supported"); throw new SQLException(
format(Locale.ROOT, "Unable to convert value [%.128s] of type [%s] to a Boolean", val, columnType.getName()));
} }
} }
@ -355,10 +364,16 @@ final class TypeConverter {
case FLOAT: case FLOAT:
case DOUBLE: case DOUBLE:
return safeToByte(safeToLong(((Number) val).doubleValue())); return safeToByte(safeToLong(((Number) val).doubleValue()));
case VARCHAR:
try {
return Byte.valueOf((String) val);
} catch (NumberFormatException e) {
throw new SQLException(format(Locale.ROOT, "Unable to convert value [%.128s] of type [VARCHAR] to a Byte", val), e);
}
default: default:
} }
throw new SQLException("Conversion from type [" + columnType + "] to [Byte] not supported"); throw new SQLException(format(Locale.ROOT, "Unable to convert value [%.128s] of type [%s] to a Byte", val, columnType.getName()));
} }
private static Short asShort(Object val, JDBCType columnType) throws SQLException { private static Short asShort(Object val, JDBCType columnType) throws SQLException {
@ -374,10 +389,16 @@ final class TypeConverter {
case FLOAT: case FLOAT:
case DOUBLE: case DOUBLE:
return safeToShort(safeToLong(((Number) val).doubleValue())); return safeToShort(safeToLong(((Number) val).doubleValue()));
case VARCHAR:
try {
return Short.valueOf((String) val);
} catch (NumberFormatException e) {
throw new SQLException(format(Locale.ROOT, "Unable to convert value [%.128s] of type [VARCHAR] to a Short", val), e);
}
default: default:
} }
throw new SQLException("Conversion from type [" + columnType + "] to [Short] not supported"); throw new SQLException(format(Locale.ROOT, "Unable to convert value [%.128s] of type [%s] to a Short", val, columnType.getName()));
} }
private static Integer asInteger(Object val, JDBCType columnType) throws SQLException { private static Integer asInteger(Object val, JDBCType columnType) throws SQLException {
@ -393,10 +414,18 @@ final class TypeConverter {
case FLOAT: case FLOAT:
case DOUBLE: case DOUBLE:
return safeToInt(safeToLong(((Number) val).doubleValue())); return safeToInt(safeToLong(((Number) val).doubleValue()));
case VARCHAR:
try {
return Integer.valueOf((String) val);
} catch (NumberFormatException e) {
throw new SQLException(
format(Locale.ROOT, "Unable to convert value [%.128s] of type [VARCHAR] to an Integer", val), e);
}
default: default:
} }
throw new SQLException("Conversion from type [" + columnType + "] to [Integer] not supported"); throw new SQLException(
format(Locale.ROOT, "Unable to convert value [%.128s] of type [%s] to an Integer", val, columnType.getName()));
} }
private static Long asLong(Object val, JDBCType columnType) throws SQLException { private static Long asLong(Object val, JDBCType columnType) throws SQLException {
@ -412,12 +441,21 @@ final class TypeConverter {
case FLOAT: case FLOAT:
case DOUBLE: case DOUBLE:
return safeToLong(((Number) val).doubleValue()); return safeToLong(((Number) val).doubleValue());
case TIMESTAMP: //TODO: should we support conversion to TIMESTAMP?
return ((Number) val).longValue(); //The spec says that getLong() should support the following types conversions:
//TINYINT, SMALLINT, INTEGER, BIGINT, REAL, FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, BOOLEAN, CHAR, VARCHAR, LONGVARCHAR
//case TIMESTAMP:
// return ((Number) val).longValue();
case VARCHAR:
try {
return Long.valueOf((String) val);
} catch (NumberFormatException e) {
throw new SQLException(format(Locale.ROOT, "Unable to convert value [%.128s] of type [VARCHAR] to a Long", val), e);
}
default: default:
} }
throw new SQLException("Conversion from type [" + columnType + "] to [Long] not supported"); throw new SQLException(format(Locale.ROOT, "Unable to convert value [%.128s] of type [%s] to a Long", val, columnType.getName()));
} }
private static Float asFloat(Object val, JDBCType columnType) throws SQLException { private static Float asFloat(Object val, JDBCType columnType) throws SQLException {
@ -433,10 +471,16 @@ final class TypeConverter {
case FLOAT: case FLOAT:
case DOUBLE: case DOUBLE:
return Float.valueOf((((float) ((Number) val).doubleValue()))); return Float.valueOf((((float) ((Number) val).doubleValue())));
case VARCHAR:
try {
return Float.valueOf((String) val);
} catch (NumberFormatException e) {
throw new SQLException(format(Locale.ROOT, "Unable to convert value [%.128s] of type [VARCHAR] to a Float", val), e);
}
default: default:
} }
throw new SQLException("Conversion from type [" + columnType + "] to [Float] not supported"); throw new SQLException(format(Locale.ROOT, "Unable to convert value [%.128s] of type [%s] to a Float", val, columnType.getName()));
} }
private static Double asDouble(Object val, JDBCType columnType) throws SQLException { private static Double asDouble(Object val, JDBCType columnType) throws SQLException {
@ -451,32 +495,41 @@ final class TypeConverter {
case REAL: case REAL:
case FLOAT: case FLOAT:
case DOUBLE: case DOUBLE:
return Double.valueOf(((Number) val).doubleValue()); return Double.valueOf(((Number) val).doubleValue());
case VARCHAR:
try {
return Double.valueOf((String) val);
} catch (NumberFormatException e) {
throw new SQLException(format(Locale.ROOT, "Unable to convert value [%.128s] of type [VARCHAR] to a Double", val), e);
}
default: default:
} }
throw new SQLException("Conversion from type [" + columnType + "] to [Double] not supported"); throw new SQLException(
format(Locale.ROOT, "Unable to convert value [%.128s] of type [%s] to a Double", val, columnType.getName()));
} }
private static Date asDate(Object val, JDBCType columnType) throws SQLException { private static Date asDate(Object val, JDBCType columnType) throws SQLException {
if (columnType == JDBCType.TIMESTAMP) { if (columnType == JDBCType.TIMESTAMP) {
return new Date(utcMillisRemoveTime(((Number) val).longValue())); return new Date(utcMillisRemoveTime(((Number) val).longValue()));
} }
throw new SQLException("Conversion from type [" + columnType + "] to [Date] not supported"); throw new SQLException(format(Locale.ROOT, "Unable to convert value [%.128s] of type [%s] to a Date", val, columnType.getName()));
} }
private static Time asTime(Object val, JDBCType columnType) throws SQLException { private static Time asTime(Object val, JDBCType columnType) throws SQLException {
if (columnType == JDBCType.TIMESTAMP) { if (columnType == JDBCType.TIMESTAMP) {
return new Time(utcMillisRemoveDate(((Number) val).longValue())); return new Time(utcMillisRemoveDate(((Number) val).longValue()));
} }
throw new SQLException("Conversion from type [" + columnType + "] to [Time] not supported"); throw new SQLException(format(Locale.ROOT, "Unable to convert value [%.128s] of type [%s] to a Time", val, columnType.getName()));
} }
private static Timestamp asTimestamp(Object val, JDBCType columnType) throws SQLException { private static Timestamp asTimestamp(Object val, JDBCType columnType) throws SQLException {
if (columnType == JDBCType.TIMESTAMP) { if (columnType == JDBCType.TIMESTAMP) {
return new Timestamp(((Number) val).longValue()); return new Timestamp(((Number) val).longValue());
} }
throw new SQLException("Conversion from type [" + columnType + "] to [Timestamp] not supported"); throw new SQLException(
format(Locale.ROOT, "Unable to convert value [%.128s] of type [%s] to a Timestamp", val, columnType.getName()));
} }
private static byte[] asByteArray(Object val, JDBCType columnType) { private static byte[] asByteArray(Object val, JDBCType columnType) {

View File

@ -25,6 +25,7 @@ import java.util.Date;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import static java.lang.String.format;
import static java.sql.JDBCType.BIGINT; import static java.sql.JDBCType.BIGINT;
import static java.sql.JDBCType.BOOLEAN; import static java.sql.JDBCType.BOOLEAN;
import static java.sql.JDBCType.DOUBLE; import static java.sql.JDBCType.DOUBLE;
@ -68,7 +69,7 @@ public class JdbcPreparedStatementTests extends ESTestCase {
JdbcPreparedStatement jps = createJdbcPreparedStatement(); JdbcPreparedStatement jps = createJdbcPreparedStatement();
SQLException sqle = expectThrows(SQLException.class, () -> jps.setObject(1, true, Types.TIMESTAMP)); SQLException sqle = expectThrows(SQLException.class, () -> jps.setObject(1, true, Types.TIMESTAMP));
assertEquals("Conversion from type [BOOLEAN] to [Timestamp] not supported", sqle.getMessage()); assertEquals("Unable to convert value [true] of type [BOOLEAN] to a Timestamp", sqle.getMessage());
} }
public void testSettingStringValues() throws SQLException { public void testSettingStringValues() throws SQLException {
@ -92,7 +93,7 @@ public class JdbcPreparedStatementTests extends ESTestCase {
JdbcPreparedStatement jps = createJdbcPreparedStatement(); JdbcPreparedStatement jps = createJdbcPreparedStatement();
SQLException sqle = expectThrows(SQLException.class, () -> jps.setObject(1, "foo bar", Types.INTEGER)); SQLException sqle = expectThrows(SQLException.class, () -> jps.setObject(1, "foo bar", Types.INTEGER));
assertEquals("Conversion from type [VARCHAR] to [Integer] not supported", sqle.getMessage()); assertEquals("Unable to convert value [foo bar] of type [VARCHAR] to an Integer", sqle.getMessage());
} }
public void testSettingByteTypeValues() throws SQLException { public void testSettingByteTypeValues() throws SQLException {
@ -128,7 +129,7 @@ public class JdbcPreparedStatementTests extends ESTestCase {
JdbcPreparedStatement jps = createJdbcPreparedStatement(); JdbcPreparedStatement jps = createJdbcPreparedStatement();
SQLException sqle = expectThrows(SQLException.class, () -> jps.setObject(1, (byte) 6, Types.TIMESTAMP)); SQLException sqle = expectThrows(SQLException.class, () -> jps.setObject(1, (byte) 6, Types.TIMESTAMP));
assertEquals("Conversion from type [TINYINT] to [Timestamp] not supported", sqle.getMessage()); assertEquals("Unable to convert value [6] of type [TINYINT] to a Timestamp", sqle.getMessage());
} }
public void testSettingShortTypeValues() throws SQLException { public void testSettingShortTypeValues() throws SQLException {
@ -161,7 +162,7 @@ public class JdbcPreparedStatementTests extends ESTestCase {
JdbcPreparedStatement jps = createJdbcPreparedStatement(); JdbcPreparedStatement jps = createJdbcPreparedStatement();
SQLException sqle = expectThrows(SQLException.class, () -> jps.setObject(1, (short) 6, Types.TIMESTAMP)); SQLException sqle = expectThrows(SQLException.class, () -> jps.setObject(1, (short) 6, Types.TIMESTAMP));
assertEquals("Conversion from type [SMALLINT] to [Timestamp] not supported", sqle.getMessage()); assertEquals("Unable to convert value [6] of type [SMALLINT] to a Timestamp", sqle.getMessage());
sqle = expectThrows(SQLException.class, () -> jps.setObject(1, 256, Types.TINYINT)); sqle = expectThrows(SQLException.class, () -> jps.setObject(1, 256, Types.TINYINT));
assertEquals("Numeric " + 256 + " out of range", sqle.getMessage()); assertEquals("Numeric " + 256 + " out of range", sqle.getMessage());
@ -195,7 +196,7 @@ public class JdbcPreparedStatementTests extends ESTestCase {
int someInt = randomInt(); int someInt = randomInt();
SQLException sqle = expectThrows(SQLException.class, () -> jps.setObject(1, someInt, Types.TIMESTAMP)); SQLException sqle = expectThrows(SQLException.class, () -> jps.setObject(1, someInt, Types.TIMESTAMP));
assertEquals("Conversion from type [INTEGER] to [Timestamp] not supported", sqle.getMessage()); assertEquals(format(Locale.ROOT, "Unable to convert value [%.128s] of type [INTEGER] to a Timestamp", someInt), sqle.getMessage());
Integer randomIntNotShort = randomIntBetween(32768, Integer.MAX_VALUE); Integer randomIntNotShort = randomIntBetween(32768, Integer.MAX_VALUE);
sqle = expectThrows(SQLException.class, () -> jps.setObject(1, randomIntNotShort, Types.SMALLINT)); sqle = expectThrows(SQLException.class, () -> jps.setObject(1, randomIntNotShort, Types.SMALLINT));
@ -236,7 +237,7 @@ public class JdbcPreparedStatementTests extends ESTestCase {
long someLong = randomLong(); long someLong = randomLong();
SQLException sqle = expectThrows(SQLException.class, () -> jps.setObject(1, someLong, Types.TIMESTAMP)); SQLException sqle = expectThrows(SQLException.class, () -> jps.setObject(1, someLong, Types.TIMESTAMP));
assertEquals("Conversion from type [BIGINT] to [Timestamp] not supported", sqle.getMessage()); assertEquals(format(Locale.ROOT, "Unable to convert value [%.128s] of type [BIGINT] to a Timestamp", someLong), sqle.getMessage());
Long randomLongNotShort = randomLongBetween(Integer.MAX_VALUE + 1, Long.MAX_VALUE); Long randomLongNotShort = randomLongBetween(Integer.MAX_VALUE + 1, Long.MAX_VALUE);
sqle = expectThrows(SQLException.class, () -> jps.setObject(1, randomLongNotShort, Types.INTEGER)); sqle = expectThrows(SQLException.class, () -> jps.setObject(1, randomLongNotShort, Types.INTEGER));
@ -277,7 +278,7 @@ public class JdbcPreparedStatementTests extends ESTestCase {
float someFloat = randomFloat(); float someFloat = randomFloat();
SQLException sqle = expectThrows(SQLException.class, () -> jps.setObject(1, someFloat, Types.TIMESTAMP)); SQLException sqle = expectThrows(SQLException.class, () -> jps.setObject(1, someFloat, Types.TIMESTAMP));
assertEquals("Conversion from type [REAL] to [Timestamp] not supported", sqle.getMessage()); assertEquals(format(Locale.ROOT, "Unable to convert value [%.128s] of type [REAL] to a Timestamp", someFloat), sqle.getMessage());
Float floatNotInt = 5_155_000_000f; Float floatNotInt = 5_155_000_000f;
sqle = expectThrows(SQLException.class, () -> jps.setObject(1, floatNotInt, Types.INTEGER)); sqle = expectThrows(SQLException.class, () -> jps.setObject(1, floatNotInt, Types.INTEGER));
@ -316,7 +317,8 @@ public class JdbcPreparedStatementTests extends ESTestCase {
double someDouble = randomDouble(); double someDouble = randomDouble();
SQLException sqle = expectThrows(SQLException.class, () -> jps.setObject(1, someDouble, Types.TIMESTAMP)); SQLException sqle = expectThrows(SQLException.class, () -> jps.setObject(1, someDouble, Types.TIMESTAMP));
assertEquals("Conversion from type [DOUBLE] to [Timestamp] not supported", sqle.getMessage()); assertEquals(
format(Locale.ROOT, "Unable to convert value [%.128s] of type [DOUBLE] to a Timestamp", someDouble), sqle.getMessage());
Double doubleNotInt = 5_155_000_000d; Double doubleNotInt = 5_155_000_000d;
sqle = expectThrows(SQLException.class, () -> jps.setObject(1, doubleNotInt, Types.INTEGER)); sqle = expectThrows(SQLException.class, () -> jps.setObject(1, doubleNotInt, Types.INTEGER));
@ -361,7 +363,7 @@ public class JdbcPreparedStatementTests extends ESTestCase {
public void testSettingTimestampValues() throws SQLException { public void testSettingTimestampValues() throws SQLException {
JdbcPreparedStatement jps = createJdbcPreparedStatement(); JdbcPreparedStatement jps = createJdbcPreparedStatement();
Timestamp someTimestamp = new Timestamp(randomMillisSinceEpoch()); Timestamp someTimestamp = new Timestamp(randomLong());
jps.setTimestamp(1, someTimestamp); jps.setTimestamp(1, someTimestamp);
assertEquals(someTimestamp.getTime(), ((Date)value(jps)).getTime()); assertEquals(someTimestamp.getTime(), ((Date)value(jps)).getTime());
assertEquals(TIMESTAMP, jdbcType(jps)); assertEquals(TIMESTAMP, jdbcType(jps));
@ -372,7 +374,7 @@ public class JdbcPreparedStatementTests extends ESTestCase {
assertEquals(1456708675000L, convertFromUTCtoCalendar(((Date)value(jps)), nonDefaultCal)); assertEquals(1456708675000L, convertFromUTCtoCalendar(((Date)value(jps)), nonDefaultCal));
assertEquals(TIMESTAMP, jdbcType(jps)); assertEquals(TIMESTAMP, jdbcType(jps));
long beforeEpochTime = -randomMillisSinceEpoch(); long beforeEpochTime = randomLongBetween(Long.MIN_VALUE, 0);
jps.setTimestamp(1, new Timestamp(beforeEpochTime), nonDefaultCal); jps.setTimestamp(1, new Timestamp(beforeEpochTime), nonDefaultCal);
assertEquals(beforeEpochTime, convertFromUTCtoCalendar(((Date)value(jps)), nonDefaultCal)); assertEquals(beforeEpochTime, convertFromUTCtoCalendar(((Date)value(jps)), nonDefaultCal));
assertTrue(value(jps) instanceof java.util.Date); assertTrue(value(jps) instanceof java.util.Date);
@ -384,7 +386,7 @@ public class JdbcPreparedStatementTests extends ESTestCase {
public void testThrownExceptionsWhenSettingTimestampValues() throws SQLException { public void testThrownExceptionsWhenSettingTimestampValues() throws SQLException {
JdbcPreparedStatement jps = createJdbcPreparedStatement(); JdbcPreparedStatement jps = createJdbcPreparedStatement();
Timestamp someTimestamp = new Timestamp(randomMillisSinceEpoch()); Timestamp someTimestamp = new Timestamp(randomLong());
SQLException sqle = expectThrows(SQLFeatureNotSupportedException.class, () -> jps.setObject(1, someTimestamp, Types.INTEGER)); SQLException sqle = expectThrows(SQLFeatureNotSupportedException.class, () -> jps.setObject(1, someTimestamp, Types.INTEGER));
assertEquals("Conversion from type java.sql.Timestamp to INTEGER not supported", sqle.getMessage()); assertEquals("Conversion from type java.sql.Timestamp to INTEGER not supported", sqle.getMessage());
@ -416,12 +418,12 @@ public class JdbcPreparedStatementTests extends ESTestCase {
public void testSettingSqlDateValues() throws SQLException { public void testSettingSqlDateValues() throws SQLException {
JdbcPreparedStatement jps = createJdbcPreparedStatement(); JdbcPreparedStatement jps = createJdbcPreparedStatement();
java.sql.Date someSqlDate = new java.sql.Date(randomMillisSinceEpoch()); java.sql.Date someSqlDate = new java.sql.Date(randomLong());
jps.setDate(1, someSqlDate); jps.setDate(1, someSqlDate);
assertEquals(someSqlDate.getTime(), ((Date)value(jps)).getTime()); assertEquals(someSqlDate.getTime(), ((Date)value(jps)).getTime());
assertEquals(TIMESTAMP, jdbcType(jps)); assertEquals(TIMESTAMP, jdbcType(jps));
someSqlDate = new java.sql.Date(randomMillisSinceEpoch()); someSqlDate = new java.sql.Date(randomLong());
Calendar nonDefaultCal = randomCalendar(); Calendar nonDefaultCal = randomCalendar();
jps.setDate(1, someSqlDate, nonDefaultCal); jps.setDate(1, someSqlDate, nonDefaultCal);
assertEquals(someSqlDate.getTime(), convertFromUTCtoCalendar(((Date)value(jps)), nonDefaultCal)); assertEquals(someSqlDate.getTime(), convertFromUTCtoCalendar(((Date)value(jps)), nonDefaultCal));
@ -435,17 +437,17 @@ public class JdbcPreparedStatementTests extends ESTestCase {
public void testThrownExceptionsWhenSettingSqlDateValues() throws SQLException { public void testThrownExceptionsWhenSettingSqlDateValues() throws SQLException {
JdbcPreparedStatement jps = createJdbcPreparedStatement(); JdbcPreparedStatement jps = createJdbcPreparedStatement();
java.sql.Date someSqlDate = new java.sql.Date(randomMillisSinceEpoch()); java.sql.Date someSqlDate = new java.sql.Date(randomLong());
SQLException sqle = expectThrows(SQLFeatureNotSupportedException.class, SQLException sqle = expectThrows(SQLFeatureNotSupportedException.class,
() -> jps.setObject(1, new java.sql.Date(randomMillisSinceEpoch()), Types.DOUBLE)); () -> jps.setObject(1, new java.sql.Date(randomLong()), Types.DOUBLE));
assertEquals("Conversion from type " + someSqlDate.getClass().getName() + " to DOUBLE not supported", sqle.getMessage()); assertEquals("Conversion from type " + someSqlDate.getClass().getName() + " to DOUBLE not supported", sqle.getMessage());
} }
public void testSettingCalendarValues() throws SQLException { public void testSettingCalendarValues() throws SQLException {
JdbcPreparedStatement jps = createJdbcPreparedStatement(); JdbcPreparedStatement jps = createJdbcPreparedStatement();
Calendar someCalendar = randomCalendar(); Calendar someCalendar = randomCalendar();
someCalendar.setTimeInMillis(randomMillisSinceEpoch()); someCalendar.setTimeInMillis(randomLong());
jps.setObject(1, someCalendar); jps.setObject(1, someCalendar);
assertEquals(someCalendar.getTime(), (Date) value(jps)); assertEquals(someCalendar.getTime(), (Date) value(jps));
@ -472,7 +474,7 @@ public class JdbcPreparedStatementTests extends ESTestCase {
public void testSettingDateValues() throws SQLException { public void testSettingDateValues() throws SQLException {
JdbcPreparedStatement jps = createJdbcPreparedStatement(); JdbcPreparedStatement jps = createJdbcPreparedStatement();
Date someDate = new Date(randomMillisSinceEpoch()); Date someDate = new Date(randomLong());
jps.setObject(1, someDate); jps.setObject(1, someDate);
assertEquals(someDate, (Date) value(jps)); assertEquals(someDate, (Date) value(jps));
@ -486,7 +488,7 @@ public class JdbcPreparedStatementTests extends ESTestCase {
public void testThrownExceptionsWhenSettingDateValues() throws SQLException { public void testThrownExceptionsWhenSettingDateValues() throws SQLException {
JdbcPreparedStatement jps = createJdbcPreparedStatement(); JdbcPreparedStatement jps = createJdbcPreparedStatement();
Date someDate = new Date(randomMillisSinceEpoch()); Date someDate = new Date(randomLong());
SQLException sqle = expectThrows(SQLFeatureNotSupportedException.class, () -> jps.setObject(1, someDate, Types.BIGINT)); SQLException sqle = expectThrows(SQLFeatureNotSupportedException.class, () -> jps.setObject(1, someDate, Types.BIGINT));
assertEquals("Conversion from type " + someDate.getClass().getName() + " to BIGINT not supported", sqle.getMessage()); assertEquals("Conversion from type " + someDate.getClass().getName() + " to BIGINT not supported", sqle.getMessage());
@ -549,10 +551,6 @@ public class JdbcPreparedStatementTests extends ESTestCase {
assertEquals("Conversion from type byte[] to DOUBLE not supported", sqle.getMessage()); assertEquals("Conversion from type byte[] to DOUBLE not supported", sqle.getMessage());
} }
private long randomMillisSinceEpoch() {
return randomLongBetween(0, System.currentTimeMillis());
}
private JdbcPreparedStatement createJdbcPreparedStatement() throws SQLException { private JdbcPreparedStatement createJdbcPreparedStatement() throws SQLException {
return new JdbcPreparedStatement(null, JdbcConfiguration.create("jdbc:es://l:1", null, 0), "?"); return new JdbcPreparedStatement(null, JdbcConfiguration.create("jdbc:es://l:1", null, 0), "?");
} }

View File

@ -0,0 +1,16 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.xpack.qa.sql.nosecurity;
import org.elasticsearch.xpack.qa.sql.jdbc.ResultSetTestCase;
/*
* Integration testing class for "no security" (cluster running without the Security plugin,
* or the Security is disbled) scenario. Runs all tests in the base class.
*/
public class JdbcResultSetIT extends ResultSetTestCase {
}

View File

@ -25,7 +25,8 @@ public class SimpleExampleTestCase extends JdbcIntegrationTestCase {
assertEquals("Don Quixote", results.getString(1)); assertEquals("Don Quixote", results.getString(1));
assertEquals(1072, results.getInt(2)); assertEquals(1072, results.getInt(2));
SQLException e = expectThrows(SQLException.class, () -> results.getInt(1)); SQLException e = expectThrows(SQLException.class, () -> results.getInt(1));
assertTrue(e.getMessage(), e.getMessage().contains("unable to convert column 1 to an int")); assertTrue(e.getMessage(),
e.getMessage().contains("Unable to convert value [Don Quixote] of type [VARCHAR] to an Integer"));
assertFalse(results.next()); assertFalse(results.next());
} }
// end::simple_example // end::simple_example