You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by vo...@apache.org on 2018/09/26 09:38:36 UTC
[9/9] ignite git commit: IGNITE-9629: JDBC: improved type conversions
for thick driver. This closes #4761.
IGNITE-9629: JDBC: improved type conversions for thick driver. This closes #4761.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/b023375c
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/b023375c
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/b023375c
Branch: refs/heads/ignite-2.7
Commit: b023375c12a81a3ed17825ac61c8c967124b26d6
Parents: 20f5246
Author: tledkov-gridgain <tl...@gridgain.com>
Authored: Wed Sep 26 11:17:50 2018 +0300
Committer: devozerov <vo...@gridgain.com>
Committed: Wed Sep 26 12:38:07 2018 +0300
----------------------------------------------------------------------
.../internal/jdbc2/JdbcResultSetSelfTest.java | 272 ++++++++++-
.../ignite/jdbc/JdbcErrorsAbstractSelfTest.java | 4 +-
.../jdbc/thin/JdbcThinResultSetSelfTest.java | 45 +-
.../ignite/internal/jdbc2/JdbcResultSet.java | 487 +++++++++++++++----
4 files changed, 682 insertions(+), 126 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/b023375c/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcResultSetSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcResultSetSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcResultSetSelfTest.java
index 9e60c25..bd73bcd 100644
--- a/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcResultSetSelfTest.java
+++ b/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcResultSetSelfTest.java
@@ -151,7 +151,7 @@ public class JdbcResultSetSelfTest extends GridCommonAbstractTest {
o.floatVal = 1.0f;
o.doubleVal = 1.0d;
o.bigVal = new BigDecimal(1);
- o.strVal = "str";
+ o.strVal = "1";
o.arrVal = new byte[] {1};
o.dateVal = new Date(1, 1, 1);
o.timeVal = new Time(1, 1, 1);
@@ -173,12 +173,72 @@ public class JdbcResultSetSelfTest extends GridCommonAbstractTest {
if (cnt == 0) {
assert rs.getBoolean("boolVal");
assert rs.getBoolean(2);
+ assert rs.getByte(2) == 1;
+ assert rs.getInt(2) == 1;
+ assert rs.getShort(2) == 1;
+ assert rs.getLong(2) == 1;
+ assert rs.getDouble(2) == 1.0;
+ assert rs.getFloat(2) == 1.0f;
+ assert rs.getBigDecimal(2).equals(new BigDecimal(1));
+ assert rs.getString(2).equals("true");
+
+ assert rs.getObject(2, Boolean.class);
+ assert rs.getObject(2, Byte.class) == 1;
+ assert rs.getObject(2, Short.class) == 1;
+ assert rs.getObject(2, Integer.class) == 1;
+ assert rs.getObject(2, Long.class) == 1;
+ assert rs.getObject(2, Float.class) == 1.f;
+ assert rs.getObject(2, Double.class) == 1;
+ assert rs.getObject(2, BigDecimal.class).equals(new BigDecimal(1));
+ assert rs.getObject(2, String.class).equals("true");
}
cnt++;
}
assert cnt == 1;
+
+ ResultSet rs0 = stmt.executeQuery("select 1");
+
+ assert rs0.next();
+ assert rs0.getBoolean(1);
+
+ rs0 = stmt.executeQuery("select 0");
+
+ assert rs0.next();
+ assert !rs0.getBoolean(1);
+
+ rs0 = stmt.executeQuery("select '1'");
+
+ assert rs0.next();
+ assert rs0.getBoolean(1);
+
+ rs0 = stmt.executeQuery("select '0'");
+
+ assert rs0.next();
+ assert !rs0.getBoolean(1);
+
+ GridTestUtils.assertThrowsAnyCause(log, new Callable<Void>() {
+ @Override public Void call() throws Exception {
+ ResultSet rs0 = stmt.executeQuery("select ''");
+
+ assert rs0.next();
+ assert rs0.getBoolean(1);
+
+ return null;
+ }
+ }, SQLException.class, "Cannot convert to boolean: ");
+
+ GridTestUtils.assertThrowsAnyCause(log, new Callable<Void>() {
+ @Override public Void call() throws Exception {
+ ResultSet rs0 = stmt.executeQuery("select 'qwe'");
+
+ assert rs0.next();
+ assert rs0.getBoolean(1);
+
+ return null;
+ }
+ }, SQLException.class, "Cannot convert to boolean: qwe");
}
/**
@@ -253,6 +313,26 @@ public class JdbcResultSetSelfTest extends GridCommonAbstractTest {
if (cnt == 0) {
assert rs.getByte("byteVal") == 1;
assert rs.getByte(3) == 1;
+
+ assert rs.getBoolean(3);
+ assert rs.getByte(3) == 1;
+ assert rs.getInt(3) == 1;
+ assert rs.getShort(3) == 1;
+ assert rs.getLong(3) == 1;
+ assert rs.getDouble(3) == 1.0;
+ assert rs.getFloat(3) == 1.0f;
+ assert rs.getBigDecimal(3).equals(new BigDecimal(1));
+ assert rs.getString(3).equals("1");
+
+ assert rs.getObject(3, Boolean.class);
+ assert rs.getObject(3, Byte.class) == 1;
+ assert rs.getObject(3, Short.class) == 1;
+ assert rs.getObject(3, Integer.class) == 1;
+ assert rs.getObject(3, Long.class) == 1;
+ assert rs.getObject(3, Float.class) == 1.f;
+ assert rs.getObject(3, Double.class) == 1;
+ assert rs.getObject(3, BigDecimal.class).equals(new BigDecimal(1));
+ assert rs.getObject(3, String.class).equals("1");
}
cnt++;
@@ -273,6 +353,26 @@ public class JdbcResultSetSelfTest extends GridCommonAbstractTest {
if (cnt == 0) {
assert rs.getShort("shortVal") == 1;
assert rs.getShort(4) == 1;
+
+ assert rs.getBoolean(4);
+ assert rs.getByte(4) == 1;
+ assert rs.getShort(4) == 1;
+ assert rs.getInt(4) == 1;
+ assert rs.getLong(4) == 1;
+ assert rs.getDouble(4) == 1.0;
+ assert rs.getFloat(4) == 1.0f;
+ assert rs.getBigDecimal(4).equals(new BigDecimal(1));
+ assert rs.getString(4).equals("1");
+
+ assert rs.getObject(4, Boolean.class);
+ assert rs.getObject(4, Byte.class) == 1;
+ assert rs.getObject(4, Short.class) == 1;
+ assert rs.getObject(4, Integer.class) == 1;
+ assert rs.getObject(4, Long.class) == 1;
+ assert rs.getObject(4, Float.class) == 1.f;
+ assert rs.getObject(4, Double.class) == 1;
+ assert rs.getObject(4, BigDecimal.class).equals(new BigDecimal(1));
+ assert rs.getObject(4, String.class).equals("1");
}
cnt++;
@@ -293,6 +393,26 @@ public class JdbcResultSetSelfTest extends GridCommonAbstractTest {
if (cnt == 0) {
assert rs.getInt("intVal") == 1;
assert rs.getInt(5) == 1;
+
+ assert rs.getBoolean(5);
+ assert rs.getByte(5) == 1;
+ assert rs.getShort(5) == 1;
+ assert rs.getInt(5) == 1;
+ assert rs.getLong(5) == 1;
+ assert rs.getDouble(5) == 1.0;
+ assert rs.getFloat(5) == 1.0f;
+ assert rs.getBigDecimal(5).equals(new BigDecimal(1));
+ assert rs.getString(5).equals("1");
+
+ assert rs.getObject(5, Boolean.class);
+ assert rs.getObject(5, Byte.class) == 1;
+ assert rs.getObject(5, Short.class) == 1;
+ assert rs.getObject(5, Integer.class) == 1;
+ assert rs.getObject(5, Long.class) == 1;
+ assert rs.getObject(5, Float.class) == 1.f;
+ assert rs.getObject(5, Double.class) == 1;
+ assert rs.getObject(5, BigDecimal.class).equals(new BigDecimal(1));
+ assert rs.getObject(5, String.class).equals("1");
}
cnt++;
@@ -313,6 +433,26 @@ public class JdbcResultSetSelfTest extends GridCommonAbstractTest {
if (cnt == 0) {
assert rs.getLong("longVal") == 1;
assert rs.getLong(6) == 1;
+
+ assert rs.getBoolean(6);
+ assert rs.getByte(6) == 1;
+ assert rs.getShort(6) == 1;
+ assert rs.getInt(6) == 1;
+ assert rs.getLong(6) == 1;
+ assert rs.getDouble(6) == 1.0;
+ assert rs.getFloat(6) == 1.0f;
+ assert rs.getBigDecimal(6).equals(new BigDecimal(1));
+ assert rs.getString(6).equals("1");
+
+ assert rs.getObject(6, Boolean.class);
+ assert rs.getObject(6, Byte.class) == 1;
+ assert rs.getObject(6, Short.class) == 1;
+ assert rs.getObject(6, Integer.class) == 1;
+ assert rs.getObject(6, Long.class) == 1;
+ assert rs.getObject(6, Float.class) == 1.f;
+ assert rs.getObject(6, Double.class) == 1;
+ assert rs.getObject(6, BigDecimal.class).equals(new BigDecimal(1));
+ assert rs.getObject(6, String.class).equals("1");
}
cnt++;
@@ -333,6 +473,26 @@ public class JdbcResultSetSelfTest extends GridCommonAbstractTest {
if (cnt == 0) {
assert rs.getFloat("floatVal") == 1.0;
assert rs.getFloat(7) == 1.0;
+
+ assert rs.getBoolean(7);
+ assert rs.getByte(7) == 1;
+ assert rs.getShort(7) == 1;
+ assert rs.getInt(7) == 1;
+ assert rs.getLong(7) == 1;
+ assert rs.getDouble(7) == 1.0;
+ assert rs.getFloat(7) == 1.0f;
+ assert rs.getBigDecimal(7).equals(new BigDecimal(1));
+ assert rs.getString(7).equals("1.0");
+
+ assert rs.getObject(7, Boolean.class);
+ assert rs.getObject(7, Byte.class) == 1;
+ assert rs.getObject(7, Short.class) == 1;
+ assert rs.getObject(7, Integer.class) == 1;
+ assert rs.getObject(7, Long.class) == 1;
+ assert rs.getObject(7, Float.class) == 1.f;
+ assert rs.getObject(7, Double.class) == 1;
+ assert rs.getObject(7, BigDecimal.class).equals(new BigDecimal(1));
+ assert rs.getObject(7, String.class).equals("1.0");
}
cnt++;
@@ -353,6 +513,26 @@ public class JdbcResultSetSelfTest extends GridCommonAbstractTest {
if (cnt == 0) {
assert rs.getDouble("doubleVal") == 1.0;
assert rs.getDouble(8) == 1.0;
+
+ assert rs.getBoolean(8);
+ assert rs.getByte(8) == 1;
+ assert rs.getShort(8) == 1;
+ assert rs.getInt(8) == 1;
+ assert rs.getLong(8) == 1;
+ assert rs.getDouble(8) == 1.0;
+ assert rs.getFloat(8) == 1.0f;
+ assert rs.getBigDecimal(8).equals(new BigDecimal(1));
+ assert rs.getString(8).equals("1.0");
+
+ assert rs.getObject(8, Boolean.class);
+ assert rs.getObject(8, Byte.class) == 1;
+ assert rs.getObject(8, Short.class) == 1;
+ assert rs.getObject(8, Integer.class) == 1;
+ assert rs.getObject(8, Long.class) == 1;
+ assert rs.getObject(8, Float.class) == 1.f;
+ assert rs.getObject(8, Double.class) == 1;
+ assert rs.getObject(8, BigDecimal.class).equals(new BigDecimal(1));
+ assert rs.getObject(8, String.class).equals("1.0");
}
cnt++;
@@ -373,6 +553,26 @@ public class JdbcResultSetSelfTest extends GridCommonAbstractTest {
if (cnt == 0) {
assert rs.getBigDecimal("bigVal").intValue() == 1;
assert rs.getBigDecimal(9).intValue() == 1;
+
+ assert rs.getBoolean(9);
+ assert rs.getByte(9) == 1;
+ assert rs.getShort(9) == 1;
+ assert rs.getInt(9) == 1;
+ assert rs.getLong(9) == 1;
+ assert rs.getDouble(9) == 1.0;
+ assert rs.getFloat(9) == 1.0f;
+ assert rs.getBigDecimal(9).equals(new BigDecimal(1));
+ assert rs.getString(9).equals("1");
+
+ assert rs.getObject(9, Boolean.class);
+ assert rs.getObject(9, Byte.class) == 1;
+ assert rs.getObject(9, Short.class) == 1;
+ assert rs.getObject(9, Integer.class) == 1;
+ assert rs.getObject(9, Long.class) == 1;
+ assert rs.getObject(9, Float.class) == 1.f;
+ assert rs.getObject(9, Double.class) == 1;
+ assert rs.getObject(9, BigDecimal.class).equals(new BigDecimal(1));
+ assert rs.getObject(9, String.class).equals("1");
}
cnt++;
@@ -384,6 +584,30 @@ public class JdbcResultSetSelfTest extends GridCommonAbstractTest {
/**
* @throws Exception If failed.
*/
+ public void testBigDecimalScale() throws Exception {
+ assert "0.12".equals(convertStringToBigDecimalViaJdbc("0.1234", 2).toString());
+ assert "1.001".equals(convertStringToBigDecimalViaJdbc("1.0005", 3).toString());
+ assert "1E+3".equals(convertStringToBigDecimalViaJdbc("1205.5", -3).toString());
+ assert "1.3E+4".equals(convertStringToBigDecimalViaJdbc("12505.5", -3).toString());
+ }
+
+ /**
+ * @param strDec String representation of a decimal value.
+ * @param scale Scale.
+ * @return BigDecimal object.
+ * @throws SQLException On error.
+ */
+ private BigDecimal convertStringToBigDecimalViaJdbc(String strDec, int scale) throws SQLException {
+ try(ResultSet rs = stmt.executeQuery("select '" + strDec + "'")) {
+ assert rs.next();
+
+ return rs.getBigDecimal(1, scale);
+ }
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
public void testString() throws Exception {
ResultSet rs = stmt.executeQuery(SQL);
@@ -391,8 +615,27 @@ public class JdbcResultSetSelfTest extends GridCommonAbstractTest {
while (rs.next()) {
if (cnt == 0) {
- assert "str".equals(rs.getString("strVal"));
- assert "str".equals(rs.getString(10));
+ assert "1".equals(rs.getString("strVal"));
+
+ assert rs.getBoolean(10);
+ assert rs.getByte(10) == 1;
+ assert rs.getShort(10) == 1;
+ assert rs.getInt(10) == 1;
+ assert rs.getLong(10) == 1;
+ assert rs.getDouble(10) == 1.0;
+ assert rs.getFloat(10) == 1.0f;
+ assert rs.getBigDecimal(10).equals(new BigDecimal("1"));
+ assert rs.getString(10).equals("1");
+
+ assert rs.getObject(10, Boolean.class);
+ assert rs.getObject(10, Byte.class) == 1;
+ assert rs.getObject(10, Short.class) == 1;
+ assert rs.getObject(10, Integer.class) == 1;
+ assert rs.getObject(10, Long.class) == 1;
+ assert rs.getObject(10, Float.class) == 1.f;
+ assert rs.getObject(10, Double.class) == 1;
+ assert rs.getObject(10, BigDecimal.class).equals(new BigDecimal(1));
+ assert rs.getObject(10, String.class).equals("1");
}
cnt++;
@@ -433,7 +676,14 @@ public class JdbcResultSetSelfTest extends GridCommonAbstractTest {
while (rs.next()) {
if (cnt == 0) {
assert rs.getDate("dateVal").equals(new Date(1, 1, 1));
+
assert rs.getDate(12).equals(new Date(1, 1, 1));
+ assert rs.getTime(12).equals(new Time(new Date(1, 1, 1).getTime()));
+ assert rs.getTimestamp(12).equals(new Timestamp(new Date(1, 1, 1).getTime()));
+
+ assert rs.getObject(12, Date.class).equals(new Date(1, 1, 1));
+ assert rs.getObject(12, Time.class).equals(new Time(new Date(1, 1, 1).getTime()));
+ assert rs.getObject(12, Timestamp.class).equals(new Timestamp(new Date(1, 1, 1).getTime()));
}
cnt++;
@@ -454,7 +704,14 @@ public class JdbcResultSetSelfTest extends GridCommonAbstractTest {
while (rs.next()) {
if (cnt == 0) {
assert rs.getTime("timeVal").equals(new Time(1, 1, 1));
+
+ assert rs.getDate(13).equals(new Date(new Time(1, 1, 1).getTime()));
assert rs.getTime(13).equals(new Time(1, 1, 1));
+ assert rs.getTimestamp(13).equals(new Timestamp(new Time(1, 1, 1).getTime()));
+
+ assert rs.getObject(13, Date.class).equals(new Date(new Time(1, 1, 1).getTime()));
+ assert rs.getObject(13, Time.class).equals(new Time(1, 1, 1));
+ assert rs.getObject(13, Timestamp.class).equals(new Timestamp(new Time(1, 1, 1).getTime()));
}
cnt++;
@@ -474,7 +731,14 @@ public class JdbcResultSetSelfTest extends GridCommonAbstractTest {
while (rs.next()) {
if (cnt == 0) {
assert rs.getTimestamp("tsVal").getTime() == 1;
- assert rs.getTimestamp(14).getTime() == 1;
+
+ assert rs.getDate(14).equals(new Date(new Timestamp(1).getTime()));
+ assert rs.getTime(14).equals(new Time(new Timestamp(1).getTime()));
+ assert rs.getTimestamp(14).equals(new Timestamp(1));
+
+ assert rs.getObject(14, Date.class).equals(new Date(new Timestamp(1).getTime()));
+ assert rs.getObject(14, Time.class).equals(new Time(new Timestamp(1).getTime()));
+ assert rs.getObject(14, Timestamp.class).equals(new Timestamp(1));
}
cnt++;
http://git-wip-us.apache.org/repos/asf/ignite/blob/b023375c/modules/clients/src/test/java/org/apache/ignite/jdbc/JdbcErrorsAbstractSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/java/org/apache/ignite/jdbc/JdbcErrorsAbstractSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/jdbc/JdbcErrorsAbstractSelfTest.java
index 59535f8..c44e007 100644
--- a/modules/clients/src/test/java/org/apache/ignite/jdbc/JdbcErrorsAbstractSelfTest.java
+++ b/modules/clients/src/test/java/org/apache/ignite/jdbc/JdbcErrorsAbstractSelfTest.java
@@ -260,10 +260,10 @@ public abstract class JdbcErrorsAbstractSelfTest extends GridCommonAbstractTest
rs.next();
- rs.getLong(1);
+ rs.getInt(1);
}
}
- }, "0700B", "Cannot convert to long");
+ }, "0700B", "Cannot convert to int");
}
/**
http://git-wip-us.apache.org/repos/asf/ignite/blob/b023375c/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinResultSetSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinResultSetSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinResultSetSelfTest.java
index 6b7cdf4..36a0a15 100644
--- a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinResultSetSelfTest.java
+++ b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinResultSetSelfTest.java
@@ -38,7 +38,6 @@ import java.util.Arrays;
import java.util.GregorianCalendar;
import java.util.concurrent.Callable;
import org.apache.ignite.IgniteCache;
-import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.cache.query.annotations.QuerySqlField;
import org.apache.ignite.configuration.CacheConfiguration;
import org.apache.ignite.configuration.IgniteConfiguration;
@@ -151,7 +150,7 @@ public class JdbcThinResultSetSelfTest extends JdbcThinAbstractSelfTest {
o.floatVal = 1.0f;
o.doubleVal = 1.0d;
o.bigVal = new BigDecimal(1);
- o.strVal = "1.0";
+ o.strVal = "1";
o.arrVal = new byte[] {1};
o.dateVal = new Date(1, 1, 1);
o.timeVal = new Time(1, 1, 1);
@@ -548,27 +547,27 @@ public class JdbcThinResultSetSelfTest extends JdbcThinAbstractSelfTest {
while (rs.next()) {
if (cnt == 0) {
- assert "1.0".equals(rs.getString("strVal"));
-
- assert rs.getBoolean(7);
- assert rs.getByte(7) == 1;
- assert rs.getShort(7) == 1;
- assert rs.getInt(7) == 1;
- assert rs.getLong(7) == 1;
- assert rs.getDouble(7) == 1.0;
- assert rs.getFloat(7) == 1.0f;
- assert rs.getBigDecimal(7).equals(new BigDecimal(1));
- assert rs.getString(7).equals("1.0");
-
- assert rs.getObject(7, Boolean.class);
- assert rs.getObject(7, Byte.class) == 1;
- assert rs.getObject(7, Short.class) == 1;
- assert rs.getObject(7, Integer.class) == 1;
- assert rs.getObject(7, Long.class) == 1;
- assert rs.getObject(7, Float.class) == 1.f;
- assert rs.getObject(7, Double.class) == 1;
- assert rs.getObject(7, BigDecimal.class).equals(new BigDecimal(1));
- assert rs.getObject(7, String.class).equals("1.0");
+ assert "1".equals(rs.getString("strVal"));
+
+ assert rs.getBoolean(10);
+ assert rs.getByte(10) == 1;
+ assert rs.getShort(10) == 1;
+ assert rs.getInt(10) == 1;
+ assert rs.getLong(10) == 1;
+ assert rs.getDouble(10) == 1.0;
+ assert rs.getFloat(10) == 1.0f;
+ assert rs.getBigDecimal(10).equals(new BigDecimal("1"));
+ assert rs.getString(10).equals("1");
+
+ assert rs.getObject(10, Boolean.class);
+ assert rs.getObject(10, Byte.class) == 1;
+ assert rs.getObject(10, Short.class) == 1;
+ assert rs.getObject(10, Integer.class) == 1;
+ assert rs.getObject(10, Long.class) == 1;
+ assert rs.getObject(10, Float.class) == 1.f;
+ assert rs.getObject(10, Double.class) == 1;
+ assert rs.getObject(10, BigDecimal.class).equals(new BigDecimal(1));
+ assert rs.getObject(10, String.class).equals("1");
}
cnt++;
http://git-wip-us.apache.org/repos/asf/ignite/blob/b023375c/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcResultSet.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcResultSet.java b/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcResultSet.java
index e6e8488..2025b90 100755
--- a/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcResultSet.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcResultSet.java
@@ -20,6 +20,7 @@ package org.apache.ignite.internal.jdbc2;
import java.io.InputStream;
import java.io.Reader;
import java.math.BigDecimal;
+import java.net.MalformedURLException;
import java.net.URL;
import java.sql.Array;
import java.sql.Blob;
@@ -37,6 +38,9 @@ import java.sql.SQLXML;
import java.sql.Statement;
import java.sql.Time;
import java.sql.Timestamp;
+import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
+import java.text.ParseException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
@@ -55,6 +59,25 @@ import static org.apache.ignite.internal.jdbc2.JdbcUtils.convertToSqlException;
* JDBC result set implementation.
*/
public class JdbcResultSet implements ResultSet {
+ /** Decimal format to convert streing to decimal. */
+ private static final ThreadLocal<DecimalFormat> decimalFormat = new ThreadLocal<DecimalFormat>() {
+ /** {@inheritDoc} */
+ @Override protected DecimalFormat initialValue() {
+ DecimalFormatSymbols symbols = new DecimalFormatSymbols();
+
+ symbols.setGroupingSeparator(',');
+ symbols.setDecimalSeparator('.');
+
+ String ptrn = "#,##0.0#";
+
+ DecimalFormat decimalFormat = new DecimalFormat(ptrn, symbols);
+
+ decimalFormat.setParseBigDecimal(true);
+
+ return decimalFormat;
+ }
+ };
+
/** Is query. */
private final boolean isQry;
@@ -189,7 +212,9 @@ public class JdbcResultSet implements ResultSet {
}
/**
+ * Fetch next results page.
*
+ * @throws SQLException On error.
*/
private void fetchPage() throws SQLException {
JdbcConnection conn = (JdbcConnection)stmt.getConnection();
@@ -253,81 +278,277 @@ public class JdbcResultSet implements ResultSet {
/** {@inheritDoc} */
@Override public String getString(int colIdx) throws SQLException {
- return getTypedValue(colIdx, String.class);
+ Object val = getValue(colIdx);
+
+ return val == null ? null : String.valueOf(val);
}
/** {@inheritDoc} */
@Override public boolean getBoolean(int colIdx) throws SQLException {
- Boolean val = getTypedValue(colIdx, Boolean.class);
+ Object val = getValue(colIdx);
+
+ if (val == null)
+ return false;
+
+ Class<?> cls = val.getClass();
- return val != null ? val : false;
+ if (cls == Boolean.class)
+ return ((Boolean)val);
+ else if (val instanceof Number)
+ return ((Number)val).intValue() != 0;
+ else if (cls == String.class || cls == Character.class) {
+ try {
+ return Integer.parseInt(val.toString()) != 0;
+ }
+ catch (NumberFormatException e) {
+ throw new SQLException("Cannot convert to boolean: " + val, SqlStateCode.CONVERSION_FAILED, e);
+ }
+ }
+ else
+ throw new SQLException("Cannot convert to boolean: " + val, SqlStateCode.CONVERSION_FAILED);
}
/** {@inheritDoc} */
@Override public byte getByte(int colIdx) throws SQLException {
- Byte val = getTypedValue(colIdx, Byte.class);
+ Object val = getValue(colIdx);
+
+ if (val == null)
+ return 0;
- return val != null ? val : 0;
+ Class<?> cls = val.getClass();
+
+ if (val instanceof Number)
+ return ((Number)val).byteValue();
+ else if (cls == Boolean.class)
+ return (Boolean) val ? (byte) 1 : (byte) 0;
+ else if (cls == String.class || cls == Character.class) {
+ try {
+ return Byte.parseByte(val.toString());
+ }
+ catch (NumberFormatException e) {
+ throw new SQLException("Cannot convert to byte: " + val, SqlStateCode.CONVERSION_FAILED, e);
+ }
+ }
+ else
+ throw new SQLException("Cannot convert to byte: " + val, SqlStateCode.CONVERSION_FAILED);
}
/** {@inheritDoc} */
@Override public short getShort(int colIdx) throws SQLException {
- Short val = getTypedValue(colIdx, Short.class);
+ Object val = getValue(colIdx);
+
+ if (val == null)
+ return 0;
+
+ Class<?> cls = val.getClass();
- return val != null ? val : 0;
+ if (val instanceof Number)
+ return ((Number) val).shortValue();
+ else if (cls == Boolean.class)
+ return (Boolean) val ? (short) 1 : (short) 0;
+ else if (cls == String.class || cls == Character.class) {
+ try {
+ return Short.parseShort(val.toString());
+ }
+ catch (NumberFormatException e) {
+ throw new SQLException("Cannot convert to short: " + val, SqlStateCode.CONVERSION_FAILED, e);
+ }
+ }
+ else
+ throw new SQLException("Cannot convert to short: " + val, SqlStateCode.CONVERSION_FAILED);
}
/** {@inheritDoc} */
@Override public int getInt(int colIdx) throws SQLException {
- Integer val = getTypedValue(colIdx, Integer.class);
+ Object val = getValue(colIdx);
- return val != null ? val : 0;
+ if (val == null)
+ return 0;
+
+ Class<?> cls = val.getClass();
+
+ if (val instanceof Number)
+ return ((Number) val).intValue();
+ else if (cls == Boolean.class)
+ return (Boolean) val ? 1 : 0;
+ else if (cls == String.class || cls == Character.class) {
+ try {
+ return Integer.parseInt(val.toString());
+ }
+ catch (NumberFormatException e) {
+ throw new SQLException("Cannot convert to int: " + val, SqlStateCode.CONVERSION_FAILED, e);
+ }
+ }
+ else
+ throw new SQLException("Cannot convert to int: " + val, SqlStateCode.CONVERSION_FAILED);
}
/** {@inheritDoc} */
@Override public long getLong(int colIdx) throws SQLException {
- Long val = getTypedValue(colIdx, Long.class);
+ Object val = getValue(colIdx);
+
+ if (val == null)
+ return 0;
+
+ Class<?> cls = val.getClass();
- return val != null ? val : 0;
+ if (val instanceof Number)
+ return ((Number)val).longValue();
+ else if (cls == Boolean.class)
+ return (long) ((Boolean) val ? 1 : 0);
+ else if (cls == String.class || cls == Character.class) {
+ try {
+ return Long.parseLong(val.toString());
+ }
+ catch (NumberFormatException e) {
+ throw new SQLException("Cannot convert to long: " + val, SqlStateCode.CONVERSION_FAILED, e);
+ }
+ }
+ else
+ throw new SQLException("Cannot convert to long: " + val, SqlStateCode.CONVERSION_FAILED);
}
/** {@inheritDoc} */
@Override public float getFloat(int colIdx) throws SQLException {
- Float val = getTypedValue(colIdx, Float.class);
+ Object val = getValue(colIdx);
- return val != null ? val : 0;
+ if (val == null)
+ return 0;
+
+ Class<?> cls = val.getClass();
+
+ if (val instanceof Number)
+ return ((Number) val).floatValue();
+ else if (cls == Boolean.class)
+ return (float) ((Boolean) val ? 1 : 0);
+ else if (cls == String.class || cls == Character.class) {
+ try {
+ return Float.parseFloat(val.toString());
+ }
+ catch (NumberFormatException e) {
+ throw new SQLException("Cannot convert to float: " + val, SqlStateCode.CONVERSION_FAILED, e);
+ }
+ }
+ else
+ throw new SQLException("Cannot convert to float: " + val, SqlStateCode.CONVERSION_FAILED);
}
/** {@inheritDoc} */
@Override public double getDouble(int colIdx) throws SQLException {
- Double val = getTypedValue(colIdx, Double.class);
+ Object val = getValue(colIdx);
+
+ if (val == null)
+ return 0;
+
+ Class<?> cls = val.getClass();
- return val != null ? val : 0;
+ if (val instanceof Number)
+ return ((Number) val).doubleValue();
+ else if (cls == Boolean.class)
+ return (double)((Boolean) val ? 1 : 0);
+ else if (cls == String.class || cls == Character.class) {
+ try {
+ return Double.parseDouble(val.toString());
+ }
+ catch (NumberFormatException e) {
+ throw new SQLException("Cannot convert to double: " + val, SqlStateCode.CONVERSION_FAILED, e);
+ }
+ }
+ else
+ throw new SQLException("Cannot convert to double: " + val, SqlStateCode.CONVERSION_FAILED);
}
/** {@inheritDoc} */
@Override public BigDecimal getBigDecimal(int colIdx, int scale) throws SQLException {
- return getTypedValue(colIdx, BigDecimal.class);
+ BigDecimal val = getBigDecimal(colIdx);
+
+ return val == null ? null : val.setScale(scale, BigDecimal.ROUND_HALF_UP);
}
/** {@inheritDoc} */
@Override public byte[] getBytes(int colIdx) throws SQLException {
- return getTypedValue(colIdx, byte[].class);
+ Object val = getValue(colIdx);
+
+ if (val == null)
+ return null;
+
+ Class<?> cls = val.getClass();
+
+ if (cls == byte[].class)
+ return (byte[])val;
+ else if (cls == Byte.class)
+ return new byte[] {(byte)val};
+ else if (cls == Short.class) {
+ short x = (short)val;
+
+ return new byte[] {(byte)(x >> 8), (byte)x};
+ }
+ else if (cls == Integer.class) {
+ int x = (int)val;
+
+ return new byte[] { (byte) (x >> 24), (byte) (x >> 16), (byte) (x >> 8), (byte) x};
+ }
+ else if (cls == Long.class) {
+ long x = (long)val;
+
+ return new byte[] {(byte) (x >> 56), (byte) (x >> 48), (byte) (x >> 40), (byte) (x >> 32),
+ (byte) (x >> 24), (byte) (x >> 16), (byte) (x >> 8), (byte) x};
+ }
+ else if (cls == String.class)
+ return ((String)val).getBytes();
+ else
+ throw new SQLException("Cannot convert to byte[]: " + val, SqlStateCode.CONVERSION_FAILED);
}
/** {@inheritDoc} */
@Override public Date getDate(int colIdx) throws SQLException {
- return getTypedValue(colIdx, Date.class);
+ Object val = getValue(colIdx);
+
+ if (val == null)
+ return null;
+
+ Class<?> cls = val.getClass();
+
+ if (cls == Date.class)
+ return (Date)val;
+ else if (cls == java.util.Date.class || cls == Time.class || cls == Timestamp.class)
+ return new Date(((java.util.Date)val).getTime());
+ else
+ throw new SQLException("Cannot convert to date: " + val, SqlStateCode.CONVERSION_FAILED);
}
/** {@inheritDoc} */
@Override public Time getTime(int colIdx) throws SQLException {
- return getTypedValue(colIdx, Time.class);
+ Object val = getValue(colIdx);
+
+ if (val == null)
+ return null;
+
+ Class<?> cls = val.getClass();
+
+ if (cls == Time.class)
+ return (Time)val;
+ else if (cls == java.util.Date.class || cls == Date.class || cls == Timestamp.class)
+ return new Time(((java.util.Date)val).getTime());
+ else
+ throw new SQLException("Cannot convert to time: " + val, SqlStateCode.CONVERSION_FAILED);
}
/** {@inheritDoc} */
@Override public Timestamp getTimestamp(int colIdx) throws SQLException {
- return getTypedValue(colIdx, Timestamp.class);
+ Object val = getValue(colIdx);
+
+ if (val == null)
+ return null;
+
+ Class<?> cls = val.getClass();
+
+ if (cls == Timestamp.class)
+ return (Timestamp)val;
+ else if (cls == java.util.Date.class || cls == Date.class || cls == Time.class)
+ return new Timestamp(((java.util.Date)val).getTime());
+ else
+ throw new SQLException("Cannot convert to timestamp: " + val, SqlStateCode.CONVERSION_FAILED);
}
/** {@inheritDoc} */
@@ -353,81 +574,93 @@ public class JdbcResultSet implements ResultSet {
/** {@inheritDoc} */
@Override public String getString(String colLb) throws SQLException {
- return getTypedValue(colLb, String.class);
+ int colIdx = findColumn(colLb);
+
+ return getString(colIdx);
}
/** {@inheritDoc} */
@Override public boolean getBoolean(String colLb) throws SQLException {
- Boolean val = getTypedValue(colLb, Boolean.class);
+ int colIdx = findColumn(colLb);
- return val != null ? val : false;
+ return getBoolean(colIdx);
}
/** {@inheritDoc} */
@Override public byte getByte(String colLb) throws SQLException {
- Byte val = getTypedValue(colLb, Byte.class);
+ int colIdx = findColumn(colLb);
- return val != null ? val : 0;
+ return getByte(colIdx);
}
/** {@inheritDoc} */
@Override public short getShort(String colLb) throws SQLException {
- Short val = getTypedValue(colLb, Short.class);
+ int colIdx = findColumn(colLb);
- return val != null ? val : 0;
+ return getShort(colIdx);
}
/** {@inheritDoc} */
@Override public int getInt(String colLb) throws SQLException {
- Integer val = getTypedValue(colLb, Integer.class);
+ int colIdx = findColumn(colLb);
- return val != null ? val : 0;
+ return getInt(colIdx);
}
/** {@inheritDoc} */
@Override public long getLong(String colLb) throws SQLException {
- Long val = getTypedValue(colLb, Long.class);
+ int colIdx = findColumn(colLb);
- return val != null ? val : 0;
+ return getLong(colIdx);
}
/** {@inheritDoc} */
@Override public float getFloat(String colLb) throws SQLException {
- Float val = getTypedValue(colLb, Float.class);
+ int colIdx = findColumn(colLb);
- return val != null ? val : 0;
+ return getFloat(colIdx);
}
/** {@inheritDoc} */
@Override public double getDouble(String colLb) throws SQLException {
- Double val = getTypedValue(colLb, Double.class);
+ int colIdx = findColumn(colLb);
- return val != null ? val : 0;
+ return getDouble(colIdx);
}
/** {@inheritDoc} */
@Override public BigDecimal getBigDecimal(String colLb, int scale) throws SQLException {
- return getTypedValue(colLb, BigDecimal.class);
+ int colIdx = findColumn(colLb);
+
+ return getBigDecimal(colIdx, scale);
}
/** {@inheritDoc} */
@Override public byte[] getBytes(String colLb) throws SQLException {
- return getTypedValue(colLb, byte[].class);
+ int colIdx = findColumn(colLb);
+
+ return getBytes(colIdx);
}
/** {@inheritDoc} */
@Override public Date getDate(String colLb) throws SQLException {
- return getTypedValue(colLb, Date.class);
+ int colIdx = findColumn(colLb);
+
+ return getDate(colIdx);
}
/** {@inheritDoc} */
@Override public Time getTime(String colLb) throws SQLException {
- return getTypedValue(colLb, Time.class);
+ int colIdx = findColumn(colLb);
+
+ return getTime(colIdx);
}
/** {@inheritDoc} */
@Override public Timestamp getTimestamp(String colLb) throws SQLException {
- return getTypedValue(colLb, Timestamp.class);
+ int colIdx = findColumn(colLb);
+
+ return getTimestamp(colIdx);
}
/** {@inheritDoc} */
@@ -482,12 +715,14 @@ public class JdbcResultSet implements ResultSet {
/** {@inheritDoc} */
@Override public Object getObject(int colIdx) throws SQLException {
- return getTypedValue(colIdx, Object.class);
+ return getValue(colIdx);
}
/** {@inheritDoc} */
@Override public Object getObject(String colLb) throws SQLException {
- return getTypedValue(colLb, Object.class);
+ int colIdx = findColumn(colLb);
+
+ return getValue(colIdx);
}
/** {@inheritDoc} */
@@ -499,6 +734,8 @@ public class JdbcResultSet implements ResultSet {
if (idx == -1)
throw new SQLException("Column not found: " + colLb);
+ assert idx >= 0;
+
return idx + 1;
}
@@ -518,12 +755,36 @@ public class JdbcResultSet implements ResultSet {
/** {@inheritDoc} */
@Override public BigDecimal getBigDecimal(int colIdx) throws SQLException {
- return getTypedValue(colIdx, BigDecimal.class);
+ Object val = getValue(colIdx);
+
+ if (val == null)
+ return null;
+
+ Class<?> cls = val.getClass();
+
+ if (cls == BigDecimal.class)
+ return (BigDecimal)val;
+ else if (val instanceof Number)
+ return new BigDecimal(((Number)val).doubleValue());
+ else if (cls == Boolean.class)
+ return new BigDecimal((Boolean)val ? 1 : 0);
+ else if (cls == String.class || cls == Character.class) {
+ try {
+ return (BigDecimal)decimalFormat.get().parse(val.toString());
+ }
+ catch (ParseException e) {
+ throw new SQLException("Cannot convert to BigDecimal: " + val, SqlStateCode.CONVERSION_FAILED, e);
+ }
+ }
+ else
+ throw new SQLException("Cannot convert to BigDecimal: " + val, SqlStateCode.CONVERSION_FAILED);
}
/** {@inheritDoc} */
@Override public BigDecimal getBigDecimal(String colLb) throws SQLException {
- return getTypedValue(colLb, BigDecimal.class);
+ int colIdx = findColumn(colLb);
+
+ return getBigDecimal(colIdx);
}
/** {@inheritDoc} */
@@ -997,7 +1258,7 @@ public class JdbcResultSet implements ResultSet {
/** {@inheritDoc} */
@Override public Object getObject(int colIdx, Map<String, Class<?>> map) throws SQLException {
- return getTypedValue(colIdx, Object.class);
+ throw new SQLFeatureNotSupportedException("SQL structured type are not supported.");
}
/** {@inheritDoc} */
@@ -1028,7 +1289,7 @@ public class JdbcResultSet implements ResultSet {
/** {@inheritDoc} */
@Override public Object getObject(String colLb, Map<String, Class<?>> map) throws SQLException {
- return getTypedValue(colLb, Object.class);
+ throw new SQLFeatureNotSupportedException("SQL structured type are not supported.");
}
/** {@inheritDoc} */
@@ -1059,42 +1320,62 @@ public class JdbcResultSet implements ResultSet {
/** {@inheritDoc} */
@Override public Date getDate(int colIdx, Calendar cal) throws SQLException {
- return getTypedValue(colIdx, Date.class);
+ return getDate(colIdx);
}
/** {@inheritDoc} */
@Override public Date getDate(String colLb, Calendar cal) throws SQLException {
- return getTypedValue(colLb, Date.class);
+ return getDate(colLb);
}
/** {@inheritDoc} */
@Override public Time getTime(int colIdx, Calendar cal) throws SQLException {
- return getTypedValue(colIdx, Time.class);
+ return getTime(colIdx);
}
/** {@inheritDoc} */
@Override public Time getTime(String colLb, Calendar cal) throws SQLException {
- return getTypedValue(colLb, Time.class);
+ return getTime(colLb);
}
/** {@inheritDoc} */
@Override public Timestamp getTimestamp(int colIdx, Calendar cal) throws SQLException {
- return getTypedValue(colIdx, Timestamp.class);
+ return getTimestamp(colIdx);
}
/** {@inheritDoc} */
@Override public Timestamp getTimestamp(String colLb, Calendar cal) throws SQLException {
- return getTypedValue(colLb, Timestamp.class);
+ return getTimestamp(colLb);
}
/** {@inheritDoc} */
@Override public URL getURL(int colIdx) throws SQLException {
- return getTypedValue(colIdx, URL.class);
+ Object val = getValue(colIdx);
+
+ if (val == null)
+ return null;
+
+ Class<?> cls = val.getClass();
+
+ if (cls == URL.class)
+ return (URL)val;
+ else if (cls == String.class) {
+ try {
+ return new URL(val.toString());
+ }
+ catch (MalformedURLException e) {
+ throw new SQLException("Cannot convert to URL: " + val, SqlStateCode.CONVERSION_FAILED, e);
+ }
+ }
+ else
+ throw new SQLException("Cannot convert to URL: " + val, SqlStateCode.CONVERSION_FAILED);
}
/** {@inheritDoc} */
@Override public URL getURL(String colLb) throws SQLException {
- return getTypedValue(colLb, URL.class);
+ int colIdx = findColumn(colLb);
+
+ return getURL(colIdx);
}
/** {@inheritDoc} */
@@ -1486,57 +1767,77 @@ public class JdbcResultSet implements ResultSet {
}
/** {@inheritDoc} */
- @Override public <T> T getObject(int colIdx, Class<T> type) throws SQLException {
- return getTypedValue(colIdx, type);
+ @Override public <T> T getObject(int colIdx, Class<T> targetCls) throws SQLException {
+ return (T)getObject0(colIdx, targetCls);
}
/** {@inheritDoc} */
- @Override public <T> T getObject(String colLb, Class<T> type) throws SQLException {
- return getTypedValue(colLb, type);
+ @Override public <T> T getObject(String colLb, Class<T> targetCls) throws SQLException {
+ int colIdx = findColumn(colLb);
+
+ return getObject(colIdx, targetCls);
}
/**
- * Gets casted field value by label.
- *
- * @param colLb Column label.
- * @param cls Value class.
- * @return Casted field value.
- * @throws SQLException In case of error.
+ * @param colIdx Column index.
+ * @param targetCls Class representing the Java data type to convert the designated column to.
+ * @return Converted object.
+ * @throws SQLException On error.
*/
- private <T> T getTypedValue(String colLb, Class<T> cls) throws SQLException {
- ensureNotClosed();
- ensureHasCurrentRow();
-
- String name = colLb.toUpperCase();
-
- Integer idx = stmt.fieldsIdxs.get(name);
-
- int colIdx;
-
- if (idx != null)
- colIdx = idx;
+ private Object getObject0(int colIdx, Class<?> targetCls) throws SQLException {
+ if (targetCls == Boolean.class)
+ return getBoolean(colIdx);
+ else if (targetCls == Byte.class)
+ return getByte(colIdx);
+ else if (targetCls == Short.class)
+ return getShort(colIdx);
+ else if (targetCls == Integer.class)
+ return getInt(colIdx);
+ else if (targetCls == Long.class)
+ return getLong(colIdx);
+ else if (targetCls == Float.class)
+ return getFloat(colIdx);
+ else if (targetCls == Double.class)
+ return getDouble(colIdx);
+ else if (targetCls == String.class)
+ return getString(colIdx);
+ else if (targetCls == BigDecimal.class)
+ return getBigDecimal(colIdx);
+ else if (targetCls == Date.class)
+ return getDate(colIdx);
+ else if (targetCls == Time.class)
+ return getTime(colIdx);
+ else if (targetCls == Timestamp.class)
+ return getTimestamp(colIdx);
+ else if (targetCls == byte[].class)
+ return getBytes(colIdx);
+ else if (targetCls == URL.class)
+ return getURL(colIdx);
else {
- colIdx = cols.indexOf(name) + 1;
+ Object val = getValue(colIdx);
- if (colIdx <= 0)
- throw new SQLException("Invalid column label: " + colLb);
+ if (val == null)
+ return null;
- stmt.fieldsIdxs.put(name, colIdx);
- }
+ Class<?> cls = val.getClass();
- return getTypedValue(colIdx, cls);
+ if (targetCls == cls)
+ return val;
+ else
+ throw new SQLException("Cannot convert to " + targetCls.getName() + ": " + val,
+ SqlStateCode.CONVERSION_FAILED);
+ }
}
/**
- * Gets casted field value by index.
+ * Gets object field value by index.
*
* @param colIdx Column index.
- * @param cls Value class.
- * @return Casted field value.
+ * @return Object field value.
* @throws SQLException In case of error.
*/
@SuppressWarnings("unchecked")
- private <T> T getTypedValue(int colIdx, Class<T> cls) throws SQLException {
+ private Object getValue(int colIdx) throws SQLException {
ensureNotClosed();
ensureHasCurrentRow();
@@ -1545,18 +1846,10 @@ public class JdbcResultSet implements ResultSet {
wasNull = val == null;
- if (val == null)
- return null;
- else if (cls == String.class)
- return (T)String.valueOf(val);
- else
- return cls.cast(val);
- }
- catch (IndexOutOfBoundsException ignored) {
- throw new SQLException("Invalid column index: " + colIdx);
+ return val;
}
- catch (ClassCastException ignored) {
- throw new SQLException("Cannot convert to " + cls.getSimpleName().toLowerCase(), SqlStateCode.CONVERSION_FAILED);
+ catch (IndexOutOfBoundsException e) {
+ throw new SQLException("Invalid column index: " + colIdx, e);
}
}