/*
Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
The MySQL Connector/J is licensed under the terms of the GPLv2
<http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most MySQL Connectors.
There are special exceptions to the terms and conditions of the GPLv2 as it is applied to
this software, see the FLOSS License Exception
<http://www.mysql.com/about/legal/licensing/foss-exception.html>.
This program is free software; you can redistribute it and/or modify it under the terms
of the GNU General Public License as published by the Free Software Foundation; version 2
of the License.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this
program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth
Floor, Boston, MA 02110-1301 USA
*/
package testsuite.regression;
import java.io.Reader;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.sql.CallableStatement;
import java.sql.Clob;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Timestamp;
import java.sql.Types;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Locale;
import java.util.Properties;
import java.util.TimeZone;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import javax.sql.rowset.CachedRowSet;
import testsuite.BaseTestCase;
import com.mysql.jdbc.Messages;
import com.mysql.jdbc.MysqlDataTruncation;
import com.mysql.jdbc.NotUpdatable;
import com.mysql.jdbc.SQLError;
import com.mysql.jdbc.Util;
import com.mysql.jdbc.log.StandardLogger;
/**
* Regression test cases for the ResultSet class.
*
* @author Mark Matthews
*/
public class ResultSetRegressionTest extends BaseTestCase {
/**
* Creates a new ResultSetRegressionTest
*
* @param name
* the name of the test to run
*/
public ResultSetRegressionTest(String name) {
super(name);
}
/**
* Runs all test cases in this test suite
*
* @param args
*/
public static void main(String[] args) {
junit.textui.TestRunner.run(ResultSetRegressionTest.class);
}
/**
* Tests fix for BUG#???? -- Numeric types and server-side prepared
* statements incorrectly detect nulls.
*
* @throws Exception
* if the test fails
*/
public void testBug2359() throws Exception {
/*
* this.stmt.executeUpdate("DROP TABLE IF EXISTS testBug2359");
* this.stmt.executeUpdate("CREATE TABLE testBug2359 (field1 INT)
* TYPE=InnoDB"); this.stmt.executeUpdate("INSERT INTO testBug2359
* VALUES (null), (1)");
*
* this.pstmt = this.conn.prepareStatement("SELECT field1 FROM
* testBug2359 WHERE field1 IS NULL"); this.rs =
* this.pstmt.executeQuery();
*
* assertTrue(this.rs.next());
*
* assertTrue(this.rs.getByte(1) == 0); assertTrue(this.rs.wasNull());
*
* assertTrue(this.rs.getShort(1) == 0); assertTrue(this.rs.wasNull());
*
* assertTrue(this.rs.getInt(1) == 0); assertTrue(this.rs.wasNull());
*
* assertTrue(this.rs.getLong(1) == 0); assertTrue(this.rs.wasNull());
*
* assertTrue(this.rs.getFloat(1) == 0); assertTrue(this.rs.wasNull());
*
* assertTrue(this.rs.getDouble(1) == 0); assertTrue(this.rs.wasNull());
*
* assertTrue(this.rs.getBigDecimal(1) == null);
* assertTrue(this.rs.wasNull());
*
* this.rs.close();
*
* this.pstmt = this.conn.prepareStatement("SELECT max(field1) FROM
* testBug2359 WHERE field1 IS NOT NULL"); this.rs =
* this.pstmt.executeQuery(); assertTrue(this.rs.next());
*
* assertTrue(this.rs.getByte(1) == 1); assertTrue(!this.rs.wasNull());
*
* assertTrue(this.rs.getShort(1) == 1); assertTrue(!this.rs.wasNull());
*
* assertTrue(this.rs.getInt(1) == 1); assertTrue(!this.rs.wasNull());
*
* assertTrue(this.rs.getLong(1) == 1); assertTrue(!this.rs.wasNull());
*
* assertTrue(this.rs.getFloat(1) == 1); assertTrue(!this.rs.wasNull());
*
* assertTrue(this.rs.getDouble(1) == 1);
* assertTrue(!this.rs.wasNull());
*
* assertTrue(this.rs.getBigDecimal(1) != null);
* assertTrue(!this.rs.wasNull());
*/
createTable("testBug2359_1", "(id INT)", "InnoDB");
this.stmt.executeUpdate("INSERT INTO testBug2359_1 VALUES (1)");
this.pstmt = this.conn
.prepareStatement("SELECT max(id) FROM testBug2359_1");
this.rs = this.pstmt.executeQuery();
if (this.rs.next()) {
assertTrue(this.rs.getInt(1) != 0);
this.rs.close();
}
this.rs.close();
}
/**
* Tests fix for BUG#2643, ClassCastException when using this.rs.absolute()
* and server-side prepared statements.
*
* @throws Exception
*/
public void testBug2623() throws Exception {
PreparedStatement pStmt = null;
try {
pStmt = this.conn
.prepareStatement("SELECT NOW()",
ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_READ_ONLY);
this.rs = pStmt.executeQuery();
this.rs.absolute(1);
} finally {
if (this.rs != null) {
this.rs.close();
}
this.rs = null;
if (pStmt != null) {
pStmt.close();
}
}
}
/**
* Tests fix for BUG#2654, "Column 'column.table' not found" when "order by"
* in query"
*
* @throws Exception
* if the test fails
*/
public void testBug2654() throws Exception {
if (false) { // this is currently a server-level bug
createTable("foo", "(" + " id tinyint(3) default NULL,"
+ " data varchar(255) default NULL"
+ ") DEFAULT CHARSET=latin1", "MyISAM ");
this.stmt
.executeUpdate("INSERT INTO foo VALUES (1,'male'),(2,'female')");
createTable("bar", "(" + "id tinyint(3) unsigned default NULL,"
+ "data char(3) default '0'" + ") DEFAULT CHARSET=latin1",
"MyISAM ");
this.stmt
.executeUpdate("INSERT INTO bar VALUES (1,'yes'),(2,'no')");
String statement = "select foo.id, foo.data, "
+ "bar.data from foo, bar" + " where "
+ "foo.id = bar.id order by foo.id";
String column = "foo.data";
this.rs = this.stmt.executeQuery(statement);
ResultSetMetaData rsmd = this.rs.getMetaData();
System.out.println(rsmd.getTableName(1));
System.out.println(rsmd.getColumnName(1));
this.rs.next();
String fooData = this.rs.getString(column);
}
}
/**
* Tests for fix to BUG#1130
*
* @throws Exception
* if the test fails
*/
public void testClobTruncate() throws Exception {
if (isRunningOnJdk131()) {
return; // test not valid on JDK-1.3.1
}
createTable("testClobTruncate", "(field1 TEXT)");
this.stmt
.executeUpdate("INSERT INTO testClobTruncate VALUES ('abcdefg')");
this.rs = this.stmt.executeQuery("SELECT * FROM testClobTruncate");
this.rs.next();
Clob clob = this.rs.getClob(1);
clob.truncate(3);
Reader reader = clob.getCharacterStream();
char[] buf = new char[8];
int charsRead = reader.read(buf);
String clobAsString = new String(buf, 0, charsRead);
assertTrue(clobAsString.equals("abc"));
}
/**
* Tests that streaming result sets are registered correctly.
*
* @throws Exception
* if any errors occur
*/
public void testClobberStreamingRS() throws Exception {
try {
Properties props = new Properties();
props.setProperty("clobberStreamingResults", "true");
Connection clobberConn = getConnectionWithProps(props);
Statement clobberStmt = clobberConn.createStatement();
clobberStmt.executeUpdate("DROP TABLE IF EXISTS StreamingClobber");
clobberStmt
.executeUpdate("CREATE TABLE StreamingClobber ( DUMMYID "
+ " INTEGER NOT NULL, DUMMYNAME VARCHAR(32),PRIMARY KEY (DUMMYID) )");
clobberStmt
.executeUpdate("INSERT INTO StreamingClobber (DUMMYID, DUMMYNAME) VALUES (0, NULL)");
clobberStmt
.executeUpdate("INSERT INTO StreamingClobber (DUMMYID, DUMMYNAME) VALUES (1, 'nro 1')");
clobberStmt
.executeUpdate("INSERT INTO StreamingClobber (DUMMYID, DUMMYNAME) VALUES (2, 'nro 2')");
clobberStmt
.executeUpdate("INSERT INTO StreamingClobber (DUMMYID, DUMMYNAME) VALUES (3, 'nro 3')");
Statement streamStmt = null;
try {
streamStmt = clobberConn.createStatement(
java.sql.ResultSet.TYPE_FORWARD_ONLY,
java.sql.ResultSet.CONCUR_READ_ONLY);
streamStmt.setFetchSize(Integer.MIN_VALUE);
this.rs = streamStmt.executeQuery("SELECT DUMMYID, DUMMYNAME "
+ "FROM StreamingClobber ORDER BY DUMMYID");
this.rs.next();
// This should proceed normally, after the driver
// clears the input stream
clobberStmt.executeQuery("SHOW VARIABLES");
this.rs.close();
} finally {
if (streamStmt != null) {
streamStmt.close();
}
}
} finally {
this.stmt.executeUpdate("DROP TABLE IF EXISTS StreamingClobber");
}
}
/**
* DOCUMENT ME!
*
* @throws Exception
* DOCUMENT ME!
*/
public void testEmptyResultSetGet() throws Exception {
try {
this.rs = this.stmt.executeQuery("SHOW VARIABLES LIKE 'foo'");
System.out.println(this.rs.getInt(1));
} catch (SQLException sqlEx) {
assertTrue(
"Correct exception not thrown",
SQLError.SQL_STATE_GENERAL_ERROR.equals(sqlEx.getSQLState()));
}
}
/**
* Checks fix for BUG#1592 -- cross-database updatable result sets are not
* checked for updatability correctly.
*
* @throws Exception
* if the test fails.
*/
public void testFixForBug1592() throws Exception {
if (versionMeetsMinimum(4, 1)) {
Statement updatableStmt = this.conn
.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_UPDATABLE);
try {
updatableStmt.execute("SELECT * FROM mysql.user");
this.rs = updatableStmt.getResultSet();
} catch (SQLException sqlEx) {
String message = sqlEx.getMessage();
if ((message != null) && (message.indexOf("denied") != -1)) {
System.err
.println("WARN: Can't complete testFixForBug1592(), access to"
+ " 'mysql' database not allowed");
} else {
throw sqlEx;
}
}
}
}
/**
* Tests fix for BUG#2006, where 2 columns with same name in a result set
* are returned via findColumn() in the wrong order...The JDBC spec states,
* that the _first_ matching column should be returned.
*
* @throws Exception
* if the test fails
*/
public void testFixForBug2006() throws Exception {
createTable("testFixForBug2006_1", "(key_field INT NOT NULL)");
createTable("testFixForBug2006_2", "(key_field INT NULL)");
this.stmt.executeUpdate("INSERT INTO testFixForBug2006_1 VALUES (1)");
this.rs = this.stmt
.executeQuery("SELECT testFixForBug2006_1.key_field, testFixForBug2006_2.key_field FROM testFixForBug2006_1 LEFT JOIN testFixForBug2006_2 USING(key_field)");
ResultSetMetaData rsmd = this.rs.getMetaData();
assertTrue(rsmd.getColumnName(1).equals(rsmd.getColumnName(2)));
assertTrue(rsmd.isNullable(this.rs.findColumn("key_field")) == ResultSetMetaData.columnNoNulls);
assertTrue(rsmd.isNullable(2) == ResultSetMetaData.columnNullable);
assertTrue(this.rs.next());
assertTrue(this.rs.getObject(1) != null);
assertTrue(this.rs.getObject(2) == null);
}
/**
* Tests that ResultSet.getLong() does not truncate values.
*
* @throws Exception
* if any errors occur
*/
public void testGetLongBug() throws Exception {
createTable("getLongBug", "(int_col int, bigint_col bigint)");
int intVal = 123456;
long longVal1 = 123456789012345678L;
long longVal2 = -2079305757640172711L;
this.stmt.executeUpdate("INSERT INTO getLongBug "
+ "(int_col, bigint_col) " + "VALUES (" + intVal + ", "
+ longVal1 + "), " + "(" + intVal + ", " + longVal2 + ")");
this.rs = this.stmt
.executeQuery("SELECT int_col, bigint_col FROM getLongBug ORDER BY bigint_col DESC");
this.rs.next();
assertTrue(
"Values not decoded correctly",
((this.rs.getInt(1) == intVal) && (this.rs.getLong(2) == longVal1)));
this.rs.next();
assertTrue(
"Values not decoded correctly",
((this.rs.getInt(1) == intVal) && (this.rs.getLong(2) == longVal2)));
}
/**
* DOCUMENT ME!
*
* @throws Exception
* DOCUMENT ME!
*/
public void testGetTimestampWithDate() throws Exception {
createTable("testGetTimestamp", "(d date)");
this.stmt.executeUpdate("INSERT INTO testGetTimestamp values (now())");
this.rs = this.stmt.executeQuery("SELECT * FROM testGetTimestamp");
this.rs.next();
System.out.println(this.rs.getTimestamp(1));
}
/**
* Tests a bug where ResultSet.isBefireFirst() would return true when the
* result set was empty (which is incorrect)
*
* @throws Exception
* if an error occurs.
*/
public void testIsBeforeFirstOnEmpty() throws Exception {
// Query with valid rows: isBeforeFirst() correctly returns True
this.rs = this.stmt.executeQuery("SHOW VARIABLES LIKE 'version'");
assertTrue("Non-empty search should return true",
this.rs.isBeforeFirst());
// Query with empty result: isBeforeFirst() falsely returns True
// Sun's documentation says it should return false
this.rs = this.stmt.executeQuery("SHOW VARIABLES LIKE 'garbage'");
assertTrue("Empty search should return false ",
!this.rs.isBeforeFirst());
}
/**
* Tests a bug where ResultSet.isBefireFirst() would return true when the
* result set was empty (which is incorrect)
*
* @throws Exception
* if an error occurs.
*/
public void testMetaDataIsWritable() throws Exception {
// Query with valid rows
this.rs = this.stmt.executeQuery("SHOW VARIABLES LIKE 'version'");
ResultSetMetaData rsmd = this.rs.getMetaData();
int numColumns = rsmd.getColumnCount();
for (int i = 1; i <= numColumns; i++) {
assertTrue("rsmd.isWritable() should != rsmd.isReadOnly()",
rsmd.isWritable(i) != rsmd.isReadOnly(i));
}
}
/**
* Tests fix for bug # 496
*
* @throws Exception
* if an error happens.
*/
public void testNextAndPrevious() throws Exception {
createTable("testNextAndPrevious", "(field1 int)");
this.stmt.executeUpdate("INSERT INTO testNextAndPrevious VALUES (1)");
this.rs = this.stmt.executeQuery("SELECT * from testNextAndPrevious");
System.out.println("Currently at row " + this.rs.getRow());
this.rs.next();
System.out.println("Value at row " + this.rs.getRow() + " is "
+ this.rs.getString(1));
this.rs.previous();
try {
System.out.println("Value at row " + this.rs.getRow() + " is "
+ this.rs.getString(1));
fail("Should not be able to retrieve values with invalid cursor");
} catch (SQLException sqlEx) {
assertTrue(sqlEx.getMessage().startsWith("Before start"));
}
this.rs.next();
this.rs.next();
try {
System.out.println("Value at row " + this.rs.getRow() + " is "
+ this.rs.getString(1));
fail("Should not be able to retrieve values with invalid cursor");
} catch (SQLException sqlEx) {
assertTrue(sqlEx.getMessage().startsWith("After end"));
}
}
/**
* Tests fix for BUG#1630 (not updatable exception turning into NPE on
* second updateFoo() method call.
*
* @throws Exception
* if an unexpected exception is thrown.
*/
public void testNotUpdatable() throws Exception {
this.rs = null;
String sQuery = "SHOW VARIABLES";
this.pstmt = this.conn.prepareStatement(sQuery,
ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
this.rs = this.pstmt.executeQuery();
if (this.rs.next()) {
this.rs.absolute(1);
try {
this.rs.updateInt(1, 1);
} catch (SQLException sqlEx) {
assertTrue(sqlEx instanceof NotUpdatable);
}
try {
this.rs.updateString(1, "1");
} catch (SQLException sqlEx) {
assertTrue(sqlEx instanceof NotUpdatable);
}
}
}
/**
* Tests that streaming result sets are registered correctly.
*
* @throws Exception
* if any errors occur
*/
public void testStreamingRegBug() throws Exception {
createTable(
"StreamingRegBug",
"( DUMMYID "
+ " INTEGER NOT NULL, DUMMYNAME VARCHAR(32),PRIMARY KEY (DUMMYID) )");
this.stmt
.executeUpdate("INSERT INTO StreamingRegBug (DUMMYID, DUMMYNAME) VALUES (0, NULL)");
this.stmt
.executeUpdate("INSERT INTO StreamingRegBug (DUMMYID, DUMMYNAME) VALUES (1, 'nro 1')");
this.stmt
.executeUpdate("INSERT INTO StreamingRegBug (DUMMYID, DUMMYNAME) VALUES (2, 'nro 2')");
this.stmt
.executeUpdate("INSERT INTO StreamingRegBug (DUMMYID, DUMMYNAME) VALUES (3, 'nro 3')");
PreparedStatement streamStmt = null;
try {
streamStmt = this.conn.prepareStatement(
"SELECT DUMMYID, DUMMYNAME "
+ "FROM StreamingRegBug ORDER BY DUMMYID",
java.sql.ResultSet.TYPE_FORWARD_ONLY,
java.sql.ResultSet.CONCUR_READ_ONLY);
streamStmt.setFetchSize(Integer.MIN_VALUE);
this.rs = streamStmt.executeQuery();
while (this.rs.next()) {
this.rs.getString(1);
}
this.rs.close(); // error occurs here
} catch (SQLException sqlEx) {
} finally {
if (streamStmt != null) {
try {
streamStmt.close();
} catch (SQLException exWhileClose) {
exWhileClose.printStackTrace();
}
}
}
}
/**
* Tests that result sets can be updated when all parameters are correctly
* set.
*
* @throws Exception
* if any errors occur
*/
public void testUpdatability() throws Exception {
this.rs = null;
createTable("updatabilityBug", "("
+ " id int(10) unsigned NOT NULL auto_increment,"
+ " field1 varchar(32) NOT NULL default '',"
+ " field2 varchar(128) NOT NULL default '',"
+ " field3 varchar(128) default NULL,"
+ " field4 varchar(128) default NULL,"
+ " field5 varchar(64) default NULL,"
+ " field6 int(10) unsigned default NULL,"
+ " field7 varchar(64) default NULL," + " PRIMARY KEY (id)"
+ ") ", "InnoDB");
this.stmt.executeUpdate("insert into updatabilityBug (id) values (1)");
String sQuery = " SELECT * FROM updatabilityBug WHERE id = ? ";
this.pstmt = this.conn.prepareStatement(sQuery,
ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
this.conn.setAutoCommit(false);
this.pstmt.setInt(1, 1);
this.rs = this.pstmt.executeQuery();
if (this.rs.next()) {
this.rs.absolute(1);
this.rs.updateInt("id", 1);
this.rs.updateString("field1", "1");
this.rs.updateString("field2", "1");
this.rs.updateString("field3", "1");
this.rs.updateString("field4", "1");
this.rs.updateString("field5", "1");
this.rs.updateInt("field6", 1);
this.rs.updateString("field7", "1");
this.rs.updateRow();
}
this.conn.commit();
this.conn.setAutoCommit(true);
}
/**
* Test fixes for BUG#1071
*
* @throws Exception
* if the test fails.
*/
public void testUpdatabilityAndEscaping() throws Exception {
Properties props = new Properties();
props.setProperty("useUnicode", "true");
props.setProperty("characterEncoding", "big5");
Connection updConn = getConnectionWithProps(props);
Statement updStmt = updConn.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
try {
updStmt.executeUpdate("DROP TABLE IF EXISTS testUpdatesWithEscaping");
updStmt.executeUpdate("CREATE TABLE testUpdatesWithEscaping (field1 INT PRIMARY KEY, field2 VARCHAR(64))");
updStmt.executeUpdate("INSERT INTO testUpdatesWithEscaping VALUES (1, null)");
String stringToUpdate = "\" \\ '";
this.rs = updStmt
.executeQuery("SELECT * from testUpdatesWithEscaping");
this.rs.next();
this.rs.updateString(2, stringToUpdate);
this.rs.updateRow();
assertTrue(stringToUpdate.equals(this.rs.getString(2)));
} finally {
updStmt.executeUpdate("DROP TABLE IF EXISTS testUpdatesWithEscaping");
updStmt.close();
updConn.close();
}
}
/**
* Tests the fix for BUG#661 ... refreshRow() fails when primary key values
* have escaped data in them.
*
* @throws Exception
* if an error occurs
*/
public void testUpdatabilityWithQuotes() throws Exception {
Statement updStmt = null;
try {
createTable("testUpdWithQuotes",
"(keyField CHAR(32) PRIMARY KEY NOT NULL, field2 int)");
PreparedStatement pStmt = this.conn
.prepareStatement("INSERT INTO testUpdWithQuotes VALUES (?, ?)");
pStmt.setString(1, "Abe's");
pStmt.setInt(2, 1);
pStmt.executeUpdate();
updStmt = this.conn
.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_UPDATABLE);
this.rs = updStmt.executeQuery("SELECT * FROM testUpdWithQuotes");
this.rs.next();
this.rs.updateInt(2, 2);
this.rs.updateRow();
} finally {
if (updStmt != null) {
updStmt.close();
}
updStmt = null;
}
}
/**
* Checks whether or not ResultSet.updateClob() is implemented
*
* @throws Exception
* if the test fails
*/
public void testUpdateClob() throws Exception {
if (isRunningOnJdk131()) {
return; // test not valid on JDK-1.3.1
}
Statement updatableStmt = this.conn.createStatement(
ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
createTable("testUpdateClob",
"(intField INT NOT NULL PRIMARY KEY, clobField TEXT)");
this.stmt.executeUpdate("INSERT INTO testUpdateClob VALUES (1, 'foo')");
this.rs = updatableStmt
.executeQuery("SELECT intField, clobField FROM testUpdateClob");
this.rs.next();
Clob clob = this.rs.getClob(2);
clob.setString(1, "bar");
this.rs.updateClob(2, clob);
this.rs.updateRow();
this.rs.moveToInsertRow();
clob.setString(1, "baz");
this.rs.updateInt(1, 2);
this.rs.updateClob(2, clob);
this.rs.insertRow();
clob.setString(1, "bat");
this.rs.updateInt(1, 3);
this.rs.updateClob(2, clob);
this.rs.insertRow();
this.rs.close();
this.rs = this.stmt
.executeQuery("SELECT intField, clobField FROM testUpdateClob ORDER BY intField");
this.rs.next();
assertTrue((this.rs.getInt(1) == 1)
&& this.rs.getString(2).equals("bar"));
this.rs.next();
assertTrue((this.rs.getInt(1) == 2)
&& this.rs.getString(2).equals("baz"));
this.rs.next();
assertTrue((this.rs.getInt(1) == 3)
&& this.rs.getString(2).equals("bat"));
}
/**
* Tests fix for BUG#4482, ResultSet.getObject() returns wrong type for
* strings when using prepared statements.
*
* @throws Exception
* if the test fails.
*/
public void testBug4482() throws Exception {
this.rs = this.conn.prepareStatement("SELECT 'abcdef'").executeQuery();
assertTrue(this.rs.next());
assertTrue(this.rs.getObject(1) instanceof String);
}
/**
* Test fix for BUG#4689 - WasNull not getting set correctly for binary
* result sets.
*/
public void testBug4689() throws Exception {
createTable("testBug4689",
"(tinyintField tinyint, tinyintFieldNull tinyint, "
+ "intField int, intFieldNull int, "
+ "bigintField bigint, bigintFieldNull bigint, "
+ "shortField smallint, shortFieldNull smallint, "
+ "doubleField double, doubleFieldNull double)");
this.stmt.executeUpdate("INSERT INTO testBug4689 VALUES (1, null, "
+ "1, null, " + "1, null, " + "1, null, " + "1, null)");
PreparedStatement pStmt = this.conn
.prepareStatement("SELECT tinyintField, tinyintFieldNull,"
+ "intField, intFieldNull, "
+ "bigintField, bigintFieldNull, "
+ "shortField, shortFieldNull, "
+ "doubleField, doubleFieldNull FROM testBug4689");
this.rs = pStmt.executeQuery();
assertTrue(this.rs.next());
assertTrue(this.rs.getByte(1) == 1);
assertTrue(this.rs.wasNull() == false);
assertTrue(this.rs.getByte(2) == 0);
assertTrue(this.rs.wasNull() == true);
assertTrue(this.rs.getInt(3) == 1);
assertTrue(this.rs.wasNull() == false);
assertTrue(this.rs.getInt(4) == 0);
assertTrue(this.rs.wasNull() == true);
assertTrue(this.rs.getInt(5) == 1);
assertTrue(this.rs.wasNull() == false);
assertTrue(this.rs.getInt(6) == 0);
assertTrue(this.rs.wasNull() == true);
assertTrue(this.rs.getShort(7) == 1);
assertTrue(this.rs.wasNull() == false);
assertTrue(this.rs.getShort(8) == 0);
assertTrue(this.rs.wasNull() == true);
assertTrue(this.rs.getDouble(9) == 1);
assertTrue(this.rs.wasNull() == false);
assertTrue(this.rs.getDouble(10) == 0);
assertTrue(this.rs.wasNull() == true);
}
/**
* Tests fix for BUG#5032 -- ResultSet.getObject() doesn't return type
* Boolean for pseudo-bit types from prepared statements on 4.1.x.
*
* @throws Exception
* if the test fails.
*/
public void testBug5032() throws Exception {
if (versionMeetsMinimum(4, 1)) {
createTable("testBug5032", "(field1 BIT)");
this.stmt.executeUpdate("INSERT INTO testBug5032 VALUES (1)");
this.pstmt = this.conn
.prepareStatement("SELECT field1 FROM testBug5032");
this.rs = this.pstmt.executeQuery();
assertTrue(this.rs.next());
assertTrue(this.rs.getObject(1) instanceof Boolean);
}
}
/**
* Tests fix for BUG#5069 -- ResultSet.getMetaData() should not return
* incorrectly-initialized metadata if the result set has been closed, but
* should instead throw a SQLException. Also tests fix for getRow() and
* getWarnings() and traversal methods.
*
* @throws Exception
* if the test fails.
*/
public void testBug5069() throws Exception {
this.rs = this.stmt.executeQuery("SELECT 1");
this.rs.close();
try {
@SuppressWarnings("unused")
ResultSetMetaData md = this.rs.getMetaData();
} catch (NullPointerException npEx) {
fail("Should not catch NullPointerException here");
} catch (SQLException sqlEx) {
assertTrue(SQLError.SQL_STATE_GENERAL_ERROR.equals(sqlEx
.getSQLState()));
}
try {
this.rs.getRow();
} catch (NullPointerException npEx) {
fail("Should not catch NullPointerException here");
} catch (SQLException sqlEx) {
assertTrue(SQLError.SQL_STATE_GENERAL_ERROR.equals(sqlEx
.getSQLState()));
}
try {
this.rs.getWarnings();
} catch (NullPointerException npEx) {
fail("Should not catch NullPointerException here");
} catch (SQLException sqlEx) {
assertTrue(SQLError.SQL_STATE_GENERAL_ERROR.equals(sqlEx
.getSQLState()));
}
try {
this.rs.first();
} catch (NullPointerException npEx) {
fail("Should not catch NullPointerException here");
} catch (SQLException sqlEx) {
assertTrue(SQLError.SQL_STATE_GENERAL_ERROR.equals(sqlEx
.getSQLState()));
}
try {
this.rs.beforeFirst();
} catch (NullPointerException npEx) {
fail("Should not catch NullPointerException here");
} catch (SQLException sqlEx) {
assertTrue(SQLError.SQL_STATE_GENERAL_ERROR.equals(sqlEx
.getSQLState()));
}
try {
this.rs.last();
} catch (NullPointerException npEx) {
fail("Should not catch NullPointerException here");
} catch (SQLException sqlEx) {
assertTrue(SQLError.SQL_STATE_GENERAL_ERROR.equals(sqlEx
.getSQLState()));
}
try {
this.rs.afterLast();
} catch (NullPointerException npEx) {
fail("Should not catch NullPointerException here");
} catch (SQLException sqlEx) {
assertTrue(SQLError.SQL_STATE_GENERAL_ERROR.equals(sqlEx
.getSQLState()));
}
try {
this.rs.relative(0);
} catch (NullPointerException npEx) {
fail("Should not catch NullPointerException here");
} catch (SQLException sqlEx) {
assertTrue(SQLError.SQL_STATE_GENERAL_ERROR.equals(sqlEx
.getSQLState()));
}
try {
this.rs.next();
} catch (NullPointerException npEx) {
fail("Should not catch NullPointerException here");
} catch (SQLException sqlEx) {
assertTrue(SQLError.SQL_STATE_GENERAL_ERROR.equals(sqlEx
.getSQLState()));
}
try {
this.rs.previous();
} catch (NullPointerException npEx) {
fail("Should not catch NullPointerException here");
} catch (SQLException sqlEx) {
assertTrue(SQLError.SQL_STATE_GENERAL_ERROR.equals(sqlEx
.getSQLState()));
}
try {
this.rs.isBeforeFirst();
} catch (NullPointerException npEx) {
fail("Should not catch NullPointerException here");
} catch (SQLException sqlEx) {
assertTrue(SQLError.SQL_STATE_GENERAL_ERROR.equals(sqlEx
.getSQLState()));
}
try {
this.rs.isFirst();
} catch (NullPointerException npEx) {
fail("Should not catch NullPointerException here");
} catch (SQLException sqlEx) {
assertTrue(SQLError.SQL_STATE_GENERAL_ERROR.equals(sqlEx
.getSQLState()));
}
try {
this.rs.isAfterLast();
} catch (NullPointerException npEx) {
fail("Should not catch NullPointerException here");
} catch (SQLException sqlEx) {
assertTrue(SQLError.SQL_STATE_GENERAL_ERROR.equals(sqlEx
.getSQLState()));
}
try {
this.rs.isLast();
} catch (NullPointerException npEx) {
fail("Should not catch NullPointerException here");
} catch (SQLException sqlEx) {
assertTrue(SQLError.SQL_STATE_GENERAL_ERROR.equals(sqlEx
.getSQLState()));
}
}
/**
* Tests for BUG#5235, ClassCastException on all-zero date field when
* zeroDatetimeBehavior is 'convertToNull'...however it appears that this
* bug doesn't exist. This is a placeholder until we get more data from the
* user on how they provoke this bug to happen.
*
* @throws Exception
* if the test fails.
*/
public void testBug5235() throws Exception {
createTable("testBug5235", "(field1 DATE)");
this.stmt
.executeUpdate("INSERT INTO testBug5235 (field1) VALUES ('0000-00-00')");
Properties props = new Properties();
props.setProperty("zeroDateTimeBehavior", "convertToNull");
Connection nullConn = getConnectionWithProps(props);
this.rs = nullConn.createStatement().executeQuery(
"SELECT field1 FROM testBug5235");
this.rs.next();
assertTrue(null == this.rs.getObject(1));
}
/**
* Tests for BUG#5136, GEOMETRY types getting corrupted, turns out to be a
* server bug.
*
* @throws Exception
* if the test fails.
*/
public void testBug5136() throws Exception {
if (false) {
PreparedStatement toGeom = this.conn
.prepareStatement("select GeomFromText(?)");
PreparedStatement toText = this.conn
.prepareStatement("select AsText(?)");
String inText = "POINT(146.67596278 -36.54368233)";
// First assert that the problem is not at the server end
this.rs = this.stmt.executeQuery("select AsText(GeomFromText('"
+ inText + "'))");
this.rs.next();
String outText = this.rs.getString(1);
this.rs.close();
assertTrue(
"Server side only\n In: " + inText + "\nOut: " + outText,
inText.equals(outText));
// Now bring a binary geometry object to the client and send it back
toGeom.setString(1, inText);
this.rs = toGeom.executeQuery();
this.rs.next();
// Return a binary geometry object from the WKT
Object geom = this.rs.getObject(1);
this.rs.close();
toText.setObject(1, geom);
this.rs = toText.executeQuery();
this.rs.next();
// Return WKT from the binary geometry
outText = this.rs.getString(1);
this.rs.close();
assertTrue("Server to client and back\n In: " + inText + "\nOut: "
+ outText, inText.equals(outText));
}
}
/**
* Tests fix for BUG#5664, ResultSet.updateByte() when on insert row throws
* ArrayOutOfBoundsException.
*
* @throws Exception
* if the test fails.
*/
public void testBug5664() throws Exception {
createTable("testBug5664",
"(pkfield int PRIMARY KEY NOT NULL, field1 SMALLINT)");
this.stmt.executeUpdate("INSERT INTO testBug5664 VALUES (1, 1)");
Statement updatableStmt = this.conn.createStatement(
ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
this.rs = updatableStmt
.executeQuery("SELECT pkfield, field1 FROM testBug5664");
this.rs.next();
this.rs.moveToInsertRow();
this.rs.updateInt(1, 2);
this.rs.updateByte(2, (byte) 2);
}
public void testBogusTimestampAsString() throws Exception {
this.rs = this.stmt.executeQuery("SELECT '2004-08-13 13:21:17.'");
this.rs.next();
// We're only checking for an exception being thrown here as the bug
this.rs.getTimestamp(1);
}
/**
* Tests our ability to reject NaN and +/- INF in
* PreparedStatement.setDouble();
*/
public void testBug5717() throws Exception {
createTable("testBug5717", "(field1 DOUBLE)");
this.pstmt = this.conn
.prepareStatement("INSERT INTO testBug5717 VALUES (?)");
try {
this.pstmt.setDouble(1, Double.NEGATIVE_INFINITY);
fail("Exception should've been thrown");
} catch (Exception ex) {
// expected
}
try {
this.pstmt.setDouble(1, Double.POSITIVE_INFINITY);
fail("Exception should've been thrown");
} catch (Exception ex) {
// expected
}
try {
this.pstmt.setDouble(1, Double.NaN);
fail("Exception should've been thrown");
} catch (Exception ex) {
// expected
}
}
/**
* Tests fix for server issue that drops precision on aggregate operations
* on DECIMAL types, because they come back as DOUBLEs.
*
* @throws Exception
* if the test fails.
*/
public void testBug6537() throws Exception {
if (versionMeetsMinimum(4, 1, 0)) {
String tableName = "testBug6537";
createTable(
tableName,
"(`id` int(11) NOT NULL default '0',"
+ "`value` decimal(10,2) NOT NULL default '0.00', `stringval` varchar(10),"
+ "PRIMARY KEY (`id`)"
+ ") DEFAULT CHARSET=latin1", "MyISAM");
this.stmt
.executeUpdate("INSERT INTO "
+ tableName
+ "(id, value, stringval) VALUES (1, 100.00, '100.00'), (2, 200, '200')");
String sql = "SELECT SUM(value) as total FROM " + tableName
+ " WHERE id = ? ";
PreparedStatement pStmt = this.conn.prepareStatement(sql);
pStmt.setInt(1, 1);
this.rs = pStmt.executeQuery();
assertTrue(this.rs.next());
assertTrue("100.00".equals(this.rs.getBigDecimal("total")
.toString()));
sql = "SELECT stringval as total FROM " + tableName
+ " WHERE id = ? ";
pStmt = this.conn.prepareStatement(sql);
pStmt.setInt(1, 2);
this.rs = pStmt.executeQuery();
assertTrue(this.rs.next());
assertTrue("200.00".equals(this.rs.getBigDecimal("total", 2)
.toString()));
}
}
/**
* Tests fix for BUG#6231, ResultSet.getTimestamp() on a column with TIME in
* it fails.
*
* @throws Exception
* if the test fails.
*/
public void testBug6231() throws Exception {
createTable("testBug6231", "(field1 TIME)");
this.stmt.executeUpdate("INSERT INTO testBug6231 VALUES ('09:16:00')");
this.rs = this.stmt.executeQuery("SELECT field1 FROM testBug6231");
this.rs.next();
long asMillis = this.rs.getTimestamp(1).getTime();
Calendar cal = Calendar.getInstance();
if (isRunningOnJdk131()) {
cal.setTime(new Date(asMillis));
} else {
cal.setTimeInMillis(asMillis);
}
assertEquals(9, cal.get(Calendar.HOUR));
assertEquals(16, cal.get(Calendar.MINUTE));
assertEquals(0, cal.get(Calendar.SECOND));
}
public void testBug6619() throws Exception {
createTable("testBug6619", "(field1 int)");
this.stmt.executeUpdate("INSERT INTO testBug6619 VALUES (1), (2)");
PreparedStatement pStmt = this.conn
.prepareStatement("SELECT SUM(field1) FROM testBug6619");
this.rs = pStmt.executeQuery();
this.rs.next();
System.out.println(this.rs.getString(1));
}
public void testBug6743() throws Exception {
// 0x835C U+30BD # KATAKANA LETTER SO
String katakanaStr = "\u30BD";
Properties props = new Properties();
props.setProperty("useUnicode", "true");
props.setProperty("characterEncoding", "SJIS");
Connection sjisConn = null;
Statement sjisStmt = null;
try {
sjisConn = getConnectionWithProps(props);
sjisStmt = sjisConn.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE);
sjisStmt.executeUpdate("DROP TABLE IF EXISTS testBug6743");
StringBuffer queryBuf = new StringBuffer(
"CREATE TABLE testBug6743 (pkField INT NOT NULL PRIMARY KEY, field1 VARCHAR(32)");
if (versionMeetsMinimum(4, 1)) {
queryBuf.append(" CHARACTER SET SJIS");
}
queryBuf.append(")");
sjisStmt.executeUpdate(queryBuf.toString());
sjisStmt.executeUpdate("INSERT INTO testBug6743 VALUES (1, 'abc')");
this.rs = sjisStmt
.executeQuery("SELECT pkField, field1 FROM testBug6743");
this.rs.next();
this.rs.updateString(2, katakanaStr);
this.rs.updateRow();
String retrString = this.rs.getString(2);
assertTrue(katakanaStr.equals(retrString));
this.rs = sjisStmt
.executeQuery("SELECT pkField, field1 FROM testBug6743");
this.rs.next();
retrString = this.rs.getString(2);
assertTrue(katakanaStr.equals(retrString));
} finally {
this.stmt.executeUpdate("DROP TABLE IF EXISTS testBug6743");
if (sjisStmt != null) {
sjisStmt.close();
}
if (sjisConn != null) {
sjisConn.close();
}
}
}
/**
* Tests for presence of BUG#6561, NPE thrown when dealing with 0 dates and
* non-unpacked result sets.
*
* @throws Exception
* if the test occurs.
*/
public void testBug6561() throws Exception {
Properties props = new Properties();
props.setProperty("zeroDateTimeBehavior", "convertToNull");
Connection zeroConn = getConnectionWithProps(props);
createTable("testBug6561",
"(ofield int, field1 DATE, field2 integer, field3 integer)");
this.stmt
.executeUpdate("INSERT INTO testBug6561 (ofield, field1,field2,field3) VALUES (1, 0,NULL,0)");
this.stmt
.executeUpdate("INSERT INTO testBug6561 (ofield, field1,field2,field3) VALUES (2, '2004-11-20',NULL,0)");
PreparedStatement ps = zeroConn
.prepareStatement("SELECT field1,field2,field3 FROM testBug6561 ORDER BY ofield");
this.rs = ps.executeQuery();
assertTrue(this.rs.next());
assertTrue(null == this.rs.getObject("field1"));
assertTrue(null == this.rs.getObject("field2"));
assertTrue(0 == this.rs.getInt("field3"));
assertTrue(this.rs.next());
assertEquals("2004-11-20", this.rs.getString("field1"));
assertTrue(null == this.rs.getObject("field2"));
assertTrue(0 == this.rs.getInt("field3"));
ps.close();
}
public void testBug7686() throws SQLException {
String tableName = "testBug7686";
createTable(tableName, "(id1 int(10) unsigned NOT NULL,"
+ " id2 DATETIME, "
+ " field1 varchar(128) NOT NULL default '',"
+ " PRIMARY KEY (id1, id2))", "InnoDB;");
this.stmt.executeUpdate("insert into " + tableName
+ " (id1, id2, field1)"
+ " values (1, '2005-01-05 13:59:20', 'foo')");
String sQuery = " SELECT * FROM " + tableName
+ " WHERE id1 = ? AND id2 = ?";
this.pstmt = this.conn.prepareStatement(sQuery,
ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
this.conn.setAutoCommit(false);
this.pstmt.setInt(1, 1);
GregorianCalendar cal = new GregorianCalendar();
cal.clear();
cal.set(2005, 00, 05, 13, 59, 20);
Timestamp jan5before2pm = null;
if (isRunningOnJdk131()) {
jan5before2pm = new java.sql.Timestamp(cal.getTime().getTime());
} else {
jan5before2pm = new java.sql.Timestamp(cal.getTimeInMillis());
}
this.pstmt.setTimestamp(2, jan5before2pm);
this.rs = this.pstmt.executeQuery();
assertTrue(this.rs.next());
this.rs.absolute(1);
this.rs.updateString("field1", "bar");
this.rs.updateRow();
this.conn.commit();
this.conn.setAutoCommit(true);
}
/**
* Tests fix for BUG#7715 - Timestamps converted incorrectly to strings with
* SSPS and Upd. Result Sets.
*
* @throws Exception
* if the test fails.
*/
public void testBug7715() throws Exception {
PreparedStatement pStmt = null;
createTable(
"testConvertedBinaryTimestamp",
"(field1 VARCHAR(32), field2 VARCHAR(32), field3 VARCHAR(32), field4 TIMESTAMP)");
this.stmt
.executeUpdate("INSERT INTO testConvertedBinaryTimestamp VALUES ('abc', 'def', 'ghi', NOW())");
pStmt = this.conn
.prepareStatement(
"SELECT field1, field2, field3, field4 FROM testConvertedBinaryTimestamp",
ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_UPDATABLE);
this.rs = pStmt.executeQuery();
assertTrue(this.rs.next());
this.rs.getObject(4); // fails if bug exists
}
/**
* Tests fix for BUG#8428 - getString() doesn't maintain format stored on
* server.
*
* @throws Exception
* if the test fails.
*/
public void testBug8428() throws Exception {
Connection noSyncConn = null;
createTable("testBug8428", "(field1 YEAR, field2 DATETIME)");
this.stmt
.executeUpdate("INSERT INTO testBug8428 VALUES ('1999', '2005-02-11 12:54:41')");
Properties props = new Properties();
props.setProperty("noDatetimeStringSync", "true");
props.setProperty("useUsageAdvisor", "true");
props.setProperty("yearIsDateType", "false"); // for 3.1.9+
noSyncConn = getConnectionWithProps(props);
this.rs = noSyncConn.createStatement().executeQuery(
"SELECT field1, field2 FROM testBug8428");
this.rs.next();
assertEquals("1999", this.rs.getString(1));
assertEquals("2005-02-11 12:54:41", this.rs.getString(2));
this.rs = noSyncConn.prepareStatement(
"SELECT field1, field2 FROM testBug8428").executeQuery();
this.rs.next();
assertEquals("1999", this.rs.getString(1));
assertEquals("2005-02-11 12:54:41", this.rs.getString(2));
}
/**
* Tests fix for Bug#8868, DATE_FORMAT() queries returned as BLOBs from
* getObject().
*
* @throws Exception
* if the test fails.
*/
public void testBug8868() throws Exception {
if (versionMeetsMinimum(4, 1)) {
createTable("testBug8868",
"(field1 DATE, field2 VARCHAR(32) CHARACTER SET BINARY)");
this.stmt
.executeUpdate("INSERT INTO testBug8868 VALUES (NOW(), 'abcd')");
this.rs = this.stmt
.executeQuery("SELECT DATE_FORMAT(field1,'%b-%e %l:%i%p') as fmtddate, field2 FROM testBug8868");
this.rs.next();
assertEquals("java.lang.String", this.rs.getObject(1).getClass()
.getName());
}
}
/**
* Tests fix for BUG#9098 - Server doesn't give us info to distinguish
* between CURRENT_TIMESTAMP and 'CURRENT_TIMESTAMP' for default values.
*
* @throws Exception
* if the test fails
*/
public void testBug9098() throws Exception {
if (versionMeetsMinimum(4, 1, 10)) {
Statement updatableStmt = null;
createTable(
"testBug9098",
"(pkfield INT PRIMARY KEY NOT NULL AUTO_INCREMENT, \n"
+ "tsfield TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, tsfield2 TIMESTAMP NOT NULL DEFAULT '2005-12-25 12:20:52', charfield VARCHAR(4) NOT NULL DEFAULT 'abcd')");
updatableStmt = this.conn.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE);
this.rs = updatableStmt
.executeQuery("SELECT pkfield, tsfield, tsfield2, charfield FROM testBug9098");
this.rs.moveToInsertRow();
this.rs.insertRow();
}
}
/**
* Tests fix for BUG#9236, a continuation of BUG#8868, where functions used
* in queries that should return non-string types when resolved by temporary
* tables suddenly become opaque binary strings (work-around for server
* limitation)
*
* @throws Exception
* if the test fails.
*/
public void testBug9236() throws Exception {
if (versionMeetsMinimum(4, 1)) {
createTable(
"testBug9236",
"("
+ "field_1 int(18) NOT NULL auto_increment,"
+ "field_2 varchar(50) NOT NULL default '',"
+ "field_3 varchar(12) default NULL,"
+ "field_4 int(18) default NULL,"
+ "field_5 int(18) default NULL,"
+ "field_6 datetime default NULL,"
+ "field_7 varchar(30) default NULL,"
+ "field_8 varchar(50) default NULL,"
+ "field_9 datetime default NULL,"
+ "field_10 int(18) NOT NULL default '0',"
+ "field_11 int(18) default NULL,"
+ "field_12 datetime NOT NULL default '0000-00-00 00:00:00',"
+ "PRIMARY KEY (field_1)," + "KEY (field_4),"
+ "KEY (field_2)," + "KEY (field_3),"
+ "KEY (field_7,field_1)," + "KEY (field_5),"
+ "KEY (field_6,field_10,field_9),"
+ "KEY (field_11,field_10),"
+ "KEY (field_12,field_10)"
+ ") DEFAULT CHARSET=latin1", "InnoDB");
this.stmt
.executeUpdate("INSERT INTO testBug9236 VALUES "
+ "(1,'0',NULL,-1,0,'0000-00-00 00:00:00','123456789','-1','2004-03-13 14:21:38',0,NULL,'2004-03-13 14:21:38'),"
+ "(2,'0',NULL,1,0,'0000-00-00 00:00:00',NULL,'1',NULL,0,NULL,'2004-07-13 14:29:52'),"
+ "(3,'0',NULL,1,0,'0000-00-00 00:00:00',NULL,'2',NULL,0,NULL,'2004-07-16 13:20:51'),"
+ "(4,'0',NULL,1,0,'0000-00-00 00:00:00',NULL,'3','2004-07-16 13:43:39',0,NULL,'2004-07-16 13:22:01'),"
+ "(5,'0',NULL,1,0,'0000-00-00 00:00:00',NULL,'4','2004-07-16 13:23:48',0,NULL,'2004-07-16 13:23:01'),"
+ "(6,'0',NULL,1,0,'0000-00-00 00:00:00',NULL,'5',NULL,0,NULL,'2004-07-16 14:41:07'),"
+ "(7,'0',NULL,1,0,'0000-00-00 00:00:00',NULL,'6',NULL,0,NULL,'2004-07-16 14:41:34'),"
+ "(8,'0',NULL,1,0,'0000-00-00 00:00:00',NULL,'7',NULL,0,NULL,'2004-07-16 14:41:54'),"
+ "(9,'0',NULL,1,0,'0000-00-00 00:00:00',NULL,'8',NULL,0,NULL,'2004-07-16 14:42:42'),"
+ "(10,'0','PI',1,0,'0000-00-00 00:00:00',NULL,'9',NULL,0,NULL,'2004-07-18 10:51:30'),"
+ "(11,'0',NULL,1,0,'0000-00-00 00:00:00',NULL,'10','2004-07-23 17:23:06',0,NULL,'2004-07-23 17:18:19'),"
+ "(12,'0',NULL,1,0,'0000-00-00 00:00:00',NULL,'11','2004-07-23 17:24:45',0,NULL,'2004-07-23 17:23:57'),"
+ "(13,'0',NULL,1,0,'0000-00-00 00:00:00',NULL,'12','2004-07-23 17:30:51',0,NULL,'2004-07-23 17:30:15'),"
+ "(14,'0',NULL,1,0,'0000-00-00 00:00:00',NULL,'13','2004-07-26 17:50:19',0,NULL,'2004-07-26 17:49:38'),"
+ "(15,'0','FRL',1,0,'0000-00-00 00:00:00',NULL,'1',NULL,0,NULL,'2004-08-19 18:29:18'),"
+ "(16,'0','FRL',1,0,'0000-00-00 00:00:00',NULL,'15',NULL,0,NULL,'2005-03-16 12:08:28')");
createTable("testBug9236_1",
"(field1 CHAR(2) CHARACTER SET BINARY)");
this.stmt.executeUpdate("INSERT INTO testBug9236_1 VALUES ('ab')");
this.rs = this.stmt
.executeQuery("SELECT field1 FROM testBug9236_1");
ResultSetMetaData rsmd = this.rs.getMetaData();
assertEquals("[B", rsmd.getColumnClassName(1));
assertTrue(this.rs.next());
Object asObject = this.rs.getObject(1);
assertEquals("[B", asObject.getClass().getName());
this.rs = this.stmt
.executeQuery("select DATE_FORMAT(field_12, '%Y-%m-%d') as date, count(*) as count from testBug9236 where field_10 = 0 and field_3 = 'FRL' and field_12 >= '2005-03-02 00:00:00' and field_12 <= '2005-03-17 00:00:00' group by date");
rsmd = this.rs.getMetaData();
assertEquals("java.lang.String", rsmd.getColumnClassName(1));
this.rs.next();
asObject = this.rs.getObject(1);
assertEquals("java.lang.String", asObject.getClass().getName());
this.rs.close();
createTable("testBug8868_2",
"(field1 CHAR(4) CHARACTER SET BINARY)");
this.stmt.executeUpdate("INSERT INTO testBug8868_2 VALUES ('abc')");
this.rs = this.stmt
.executeQuery("SELECT field1 FROM testBug8868_2");
rsmd = this.rs.getMetaData();
assertEquals("[B", rsmd.getColumnClassName(1));
this.rs.next();
asObject = this.rs.getObject(1);
assertEquals("[B", asObject.getClass().getName());
}
}
/**
* Tests fix for BUG#9437, IF() returns type of [B or java.lang.String
* depending on platform. Fixed earlier, but in here to catch if it ever
* regresses.
*
* @throws Exception
* if the test fails.
*/
public void testBug9437() throws Exception {
String tableName = "testBug9437";
if (versionMeetsMinimum(4, 1, 0)) {
createTable(
tableName,
"("
+ "languageCode char(2) NOT NULL default '',"
+ "countryCode char(2) NOT NULL default '',"
+ "supported enum('no','yes') NOT NULL default 'no',"
+ "ordering int(11) default NULL,"
+ "createDate datetime NOT NULL default '1000-01-01 00:00:03',"
+ "modifyDate timestamp NOT NULL default CURRENT_TIMESTAMP on update"
+ " CURRENT_TIMESTAMP,"
+ "PRIMARY KEY (languageCode,countryCode),"
+ "KEY languageCode (languageCode),"
+ "KEY countryCode (countryCode),"
+ "KEY ordering (ordering),"
+ "KEY modifyDate (modifyDate)"
+ ") DEFAULT CHARSET=utf8", "InnoDB");
this.stmt.executeUpdate("INSERT INTO " + tableName
+ " (languageCode) VALUES ('en')");
String alias = "someLocale";
String sql = "select if ( languageCode = ?, ?, ? ) as " + alias
+ " from " + tableName;
this.pstmt = this.conn.prepareStatement(sql);
int count = 1;
this.pstmt.setObject(count++, "en");
this.pstmt.setObject(count++, "en_US");
this.pstmt.setObject(count++, "en_GB");
this.rs = this.pstmt.executeQuery();
assertTrue(this.rs.next());
Object object = this.rs.getObject(alias);
if (object != null) {
assertEquals("java.lang.String", object.getClass().getName());
assertEquals("en_US", object.toString());
}
}
}
public void testBug9684() throws Exception {
if (versionMeetsMinimum(4, 1, 9)) {
String tableName = "testBug9684";
createTable(tableName,
"(sourceText text character set utf8 collate utf8_bin)");
this.stmt.executeUpdate("INSERT INTO " + tableName
+ " VALUES ('abc')");
this.rs = this.stmt.executeQuery("SELECT sourceText FROM "
+ tableName);
assertTrue(this.rs.next());
assertEquals("java.lang.String", this.rs.getString(1).getClass()
.getName());
assertEquals("abc", this.rs.getString(1));
}
}
/**
* Tests fix for BUG#10156 - Unsigned SMALLINT treated as signed
*
* @throws Exception
* if the test fails.
*/
public void testBug10156() throws Exception {
String tableName = "testBug10156";
createTable(tableName, "(field1 smallint(5) unsigned, "
+ "field2 tinyint unsigned," + "field3 int unsigned)");
this.stmt.executeUpdate("INSERT INTO " + tableName
+ " VALUES (32768, 255, 4294967295)");
this.rs = this.conn.prepareStatement(
"SELECT field1, field2, field3 FROM " + tableName)
.executeQuery();
assertTrue(this.rs.next());
assertEquals(32768, this.rs.getInt(1));
assertEquals(255, this.rs.getInt(2));
assertEquals(4294967295L, this.rs.getLong(3));
assertEquals(String.valueOf(this.rs.getObject(1)),
String.valueOf(this.rs.getInt(1)));
assertEquals(String.valueOf(this.rs.getObject(2)),
String.valueOf(this.rs.getInt(2)));
assertEquals(String.valueOf(this.rs.getObject(3)),
String.valueOf(this.rs.getLong(3)));
}
public void testBug10212() throws Exception {
String tableName = "testBug10212";
createTable(tableName, "(field1 YEAR(4))");
this.stmt.executeUpdate("INSERT INTO " + tableName + " VALUES (1974)");
this.rs = this.conn.prepareStatement("SELECT field1 FROM " + tableName)
.executeQuery();
ResultSetMetaData rsmd = this.rs.getMetaData();
assertTrue(this.rs.next());
assertEquals("java.sql.Date", rsmd.getColumnClassName(1));
assertEquals("java.sql.Date", this.rs.getObject(1).getClass().getName());
this.rs = this.stmt.executeQuery("SELECT field1 FROM " + tableName);
rsmd = this.rs.getMetaData();
assertTrue(this.rs.next());
assertEquals("java.sql.Date", rsmd.getColumnClassName(1));
assertEquals("java.sql.Date", this.rs.getObject(1).getClass().getName());
}
/**
* Tests fix for BUG#11190 - ResultSet.moveToCurrentRow() fails to work when
* preceeded with .moveToInsertRow().
*
* @throws Exception
* if the test fails.
*/
public void testBug11190() throws Exception {
createTable("testBug11190", "(a CHAR(4) PRIMARY KEY, b VARCHAR(20))");
this.stmt
.executeUpdate("INSERT INTO testBug11190 VALUES('3000','L'),('3001','H'),('1050','B')");
Statement updStmt = null;
try {
updStmt = this.conn
.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_UPDATABLE);
this.rs = updStmt.executeQuery("select * from testBug11190");
assertTrue("must return a row", this.rs.next());
String savedValue = this.rs.getString(1);
this.rs.moveToInsertRow();
this.rs.updateString(1, "4000");
this.rs.updateString(2, "C");
this.rs.insertRow();
this.rs.moveToCurrentRow();
assertEquals(savedValue, this.rs.getString(1));
} finally {
if (updStmt != null) {
updStmt.close();
}
}
}
/**
* Tests fix for BUG#12104 - Geometry types not handled with server-side
* prepared statements.
*
* @throws Exception
* if the test fails
*/
public void testBug12104() throws Exception {
if (versionMeetsMinimum(4, 1)) {
createTable("testBug12104", "(field1 GEOMETRY)", "MyISAM");
this.stmt
.executeUpdate("INSERT INTO testBug12104 VALUES (GeomFromText('POINT(1 1)'))");
this.pstmt = this.conn
.prepareStatement("SELECT field1 FROM testBug12104");
this.rs = this.pstmt.executeQuery();
assertTrue(this.rs.next());
System.out.println(this.rs.getObject(1));
}
}
/**
* Tests fix for BUG#13043 - when 'gatherPerfMetrics' is enabled for servers
* < 4.1.0, a NPE is thrown from the constructor of ResultSet if the query
* doesn't use any tables.
*
* @throws Exception
* if the test fails
*/
public void testBug13043() throws Exception {
if (!versionMeetsMinimum(4, 1)) {
Connection perfConn = null;
try {
Properties props = new Properties();
props.put("gatherPerfMetrics", "true"); // this property is
// reported as the cause
// of
// NullPointerException
props.put("reportMetricsIntervalMillis", "30000"); // this
// property
// is
// reported
// as the
// cause of
// NullPointerException
perfConn = getConnectionWithProps(props);
perfConn.createStatement().executeQuery("SELECT 1");
} finally {
if (perfConn != null) {
perfConn.close();
}
}
}
}
/**
* Tests fix for BUG#13374 - ResultSet.getStatement() on closed result set
* returns NULL (as per JDBC 4.0 spec, but not backwards-compatible).
*
* @throws Exception
* if the test fails
*/
public void testBug13374() throws Exception {
Statement retainStmt = null;
Connection retainConn = null;
try {
Properties props = new Properties();
props.setProperty("retainStatementAfterResultSetClose", "true");
retainConn = getConnectionWithProps(props);
retainStmt = retainConn.createStatement();
this.rs = retainStmt.executeQuery("SELECT 1");
this.rs.close();
assertNotNull(this.rs.getStatement());
this.rs = this.stmt.executeQuery("SELECT 1");
this.rs.close();
try {
this.rs.getStatement();
} catch (SQLException sqlEx) {
assertEquals(sqlEx.getSQLState(),
SQLError.SQL_STATE_GENERAL_ERROR);
}
} finally {
if (retainStmt != null) {
retainStmt.close();
}
if (retainConn != null) {
retainConn.close();
}
}
}
/**
* Tests bugfix for BUG#14562 - metadata/type for MEDIUMINT UNSIGNED is
* incorrect.
*
* @throws Exception
* if the test fails.
*/
public void testBug14562() throws Exception {
createTable("testBug14562",
"(row_order INT, signed_field MEDIUMINT, unsigned_field MEDIUMINT UNSIGNED)");
this.stmt
.executeUpdate("INSERT INTO testBug14562 VALUES (1, -8388608, 0), (2, 8388607, 16777215)");
this.rs = this.stmt
.executeQuery("SELECT signed_field, unsigned_field FROM testBug14562 ORDER BY row_order");
traverseResultSetBug14562();
this.rs = this.conn
.prepareStatement(
"SELECT signed_field, unsigned_field FROM testBug14562 ORDER BY row_order")
.executeQuery();
traverseResultSetBug14562();
if (versionMeetsMinimum(5, 0)) {
CallableStatement storedProc = null;
try {
createProcedure(
"sp_testBug14562",
"() BEGIN SELECT signed_field, unsigned_field FROM testBug14562 ORDER BY row_order; END");
storedProc = this.conn.prepareCall("{call sp_testBug14562()}");
storedProc.execute();
this.rs = storedProc.getResultSet();
traverseResultSetBug14562();
createProcedure(
"sp_testBug14562_1",
"(OUT param_1 MEDIUMINT, OUT param_2 MEDIUMINT UNSIGNED) BEGIN SELECT signed_field, unsigned_field INTO param_1, param_2 FROM testBug14562 WHERE row_order=1; END");
storedProc = this.conn
.prepareCall("{call sp_testBug14562_1(?, ?)}");
storedProc.registerOutParameter(1, Types.INTEGER);
storedProc.registerOutParameter(2, Types.INTEGER);
storedProc.execute();
assertEquals("java.lang.Integer", storedProc.getObject(1)
.getClass().getName());
if (versionMeetsMinimum(5, 1) || versionMeetsMinimum(5, 0, 67)) {
assertEquals("java.lang.Long", storedProc.getObject(2)
.getClass().getName());
} else {
assertEquals("java.lang.Integer", storedProc.getObject(2)
.getClass().getName());
}
} finally {
if (storedProc != null) {
storedProc.close();
}
}
}
this.rs = this.conn.getMetaData().getColumns(this.conn.getCatalog(),
null, "testBug14562", "%field");
assertTrue(this.rs.next());
assertEquals(Types.INTEGER, this.rs.getInt("DATA_TYPE"));
assertEquals("MEDIUMINT",
this.rs.getString("TYPE_NAME").toUpperCase(Locale.US));
assertTrue(this.rs.next());
assertEquals(Types.INTEGER, this.rs.getInt("DATA_TYPE"));
assertEquals("MEDIUMINT UNSIGNED", this.rs.getString("TYPE_NAME")
.toUpperCase(Locale.US));
//
// The following test is harmless in the 3.1 driver, but
// is needed for the 5.0 driver, so we'll leave it here
//
if (versionMeetsMinimum(5, 0, 14)) {
Connection infoSchemConn = null;
try {
Properties props = new Properties();
props.setProperty("useInformationSchema", "true");
infoSchemConn = getConnectionWithProps(props);
this.rs = infoSchemConn.getMetaData().getColumns(
infoSchemConn.getCatalog(), null, "testBug14562",
"%field");
assertTrue(this.rs.next());
assertEquals(Types.INTEGER, this.rs.getInt("DATA_TYPE"));
assertEquals("MEDIUMINT", this.rs.getString("TYPE_NAME")
.toUpperCase(Locale.US));
assertTrue(this.rs.next());
assertEquals(Types.INTEGER, this.rs.getInt("DATA_TYPE"));
assertEquals("MEDIUMINT UNSIGNED",
this.rs.getString("TYPE_NAME").toUpperCase(Locale.US));
} finally {
if (infoSchemConn != null) {
infoSchemConn.close();
}
}
}
}
public void testBug15604() throws Exception {
createTable("testBug15604_date_cal", "(field1 DATE)");
Properties props = new Properties();
props.setProperty("useLegacyDatetimeCode", "false");
props.setProperty("sessionVariables", "time_zone='America/Chicago'");
Connection nonLegacyConn = getConnectionWithProps(props);
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
cal.set(Calendar.YEAR, 2005);
cal.set(Calendar.MONTH, 4);
cal.set(Calendar.DAY_OF_MONTH, 15);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
java.sql.Date sqlDate = new java.sql.Date(cal.getTime().getTime());
Calendar cal2 = Calendar.getInstance();
cal2.setTime(sqlDate);
System.out.println(new java.sql.Date(cal2.getTime().getTime()));
this.pstmt = nonLegacyConn
.prepareStatement("INSERT INTO testBug15604_date_cal VALUES (?)");
this.pstmt.setDate(1, sqlDate, cal);
this.pstmt.executeUpdate();
this.rs = nonLegacyConn.createStatement().executeQuery(
"SELECT field1 FROM testBug15604_date_cal");
this.rs.next();
assertEquals(sqlDate.getTime(), this.rs.getDate(1, cal).getTime());
}
public void testBug14897() throws Exception {
createTable("table1", "(id int, name_id int)");
createTable("table2", "(id int)");
createTable(
"lang_table",
"(id int, en varchar(255) CHARACTER SET utf8, cz varchar(255) CHARACTER SET utf8)");
this.stmt.executeUpdate("insert into table1 values (0, 0)");
this.stmt.executeUpdate("insert into table2 values (0)");
this.stmt
.executeUpdate("insert into lang_table values (0, 'abcdef', 'ghijkl')");
this.rs = this.stmt
.executeQuery("select a.id, b.id, c.en, c.cz from table1 as a, table2 as b, lang_table as c where a.id = b.id and a.name_id = c.id");
assertTrue(this.rs.next());
this.rs.getString("c.cz");
this.rs = this.stmt
.executeQuery("select table1.*, table2.* FROM table1, table2");
this.rs.findColumn("table1.id");
this.rs.findColumn("table2.id");
}
/**
* Tests fix for BUG#14609 - Exception thrown for new decimal type when
* using updatable result sets.
*
* @throws Exception
* if the test fails
*/
public void testBug14609() throws Exception {
if (versionMeetsMinimum(5, 0)) {
createTable("testBug14609",
"(field1 int primary key, field2 decimal)");
this.stmt.executeUpdate("INSERT INTO testBug14609 VALUES (1, 1)");
PreparedStatement updatableStmt = this.conn.prepareStatement(
"SELECT field1, field2 FROM testBug14609",
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE);
try {
this.rs = updatableStmt.executeQuery();
} finally {
if (updatableStmt != null) {
updatableStmt.close();
}
}
}
}
/**
* Tests fix for BUG#16169 - ResultSet.getNativeShort() causes stack
* overflow error via recurisve calls.
*
* @throws Exception
* if the tests fails
*/
public void testBug16169() throws Exception {
createTable("testBug16169", "(field1 smallint)");
this.stmt.executeUpdate("INSERT INTO testBug16169 (field1) VALUES (0)");
this.pstmt = this.conn.prepareStatement("SELECT * FROM testBug16169");
this.rs = this.pstmt.executeQuery();
assertTrue(this.rs.next());
assertEquals(0, ((Integer) rs.getObject("field1")).intValue());
}
/**
* Tests fix for BUG#16841 - updatable result set doesn't return
* AUTO_INCREMENT values for insertRow() when multiple column primary keys
* are used.
*
* @throws Exception
* if the test fails.
*/
public void testBug16841() throws Exception {
createTable("testBug16841", "(" + "CID int( 20 ) NOT NULL default '0',"
+ "OID int( 20 ) NOT NULL AUTO_INCREMENT ,"
+ "PatientID int( 20 ) default NULL ,"
+ "PRIMARY KEY ( CID , OID ) ," + "KEY OID ( OID ) ,"
+ "KEY Path ( CID, PatientID)" + ")", "MYISAM");
String sSQLQuery = "SELECT * FROM testBug16841 WHERE 1 = 0";
Statement updStmt = null;
try {
updStmt = this.conn.createStatement(ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_UPDATABLE);
this.rs = updStmt.executeQuery(sSQLQuery);
this.rs.moveToInsertRow();
this.rs.updateInt("CID", 1);
this.rs.updateInt("PatientID", 1);
this.rs.insertRow();
this.rs.last();
assertEquals(1, this.rs.getInt("OID"));
} finally {
if (updStmt != null) {
updStmt.close();
}
}
}
/**
* Tests fix for BUG#17450 - ResultSet.wasNull() not always reset correctly
* for booleans when done via conversion for server-side prepared
* statements.
*
* @throws Exception
* if the test fails.
*/
public void testBug17450() throws Exception {
if (versionMeetsMinimum(4, 1, 0)) {
createTable("testBug17450", "(FOO VARCHAR(100), BAR CHAR NOT NULL)");
this.stmt
.execute("insert into testBug17450 (foo,bar) values ('foo',true)");
this.stmt
.execute("insert into testBug17450 (foo,bar) values (null,true)");
this.pstmt = this.conn
.prepareStatement("select * from testBug17450 where foo=?");
this.pstmt.setString(1, "foo");
this.rs = this.pstmt.executeQuery();
checkResult17450();
this.pstmt = this.conn
.prepareStatement("select * from testBug17450 where foo is null");
this.rs = this.pstmt.executeQuery();
checkResult17450();
this.rs = this.stmt
.executeQuery("select * from testBug17450 where foo='foo'");
checkResult17450();
this.rs = this.stmt
.executeQuery("select * from testBug17450 where foo is null");
checkResult17450();
}
}
/**
* Tests fix for BUG#19282 - ResultSet.wasNull() returns incorrect value
* when extracting native string from server-side prepared statement
* generated result set.
*
* @throws Exception
* if the test fails.
*/
public void testBug19282() throws Exception {
createTable("testBug19282", "(field1 VARCHAR(32))");
this.pstmt = this.conn
.prepareStatement("SELECT field1 FROM testBug19282");
this.stmt.executeUpdate("INSERT INTO testBug19282 VALUES ('abcdefg')");
this.rs = this.pstmt.executeQuery();
this.rs.next();
assertEquals(false, this.rs.wasNull());
this.rs.getString(1);
assertEquals(false, this.rs.wasNull());
}
private void checkResult17450() throws Exception {
this.rs.next();
this.rs.getString(1);
boolean bar = this.rs.getBoolean(2);
assertEquals("field 2 should be true", true, bar);
assertFalse("wasNull should return false", this.rs.wasNull());
}
/**
* Tests fix for BUG#
*
* @throws Exception
*/
public void testBug19568() throws Exception {
if (versionMeetsMinimum(4, 1, 0)) {
createTable("testBug19568", "(field1 BOOLEAN,"
+ (versionMeetsMinimum(5, 0, 0) ? "field2 BIT"
: "field2 BOOLEAN") + ")");
this.stmt
.executeUpdate("INSERT INTO testBug19568 VALUES (1,0), (0, 1)");
this.pstmt = this.conn
.prepareStatement("SELECT field1, field2 FROM testBug19568 ORDER BY field1 DESC");
this.rs = this.pstmt.executeQuery();
checkResultsBug19568();
this.rs = this.stmt
.executeQuery("SELECT field1, field2 FROM testBug19568 ORDER BY field1 DESC");
checkResultsBug19568();
}
}
private void checkResultsBug19568() throws SQLException {
// Test all numerical getters, and make sure to alternate true/false
// across rows so we can catch
// false-positives if off-by-one errors exist in the column getters.
for (int i = 0; i < 2; i++) {
assertTrue(this.rs.next());
for (int j = 0; j < 2; j++) {
assertEquals((i == 1 && j == 1) || (i == 0 && j == 0),
this.rs.getBoolean(j + 1));
assertEquals(
((i == 1 && j == 1) || (i == 0 && j == 0) ? 1 : 0),
this.rs.getBigDecimal(j + 1).intValue());
assertEquals(
((i == 1 && j == 1) || (i == 0 && j == 0) ? 1 : 0),
this.rs.getByte(j + 1));
assertEquals(
((i == 1 && j == 1) || (i == 0 && j == 0) ? 1 : 0),
this.rs.getShort(j + 1));
assertEquals(
((i == 1 && j == 1) || (i == 0 && j == 0) ? 1 : 0),
this.rs.getInt(j + 1));
assertEquals(
((i == 1 && j == 1) || (i == 0 && j == 0) ? 1 : 0),
this.rs.getLong(j + 1));
assertEquals(
((i == 1 && j == 1) || (i == 0 && j == 0) ? 1 : 0),
this.rs.getFloat(j + 1), .1);
assertEquals(
((i == 1 && j == 1) || (i == 0 && j == 0) ? 1 : 0),
this.rs.getDouble(j + 1), .1);
}
}
}
public void testBug19724() throws Exception {
if (versionMeetsMinimum(4, 1)) {
// can't set this via session on 4.0 :(
createTable("test19724",
"(col1 INTEGER NOT NULL, col2 VARCHAR(255) NULL, PRIMARY KEY (col1))");
this.stmt
.execute("INSERT IGNORE INTO test19724 VALUES (0, 'Blah'),(1,'Boo')");
Connection ansiConn = null;
Statement updStmt = null;
Properties props = new Properties();
props.setProperty("sessionVariables", "sql_mode=ansi");
try {
ansiConn = getConnectionWithProps(props);
updStmt = ansiConn.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE);
this.rs = updStmt.executeQuery("SELECT * FROM test19724");
this.rs.beforeFirst();
this.rs.next();
this.rs.updateString("col2", "blah2");
this.rs.updateRow();
} finally {
if (ansiConn != null) {
ansiConn.close();
}
}
}
}
private void traverseResultSetBug14562() throws SQLException {
assertTrue(this.rs.next());
ResultSetMetaData rsmd = this.rs.getMetaData();
assertEquals("MEDIUMINT", rsmd.getColumnTypeName(1));
assertEquals("MEDIUMINT UNSIGNED", rsmd.getColumnTypeName(2));
assertEquals(Types.INTEGER, rsmd.getColumnType(1));
assertEquals(Types.INTEGER, rsmd.getColumnType(2));
assertEquals("java.lang.Integer", rsmd.getColumnClassName(1));
assertEquals("java.lang.Integer", rsmd.getColumnClassName(2));
assertEquals(-8388608, this.rs.getInt(1));
assertEquals(0, this.rs.getInt(2));
assertEquals("java.lang.Integer", this.rs.getObject(1).getClass()
.getName());
assertEquals("java.lang.Integer", this.rs.getObject(2).getClass()
.getName());
assertTrue(this.rs.next());
assertEquals(8388607, this.rs.getInt(1));
assertEquals(16777215, this.rs.getInt(2));
assertEquals("java.lang.Integer", this.rs.getObject(1).getClass()
.getName());
assertEquals("java.lang.Integer", this.rs.getObject(2).getClass()
.getName());
}
/*
* public void testBug16458() throws Exception { createTable("a", "(id
* INTEGER NOT NULL, primary key (id)) Type=InnoDB"); createTable("b", "(id
* INTEGER NOT NULL, primary key (id)) Type=InnoDB"); createTable("c", "(id
* INTEGER NOT NULL, primary key (id)) Type=InnoDB");
*
* createTable( "problem_table", "(id int(11) NOT NULL auto_increment," +
* "a_id int(11) NOT NULL default '0'," + "b_id int(11) NOT NULL default
* '0'," + "c_id int(11) default NULL," + "order_num int(2) NOT NULL default
* '0'," + "PRIMARY KEY (id)," + "KEY idx_problem_table__b_id (b_id)," +
* "KEY idx_problem_table__a_id (a_id)," + "KEY idx_problem_table__c_id
* (c_id)," + "CONSTRAINT fk_problem_table__c FOREIGN KEY (c_id) REFERENCES
* c (id)," + "CONSTRAINT fk_problem_table__a FOREIGN KEY (a_id) REFERENCES
* a (id)," + "CONSTRAINT fk_problem_table__b FOREIGN KEY (b_id) REFERENCES
* b (id)" + ")" + "Type=InnoDB");
*
* this.stmt .executeUpdate("INSERT INTO `a` VALUES " +
* "(1),(4),(9),(10),(11),(12),(13),(14),(15),(16),(17),(18),(19),(20),(21),(22),(23"
* +
* "),(24),(25),(26),(27),(28),(29),(30),(31),(32),(33),(34),(35),(36),(37),(38),(39"
* + "),(40),(41),(42),(43),(45),(46),(47),(48),(49),(50)");
*
* this.stmt .executeUpdate("INSERT INTO `b` VALUES " +
* "(1),(2),(4),(5),(6),(7),(8),(9),(10),(11),(12),(13),(14),(15),(16),(17),(18),(19"
* + "),(20)");
*
* this.stmt .executeUpdate("INSERT INTO `c` VALUES " +
* "(1),(2),(3),(13),(15),(16),(22),(30),(31),(32),(33),(34),(35),(36),(37),(148),(1"
* +
* "59),(167),(174),(176),(177),(178),(179),(180),(187),(188),(189),(190),(191),(192"
* +
* "),(193),(194),(195),(196),(197),(198),(199),(200),(201),(202),(203),(204),(205),"
* + "(206),(207),(208)");
*
* this.stmt .executeUpdate("INSERT INTO `problem_table` VALUES " +
* "(1,1,1,NULL,1),(2,1,4,NULL,1),(3,1,5,NULL,1),(4,1,8,NULL,1),(5,23,1,NULL,1),(6,2"
* +
* "3,4,NULL,1),(7,24,1,NULL,1),(8,24,2,NULL,1),(9,24,4,NULL,1),(10,25,1,NULL,1),(11"
* +
* ",25,2,NULL,1),(12,25,4,NULL,1),(13,27,1,NULL,1),(14,28,1,NULL,1),(15,29,1,NULL,1"
* +
* "),(16,15,2,NULL,1),(17,15,5,NULL,1),(18,15,8,NULL,1),(19,30,1,NULL,1),(20,31,1,N"
* +
* "ULL,1),(21,31,4,NULL,1),(22,32,2,NULL,1),(23,32,4,NULL,1),(24,32,6,NULL,1),(25,3"
* +
* "2,8,NULL,1),(26,32,10,NULL,1),(27,32,11,NULL,1),(28,32,13,NULL,1),(29,32,16,NULL"
* +
* ",1),(30,32,17,NULL,1),(31,32,18,NULL,1),(32,32,19,NULL,1),(33,32,20,NULL,1),(34,"
* +
* "33,15,NULL,1),(35,33,15,NULL,1),(36,32,20,206,1),(96,32,9,NULL,1),(100,47,6,NULL"
* + ",1),(101,47,10,NULL,1),(102,47,5,NULL,1),(105,47,19,NULL,1)");
* PreparedStatement ps = null;
*
* try { ps = conn.prepareStatement("SELECT DISTINCT id,order_num FROM
* problem_table WHERE a_id=? FOR UPDATE", ResultSet.TYPE_FORWARD_ONLY,
* ResultSet.CONCUR_UPDATABLE);
*
* ps.setInt(1, 32);
*
* this.rs = ps.executeQuery();
*
* while(this.rs.next()) { this.rs.updateInt(3, 51);
*
* this.rs.updateRow(); } } finally { if (this.rs != null) { ResultSet
* toCloseRs = this.rs; this.rs = null; toCloseRs.close(); }
*
* if (ps != null) { PreparedStatement toClosePs = ps; ps = null;
* toClosePs.close(); } } }
*/
public void testNPEWithUsageAdvisor() throws Exception {
Connection advisorConn = null;
Properties props = new Properties();
props.setProperty("useUsageAdvisor", "true");
advisorConn = getConnectionWithProps(props);
this.pstmt = advisorConn.prepareStatement("SELECT 1");
this.rs = this.pstmt.executeQuery();
this.rs.close();
this.rs = this.pstmt.executeQuery();
}
public void testAllTypesForNull() throws Exception {
if (!isRunningOnJdk131()) {
Properties props = new Properties();
props.setProperty("jdbcCompliantTruncation", "false");
props.setProperty("zeroDateTimeBehavior", "round");
Connection conn2 = getConnectionWithProps(props);
Statement stmt2 = conn2.createStatement();
DatabaseMetaData dbmd = this.conn.getMetaData();
this.rs = dbmd.getTypeInfo();
boolean firstColumn = true;
int numCols = 1;
StringBuffer createStatement = new StringBuffer(
"CREATE TABLE testAllTypes (");
List<Boolean> wasDatetimeTypeList = new ArrayList<Boolean>();
while (this.rs.next()) {
String dataType = this.rs.getString("TYPE_NAME").toUpperCase();
boolean wasDateTime = false;
if (dataType.indexOf("DATE") != -1
|| dataType.indexOf("TIME") != -1) {
wasDateTime = true;
}
if (!"BOOL".equalsIgnoreCase(dataType)
&& !"LONG VARCHAR".equalsIgnoreCase(dataType)
&& !"LONG VARBINARY".equalsIgnoreCase(dataType)
&& !"ENUM".equalsIgnoreCase(dataType)
&& !"SET".equalsIgnoreCase(dataType)) {
wasDatetimeTypeList.add(new Boolean(wasDateTime));
createStatement.append("\n\t");
if (!firstColumn) {
createStatement.append(",");
} else {
firstColumn = false;
}
createStatement.append("field_");
createStatement.append(numCols++);
createStatement.append(" ");
createStatement.append(dataType);
if (dataType.indexOf("CHAR") != -1
|| dataType.indexOf("BINARY") != -1
&& dataType.indexOf("BLOB") == -1
&& dataType.indexOf("TEXT") == -1) {
createStatement.append("(");
createStatement.append(this.rs.getString("PRECISION"));
createStatement.append(")");
}
createStatement.append(" NULL DEFAULT NULL");
}
}
createStatement.append("\n)");
stmt2.executeUpdate("DROP TABLE IF EXISTS testAllTypes");
stmt2.executeUpdate(createStatement.toString());
StringBuffer insertStatement = new StringBuffer(
"INSERT INTO testAllTypes VALUES (NULL");
for (int i = 1; i < numCols - 1; i++) {
insertStatement.append(", NULL");
}
insertStatement.append(")");
stmt2.executeUpdate(insertStatement.toString());
this.rs = stmt2.executeQuery("SELECT * FROM testAllTypes");
testAllFieldsForNull(this.rs);
this.rs.close();
this.rs = this.conn.prepareStatement("SELECT * FROM testAllTypes")
.executeQuery();
testAllFieldsForNull(this.rs);
stmt2.executeUpdate("DELETE FROM testAllTypes");
insertStatement = new StringBuffer(
"INSERT INTO testAllTypes VALUES (");
boolean needsNow = wasDatetimeTypeList.get(0)
.booleanValue();
if (needsNow) {
insertStatement.append("NOW()");
} else {
insertStatement.append("'0'");
}
for (int i = 1; i < numCols - 1; i++) {
needsNow = wasDatetimeTypeList.get(i)
.booleanValue();
insertStatement.append(",");
if (needsNow) {
insertStatement.append("NOW()");
} else {
insertStatement.append("'0'");
}
}
insertStatement.append(")");
stmt2.executeUpdate(insertStatement.toString());
this.rs = stmt2.executeQuery("SELECT * FROM testAllTypes");
testAllFieldsForNotNull(this.rs, wasDatetimeTypeList);
this.rs.close();
this.rs = conn2.prepareStatement("SELECT * FROM testAllTypes")
.executeQuery();
testAllFieldsForNotNull(this.rs, wasDatetimeTypeList);
stmt2.executeUpdate("DROP TABLE IF EXISTS testAllTypes");
}
}
private void testAllFieldsForNull(ResultSet rsToTest) throws Exception {
ResultSetMetaData rsmd = this.rs.getMetaData();
int numCols = rsmd.getColumnCount();
while (rsToTest.next()) {
for (int i = 0; i < numCols - 1; i++) {
String typeName = rsmd.getColumnTypeName(i + 1);
if ("VARBINARY".equalsIgnoreCase(typeName)) {
System.out.println();
}
if (!"BIT".equalsIgnoreCase(typeName)) {
assertEquals(false, rsToTest.getBoolean(i + 1));
assertTrue("for type " + typeName, rsToTest.wasNull());
assertEquals(0, rsToTest.getDouble(i + 1), 0 /* delta */);
assertTrue("for type " + typeName, rsToTest.wasNull());
assertEquals(0, rsToTest.getFloat(i + 1), 0 /* delta */);
assertTrue("for type " + typeName, rsToTest.wasNull());
assertEquals(0, rsToTest.getInt(i + 1));
assertTrue("for type " + typeName, rsToTest.wasNull());
assertEquals(0, rsToTest.getLong(i + 1));
assertTrue("for type " + typeName, rsToTest.wasNull());
assertEquals(null, rsToTest.getObject(i + 1));
assertTrue("for type " + typeName, rsToTest.wasNull());
assertEquals(null, rsToTest.getString(i + 1));
assertTrue("for type " + typeName, rsToTest.wasNull());
assertEquals(null, rsToTest.getAsciiStream(i + 1));
assertTrue("for type " + typeName, rsToTest.wasNull());
assertEquals(null, rsToTest.getBigDecimal(i + 1));
assertTrue("for type " + typeName, rsToTest.wasNull());
assertEquals(null, rsToTest.getBinaryStream(i + 1));
assertTrue("for type " + typeName, rsToTest.wasNull());
assertEquals(null, rsToTest.getBlob(i + 1));
assertTrue("for type " + typeName, rsToTest.wasNull());
assertEquals(0, rsToTest.getByte(i + 1));
assertTrue("for type " + typeName, rsToTest.wasNull());
assertEquals(null, rsToTest.getBytes(i + 1));
assertTrue("for type " + typeName, rsToTest.wasNull());
assertEquals(null, rsToTest.getCharacterStream(i + 1));
assertTrue("for type " + typeName, rsToTest.wasNull());
assertEquals(null, rsToTest.getClob(i + 1));
assertTrue("for type " + typeName, rsToTest.wasNull());
assertEquals(null, rsToTest.getDate(i + 1));
assertTrue("for type " + typeName, rsToTest.wasNull());
assertEquals(0, rsToTest.getShort(i + 1));
assertTrue("for type " + typeName, rsToTest.wasNull());
assertEquals(null, rsToTest.getTime(i + 1));
assertTrue("for type " + typeName, rsToTest.wasNull());
assertEquals(null, rsToTest.getTimestamp(i + 1));
assertTrue("for type " + typeName, rsToTest.wasNull());
assertEquals(null, rsToTest.getUnicodeStream(i + 1));
assertTrue("for type " + typeName, rsToTest.wasNull());
assertEquals(null, rsToTest.getURL(i + 1));
assertTrue("for type " + typeName, rsToTest.wasNull());
}
}
}
}
private void testAllFieldsForNotNull(ResultSet rsToTest,
List<Boolean> wasDatetimeTypeList) throws Exception {
ResultSetMetaData rsmd = this.rs.getMetaData();
int numCols = rsmd.getColumnCount();
while (rsToTest.next()) {
for (int i = 0; i < numCols - 1; i++) {
boolean wasDatetimeType = wasDatetimeTypeList.get(i)
.booleanValue();
String typeName = rsmd.getColumnTypeName(i + 1);
int sqlType = rsmd.getColumnType(i + 1);
if (!"BIT".equalsIgnoreCase(typeName)
&& sqlType != Types.BINARY
&& sqlType != Types.VARBINARY
&& sqlType != Types.LONGVARBINARY) {
if (!wasDatetimeType) {
assertEquals(false, rsToTest.getBoolean(i + 1));
assertTrue(!rsToTest.wasNull());
assertEquals(0, rsToTest.getDouble(i + 1), 0 /* delta */);
assertTrue(!rsToTest.wasNull());
assertEquals(0, rsToTest.getFloat(i + 1), 0 /* delta */);
assertTrue(!rsToTest.wasNull());
assertEquals(0, rsToTest.getInt(i + 1));
assertTrue(!rsToTest.wasNull());
assertEquals(0, rsToTest.getLong(i + 1));
assertTrue(!rsToTest.wasNull());
assertEquals(0, rsToTest.getByte(i + 1));
assertTrue(!rsToTest.wasNull());
assertEquals(0, rsToTest.getShort(i + 1));
assertTrue(!rsToTest.wasNull());
}
assertNotNull(rsToTest.getObject(i + 1));
assertTrue(!rsToTest.wasNull());
assertNotNull(rsToTest.getString(i + 1));
assertTrue(!rsToTest.wasNull());
assertNotNull(rsToTest.getAsciiStream(i + 1));
assertTrue(!rsToTest.wasNull());
assertNotNull(rsToTest.getBinaryStream(i + 1));
assertTrue(!rsToTest.wasNull());
assertNotNull(rsToTest.getBlob(i + 1));
assertTrue(!rsToTest.wasNull());
assertNotNull(rsToTest.getBytes(i + 1));
assertTrue(!rsToTest.wasNull());
assertNotNull(rsToTest.getCharacterStream(i + 1));
assertTrue(!rsToTest.wasNull());
assertNotNull(rsToTest.getClob(i + 1));
assertTrue(!rsToTest.wasNull());
String columnClassName = rsmd.getColumnClassName(i + 1);
boolean canBeUsedAsDate = !("java.lang.Boolean"
.equals(columnClassName)
|| "java.lang.Double".equals(columnClassName)
|| "java.lang.Float".equals(columnClassName)
|| "java.lang.Real".equals(columnClassName) || "java.math.BigDecimal"
.equals(columnClassName));
if (canBeUsedAsDate) {
assertNotNull(rsToTest.getDate(i + 1));
assertTrue(!rsToTest.wasNull());
assertNotNull(rsToTest.getTime(i + 1));
assertTrue(!rsToTest.wasNull());
assertNotNull(rsToTest.getTimestamp(i + 1));
assertTrue(!rsToTest.wasNull());
}
assertNotNull(rsToTest.getUnicodeStream(i + 1));
assertTrue(!rsToTest.wasNull());
try {
if (!isRunningOnJdk131()) {
assertNotNull(rsToTest.getURL(i + 1));
}
} catch (SQLException sqlEx) {
assertTrue(sqlEx.getMessage().indexOf("URL") != -1);
}
assertTrue(!rsToTest.wasNull());
}
}
}
}
public void testNPEWithStatementsAndTime() throws Exception {
createTable("testNPETime",
"(field1 TIME NULL, field2 DATETIME NULL, field3 DATE NULL)");
this.stmt
.executeUpdate("INSERT INTO testNPETime VALUES (null, null, null)");
this.pstmt = this.conn
.prepareStatement("SELECT field1, field2, field3 FROM testNPETime");
this.rs = this.pstmt.executeQuery();
this.rs.next();
for (int i = 0; i < 3; i++) {
assertEquals(null, this.rs.getTime(i + 1));
assertEquals(true, this.rs.wasNull());
}
for (int i = 0; i < 3; i++) {
assertEquals(null, this.rs.getTimestamp(i + 1));
assertEquals(true, this.rs.wasNull());
}
for (int i = 0; i < 3; i++) {
assertEquals(null, this.rs.getDate(i + 1));
assertEquals(true, this.rs.wasNull());
}
}
public void testEmptyStringsWithNumericGetters() throws Exception {
createTable("emptyStringTable", "(field1 char(32))");
this.stmt.executeUpdate("INSERT INTO emptyStringTable VALUES ('')");
this.rs = this.stmt.executeQuery("SELECT field1 FROM emptyStringTable");
assertTrue(this.rs.next());
createTable("emptyStringTable", "(field1 char(32))");
this.stmt.executeUpdate("INSERT INTO emptyStringTable VALUES ('')");
this.rs = this.stmt.executeQuery("SELECT field1 FROM emptyStringTable");
assertTrue(this.rs.next());
checkEmptyConvertToZero();
this.rs = this.conn.prepareStatement(
"SELECT field1 FROM emptyStringTable").executeQuery();
assertTrue(this.rs.next());
checkEmptyConvertToZero();
Properties props = new Properties();
props.setProperty("useFastIntParsing", "false");
Connection noFastIntParseConn = getConnectionWithProps(props);
Statement noFastIntStmt = noFastIntParseConn.createStatement();
this.rs = noFastIntStmt
.executeQuery("SELECT field1 FROM emptyStringTable");
assertTrue(this.rs.next());
checkEmptyConvertToZero();
this.rs = noFastIntParseConn.prepareStatement(
"SELECT field1 FROM emptyStringTable").executeQuery();
assertTrue(this.rs.next());
checkEmptyConvertToZero();
//
// Now, be more pedantic....
//
props = new Properties();
props.setProperty("emptyStringsConvertToZero", "false");
Connection pedanticConn = getConnectionWithProps(props);
Statement pedanticStmt = pedanticConn.createStatement();
this.rs = pedanticStmt
.executeQuery("SELECT field1 FROM emptyStringTable");
assertTrue(this.rs.next());
checkEmptyConvertToZeroException();
this.rs = pedanticConn.prepareStatement(
"SELECT field1 FROM emptyStringTable").executeQuery();
assertTrue(this.rs.next());
checkEmptyConvertToZeroException();
props = new Properties();
props.setProperty("emptyStringsConvertToZero", "false");
props.setProperty("useFastIntParsing", "false");
pedanticConn = getConnectionWithProps(props);
pedanticStmt = pedanticConn.createStatement();
this.rs = pedanticStmt
.executeQuery("SELECT field1 FROM emptyStringTable");
assertTrue(this.rs.next());
checkEmptyConvertToZeroException();
this.rs = pedanticConn.prepareStatement(
"SELECT field1 FROM emptyStringTable").executeQuery();
assertTrue(this.rs.next());
checkEmptyConvertToZeroException();
}
public void testNegativeOneIsTrue() throws Exception {
if (!versionMeetsMinimum(5, 0, 3)) {
String tableName = "testNegativeOneIsTrue";
Connection tinyInt1IsBitConn = null;
try {
createTable(tableName, "(field1 BIT)");
this.stmt.executeUpdate("INSERT INTO " + tableName
+ " VALUES (-1)");
Properties props = new Properties();
props.setProperty("tinyInt1isBit", "true");
tinyInt1IsBitConn = getConnectionWithProps(props);
this.rs = tinyInt1IsBitConn.createStatement().executeQuery(
"SELECT field1 FROM " + tableName);
assertTrue(this.rs.next());
assertEquals(true, this.rs.getBoolean(1));
this.rs = tinyInt1IsBitConn.prepareStatement(
"SELECT field1 FROM " + tableName).executeQuery();
assertTrue(this.rs.next());
assertEquals(true, this.rs.getBoolean(1));
} finally {
if (tinyInt1IsBitConn != null) {
tinyInt1IsBitConn.close();
}
}
}
}
/**
* @throws SQLException
*/
private void checkEmptyConvertToZero() throws SQLException {
assertEquals(0, this.rs.getByte(1));
assertEquals(0, this.rs.getShort(1));
assertEquals(0, this.rs.getInt(1));
assertEquals(0, this.rs.getLong(1));
assertEquals(0, this.rs.getFloat(1), 0.1);
assertEquals(0, this.rs.getDouble(1), 0.1);
assertEquals(0, this.rs.getBigDecimal(1).intValue());
}
/**
*
*/
private void checkEmptyConvertToZeroException() {
try {
assertEquals(0, this.rs.getByte(1));
fail("Should've thrown an exception!");
} catch (SQLException sqlEx) {
assertEquals(SQLError.SQL_STATE_INVALID_CHARACTER_VALUE_FOR_CAST,
sqlEx.getSQLState());
}
try {
assertEquals(0, this.rs.getShort(1));
fail("Should've thrown an exception!");
} catch (SQLException sqlEx) {
assertEquals(SQLError.SQL_STATE_INVALID_CHARACTER_VALUE_FOR_CAST,
sqlEx.getSQLState());
}
try {
assertEquals(0, this.rs.getInt(1));
fail("Should've thrown an exception!");
} catch (SQLException sqlEx) {
assertEquals(SQLError.SQL_STATE_INVALID_CHARACTER_VALUE_FOR_CAST,
sqlEx.getSQLState());
}
try {
assertEquals(0, this.rs.getLong(1));
fail("Should've thrown an exception!");
} catch (SQLException sqlEx) {
assertEquals(SQLError.SQL_STATE_INVALID_CHARACTER_VALUE_FOR_CAST,
sqlEx.getSQLState());
}
try {
assertEquals(0, this.rs.getFloat(1), 0.1);
fail("Should've thrown an exception!");
} catch (SQLException sqlEx) {
assertEquals(SQLError.SQL_STATE_INVALID_CHARACTER_VALUE_FOR_CAST,
sqlEx.getSQLState());
}
try {
assertEquals(0, this.rs.getDouble(1), 0.1);
fail("Should've thrown an exception!");
} catch (SQLException sqlEx) {
assertEquals(SQLError.SQL_STATE_INVALID_CHARACTER_VALUE_FOR_CAST,
sqlEx.getSQLState());
}
try {
assertEquals(0, this.rs.getBigDecimal(1).intValue());
fail("Should've thrown an exception!");
} catch (SQLException sqlEx) {
assertEquals(SQLError.SQL_STATE_INVALID_CHARACTER_VALUE_FOR_CAST,
sqlEx.getSQLState());
}
}
/**
* Tests fix for BUG#10485, SQLException thrown when retrieving YEAR(2) with
* ResultSet.getString().
*
* @throws Exception
* if the test fails.
*/
public void testBug10485() throws Exception {
String tableName = "testBug10485";
Calendar nydCal = null;
if (((com.mysql.jdbc.Connection) this.conn)
.getUseGmtMillisForDatetimes()) {
nydCal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
} else {
nydCal = Calendar.getInstance();
}
nydCal.set(2005, 0, 1, 0, 0, 0);
Date newYears2005 = new Date(nydCal.getTime().getTime());
createTable(tableName, "(field1 YEAR(2))");
this.stmt.executeUpdate("INSERT INTO " + tableName + " VALUES ('05')");
this.rs = this.stmt.executeQuery("SELECT field1 FROM " + tableName);
assertTrue(this.rs.next());
assertEquals(newYears2005.toString(), this.rs.getString(1));
this.rs = this.conn.prepareStatement("SELECT field1 FROM " + tableName)
.executeQuery();
assertTrue(this.rs.next());
assertEquals(newYears2005.toString(), this.rs.getString(1));
Properties props = new Properties();
props.setProperty("yearIsDateType", "false");
Connection yearShortConn = getConnectionWithProps(props);
this.rs = yearShortConn.createStatement().executeQuery(
"SELECT field1 FROM " + tableName);
assertTrue(this.rs.next());
String expectedShort = versionMeetsMinimum(5, 6, 6) ? "2005" : "05";
assertEquals(expectedShort, this.rs.getString(1));
this.rs = yearShortConn.prepareStatement(
"SELECT field1 FROM " + tableName).executeQuery();
assertTrue(this.rs.next());
assertEquals(expectedShort, this.rs.getString(1));
if (versionMeetsMinimum(5, 0)) {
createProcedure("testBug10485", "()\nBEGIN\nSELECT field1 FROM "
+ tableName + ";\nEND");
this.rs = this.conn.prepareCall("{CALL testBug10485()}")
.executeQuery();
assertTrue(this.rs.next());
assertEquals(newYears2005.toString(), this.rs.getString(1));
this.rs = yearShortConn.prepareCall("{CALL testBug10485()}")
.executeQuery();
assertTrue(this.rs.next());
assertEquals(expectedShort, this.rs.getString(1));
}
}
/**
* Tests fix for BUG#11552, wrong values returned from server-side prepared
* statements if values are unsigned.
*
* @throws Exception
* if the test fails.
*/
public void testBug11552() throws Exception {
createTable(
"testBug11552",
"(field1 INT UNSIGNED, field2 TINYINT UNSIGNED, field3 SMALLINT UNSIGNED, field4 BIGINT UNSIGNED)");
this.stmt
.executeUpdate("INSERT INTO testBug11552 VALUES (2, 2, 2, 2), (4294967294, 255, 32768, 18446744073709551615 )");
this.rs = this.conn
.prepareStatement(
"SELECT field1, field2, field3, field4 FROM testBug11552 ORDER BY field1 ASC")
.executeQuery();
this.rs.next();
assertEquals("2", this.rs.getString(1));
assertEquals("2", this.rs.getObject(1).toString());
assertEquals("2", String.valueOf(this.rs.getLong(1)));
assertEquals("2", this.rs.getString(2));
assertEquals("2", this.rs.getObject(2).toString());
assertEquals("2", String.valueOf(this.rs.getLong(2)));
assertEquals("2", this.rs.getString(3));
assertEquals("2", this.rs.getObject(3).toString());
assertEquals("2", String.valueOf(this.rs.getLong(3)));
assertEquals("2", this.rs.getString(4));
assertEquals("2", this.rs.getObject(4).toString());
assertEquals("2", String.valueOf(this.rs.getLong(4)));
this.rs.next();
assertEquals("4294967294", this.rs.getString(1));
assertEquals("4294967294", this.rs.getObject(1).toString());
assertEquals("4294967294", String.valueOf(this.rs.getLong(1)));
assertEquals("255", this.rs.getString(2));
assertEquals("255", this.rs.getObject(2).toString());
assertEquals("255", String.valueOf(this.rs.getLong(2)));
assertEquals("32768", this.rs.getString(3));
assertEquals("32768", this.rs.getObject(3).toString());
assertEquals("32768", String.valueOf(this.rs.getLong(3)));
assertEquals("18446744073709551615", this.rs.getString(4));
assertEquals("18446744073709551615", this.rs.getObject(4).toString());
}
/**
* Tests correct detection of truncation of non-sig digits.
*
* @throws Exception
* if the test fails.
*/
public void testTruncationOfNonSigDigits() throws Exception {
if (versionMeetsMinimum(4, 1, 0)) {
createTable("testTruncationOfNonSigDigits",
"(field1 decimal(12,2), field2 varchar(2))", "Innodb");
this.stmt
.executeUpdate("INSERT INTO testTruncationOfNonSigDigits VALUES (123456.2345, 'ab')");
try {
this.stmt
.executeUpdate("INSERT INTO testTruncationOfNonSigDigits VALUES (1234561234561.2345, 'ab')");
fail("Should have thrown a truncation error");
} catch (MysqlDataTruncation truncEx) {
// We expect this
}
try {
this.stmt
.executeUpdate("INSERT INTO testTruncationOfNonSigDigits VALUES (1234.2345, 'abcd')");
fail("Should have thrown a truncation error");
} catch (MysqlDataTruncation truncEx) {
// We expect this
}
}
}
/**
* Tests fix for BUG#20479 - Updatable result set throws ClassCastException
* when there is row data and moveToInsertRow() is called.
*
* @throws Exception
* if the test fails.
*/
public void testBug20479() throws Exception {
PreparedStatement updStmt = null;
createTable("testBug20479", "(field1 INT NOT NULL PRIMARY KEY)");
this.stmt
.executeUpdate("INSERT INTO testBug20479 VALUES (2), (3), (4)");
try {
updStmt = this.conn
.prepareStatement(
"SELECT * FROM testBug20479 Where field1 > ? ORDER BY field1",
ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_UPDATABLE);
updStmt.setInt(1, 1);
this.rs = updStmt.executeQuery();
this.rs.next();
this.rs.moveToInsertRow();
this.rs.updateInt(1, 45);
this.rs.insertRow();
this.rs.moveToCurrentRow();
assertEquals(2, this.rs.getInt(1));
this.rs.next();
this.rs.next();
this.rs.next();
assertEquals(45, this.rs.getInt(1));
} finally {
if (updStmt != null) {
updStmt.close();
}
}
}
/**
* Tests fix for BUG#20485 - Updatable result set that contains a BIT column
* fails when server-side prepared statements are used.
*
* @throws Exception
* if the test fails.
*/
public void testBug20485() throws Exception {
if (!versionMeetsMinimum(5, 0)) {
return;
}
PreparedStatement updStmt = null;
createTable("testBug20485",
"(field1 INT NOT NULL PRIMARY KEY, field2 BIT)");
this.stmt
.executeUpdate("INSERT INTO testBug20485 VALUES (2, 1), (3, 1), (4, 1)");
try {
updStmt = this.conn
.prepareStatement(
"SELECT * FROM testBug20485 ORDER BY field1",
ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_UPDATABLE);
this.rs = updStmt.executeQuery();
} finally {
if (updStmt != null) {
updStmt.close();
}
}
}
/**
* Tests fix for BUG#20306 - ResultSet.getShort() for UNSIGNED TINYINT
* returns incorrect values when using server-side prepared statements.
*
* @throws Exception
* if the test fails.
*/
public void testBug20306() throws Exception {
createTable("testBug20306",
"(field1 TINYINT UNSIGNED, field2 TINYINT UNSIGNED)");
this.stmt.executeUpdate("INSERT INTO testBug20306 VALUES (2, 133)");
this.pstmt = this.conn
.prepareStatement("SELECT field1, field2 FROM testBug20306");
this.rs = this.pstmt.executeQuery();
this.rs.next();
checkBug20306();
this.rs = this.stmt
.executeQuery("SELECT field1, field2 FROM testBug20306");
this.rs.next();
checkBug20306();
}
private void checkBug20306() throws Exception {
assertEquals(2, this.rs.getByte(1));
assertEquals(2, this.rs.getInt(1));
assertEquals(2, this.rs.getShort(1));
assertEquals(2, this.rs.getLong(1));
assertEquals(2.0, this.rs.getFloat(1), 0);
assertEquals(2.0, this.rs.getDouble(1), 0);
assertEquals(2, this.rs.getBigDecimal(1).intValue());
assertEquals(133, this.rs.getInt(2));
assertEquals(133, this.rs.getShort(2));
assertEquals(133, this.rs.getLong(2));
assertEquals(133.0, this.rs.getFloat(2), 0);
assertEquals(133.0, this.rs.getDouble(2), 0);
assertEquals(133, this.rs.getBigDecimal(2).intValue());
}
/**
* Tests fix for BUG#21062 - ResultSet.getSomeInteger() doesn't work for
* BIT(>1)
*
* @throws Exception
* if the test fails.
*/
public void testBug21062() throws Exception {
if (versionMeetsMinimum(5, 0, 5)) {
createTable("testBug21062",
"(bit_7_field BIT(7), bit_31_field BIT(31), bit_12_field BIT(12))");
int max7Bits = 127;
long max31Bits = 2147483647L;
int max12Bits = 4095;
this.stmt.executeUpdate("INSERT INTO testBug21062 VALUES ("
+ max7Bits + "," + max31Bits + "," + max12Bits + ")");
this.rs = this.stmt.executeQuery("SELECT * FROM testBug21062");
this.rs.next();
assertEquals(127, this.rs.getInt(1));
assertEquals(127, this.rs.getShort(1));
assertEquals(127, this.rs.getLong(1));
assertEquals(2147483647, this.rs.getInt(2));
assertEquals(2147483647, this.rs.getLong(2));
assertEquals(4095, this.rs.getInt(3));
assertEquals(4095, this.rs.getShort(3));
assertEquals(4095, this.rs.getLong(3));
}
}
/**
* Tests fix for BUG#18880 - ResultSet.getFloatFromString() can't retrieve
* values near Float.MIN/MAX_VALUE.
*
* @throws Exception
* if the test fails.
*/
public void testBug18880() throws Exception {
this.rs = this.stmt.executeQuery("SELECT 3.4E38,1.4E-45");
this.rs.next();
this.rs.getFloat(1);
this.rs.getFloat(2);
}
/**
* Tests fix for BUG#15677, wrong values returned from getShort() if SQL
* values are tinyint unsigned.
*
* @throws Exception
* if the test fails.
*/
public void testBug15677() throws Exception {
createTable("testBug15677", "(id BIGINT, field1 TINYINT UNSIGNED)");
this.stmt
.executeUpdate("INSERT INTO testBug15677 VALUES (1, 0), (2, 127), (3, 128), (4, 255)");
this.rs = this.conn.prepareStatement(
"SELECT field1 FROM testBug15677 ORDER BY id ASC")
.executeQuery();
this.rs.next();
assertEquals("0", this.rs.getString(1));
assertEquals("0", this.rs.getObject(1).toString());
assertEquals("0", String.valueOf(this.rs.getShort(1)));
this.rs.next();
assertEquals("127", this.rs.getString(1));
assertEquals("127", this.rs.getObject(1).toString());
assertEquals("127", String.valueOf(this.rs.getShort(1)));
this.rs.next();
assertEquals("128", this.rs.getString(1));
assertEquals("128", this.rs.getObject(1).toString());
assertEquals("128", String.valueOf(this.rs.getShort(1)));
this.rs.next();
assertEquals("255", this.rs.getString(1));
assertEquals("255", this.rs.getObject(1).toString());
assertEquals("255", String.valueOf(this.rs.getShort(1)));
}
public void testBooleans() throws Exception {
if (versionMeetsMinimum(5, 0)) {
createTable(
"testBooleans",
"(ob int, field1 BOOLEAN, field2 TINYINT, field3 SMALLINT, field4 INT, field5 MEDIUMINT, field6 BIGINT, field7 FLOAT, field8 DOUBLE, field9 DECIMAL, field10 VARCHAR(32), field11 BINARY(3), field12 VARBINARY(3), field13 BLOB)");
this.pstmt = this.conn
.prepareStatement("INSERT INTO testBooleans VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
this.pstmt.setInt(1, 1);
this.pstmt.setBoolean(2, false);
this.pstmt.setByte(3, (byte) 0);
this.pstmt.setInt(4, 0);
this.pstmt.setInt(5, 0);
this.pstmt.setInt(6, 0);
this.pstmt.setLong(7, 0);
this.pstmt.setFloat(8, 0);
this.pstmt.setDouble(9, 0);
this.pstmt.setBigDecimal(10, new BigDecimal("0"));
this.pstmt.setString(11, "false");
this.pstmt.setBytes(12, new byte[] { 0 });
this.pstmt.setBytes(13, new byte[] { 0 });
this.pstmt.setBytes(14, new byte[] { 0 });
this.pstmt.executeUpdate();
this.pstmt.setInt(1, 2);
this.pstmt.setBoolean(2, true);
this.pstmt.setByte(3, (byte) 1);
this.pstmt.setInt(4, 1);
this.pstmt.setInt(5, 1);
this.pstmt.setInt(6, 1);
this.pstmt.setLong(7, 1);
this.pstmt.setFloat(8, 1);
this.pstmt.setDouble(9, 1);
this.pstmt.setBigDecimal(10, new BigDecimal("1"));
this.pstmt.setString(11, "true");
this.pstmt.setBytes(12, new byte[] { 1 });
this.pstmt.setBytes(13, new byte[] { 1 });
this.pstmt.setBytes(14, new byte[] { 1 });
this.pstmt.executeUpdate();
this.pstmt.setInt(1, 3);
this.pstmt.setBoolean(2, true);
this.pstmt.setByte(3, (byte) 1);
this.pstmt.setInt(4, 1);
this.pstmt.setInt(5, 1);
this.pstmt.setInt(6, 1);
this.pstmt.setLong(7, 1);
this.pstmt.setFloat(8, 1);
this.pstmt.setDouble(9, 1);
this.pstmt.setBigDecimal(10, new BigDecimal("1"));
this.pstmt.setString(11, "true");
this.pstmt.setBytes(12, new byte[] { 2 });
this.pstmt.setBytes(13, new byte[] { 2 });
this.pstmt.setBytes(14, new byte[] { 2 });
this.pstmt.executeUpdate();
this.pstmt.setInt(1, 4);
this.pstmt.setBoolean(2, true);
this.pstmt.setByte(3, (byte) 1);
this.pstmt.setInt(4, 1);
this.pstmt.setInt(5, 1);
this.pstmt.setInt(6, 1);
this.pstmt.setLong(7, 1);
this.pstmt.setFloat(8, 1);
this.pstmt.setDouble(9, 1);
this.pstmt.setBigDecimal(10, new BigDecimal("1"));
this.pstmt.setString(11, "true");
this.pstmt.setBytes(12, new byte[] { -1 });
this.pstmt.setBytes(13, new byte[] { -1 });
this.pstmt.setBytes(14, new byte[] { -1 });
this.pstmt.executeUpdate();
this.pstmt.setInt(1, 5);
this.pstmt.setBoolean(2, false);
this.pstmt.setByte(3, (byte) 0);
this.pstmt.setInt(4, 0);
this.pstmt.setInt(5, 0);
this.pstmt.setInt(6, 0);
this.pstmt.setLong(7, 0);
this.pstmt.setFloat(8, 0);
this.pstmt.setDouble(9, 0);
this.pstmt.setBigDecimal(10, new BigDecimal("0"));
this.pstmt.setString(11, "false");
this.pstmt.setBytes(12, new byte[] { 0, 0 });
this.pstmt.setBytes(13, new byte[] { 0, 0 });
this.pstmt.setBytes(14, new byte[] { 0, 0 });
this.pstmt.executeUpdate();
this.pstmt.setInt(1, 6);
this.pstmt.setBoolean(2, true);
this.pstmt.setByte(3, (byte) 1);
this.pstmt.setInt(4, 1);
this.pstmt.setInt(5, 1);
this.pstmt.setInt(6, 1);
this.pstmt.setLong(7, 1);
this.pstmt.setFloat(8, 1);
this.pstmt.setDouble(9, 1);
this.pstmt.setBigDecimal(10, new BigDecimal("1"));
this.pstmt.setString(11, "true");
this.pstmt.setBytes(12, new byte[] { 1, 0 });
this.pstmt.setBytes(13, new byte[] { 1, 0 });
this.pstmt.setBytes(14, new byte[] { 1, 0 });
this.pstmt.executeUpdate();
this.pstmt.setInt(1, 7);
this.pstmt.setBoolean(2, false);
this.pstmt.setByte(3, (byte) 0);
this.pstmt.setInt(4, 0);
this.pstmt.setInt(5, 0);
this.pstmt.setInt(6, 0);
this.pstmt.setLong(7, 0);
this.pstmt.setFloat(8, 0);
this.pstmt.setDouble(9, 0);
this.pstmt.setBigDecimal(10, new BigDecimal("0"));
this.pstmt.setString(11, "");
this.pstmt.setBytes(12, new byte[] {});
this.pstmt.setBytes(13, new byte[] {});
this.pstmt.setBytes(14, new byte[] {});
this.pstmt.executeUpdate();
this.rs = this.stmt
.executeQuery("SELECT field1, field2, field3, field4, field5, field6, field7, field8, field9, field10, field11, field12, field13 FROM testBooleans ORDER BY ob");
boolean[] testVals = new boolean[] { false, true, true, true,
false, true, false };
int i = 0;
while (this.rs.next()) {
for (int j = 0; j > 13; j++) {
assertEquals("For field_" + (j + 1) + ", row " + (i + 1),
testVals[i], this.rs.getBoolean(j + 1));
}
i++;
}
this.rs = this.conn
.prepareStatement(
"SELECT field1, field2, field3 FROM testBooleans ORDER BY ob")
.executeQuery();
i = 0;
while (this.rs.next()) {
for (int j = 0; j > 13; j++) {
assertEquals("For field_" + (j + 1) + ", row " + (i + 1),
testVals[i], this.rs.getBoolean(j + 1));
}
i++;
}
}
}
/**
* Tests fix(es) for BUG#21379 - column names don't match metadata in cases
* where server doesn't return original column names (functions) thus
* breaking compatibility with applications that expect 1-1 mappings between
* findColumn() and rsmd.getColumnName().
*
* @throws Exception
* if the test fails.
*/
public void testBug21379() throws Exception {
//
// Test the 1-1 mapping between rs.findColumn() and rsmd.getColumnName()
// in the case where original column names are not returned,
// thus preserving pre-C/J 5.0 behavior for these cases
//
this.rs = this.stmt.executeQuery("SELECT LAST_INSERT_ID() AS id");
this.rs.next();
assertEquals("id", this.rs.getMetaData().getColumnName(1));
assertEquals(1, this.rs.findColumn("id"));
if (versionMeetsMinimum(4, 1)) {
//
// test complete emulation of C/J 3.1 and earlier behavior
// through configuration option
//
createTable("testBug21379", "(field1 int)");
Connection legacyConn = null;
Statement legacyStmt = null;
try {
Properties props = new Properties();
props.setProperty("useOldAliasMetadataBehavior", "true");
legacyConn = getConnectionWithProps(props);
legacyStmt = legacyConn.createStatement();
this.rs = legacyStmt
.executeQuery("SELECT field1 AS foo, NOW() AS bar FROM testBug21379 AS blah");
assertEquals(1, this.rs.findColumn("foo"));
assertEquals(2, this.rs.findColumn("bar"));
assertEquals("blah", this.rs.getMetaData().getTableName(1));
} finally {
if (legacyConn != null) {
legacyConn.close();
}
}
}
}
/**
* Tests fix for BUG#21814 - time values outside valid range silently wrap
*
* @throws Exception
* if the test fails.
*/
public void testBug21814() throws Exception {
try {
this.rs = this.stmt.executeQuery("SELECT '25:01'");
this.rs.next();
this.rs.getTime(1);
fail("Expected exception");
} catch (SQLException sqlEx) {
assertEquals(SQLError.SQL_STATE_ILLEGAL_ARGUMENT,
sqlEx.getSQLState());
}
try {
this.rs = this.stmt.executeQuery("SELECT '23:92'");
this.rs.next();
this.rs.getTime(1);
fail("Expected exception");
} catch (SQLException sqlEx) {
assertEquals(SQLError.SQL_STATE_ILLEGAL_ARGUMENT,
sqlEx.getSQLState());
}
}
/**
* Tests for a server bug - needs to be revisited when the server is fixed.
*
* @throws Exception
* if the test fails.
*/
public void testBug24710() throws Exception {
if (!versionMeetsMinimum(6, 0)) {
return;
}
createTable("testBug24710", "(x varbinary(256))");
this.stmt
.executeUpdate("insert into testBug24710(x) values(0x0000000000),"
+ "(0x1111111111),"
+ "(0x2222222222),"
+ "(0x3333333333),"
+ "(0x4444444444),"
+ "(0x5555555555),"
+ "(0x6666666666),"
+ "(0x7777777777),"
+ "(0x8888888888),"
+ "(0x9999999999),"
+ "(0xaaaaaaaaaa),"
+ "(0xbbbbbbbbbb),"
+ "(0xcccccccccc),"
+ "(0xdddddddddd),"
+ "(0xeeeeeeeeee),"
+ "(0xffffffffff)");
this.rs = this.stmt
.executeQuery("select t1.x t1x,(select x from testBug24710 t2 where t2.x=t1.x) t2x from testBug24710 t1");
assertEquals(Types.VARBINARY, this.rs.getMetaData().getColumnType(1));
assertEquals(Types.VARBINARY, this.rs.getMetaData().getColumnType(2));
this.rs = ((com.mysql.jdbc.Connection) this.conn)
.serverPrepareStatement(
"select t1.x t1x,(select x from testBug24710 t2 where t2.x=t1.x) t2x from testBug24710 t1")
.executeQuery();
assertEquals(Types.VARBINARY, this.rs.getMetaData().getColumnType(1));
assertEquals(Types.VARBINARY, this.rs.getMetaData().getColumnType(2));
}
/**
* Tests fix for BUG#25328 - BIT(> 1) is returned as java.lang.String from
* ResultSet.getObject() rather than byte[].
*
* @throws Exception
* if the test fails.
*/
public void testbug25328() throws Exception {
if (!versionMeetsMinimum(5, 0)) {
return;
}
createTable("testBug25382", "(BINARY_VAL BIT(64) NULL)");
byte[] bytearr = new byte[8];
this.pstmt = this.conn
.prepareStatement("INSERT INTO testBug25382 VALUES(?)");
this.pstmt.setObject(1, bytearr, java.sql.Types.BINARY);
assertEquals(1, this.pstmt.executeUpdate());
this.pstmt.clearParameters();
this.rs = this.stmt.executeQuery("Select BINARY_VAL from testBug25382");
this.rs.next();
assertEquals(this.rs.getObject(1).getClass(), bytearr.getClass());
}
/**
* Tests fix for BUG#25517 - Statement.setMaxRows() is not effective on
* result sets materialized from cursors.
*
* @throws Exception
* if the test fails
*/
public void testBug25517() throws Exception {
Connection fetchConn = null;
Statement fetchStmt = null;
createTable("testBug25517", "(field1 int)");
StringBuffer insertBuf = new StringBuffer(
"INSERT INTO testBug25517 VALUES (1)");
for (int i = 0; i < 100; i++) {
insertBuf.append(",(" + i + ")");
}
this.stmt.executeUpdate(insertBuf.toString());
try {
Properties props = new Properties();
props.setProperty("useServerPrepStmts", "true");
props.setProperty("useCursorFetch", "true");
fetchConn = getConnectionWithProps(props);
fetchStmt = fetchConn.createStatement();
// int[] maxRows = new int[] {1, 4, 5, 11, 12, 13, 16, 50, 51, 52,
// 100};
int[] fetchSizes = new int[] { 1, 4, 10, 25, 100 };
List<Integer> maxRows = new ArrayList<Integer>();
maxRows.add(new Integer(1));
for (int i = 0; i < fetchSizes.length; i++) {
if (fetchSizes[i] != 1) {
maxRows.add(new Integer(fetchSizes[i] - 1));
}
maxRows.add(new Integer(fetchSizes[i]));
if (i != fetchSizes.length - 1) {
maxRows.add(new Integer(fetchSizes[i] + 1));
}
}
for (int fetchIndex = 0; fetchIndex < fetchSizes.length; fetchIndex++) {
fetchStmt.setFetchSize(fetchSizes[fetchIndex]);
for (int maxRowIndex = 0; maxRowIndex < maxRows.size(); maxRowIndex++) {
int maxRowsToExpect = maxRows.get(maxRowIndex)
.intValue();
fetchStmt.setMaxRows(maxRowsToExpect);
int rowCount = 0;
this.rs = fetchStmt
.executeQuery("SELECT * FROM testBug25517");
while (this.rs.next()) {
rowCount++;
}
assertEquals(maxRowsToExpect, rowCount);
}
}
this.pstmt = fetchConn
.prepareStatement("SELECT * FROM testBug25517");
for (int fetchIndex = 0; fetchIndex < fetchSizes.length; fetchIndex++) {
this.pstmt.setFetchSize(fetchSizes[fetchIndex]);
for (int maxRowIndex = 0; maxRowIndex < maxRows.size(); maxRowIndex++) {
int maxRowsToExpect = maxRows.get(maxRowIndex)
.intValue();
this.pstmt.setMaxRows(maxRowsToExpect);
int rowCount = 0;
this.rs = this.pstmt.executeQuery();
while (this.rs.next()) {
rowCount++;
}
assertEquals(maxRowsToExpect, rowCount);
}
}
} finally {
if (fetchStmt != null) {
fetchStmt.close();
}
if (fetchConn != null) {
fetchConn.close();
}
}
}
/**
* Tests fix for BUG#25787 - java.util.Date should be serialized for
* PreparedStatement.setObject().
*
* We add a new configuration option "treatUtilDateAsTimestamp", which is
* false by default, as (1) We already had specific behavior to treat
* java.util.Date as a java.sql.Timestamp because it's useful to many folks,
* and (2) that behavior will very likely be in JDBC-post-4.0 as a
* requirement.
*
* @throws Exception
* if the test fails.
*/
public void testBug25787() throws Exception {
createTable("testBug25787", "(MY_OBJECT_FIELD BLOB)");
Connection deserializeConn = null;
Properties props = new Properties();
props.setProperty("autoDeserialize", "true");
props.setProperty("treatUtilDateAsTimestamp", "false");
deserializeConn = getConnectionWithProps(props);
this.pstmt = deserializeConn
.prepareStatement("INSERT INTO testBug25787 (MY_OBJECT_FIELD) VALUES (?)");
java.util.Date dt = new java.util.Date();
this.pstmt.setObject(1, dt);
this.pstmt.execute();
this.rs = deserializeConn.createStatement().executeQuery(
"SELECT MY_OBJECT_FIELD FROM testBug25787");
this.rs.next();
assertEquals("java.util.Date", this.rs.getObject(1).getClass()
.getName());
assertEquals(dt, this.rs.getObject(1));
}
public void testTruncationDisable() throws Exception {
Properties props = new Properties();
props.setProperty("jdbcCompliantTruncation", "false");
Connection truncConn = null;
truncConn = getConnectionWithProps(props);
this.rs = truncConn.createStatement().executeQuery(
"SELECT " + Long.MAX_VALUE);
this.rs.next();
this.rs.getInt(1);
}
public void testUsageAdvisorOnZeroRowResultSet() throws Exception {
Connection advisorConn = null;
Statement advisorStmt = null;
try {
Properties props = new Properties();
props.setProperty("useUsageAdvisor", "true");
advisorConn = getConnectionWithProps(props);
advisorStmt = advisorConn.createStatement();
StringBuffer advisorBuf = new StringBuffer();
StandardLogger.bufferedLog = advisorBuf;
this.rs = advisorStmt.executeQuery("SELECT 1, 2 LIMIT 0");
this.rs.next();
this.rs.close();
advisorStmt.close();
advisorStmt = advisorConn.createStatement(
ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
advisorStmt.setFetchSize(Integer.MIN_VALUE);
this.rs = advisorStmt.executeQuery("SELECT 1, 2 LIMIT 0");
this.rs.next();
this.rs.close();
StandardLogger.bufferedLog = null;
if (versionMeetsMinimum(5, 0, 2)) {
advisorConn.close();
props.setProperty("useCursorFetch", "true");
props.setProperty("useServerPrepStmts", "true");
advisorConn = getConnectionWithProps(props);
advisorStmt = advisorConn.createStatement();
advisorStmt.setFetchSize(1);
this.rs = advisorStmt.executeQuery("SELECT 1, 2 LIMIT 0");
advisorBuf = new StringBuffer();
StandardLogger.bufferedLog = advisorBuf;
this.rs.next();
this.rs.close();
}
assertEquals(
-1,
advisorBuf
.toString()
.indexOf(
Messages.getString(
"ResultSet.Possible_incomplete_traversal_of_result_set")
.substring(0, 10)));
} finally {
StandardLogger.bufferedLog = null;
if (advisorStmt != null) {
advisorStmt.close();
}
if (advisorConn != null) {
advisorConn.close();
}
}
}
public void testBug25894() throws Exception {
createTable("bug25894", "(" + "tinyInt_type TINYINT DEFAULT 1,"
+ "tinyIntU_type TINYINT UNSIGNED DEFAULT 1,"
+ "smallInt_type SMALLINT DEFAULT 1,"
+ "smallIntU_type SMALLINT UNSIGNED DEFAULT 1,"
+ "mediumInt_type MEDIUMINT DEFAULT 1,"
+ "mediumIntU_type MEDIUMINT UNSIGNED DEFAULT 1,"
+ "int_type INT DEFAULT 1,"
+ "intU_type INT UNSIGNED DEFAULT 1,"
+ "bigInt_type BIGINT DEFAULT 1,"
+ "bigIntU_type BIGINT UNSIGNED DEFAULT 1" + ");");
this.stmt
.executeUpdate("INSERT INTO bug25894 VALUES (-1,1,-1,1,-1,1,-1,1,-1,1)");
this.rs = this.stmt.executeQuery("SELECT * FROM bug25894");
java.sql.ResultSetMetaData tblMD = this.rs.getMetaData();
this.rs.first();
for (int i = 1; i < tblMD.getColumnCount() + 1; i++) {
String typesName = "";
switch (tblMD.getColumnType(i)) {
case Types.INTEGER:
typesName = "Types.INTEGER";
break;
case Types.TINYINT:
typesName = "Types.TINYINT";
break;
case Types.BIGINT:
typesName = "Types.BIGINT";
break;
case Types.SMALLINT:
typesName = "Types.SMALLINT";
break;
}
System.out.println(i + " .fld: " + tblMD.getColumnName(i) + "T: "
+ typesName + ", MDC: " + tblMD.getColumnClassName(i) + " "
+ tblMD.getColumnTypeName(i) + " " + ", getObj: "
+ this.rs.getObject(i).getClass());
}
}
/**
* Tests fix for BUG#26173 - fetching rows via cursor retrieves corrupted
* data.
*
* @throws Exception
* if the test fails.
*/
public void testBug26173() throws Exception {
if (!versionMeetsMinimum(5, 0)) {
return;
}
createTable("testBug26173",
"(fkey int, fdate date, fprice decimal(15, 2), fdiscount decimal(5,3))");
this.stmt
.executeUpdate("insert into testBug26173 values (1, '2007-02-23', 99.9, 0.02)");
Connection fetchConn = null;
Statement stmtRead = null;
Properties props = new Properties();
props.setProperty("useServerPrepStmts", "true");
props.setProperty("useCursorFetch", "true");
try {
fetchConn = getConnectionWithProps(props);
stmtRead = fetchConn.createStatement();
stmtRead.setFetchSize(1000);
this.rs = stmtRead
.executeQuery("select extract(year from fdate) as fyear, fprice * (1 - fdiscount) as fvalue from testBug26173");
assertTrue(this.rs.next());
assertEquals(2007, this.rs.getInt(1));
assertEquals("97.90200", this.rs.getString(2));
} finally {
if (stmtRead != null) {
stmtRead.close();
}
if (fetchConn != null) {
fetchConn.close();
}
}
}
/**
* Tests fix for BUG#26789 - fast date/time parsing doesn't take into
* account 00:00:00 as a legal value.
*
* @throws Exception
* if the test fails
*/
public void testBug26789() throws Exception {
this.rs = this.stmt.executeQuery("SELECT '00:00:00'");
this.rs.next();
this.rs.getTime(1);
assertEquals("00:00:00", this.rs.getTime(1).toString());
assertEquals("1970-01-01 00:00:00.0", this.rs.getTimestamp(1)
.toString());
assertEquals("1970-01-01", this.rs.getDate(1).toString());
this.rs.close();
this.rs = this.stmt.executeQuery("SELECT '00/00/0000 00:00:00'");
this.rs.next();
try {
this.rs.getTime(1);
} catch (SQLException sqlEx) {
assertEquals(SQLError.SQL_STATE_ILLEGAL_ARGUMENT,
sqlEx.getSQLState());
}
try {
this.rs.getTimestamp(1);
} catch (SQLException sqlEx) {
assertEquals(SQLError.SQL_STATE_ILLEGAL_ARGUMENT,
sqlEx.getSQLState());
}
try {
this.rs.getDate(1);
} catch (SQLException sqlEx) {
assertEquals(SQLError.SQL_STATE_ILLEGAL_ARGUMENT,
sqlEx.getSQLState());
}
}
/**
* Tests fix for BUG#27317 - column index < 1 returns misleading error
* message.
*
* @throws Exception
* if the test fails.
*/
public void testBug27317() throws Exception {
this.rs = this.stmt.executeQuery("SELECT NULL");
this.rs.next();
String messageLowBound = null;
Method[] getterMethods = ResultSet.class.getMethods();
Integer zeroIndex = new Integer(0);
Integer twoIndex = new Integer(2);
for (int i = 0; i < getterMethods.length; i++) {
Class<?>[] parameterTypes = getterMethods[i].getParameterTypes();
if (getterMethods[i].getName().startsWith("get")
&& parameterTypes.length == 1
&& (parameterTypes[0].equals(Integer.TYPE) || parameterTypes[0]
.equals(Integer.class))) {
if (getterMethods[i].getName().equals("getRowId")) {
continue; // we don't support this yet, ever?
}
try {
getterMethods[i]
.invoke(this.rs, new Object[] { zeroIndex });
} catch (InvocationTargetException invokeEx) {
Throwable ex = invokeEx.getTargetException();
if (ex != null && ex instanceof SQLException) {
SQLException sqlEx = (SQLException) ex;
assertEquals(SQLError.SQL_STATE_ILLEGAL_ARGUMENT,
sqlEx.getSQLState());
messageLowBound = sqlEx.getMessage();
} else {
throw new RuntimeException(Util.stackTraceToString(ex),
ex);
}
}
String messageHighBound = null;
try {
getterMethods[i].invoke(this.rs, new Object[] { twoIndex });
} catch (InvocationTargetException invokeEx) {
Throwable ex = invokeEx.getTargetException();
if (ex != null && ex instanceof SQLException) {
SQLException sqlEx = (SQLException) ex;
assertEquals(SQLError.SQL_STATE_ILLEGAL_ARGUMENT,
sqlEx.getSQLState());
messageHighBound = sqlEx.getMessage();
} else {
throw new RuntimeException(ex);
}
}
assertNotNull("Exception message null for method "
+ getterMethods[i], messageHighBound);
assertNotNull("Exception message null for method "
+ getterMethods[i], messageLowBound);
assertTrue(!messageHighBound.equals(messageLowBound));
}
}
}
/**
* Tests fix for BUG#28085 - Need more useful error messages for diagnostics
* when the driver thinks a result set isn't updatable.
*
* @throws Exception
* if the tests fail.
*/
public void testBug28085() throws Exception {
Statement updStmt = null;
try {
createTable("testBug28085_oneKey",
"(pk int primary key not null, field2 varchar(3))");
this.stmt
.executeUpdate("INSERT INTO testBug28085_oneKey (pk, field2) VALUES (1, 'abc')");
createTable(
"testBug28085_multiKey",
"(pk1 int not null, pk2 int not null, field2 varchar(3), primary key (pk1, pk2))");
this.stmt
.executeUpdate("INSERT INTO testBug28085_multiKey VALUES (1,2,'abc')");
createTable("testBug28085_noKey", "(field1 varchar(3) not null)");
this.stmt
.executeUpdate("INSERT INTO testBug28085_noKey VALUES ('abc')");
updStmt = this.conn.createStatement(ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_UPDATABLE);
this.rs = updStmt
.executeQuery("SELECT field2 FROM testBug28085_oneKey");
exerciseUpdatableResultSet(1, "NotUpdatableReason.4");
this.rs = updStmt
.executeQuery("SELECT pk1, field2 FROM testBug28085_multiKey");
this.rs.next();
exerciseUpdatableResultSet(1, "NotUpdatableReason.7");
this.rs = updStmt
.executeQuery("SELECT t1.field2, t1.pk, t2.pk1 FROM testBug28085_oneKey t1 INNER JOIN testBug28085_multiKey t2 ON t1.pk = t2.pk1");
exerciseUpdatableResultSet(1, "NotUpdatableReason.0");
this.rs = updStmt
.executeQuery("SELECT field1 FROM testBug28085_noKey");
exerciseUpdatableResultSet(1, "NotUpdatableReason.5");
this.rs = updStmt.executeQuery("SELECT 1");
exerciseUpdatableResultSet(1, "NotUpdatableReason.3");
this.rs = updStmt
.executeQuery("SELECT pk1, pk2, LEFT(field2, 2) FROM testBug28085_multiKey");
this.rs.next();
exerciseUpdatableResultSet(1, "NotUpdatableReason.3");
} finally {
if (updStmt != null) {
updStmt.close();
}
}
}
private void exerciseUpdatableResultSet(int columnUpdateIndex,
String messageToCheck) throws Exception {
this.rs.next();
try {
this.rs.updateString(columnUpdateIndex, "def");
} catch (SQLException sqlEx) {
checkUpdatabilityMessage(sqlEx, messageToCheck);
}
try {
this.rs.moveToInsertRow();
} catch (SQLException sqlEx) {
checkUpdatabilityMessage(sqlEx, messageToCheck);
}
try {
this.rs.deleteRow();
} catch (SQLException sqlEx) {
checkUpdatabilityMessage(sqlEx, messageToCheck);
}
this.rs.close();
}
private void checkUpdatabilityMessage(SQLException sqlEx,
String messageToCheck) throws Exception {
String message = sqlEx.getMessage();
assertNotNull(message);
String localizedMessage = Messages.getString(messageToCheck);
assertTrue("Didn't find required message component '"
+ localizedMessage + "', instead found:\n\n" + message,
message.indexOf(localizedMessage) != -1);
}
public void testBug24886() throws Exception {
Properties props = new Properties();
props.setProperty("blobsAreStrings", "true");
Connection noBlobConn = getConnectionWithProps(props);
createTable("testBug24886", "(sepallength double,"
+ "sepalwidth double," + "petallength double,"
+ "petalwidth double," + "Class mediumtext, " + "fy TIMESTAMP)");
noBlobConn
.createStatement()
.executeUpdate(
"INSERT INTO testBug24886 VALUES (1,2,3,4,'1234', now()),(5,6,7,8,'12345678', now())");
this.rs = noBlobConn
.createStatement()
.executeQuery(
"SELECT concat(Class,petallength), COUNT(*) FROM `testBug24886` GROUP BY `concat(Class,petallength)`");
this.rs.next();
assertEquals("java.lang.String", this.rs.getObject(1).getClass()
.getName());
props.clear();
props.setProperty("functionsNeverReturnBlobs", "true");
noBlobConn = getConnectionWithProps(props);
this.rs = noBlobConn
.createStatement()
.executeQuery(
"SELECT concat(Class,petallength), COUNT(*) FROM `testBug24886` GROUP BY `concat(Class,petallength)`");
this.rs.next();
if (versionMeetsMinimum(4, 1)) {
assertEquals("java.lang.String", this.rs.getObject(1).getClass()
.getName());
}
}
/**
* Tests fix for BUG#30664. Note that this fix only works for MySQL server
* 5.0.25 and newer, since earlier versions didn't consistently return
* correct metadata for functions, and thus results from subqueries and
* functions were indistinguishable from each other, leading to type-related
* bugs.
*
* @throws Exception
*/
public void testBug30664() throws Exception {
if (!versionMeetsMinimum(5, 0, 25)) {
return;
}
createTable("testBug30664_1", "(id int)");
createTable("testBug30664_2", "(id int, binaryvalue varbinary(255))");
this.stmt
.executeUpdate("insert into testBug30664_1 values (1),(2),(3)");
this.stmt
.executeUpdate("insert into testBug30664_2 values (1,'���'),(2,'����'),(3,' ���')");
this.rs = this.stmt
.executeQuery("select testBug30664_1.id, (select testBug30664_2.binaryvalue from testBug30664_2 where testBug30664_2.id=testBug30664_1.id) as value from testBug30664_1");
ResultSetMetaData tblMD = this.rs.getMetaData();
for (int i = 1; i < tblMD.getColumnCount() + 1; i++) {
switch (i) {
case 1:
assertEquals("INT", tblMD.getColumnTypeName(i).toUpperCase());
break;
case 2:
assertEquals("VARBINARY", tblMD.getColumnTypeName(i)
.toUpperCase());
break;
}
}
}
/**
* Tests fix for BUG#30851, NPE with null column values when
* "padCharsWithSpace" is set to "true".
*
* @throws Exception
*/
public void testbug30851() throws Exception {
Connection padConn = getConnectionWithProps("padCharsWithSpace=true");
try {
createTable("bug30851", "(CharCol CHAR(10) DEFAULT NULL)");
this.stmt.execute("INSERT INTO bug30851 VALUES (NULL)");
this.rs = padConn.createStatement().executeQuery(
"SELECT * FROM bug30851");
this.rs.first();
String strvar = this.rs.getString(1);
assertNull("Should be null", strvar);
} finally {
if (padConn != null) {
padConn.close();
}
}
}
/**
* Tests fix for Bug#33678 - Multiple result sets not supported in
* "streaming" mode. This fix covers both normal statements, and stored
* procedures, with the exception of stored procedures with registered
* OUTPUT parameters, which can't be used at all with "streaming" result
* sets.
*
* @throws Exception
*/
public void testBug33678() throws Exception {
if (!versionMeetsMinimum(4, 1)) {
return;
}
createTable("testBug33678", "(field1 INT)");
Connection multiConn = getConnectionWithProps("allowMultiQueries=true");
Statement multiStmt = multiConn.createStatement();
try {
multiStmt.setFetchSize(Integer.MIN_VALUE);
multiStmt
.execute("SELECT 1 UNION SELECT 2; INSERT INTO testBug33678 VALUES (1); UPDATE testBug33678 set field1=2; INSERT INTO testBug33678 VALUES(3); UPDATE testBug33678 set field1=2 WHERE field1=3; UPDATE testBug33678 set field1=2; SELECT 1");
this.rs = multiStmt.getResultSet();
this.rs.next();
assertEquals("1", this.rs.getString(1));
assertFalse(multiStmt.getMoreResults());
assertEquals(1, multiStmt.getUpdateCount());
assertFalse(multiStmt.getMoreResults());
assertEquals(1, multiStmt.getUpdateCount());
assertFalse(multiStmt.getMoreResults());
assertEquals(1, multiStmt.getUpdateCount());
assertFalse(multiStmt.getMoreResults());
assertEquals(1, multiStmt.getUpdateCount());
assertFalse(multiStmt.getMoreResults());
assertEquals(2, multiStmt.getUpdateCount());
assertTrue(multiStmt.getMoreResults());
this.rs = multiStmt.getResultSet();
this.rs.next();
assertEquals("1", this.rs.getString(1));
this.rs.close();
multiStmt
.execute("INSERT INTO testBug33678 VALUES (1); INSERT INTO testBug33678 VALUES (1), (2); INSERT INTO testBug33678 VALUES (1), (2), (3)");
assertEquals(1, multiStmt.getUpdateCount());
assertFalse(multiStmt.getMoreResults());
assertEquals(2, multiStmt.getUpdateCount());
assertFalse(multiStmt.getMoreResults());
assertEquals(3, multiStmt.getUpdateCount());
assertFalse(multiStmt.getMoreResults()
&& multiStmt.getUpdateCount() == -1);
this.rs.close();
if (versionMeetsMinimum(5, 0)) {
createProcedure("spBug33678",
"() BEGIN SELECT 1; SELECT 2; SELECT 3; END");
CallableStatement cStmt = multiConn
.prepareCall("{CALL spBug33678()}");
cStmt.setFetchSize(Integer.MIN_VALUE);
cStmt.execute();
for (int i = 0; i < 2; i++) {
if (i != 0) {
assertTrue(cStmt.getMoreResults());
}
this.rs = cStmt.getResultSet();
assertTrue(this.rs.next());
assertEquals(i + 1, this.rs.getInt(1));
}
}
} finally {
multiStmt.close();
multiConn.close();
}
}
public void testBug33162() throws Exception {
if (!versionMeetsMinimum(5, 0)) {
return;
}
this.rs = this.stmt.executeQuery("select now() from dual where 1=0");
this.rs.next();
try {
this.rs.getTimestamp(1); // fails
} catch (SQLException sqlEx) {
assertEquals(SQLError.SQL_STATE_GENERAL_ERROR, sqlEx.getSQLState());
}
}
public void testBug34762() throws Exception {
createTable("testBug34762", "(field1 TIMESTAMP)");
int numRows = 10;
for (int i = 0; i < numRows; i++) {
this.stmt.executeUpdate("INSERT INTO testBug34762 VALUES (NOW())");
}
this.rs = this.stmt.executeQuery("SELECT field1 FROM testBug34762");
while (this.rs.next()) {
this.rs.getTimestamp(1);
}
this.rs = this.stmt.executeQuery("SELECT field1 FROM testBug34762");
for (int i = 1; i <= numRows; i++) {
this.rs.absolute(i);
this.rs.getTimestamp(1);
}
this.rs = this.stmt.executeQuery("SELECT field1 FROM testBug34762");
this.rs.last();
this.rs.getTimestamp(1);
while (this.rs.previous()) {
this.rs.getTimestamp(1);
}
this.rs = this.stmt.executeQuery("SELECT field1 FROM testBug34762");
this.rs.last();
while (this.rs.relative(-1)) {
this.rs.getTimestamp(1);
}
this.rs = this.stmt.executeQuery("SELECT field1 FROM testBug34762");
this.rs.beforeFirst();
while (this.rs.relative(1)) {
this.rs.getTimestamp(1);
}
}
/**
* @deprecated because we use deprecated methods
*/
public void testBug34913() throws Exception {
Timestamp ts = new Timestamp(new Date(109, 5, 1).getTime());
this.pstmt = ((com.mysql.jdbc.Connection) this.conn)
.serverPrepareStatement("SELECT 'abcdefghij', ?");
this.pstmt.setTimestamp(1, ts);
this.rs = this.pstmt.executeQuery();
this.rs.next();
assertTrue(this.rs.getTimestamp(2).getMonth() == 5);
assertTrue(this.rs.getTimestamp(2).getDate() == 1);
}
public void testBug36051() throws Exception {
this.rs = this.stmt.executeQuery("SELECT '24:00:00'");
this.rs.next();
this.rs.getTime(1);
}
/**
* Tests fix for BUG#35610, BUG#35150. We follow the JDBC Spec here, in that
* the 4.0 behavior is correct, the JDBC-3.0 (and earlier) spec has a bug,
* but you can get the buggy behavior (allowing column names *and* labels to
* be used) by setting "useColumnNamesInFindColumn" to "true".
*
* @throws Exception
*/
public void testBug35610() throws Exception {
createTable("testBug35610", "(field1 int, field2 int, field3 int)");
this.stmt.executeUpdate("INSERT INTO testBug35610 VALUES (1, 2, 3)");
exercise35610(this.stmt, false);
exercise35610(getConnectionWithProps("useColumnNamesInFindColumn=true")
.createStatement(), true);
}
private void exercise35610(Statement configuredStmt, boolean force30Behavior)
throws Exception {
this.rs = configuredStmt
.executeQuery("SELECT field1 AS f1, field2 AS f2, field3 FROM testBug35610");
ResultSetMetaData rsmd = this.rs.getMetaData();
assertEquals("field1", rsmd.getColumnName(1));
assertEquals("field2", rsmd.getColumnName(2));
assertEquals("f1", rsmd.getColumnLabel(1));
assertEquals("f2", rsmd.getColumnLabel(2));
assertEquals("field3", rsmd.getColumnName(3));
assertEquals("field3", rsmd.getColumnLabel(3));
this.rs.next();
// From ResultSet.html#getInt(java.lang.String) in JDBC-4.0
//
// Retrieves the value of the designated column in the current row of
// this ResultSet
// object as an int in the Java programming language.
//
// Parameters:
// columnLabel - the label for the column specified with the SQL AS
// clause. If the
// SQL AS clause was not specified, then the label is the name of the
// column
//
assertEquals(1, this.rs.getInt("f1"));
assertEquals(2, this.rs.getInt("f2"));
assertEquals(3, this.rs.getInt("field3"));
// Pre-JDBC 4.0, some versions of the spec say "column name *or* label"
// for the column name argument...
if (force30Behavior) {
assertEquals(1, this.rs.getInt("field1"));
assertEquals(2, this.rs.getInt("field2"));
}
if (!force30Behavior) {
try {
this.rs.findColumn("field1");
fail("findColumn(\"field1\" should have failed with an exception");
} catch (SQLException sqlEx) {
// expected
}
try {
this.rs.findColumn("field2");
fail("findColumn(\"field2\" should have failed with an exception");
} catch (SQLException sqlEx) {
// expected
}
}
}
/**
* Tests fix for BUG#39911 - We don't retrieve nanos correctly when
* -parsing- a string for a TIMESTAMP.
*/
public void testBug39911() throws Exception {
this.rs = this.stmt.executeQuery("SELECT '2008-09-26 15:47:20.797283'");
this.rs.next();
checkTimestampNanos();
this.rs = ((com.mysql.jdbc.Connection) this.conn)
.serverPrepareStatement("SELECT '2008-09-26 15:47:20.797283'")
.executeQuery();
this.rs.next();
checkTimestampNanos();
this.rs.close();
}
private void checkTimestampNanos() throws SQLException {
Timestamp ts = this.rs.getTimestamp(1);
assertEquals(797283000, ts.getNanos());
Calendar cal = Calendar.getInstance();
cal.setTime(ts);
assertEquals(797, cal.get(Calendar.MILLISECOND));
}
public void testBug38387() throws Exception {
Connection noBlobConn = null;
Properties props = new Properties();
props.put("functionsNeverReturnBlobs", "true");// toggle, no change
noBlobConn = getConnectionWithProps(props);
try {
Statement noBlobStmt = noBlobConn.createStatement();
this.rs = noBlobStmt.executeQuery("SELECT TRIM(1) AS Rslt");
while (this.rs.next()) {
assertEquals("1", this.rs.getString("Rslt"));
assertEquals("java.lang.String", this.rs.getObject(1)
.getClass().getName());
}
} finally {
noBlobConn.close();
}
}
public void testRanges() throws Exception {
createTable(
"testRanges",
"(int_field INT, long_field BIGINT, double_field DOUBLE, string_field VARCHAR(32))");
this.pstmt = this.conn
.prepareStatement("INSERT INTO testRanges VALUES (?,?,?, ?)");
this.pstmt.setInt(1, Integer.MIN_VALUE);
this.pstmt.setLong(2, Long.MIN_VALUE);
this.pstmt.setDouble(3, Long.MAX_VALUE + 1D);
this.pstmt.setString(4, "1E4");
this.pstmt.executeUpdate();
checkRangeMatrix(this.conn);
checkRangeMatrix(getConnectionWithProps("useFastIntParsing=false"));
}
private void checkRangeMatrix(Connection c) throws Exception {
this.rs = c
.createStatement()
.executeQuery(
"SELECT int_field, long_field, double_field, string_field FROM testRanges");
this.rs.next();
checkRanges();
this.rs.close();
this.pstmt = ((com.mysql.jdbc.Connection) c)
.serverPrepareStatement("SELECT int_field, long_field, double_field, string_field FROM testRanges");
this.rs = this.pstmt.executeQuery();
this.rs.next();
checkRanges();
this.rs.close();
this.pstmt.setFetchSize(Integer.MIN_VALUE);
this.rs = this.pstmt.executeQuery();
this.rs.next();
checkRanges();
this.rs.close();
this.pstmt = ((com.mysql.jdbc.Connection) c)
.clientPrepareStatement("SELECT int_field, long_field, double_field, string_field FROM testRanges");
this.rs = this.pstmt.executeQuery();
this.rs.next();
checkRanges();
this.rs.close();
this.pstmt.setFetchSize(Integer.MIN_VALUE);
this.rs = this.pstmt.executeQuery();
this.rs.next();
checkRanges();
this.rs.close();
}
private void checkRanges() throws SQLException {
assertEquals(Integer.MIN_VALUE, this.rs.getInt(1));
try {
this.rs.getInt(2);
} catch (SQLException sqlEx) {
assertTrue(sqlEx.getMessage().indexOf(" in column '2'") != -1);
}
assertEquals(Long.MIN_VALUE, this.rs.getLong(2));
try {
this.rs.getLong(3);
} catch (SQLException sqlEx) {
assertTrue(sqlEx.getMessage().indexOf(" in column '3'") != -1);
}
assertEquals(10000, this.rs.getInt(4));
assertEquals(10000, this.rs.getLong(4));
}
/**
* Bug #41484 Accessing fields by name after the ResultSet is closed throws
* NullPointerException.
*/
public void testBug41484() throws Exception {
try {
rs = stmt.executeQuery("select 1 as abc");
rs.next();
rs.getString("abc");
rs.close();
rs.getString("abc");
} catch (SQLException ex) {
/* expected */
assertEquals(0, ex.getErrorCode());
assertEquals("S1000", ex.getSQLState());
}
}
public void testBug41484_2() throws Exception {
Connection cachedRsmdConn = getConnectionWithProps("cacheResultSetMetadata=true");
try {
createTable("bug41484",
"(id int not null primary key, day date not null) DEFAULT CHARSET=utf8");
this.pstmt = cachedRsmdConn
.prepareStatement("INSERT INTO bug41484(id, day) values(1, ?)");
this.pstmt.setInt(1, 20080509);
assertEquals(1, this.pstmt.executeUpdate());
this.pstmt.close();
this.pstmt = cachedRsmdConn
.prepareStatement("SELECT * FROM bug41484 WHERE id = ?");
this.pstmt.setInt(1, 1);
this.rs = this.pstmt.executeQuery();
this.rs.first();
this.rs.getString("day");
this.rs.close();
this.pstmt.close();
this.pstmt = cachedRsmdConn
.prepareStatement("INSERT INTO bug41484(id, day) values(2, ?)");
this.pstmt.setInt(1, 20090212);
assertEquals(1, this.pstmt.executeUpdate());
this.pstmt.close();
this.pstmt = cachedRsmdConn
.prepareStatement("SELECT * FROM bug41484 WHERE id = ?");
this.pstmt.setInt(1, 2);
this.rs = this.pstmt.executeQuery();
this.rs.first();
assertEquals(this.rs.getString(1), "2");
this.rs.getString("day");
this.rs.close();
this.pstmt.close();
} finally {
cachedRsmdConn.close();
}
}
public void testBug27431() throws Exception {
createTable("bug27431", "(`ID` int(20) NOT NULL auto_increment,"
+ "`Name` varchar(255) NOT NULL default '',"
+ "PRIMARY KEY (`ID`))");
this.stmt
.executeUpdate("INSERT INTO bug27431 (`ID`, `Name`) VALUES (1, 'Lucho'),(2, 'Lily'),(3, 'Kiro')");
Statement updStmt = this.conn.createStatement(
ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE);
this.rs = updStmt.executeQuery("SELECT ID, Name FROM bug27431");
while (this.rs.next()) {
this.rs.deleteRow();
}
assertEquals(0, getRowCount("bug27431"));
}
public void testBug43759() throws Exception {
createTable("testtable_bincolumn", "("
+ "bincolumn binary(8) NOT NULL, " + "PRIMARY KEY (bincolumn)"
+ ")", "innodb");
String pkValue1 = "0123456789ABCD90";
String pkValue2 = "0123456789ABCD00";
// put some data in it
this.stmt.executeUpdate("INSERT INTO testtable_bincolumn (bincolumn) "
+ "VALUES (unhex('" + pkValue1 + "')), (unhex('" + pkValue2
+ "'))");
// cause the bug
Statement updStmt = this.conn.createStatement(
ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE);
this.rs = updStmt
.executeQuery("SELECT * FROM testtable_bincolumn WHERE bincolumn = unhex('"
+ pkValue1 + "')");
assertTrue(this.rs.next());
this.rs.deleteRow();
// At this point the row with pkValue1 should be deleted. We'll select
// it back to see.
// If the row comes back, the testcase has failed.
this.rs = this.stmt
.executeQuery("SELECT * FROM testtable_bincolumn WHERE bincolumn = unhex('"
+ pkValue1 + "')");
assertFalse(rs.next());
// Now, show a case where it happens to work, because the binary data is
// different
updStmt = this.conn.createStatement(ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_UPDATABLE);
this.rs = updStmt
.executeQuery("SELECT * FROM testtable_bincolumn WHERE bincolumn = unhex('"
+ pkValue2 + "')");
assertTrue(this.rs.next());
rs.deleteRow();
this.rs = this.stmt
.executeQuery("SELECT * FROM testtable_bincolumn WHERE bincolumn = unhex('"
+ pkValue2 + "')");
assertFalse(rs.next());
}
public void testBug32525() throws Exception {
createTable("bug32525", "(field1 date, field2 timestamp)");
this.stmt
.executeUpdate("INSERT INTO bug32525 VALUES ('0000-00-00', '0000-00-00 00:00:00')");
Connection noStringSyncConn = getConnectionWithProps("noDatetimeStringSync=true");
try {
this.rs = ((com.mysql.jdbc.Connection) noStringSyncConn)
.serverPrepareStatement(
"SELECT field1, field2 FROM bug32525")
.executeQuery();
this.rs.next();
assertEquals("0000-00-00", this.rs.getString(1));
assertEquals("0000-00-00 00:00:00", this.rs.getString(2));
} finally {
noStringSyncConn.close();
}
}
public void testBug49797() throws Exception {
createTable("testBug49797", "(`Id` int(2) not null auto_increment, "
+ "`abc` char(50) , "
+ "PRIMARY KEY (`Id`)) ENGINE=MyISAM DEFAULT CHARSET=utf8");
this.stmt
.executeUpdate("INSERT into testBug49797 VALUES (1,'1'),(2,'2'),(3,'3')");
assertEquals(3, getRowCount("testBug49797"));
Statement updStmt = conn.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
try {
this.rs = updStmt.executeQuery("SELECT * FROM testBug49797");
while (rs.next()) {
rs.deleteRow();
}
assertEquals(0, getRowCount("testBug49797"));
} finally {
updStmt.close();
}
}
public void testBug49516() throws Exception {
CachedRowSet crs;
createTable(
"bug49516",
"(`testingID` INT NOT NULL AUTO_INCREMENT PRIMARY KEY, `firstName` TEXT NOT NULL) CHARACTER SET utf8;");
this.stmt.executeUpdate("insert into bug49516 set firstName ='John'");
this.rs = this.stmt
.executeQuery("select firstName as 'first person' from bug49516");
this.rs.first();
assertEquals("John", this.rs.getString("first person"));
// this.rs.close();
// this.stmt.close();
this.rs = this.stmt
.executeQuery("select firstName as 'first person' from bug49516");
crs = (CachedRowSet)Class.forName("com.sun.rowset.CachedRowSetImpl").newInstance();
crs.populate(this.rs);
crs.first();
assertEquals("John", crs.getString(1));
}
public void testBug48820() throws Exception {
CachedRowSet crs;
Connection noBlobsConn = getConnectionWithProps("functionsNeverReturnBlobs=true");
if (versionMeetsMinimum(5, 6, 6)) {
this.rs = noBlobsConn.createStatement().executeQuery("SHOW VARIABLES LIKE 'old_passwords'");
if (this.rs.next()) {
if (this.rs.getInt(2) == 2) {
System.out.println("Skip testBug48820 due to SHA-256 password hashing.");
return;
}
}
}
this.rs = noBlobsConn.createStatement().executeQuery(
"SELECT PASSWORD ('SOMETHING')");
this.rs.first();
String fromPlainResultSet = this.rs.getString(1);
this.rs = noBlobsConn.createStatement().executeQuery(
"SELECT PASSWORD ('SOMETHING')");
crs = (CachedRowSet)Class.forName("com.sun.rowset.CachedRowSetImpl").newInstance();
crs.populate(this.rs);
crs.first();
assertEquals(fromPlainResultSet, crs.getString(1));
}
/**
* Bug #60313 bug in com.mysql.jdbc.ResultSetRow.getTimestampFast
*
*/
public void testBug60313() throws Exception {
this.stmt.executeQuery("select repeat('Z', 3000), now() + interval 1 microsecond");
this.rs = this.stmt.getResultSet();
assertTrue(this.rs.next());
assertEquals(1000, this.rs.getTimestamp(2).getNanos());
this.rs.close();
this.pstmt = this.conn.prepareStatement("select repeat('Z', 3000), now() + interval 1 microsecond");
this.rs = this.pstmt.executeQuery();
assertTrue(this.rs.next());
assertEquals(1000, this.rs.getTimestamp(2).getNanos());
this.rs.close();
Properties props = new Properties();
props.setProperty("useServerPrepStmts", "true");
Connection sspsCon = getConnectionWithProps(props);
PreparedStatement ssPStmt = sspsCon.prepareStatement("select repeat('Z', 3000), now() + interval 1 microsecond");
this.rs = ssPStmt.executeQuery();
assertTrue(this.rs.next());
assertEquals(1000, this.rs.getTimestamp(2).getNanos());
this.rs.close();
ssPStmt.close();
sspsCon.close();
}
/**
* Tests fix for BUG#65503 - ResultSets created by PreparedStatement.getGeneratedKeys() are not close()d.
*
* To get results quicker add option -Xmx10M, with this option I got an out of memory failure after about 6500 passes.
* Since it's a very long test it is disabled by default.
*
* @throws Exception
* if the test fails.
*/
public void testBug65503() throws Exception {
if (false) {
createTable("testBug65503","(id INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY, value INTEGER)");
PreparedStatement pStmt = this.conn.prepareStatement("INSERT INTO testBug65503 (value) VALUES (?)", Statement.RETURN_GENERATED_KEYS),
stmt2 = this.conn.prepareStatement("SELECT * FROM testBug65503 LIMIT 6");
for (int i = 0; i < 100000000; ++i) {
pStmt.setString(1, "48");
pStmt.executeUpdate();
ResultSet result = pStmt.getGeneratedKeys();
result.next();
result.getInt(1);
result.next();
result = stmt2.executeQuery();
while (result.next());
if (i % 500 == 0) {
System.out.printf("free-mem: %d, id: %d\n", Runtime.getRuntime().freeMemory()/1024/1024, i);
this.conn.createStatement().execute("TRUNCATE TABLE testBug65503");
}
}
}
}
/**
* Tests fix for BUG#64204 - ResultSet.close hangs if streaming query is killed
* @throws Exception
*/
public void testBug64204() throws Exception {
final Properties props = new Properties();
props.setProperty("socketTimeout", "30000");
this.conn = getConnectionWithProps(props);
this.conn.setCatalog("information_schema");
this.conn.setAutoCommit(true);
this.stmt = this.conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
this.stmt.setFetchSize(Integer.MIN_VALUE); // turn on streaming mode
this.rs = this.stmt.executeQuery("SELECT CONNECTION_ID()");
this.rs.next();
final String connectionId = this.rs.getString(1);
this.rs.close();
System.out.println("testBug64204.main: PID is " + connectionId);
ScheduledExecutorService es = Executors.newSingleThreadScheduledExecutor();
es.schedule(new Callable<Boolean>() {
public Boolean call() throws Exception {
boolean res = false;
Connection con2 = getConnectionWithProps(props);
con2.setCatalog("information_schema");
con2.setAutoCommit(true);
Statement st2 = con2.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
st2.setFetchSize(Integer.MIN_VALUE); // turn on streaming mode
try {
System.out.println("testBug64204.slave: Running KILL QUERY " + connectionId);
st2.execute("KILL QUERY " + connectionId + ";");
Thread.sleep(5000);
System.out.println("testBug64204.slave: parent thread should be hung now!!!");
res = true;
} finally {
if (st2 != null) {
st2.close();
}
if (con2 != null) {
con2.close();
}
}
System.out.println("testBug64204.slave: Done.");
return res;
}
}, 10, TimeUnit.SECONDS);
try {
this.rs = this.stmt.executeQuery("SELECT sleep(5) FROM character_sets LIMIT 10");
int rows = 0;
int columnCount = this.rs.getMetaData().getColumnCount();
System.out.println("testBug64204.main" + ": " + "fetched result set, " + columnCount + " columns");
long totalDataCount = 0;
while(this.rs.next()) {
rows++;
//get row size
long rowSize = 0;
for(int i = 0; i < columnCount; i++) {
String s = this.rs.getString(i + 1);
if (s != null) {
rowSize += s.length();
}
}
totalDataCount += rowSize;
}
System.out.println("testBug64204.main" + ": " + "character_sets total rows " + rows + ", data " + totalDataCount);
} catch(SQLException se) {
assertEquals("ER_QUERY_INTERRUPTED expected.", "70100", se.getSQLState());
if (!"70100".equals(se.getSQLState())) {
throw se;
}
}
}
/**
* Bug #45757 - ResultSet.updateRow should throw SQLException when cursor is on insert row
*/
public void testBug45757() throws SQLException {
createTable("bug45757", "(id INTEGER NOT NULL PRIMARY KEY)");
this.stmt = this.conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE);
this.rs = this.stmt.executeQuery("select id from bug45757");
this.rs.moveToInsertRow();
try {
this.rs.updateRow();
fail("updateRow() should throw an exception, not allowed to be called on insert row");
} catch(SQLException sqlEx) {
assertTrue(sqlEx.getMessage().startsWith("Can not call updateRow() when on insert row."));
}
}
}