2
Copyright (C) 2002-2007 MySQL AB
4
This program is free software; you can redistribute it and/or modify
5
it under the terms of version 2 of the GNU General Public License as
6
published by the Free Software Foundation.
8
There are special exceptions to the terms and conditions of the GPL
9
as it is applied to this software. View the full text of the
10
exception in file EXCEPTIONS-CONNECTOR-J in the directory of this
11
software distribution.
13
This program is distributed in the hope that it will be useful,
14
but WITHOUT ANY WARRANTY; without even the implied warranty of
15
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
GNU General Public License for more details.
18
You should have received a copy of the GNU General Public License
19
along with this program; if not, write to the Free Software
20
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25
package testsuite.regression;
27
import java.io.ByteArrayInputStream;
28
import java.io.ByteArrayOutputStream;
29
import java.io.CharArrayReader;
31
import java.io.FileOutputStream;
32
import java.io.FileWriter;
33
import java.io.IOException;
34
import java.io.PrintStream;
35
import java.io.StringReader;
36
import java.io.Writer;
37
import java.math.BigDecimal;
38
import java.math.BigInteger;
39
import java.sql.BatchUpdateException;
42
import java.sql.Connection;
43
import java.sql.DataTruncation;
45
import java.sql.PreparedStatement;
46
import java.sql.ResultSet;
47
import java.sql.SQLException;
48
import java.sql.SQLWarning;
49
import java.sql.Statement;
51
import java.sql.Timestamp;
52
import java.sql.Types;
53
import java.text.SimpleDateFormat;
54
import java.util.Calendar;
55
import java.util.Locale;
56
import java.util.Properties;
57
import java.util.TimeZone;
59
import testsuite.BaseTestCase;
61
import com.mysql.jdbc.SQLError;
62
import com.mysql.jdbc.ServerPreparedStatement;
63
import com.mysql.jdbc.exceptions.MySQLTimeoutException;
66
* Regression tests for the Statement class
68
* @author Mark Matthews
70
public class StatementRegressionTest extends BaseTestCase {
71
class PrepareThread extends Thread {
74
PrepareThread(Connection cn) {
79
for (int i = 0; i < 20; i++) // force this to end eventually
82
this.c.prepareStatement("SELECT 1");
83
StatementRegressionTest.this.testServerPrepStmtDeadlockCounter++;
85
} catch (SQLException sqlEx) {
86
throw new RuntimeException(sqlEx);
87
} catch (InterruptedException e) {
96
static int nextID = 1; // The next ID we expected to generate
99
* Each row in this table is to be converted into a single REPLACE
100
* statement. If the value is zero, a new record is to be created using then
101
* autoincrement feature. If the value is non-zero, the existing row of that
102
* value is to be replace with, obviously, the same key. I expect one
103
* Generated Key for each zero value - but I would accept one key for each
104
* value, with non-zero values coming back as themselves.
106
static final int[][] tests = { { 0 }, // generate 1
107
{ 1, 0, 0 }, // update 1, generate 2, 3
108
{ 2, 0, 0, }, // update 2, generate 3, 4
112
* Runs all test cases in this test suite
116
public static void main(String[] args) {
117
junit.textui.TestRunner.run(StatementRegressionTest.class);
120
private int testServerPrepStmtDeadlockCounter = 0;
123
* Constructor for StatementRegressionTest.
126
* the name of the test to run
128
public StatementRegressionTest(String name) {
132
private void addBatchItems(Statement statement, PreparedStatement pStmt,
133
String tableName, int i) throws SQLException {
134
pStmt.setString(1, "ps_batch_" + i);
135
pStmt.setString(2, "ps_batch_" + i);
138
statement.addBatch("INSERT INTO " + tableName
139
+ " (strdata1, strdata2) VALUES " + "(\"s_batch_" + i
140
+ "\",\"s_batch_" + i + "\")");
143
private void createGGKTables() throws Exception {
144
// Delete and recreate table
147
this.stmt.executeUpdate("CREATE TABLE testggk ("
148
+ "id INT AUTO_INCREMENT NOT NULL PRIMARY KEY,"
149
+ "val INT NOT NULL" + ")");
152
private void doGGKTestPreparedStatement(int[] values, boolean useUpdate)
154
// Generate the the multiple replace command
155
StringBuffer cmd = new StringBuffer("REPLACE INTO testggk VALUES ");
158
for (int i = 0; i < values.length; i++) {
161
if (values[i] == 0) {
165
cmd.append(values[i]);
173
cmd.setLength(cmd.length() - 2); // trim the final ", "
175
// execute and print it
176
System.out.println(cmd.toString());
178
PreparedStatement pStmt = this.conn.prepareStatement(cmd.toString(),
179
Statement.RETURN_GENERATED_KEYS);
182
pStmt.executeUpdate();
187
// print out what actually happened
188
System.out.println("Expect " + newKeys
189
+ " generated keys, starting from " + nextID);
191
this.rs = pStmt.getGeneratedKeys();
192
StringBuffer res = new StringBuffer("Got keys");
194
int[] generatedKeys = new int[newKeys];
197
while (this.rs.next()) {
198
if (i < generatedKeys.length) {
199
generatedKeys[i] = this.rs.getInt(1);
204
res.append(" " + this.rs.getInt(1));
207
int numberOfGeneratedKeys = i;
210
"Didn't retrieve expected number of generated keys, expected "
211
+ newKeys + ", found " + numberOfGeneratedKeys,
212
numberOfGeneratedKeys == newKeys);
213
assertTrue("Keys didn't start with correct sequence: ",
214
generatedKeys[0] == nextID);
216
System.out.println(res.toString());
218
// Read and print the new state of the table
219
this.rs = this.stmt.executeQuery("SELECT id, val FROM testggk");
220
System.out.println("New table contents ");
222
while (this.rs.next())
223
System.out.println("Id " + this.rs.getString(1) + " val "
224
+ this.rs.getString(2));
227
System.out.println("");
231
private void doGGKTestStatement(int[] values, boolean useUpdate)
233
// Generate the the multiple replace command
234
StringBuffer cmd = new StringBuffer("REPLACE INTO testggk VALUES ");
237
for (int i = 0; i < values.length; i++) {
240
if (values[i] == 0) {
244
cmd.append(values[i]);
252
cmd.setLength(cmd.length() - 2); // trim the final ", "
254
// execute and print it
255
System.out.println(cmd.toString());
258
this.stmt.executeUpdate(cmd.toString(),
259
Statement.RETURN_GENERATED_KEYS);
261
this.stmt.execute(cmd.toString(), Statement.RETURN_GENERATED_KEYS);
264
// print out what actually happened
265
System.out.println("Expect " + newKeys
266
+ " generated keys, starting from " + nextID);
268
this.rs = this.stmt.getGeneratedKeys();
269
StringBuffer res = new StringBuffer("Got keys");
271
int[] generatedKeys = new int[newKeys];
274
while (this.rs.next()) {
275
if (i < generatedKeys.length) {
276
generatedKeys[i] = this.rs.getInt(1);
281
res.append(" " + this.rs.getInt(1));
284
int numberOfGeneratedKeys = i;
287
"Didn't retrieve expected number of generated keys, expected "
288
+ newKeys + ", found " + numberOfGeneratedKeys,
289
numberOfGeneratedKeys == newKeys);
290
assertTrue("Keys didn't start with correct sequence: ",
291
generatedKeys[0] == nextID);
293
System.out.println(res.toString());
295
// Read and print the new state of the table
296
this.rs = this.stmt.executeQuery("SELECT id, val FROM testggk");
297
System.out.println("New table contents ");
299
while (this.rs.next())
300
System.out.println("Id " + this.rs.getString(1) + " val "
301
+ this.rs.getString(2));
304
System.out.println("");
308
private void dropGGKTables() throws Exception {
309
this.stmt.executeUpdate("DROP TABLE IF EXISTS testggk");
315
* @throws SQLException
317
private void execQueryBug5191(PreparedStatement pStmt, int catId)
318
throws SQLException {
319
pStmt.setInt(1, catId);
321
this.rs = pStmt.executeQuery();
323
assertTrue(this.rs.next());
324
assertTrue(this.rs.next());
325
// assertTrue(rs.next());
327
assertFalse(this.rs.next());
330
private String getByteArrayString(byte[] ba) {
331
StringBuffer buffer = new StringBuffer();
333
for (int i = 0; i < ba.length; i++) {
334
buffer.append("0x" + Integer.toHexString(ba[i] & 0xff) + " ");
337
buffer.append("null");
339
return buffer.toString();
343
* @param continueBatchOnError
344
* @throws SQLException
346
private void innerBug6823(boolean continueBatchOnError) throws SQLException {
347
Properties continueBatchOnErrorProps = new Properties();
348
continueBatchOnErrorProps.setProperty("continueBatchOnError", String
349
.valueOf(continueBatchOnError));
350
this.conn = getConnectionWithProps(continueBatchOnErrorProps);
351
Statement statement = this.conn.createStatement();
353
String tableName = "testBug6823";
355
createTable(tableName, "(id int not null primary key auto_increment,"
356
+ " strdata1 varchar(255) not null, strdata2 varchar(255),"
357
+ " UNIQUE INDEX (strdata1))");
359
PreparedStatement pStmt = this.conn.prepareStatement("INSERT INTO "
360
+ tableName + " (strdata1, strdata2) VALUES (?,?)");
363
addBatchItems(statement, pStmt, tableName, ++c);
364
addBatchItems(statement, pStmt, tableName, ++c);
365
addBatchItems(statement, pStmt, tableName, ++c);
366
addBatchItems(statement, pStmt, tableName, c); // duplicate entry
367
addBatchItems(statement, pStmt, tableName, ++c);
368
addBatchItems(statement, pStmt, tableName, ++c);
370
int expectedUpdateCounts = continueBatchOnError ? 6 : 3;
372
BatchUpdateException e1 = null;
373
BatchUpdateException e2 = null;
375
int[] updateCountsPstmt = null;
377
updateCountsPstmt = pStmt.executeBatch();
378
} catch (BatchUpdateException e) {
380
updateCountsPstmt = e1.getUpdateCounts();
383
int[] updateCountsStmt = null;
385
updateCountsStmt = statement.executeBatch();
386
} catch (BatchUpdateException e) {
388
updateCountsStmt = e1.getUpdateCounts();
394
assertEquals(expectedUpdateCounts, updateCountsPstmt.length);
395
assertEquals(expectedUpdateCounts, updateCountsStmt.length);
397
if (continueBatchOnError) {
398
assertTrue(updateCountsPstmt[3] == Statement.EXECUTE_FAILED);
399
assertTrue(updateCountsStmt[3] == Statement.EXECUTE_FAILED);
403
this.rs = this.stmt.executeQuery("SELECT * from " + tableName
404
+ " WHERE strdata1 like \"ps_%\"");
405
while (this.rs.next()) {
408
assertTrue(psRows > 0);
411
this.rs = this.stmt.executeQuery("SELECT * from " + tableName
412
+ " WHERE strdata1 like \"s_%\"");
413
while (this.rs.next()) {
416
assertTrue(sRows > 0);
418
assertTrue(psRows + "!=" + sRows, psRows == sRows);
422
* Tests fix for BUG#10155, double quotes not recognized when parsing
423
* client-side prepared statements.
428
public void testBug10155() throws Exception {
429
this.conn.prepareStatement(
430
"SELECT \"Test question mark? Test single quote'\"")
431
.executeQuery().close();
435
* Tests fix for BUG#10630, Statement.getWarnings() fails with NPE if
436
* statement has been closed.
438
public void testBug10630() throws Exception {
439
Connection conn2 = null;
440
Statement stmt2 = null;
443
conn2 = getConnectionWithProps(null);
444
stmt2 = conn2.createStatement();
448
fail("Should've caught an exception here");
449
} catch (SQLException sqlEx) {
450
assertEquals("08003", sqlEx.getSQLState());
463
* Tests fix for BUG#11115, Varbinary data corrupted when using server-side
464
* prepared statements.
466
public void testBug11115() throws Exception {
467
String tableName = "testBug11115";
469
if (versionMeetsMinimum(4, 1, 0)) {
471
createTable(tableName,
472
"(pwd VARBINARY(30)) TYPE=InnoDB DEFAULT CHARACTER SET utf8");
474
byte[] bytesToTest = new byte[] { 17, 120, -1, -73, -5 };
476
PreparedStatement insStmt = this.conn
477
.prepareStatement("INSERT INTO " + tableName
478
+ " (pwd) VALUES (?)");
479
insStmt.setBytes(1, bytesToTest);
480
insStmt.executeUpdate();
482
this.rs = this.stmt.executeQuery("SELECT pwd FROM " + tableName);
485
byte[] fromDatabase = this.rs.getBytes(1);
487
assertEquals(bytesToTest.length, fromDatabase.length);
489
for (int i = 0; i < bytesToTest.length; i++) {
490
assertEquals(bytesToTest[i], fromDatabase[i]);
494
.prepareStatement("SELECT pwd FROM " + tableName)
498
fromDatabase = this.rs.getBytes(1);
500
assertEquals(bytesToTest.length, fromDatabase.length);
502
for (int i = 0; i < bytesToTest.length; i++) {
503
assertEquals(bytesToTest[i], fromDatabase[i]);
508
public void testBug11540() throws Exception {
509
Locale originalLocale = Locale.getDefault();
510
Connection thaiConn = null;
511
Statement thaiStmt = null;
512
PreparedStatement thaiPrepStmt = null;
515
createTable("testBug11540", "(field1 DATE, field2 TIMESTAMP)");
517
.executeUpdate("INSERT INTO testBug11540 VALUES (NOW(), NOW())");
518
Locale.setDefault(new Locale("th", "TH"));
519
Properties props = new Properties();
520
props.setProperty("jdbcCompliantTruncation", "false");
522
thaiConn = getConnectionWithProps(props);
523
thaiStmt = thaiConn.createStatement();
526
.executeQuery("SELECT field1, field2 FROM testBug11540");
529
Date origDate = this.rs.getDate(1);
530
Timestamp origTimestamp = this.rs.getTimestamp(1);
533
thaiStmt.executeUpdate("TRUNCATE TABLE testBug11540");
535
thaiPrepStmt = ((com.mysql.jdbc.Connection) thaiConn)
536
.clientPrepareStatement("INSERT INTO testBug11540 VALUES (?,?)");
537
thaiPrepStmt.setDate(1, origDate);
538
thaiPrepStmt.setTimestamp(2, origTimestamp);
539
thaiPrepStmt.executeUpdate();
542
.executeQuery("SELECT field1, field2 FROM testBug11540");
545
Date testDate = this.rs.getDate(1);
546
Timestamp testTimestamp = this.rs.getTimestamp(1);
549
assertEquals(origDate, testDate);
550
assertEquals(origTimestamp, testTimestamp);
553
Locale.setDefault(originalLocale);
558
* Tests fix for BUG#11663, autoGenerateTestcaseScript uses bogus parameter
559
* names for server-side prepared statements.
564
public void testBug11663() throws Exception {
565
if (versionMeetsMinimum(4, 1, 0)
566
&& ((com.mysql.jdbc.Connection) this.conn)
567
.getUseServerPreparedStmts()) {
568
Connection testcaseGenCon = null;
569
PrintStream oldErr = System.err;
572
createTable("testBug11663", "(field1 int)");
574
Properties props = new Properties();
575
props.setProperty("autoGenerateTestcaseScript", "true");
576
testcaseGenCon = getConnectionWithProps(props);
577
ByteArrayOutputStream testStream = new ByteArrayOutputStream();
578
PrintStream testErr = new PrintStream(testStream);
579
System.setErr(testErr);
580
this.pstmt = testcaseGenCon
581
.prepareStatement("SELECT field1 FROM testBug11663 WHERE field1=?");
582
this.pstmt.setInt(1, 1);
583
this.pstmt.execute();
584
System.setErr(oldErr);
585
String testString = new String(testStream.toByteArray());
587
int setIndex = testString.indexOf("SET @debug_stmt_param");
588
int equalsIndex = testString.indexOf("=", setIndex);
589
String paramName = testString.substring(setIndex + 4,
592
int usingIndex = testString.indexOf("USING " + paramName,
595
assertTrue(usingIndex != -1);
597
System.setErr(oldErr);
599
if (this.pstmt != null) {
604
if (testcaseGenCon != null) {
605
testcaseGenCon.close();
613
* Tests fix for BUG#11798 - Pstmt.setObject(...., Types.BOOLEAN) throws
619
public void testBug11798() throws Exception {
620
if (isRunningOnJdk131()) {
621
return; // test not valid on JDK-1.3.1
625
this.pstmt = this.conn.prepareStatement("SELECT ?");
626
this.pstmt.setObject(1, Boolean.TRUE, Types.BOOLEAN);
627
this.pstmt.setObject(1, new BigDecimal("1"), Types.BOOLEAN);
628
this.pstmt.setObject(1, "true", Types.BOOLEAN);
630
if (this.pstmt != null) {
638
* Tests fix for BUG#13255 - Reconnect during middle of executeBatch()
644
public void testBug13255() throws Exception {
646
createTable("testBug13255", "(field_1 int)");
648
Properties props = new Properties();
649
props.setProperty("autoReconnect", "true");
651
Connection reconnectConn = null;
652
Statement reconnectStmt = null;
653
PreparedStatement reconnectPStmt = null;
656
reconnectConn = getConnectionWithProps(props);
657
reconnectStmt = reconnectConn.createStatement();
659
String connectionId = getSingleIndexedValueWithQuery(reconnectConn,
660
1, "SELECT CONNECTION_ID()").toString();
662
reconnectStmt.addBatch("INSERT INTO testBug13255 VALUES (1)");
663
reconnectStmt.addBatch("INSERT INTO testBug13255 VALUES (2)");
664
reconnectStmt.addBatch("KILL " + connectionId);
666
for (int i = 0; i < 100; i++) {
667
reconnectStmt.addBatch("INSERT INTO testBug13255 VALUES (" + i
672
reconnectStmt.executeBatch();
673
} catch (SQLException sqlEx) {
674
// We expect this...we killed the connection
677
assertEquals(2, getRowCount("testBug13255"));
679
this.stmt.executeUpdate("TRUNCATE TABLE testBug13255");
681
reconnectConn.close();
683
reconnectConn = getConnectionWithProps(props);
685
connectionId = getSingleIndexedValueWithQuery(reconnectConn, 1,
686
"SELECT CONNECTION_ID()").toString();
688
reconnectPStmt = reconnectConn
689
.prepareStatement("INSERT INTO testBug13255 VALUES (?)");
690
reconnectPStmt.setInt(1, 1);
691
reconnectPStmt.addBatch();
692
reconnectPStmt.setInt(1, 2);
693
reconnectPStmt.addBatch();
694
reconnectPStmt.addBatch("KILL " + connectionId);
696
for (int i = 3; i < 100; i++) {
697
reconnectPStmt.setInt(1, i);
698
reconnectPStmt.addBatch();
702
reconnectPStmt.executeBatch();
703
} catch (SQLException sqlEx) {
704
// We expect this...we killed the connection
707
assertEquals(2, getRowCount("testBug13255"));
710
if (reconnectStmt != null) {
711
reconnectStmt.close();
714
if (reconnectConn != null) {
715
reconnectConn.close();
721
* Tests fix for BUG#15024 - Driver incorrectly closes streams passed as
722
* arguments to PreparedStatements.
727
public void testBug15024() throws Exception {
728
createTable("testBug15024", "(field1 BLOB)");
731
this.pstmt = this.conn
732
.prepareStatement("INSERT INTO testBug15024 VALUES (?)");
733
testStreamsForBug15024(false, false);
735
Properties props = new Properties();
736
props.setProperty("useConfigs", "3-0-Compat");
738
Connection compatConn = null;
741
compatConn = getConnectionWithProps(props);
743
this.pstmt = compatConn
744
.prepareStatement("INSERT INTO testBug15024 VALUES (?)");
745
testStreamsForBug15024(true, false);
747
if (compatConn != null) {
752
if (this.pstmt != null) {
753
PreparedStatement toClose = this.pstmt;
762
* PreparedStatement should call EscapeProcessor.escapeSQL?
767
public void testBug15141() throws Exception {
769
createTable("testBug15141", "(field1 VARCHAR(32))");
770
this.stmt.executeUpdate("INSERT INTO testBug15141 VALUES ('abc')");
772
this.pstmt = this.conn
773
.prepareStatement("select {d '1997-05-24'} FROM testBug15141");
774
this.rs = this.pstmt.executeQuery();
775
assertTrue(this.rs.next());
776
assertEquals("1997-05-24", this.rs.getString(1));
782
this.pstmt = ((com.mysql.jdbc.Connection) this.conn)
783
.clientPrepareStatement("select {d '1997-05-24'} FROM testBug15141");
784
this.rs = this.pstmt.executeQuery();
785
assertTrue(this.rs.next());
786
assertEquals("1997-05-24", this.rs.getString(1));
792
if (this.rs != null) {
793
ResultSet toCloseRs = this.rs;
798
if (this.pstmt != null) {
799
PreparedStatement toClosePstmt = this.pstmt;
801
toClosePstmt.close();
807
* Tests fix for BUG#18041 - Server-side prepared statements don't cause
808
* truncation exceptions to be thrown.
813
public void testBug18041() throws Exception {
814
if (versionMeetsMinimum(4, 1)) {
815
createTable("testBug18041", "(`a` tinyint(4) NOT NULL,"
816
+ "`b` char(4) default NULL)");
818
Properties props = new Properties();
819
props.setProperty("jdbcCompliantTruncation", "true");
820
props.setProperty("useServerPrepStmts", "true");
822
Connection truncConn = null;
823
PreparedStatement stm = null;
826
truncConn = getConnectionWithProps(props);
829
.prepareStatement("insert into testBug18041 values (?,?)");
831
stm.setString(2, "nnnnnnnnnnnnnnnnnnnnnnnnnnnnnn");
833
fail("Truncation exception should have been thrown");
834
} catch (DataTruncation truncEx) {
837
if (this.stmt != null) {
841
if (truncConn != null) {
848
private void testStreamsForBug15024(boolean shouldBeClosedStream,
849
boolean shouldBeClosedReader) throws SQLException {
850
IsClosedInputStream bIn = new IsClosedInputStream(new byte[4]);
851
IsClosedReader readerIn = new IsClosedReader("abcdef");
853
this.pstmt.setBinaryStream(1, bIn, 4);
854
this.pstmt.execute();
855
assertEquals(shouldBeClosedStream, bIn.isClosed());
857
this.pstmt.setCharacterStream(1, readerIn, 6);
858
this.pstmt.execute();
859
assertEquals(shouldBeClosedReader, readerIn.isClosed());
864
class IsClosedReader extends StringReader {
866
boolean isClosed = false;
868
public IsClosedReader(String arg0) {
872
public void close() {
875
this.isClosed = true;
878
public boolean isClosed() {
879
return this.isClosed;
884
class IsClosedInputStream extends ByteArrayInputStream {
886
boolean isClosed = false;
888
public IsClosedInputStream(byte[] arg0, int arg1, int arg2) {
889
super(arg0, arg1, arg2);
892
public IsClosedInputStream(byte[] arg0) {
896
public void close() throws IOException {
897
// TODO Auto-generated method stub
899
this.isClosed = true;
902
public boolean isClosed() {
903
return this.isClosed;
908
* Tests fix for BUG#1774 -- Truncated words after double quote
913
public void testBug1774() throws Exception {
915
this.stmt.executeUpdate("DROP TABLE IF EXISTS testBug1774");
917
.executeUpdate("CREATE TABLE testBug1774 (field1 VARCHAR(255))");
919
PreparedStatement pStmt = this.conn
920
.prepareStatement("INSERT INTO testBug1774 VALUES (?)");
922
String testString = "The word contains \" character";
924
pStmt.setString(1, testString);
925
pStmt.executeUpdate();
927
this.rs = this.stmt.executeQuery("SELECT * FROM testBug1774");
929
assertEquals(this.rs.getString(1), testString);
931
this.stmt.executeUpdate("DROP TABLE IF EXISTS testBug1774");
936
* Tests fix for BUG#1901 -- PreparedStatement.setObject(int, Object, int,
937
* int) doesn't support CLOB or BLOB types.
940
* if this test fails for any reason
942
public void testBug1901() throws Exception {
944
this.stmt.executeUpdate("DROP TABLE IF EXISTS testBug1901");
946
.executeUpdate("CREATE TABLE testBug1901 (field1 VARCHAR(255))");
947
this.stmt.executeUpdate("INSERT INTO testBug1901 VALUES ('aaa')");
949
this.rs = this.stmt.executeQuery("SELECT field1 FROM testBug1901");
952
Clob valueAsClob = this.rs.getClob(1);
953
Blob valueAsBlob = this.rs.getBlob(1);
955
PreparedStatement pStmt = this.conn
956
.prepareStatement("INSERT INTO testBug1901 VALUES (?)");
957
pStmt.setObject(1, valueAsClob, java.sql.Types.CLOB, 0);
958
pStmt.executeUpdate();
959
pStmt.setObject(1, valueAsBlob, java.sql.Types.BLOB, 0);
960
pStmt.executeUpdate();
962
this.stmt.executeUpdate("DROP TABLE IF EXISTS testBug1901");
967
* Test fix for BUG#1933 -- Driver property 'maxRows' has no effect.
972
public void testBug1933() throws Exception {
973
if (versionMeetsMinimum(4, 0)) {
974
Connection maxRowsConn = null;
975
PreparedStatement maxRowsPrepStmt = null;
976
Statement maxRowsStmt = null;
979
Properties props = new Properties();
981
props.setProperty("maxRows", "1");
983
maxRowsConn = getConnectionWithProps(props);
985
maxRowsStmt = maxRowsConn.createStatement();
987
assertTrue(maxRowsStmt.getMaxRows() == 1);
989
this.rs = maxRowsStmt.executeQuery("SELECT 1 UNION SELECT 2");
993
maxRowsPrepStmt = maxRowsConn
994
.prepareStatement("SELECT 1 UNION SELECT 2");
996
assertTrue(maxRowsPrepStmt.getMaxRows() == 1);
998
this.rs = maxRowsPrepStmt.executeQuery();
1002
assertTrue(!this.rs.next());
1004
props.setProperty("useServerPrepStmts", "false");
1006
maxRowsConn = getConnectionWithProps(props);
1008
maxRowsPrepStmt = maxRowsConn
1009
.prepareStatement("SELECT 1 UNION SELECT 2");
1011
assertTrue(maxRowsPrepStmt.getMaxRows() == 1);
1013
this.rs = maxRowsPrepStmt.executeQuery();
1017
assertTrue(!this.rs.next());
1019
maxRowsConn.close();
1025
* Tests the fix for BUG#1934 -- prepareStatement dies silently when
1026
* encountering Statement.RETURN_GENERATED_KEY
1031
public void testBug1934() throws Exception {
1032
if (isRunningOnJdk131()) {
1033
return; // test not valid on JDK-1.3.1
1037
this.stmt.executeUpdate("DROP TABLE IF EXISTS testBug1934");
1038
this.stmt.executeUpdate("CREATE TABLE testBug1934 (field1 INT)");
1040
System.out.println("Before prepareStatement()");
1042
this.pstmt = this.conn.prepareStatement(
1043
"INSERT INTO testBug1934 VALUES (?)",
1044
java.sql.Statement.RETURN_GENERATED_KEYS);
1046
assertTrue(this.pstmt != null);
1048
System.out.println("After prepareStatement() - " + this.pstmt);
1050
this.stmt.executeUpdate("DROP TABLE IF EXISTS testBug1934");
1055
* Tests fix for BUG#1958 - Improper bounds checking on
1056
* PreparedStatement.setFoo().
1059
* if the test fails.
1061
public void testBug1958() throws Exception {
1062
PreparedStatement pStmt = null;
1065
this.stmt.executeUpdate("DROP TABLE IF EXISTS testBug1958");
1066
this.stmt.executeUpdate("CREATE TABLE testBug1958 (field1 int)");
1069
.prepareStatement("SELECT * FROM testBug1958 WHERE field1 IN (?, ?, ?)");
1073
} catch (SQLException sqlEx) {
1074
assertTrue(SQLError.SQL_STATE_ILLEGAL_ARGUMENT.equals(sqlEx
1078
if (pStmt != null) {
1082
this.stmt.executeUpdate("DROP TABLE IF EXISTS testBug1958");
1087
* Tests the fix for BUG#2606, server-side prepared statements not returning
1088
* datatype YEAR correctly.
1091
* if the test fails.
1093
public void testBug2606() throws Exception {
1095
this.stmt.executeUpdate("DROP TABLE IF EXISTS testBug2606");
1097
.executeUpdate("CREATE TABLE testBug2606(year_field YEAR)");
1098
this.stmt.executeUpdate("INSERT INTO testBug2606 VALUES (2004)");
1100
PreparedStatement yrPstmt = this.conn
1101
.prepareStatement("SELECT year_field FROM testBug2606");
1103
this.rs = yrPstmt.executeQuery();
1105
assertTrue(this.rs.next());
1107
assertEquals(2004, this.rs.getInt(1));
1109
this.stmt.executeUpdate("DROP TABLE IF EXISTS testBug2606");
1114
* Tests the fix for BUG#2671, nulls encoded incorrectly in server-side
1115
* prepared statements.
1118
* if an error occurs.
1120
public void testBug2671() throws Exception {
1121
if (versionMeetsMinimum(4, 1)) {
1123
this.stmt.executeUpdate("DROP TABLE IF EXISTS test3");
1125
.executeUpdate("CREATE TABLE test3 ("
1126
+ " `field1` int(8) NOT NULL auto_increment,"
1127
+ " `field2` int(8) unsigned zerofill default NULL,"
1128
+ " `field3` varchar(30) binary NOT NULL default '',"
1129
+ " `field4` varchar(100) default NULL,"
1130
+ " `field5` datetime NULL default '0000-00-00 00:00:00',"
1131
+ " PRIMARY KEY (`field1`),"
1132
+ " UNIQUE KEY `unq_id` (`field2`),"
1133
+ " UNIQUE KEY (`field3`),"
1134
+ " UNIQUE KEY (`field2`)"
1135
+ " ) TYPE=InnoDB CHARACTER SET utf8");
1138
.executeUpdate("insert into test3 (field1, field3, field4) values (1,'blewis','Bob Lewis')");
1140
String query = " " + "UPDATE "
1143
+ " field2=? " + " ,field3=? "
1144
+ " ,field4=? " + " ,field5=? "
1148
java.sql.Date mydate = null;
1150
this.pstmt = this.conn.prepareStatement(query);
1152
this.pstmt.setInt(1, 13);
1153
this.pstmt.setString(2, "abc");
1154
this.pstmt.setString(3, "def");
1155
this.pstmt.setDate(4, mydate);
1156
this.pstmt.setInt(5, 1);
1158
int retval = this.pstmt.executeUpdate();
1159
assertTrue(retval == 1);
1161
this.stmt.executeUpdate("DROP TABLE IF EXISTS test3");
1167
* Tests fix for BUG#3103 -- java.util.Date not accepted as parameter to
1168
* PreparedStatement.setObject().
1173
* @deprecated uses deprecated methods of Date class
1175
public void testBug3103() throws Exception {
1177
this.stmt.executeUpdate("DROP TABLE IF EXISTS testBug3103");
1179
.executeUpdate("CREATE TABLE testBug3103 (field1 DATETIME)");
1181
PreparedStatement pStmt = this.conn
1182
.prepareStatement("INSERT INTO testBug3103 VALUES (?)");
1184
java.util.Date utilDate = new java.util.Date();
1186
pStmt.setObject(1, utilDate);
1187
pStmt.executeUpdate();
1189
this.rs = this.stmt.executeQuery("SELECT field1 FROM testBug3103");
1192
java.util.Date retrUtilDate = new java.util.Date(this.rs
1193
.getTimestamp(1).getTime());
1195
// We can only compare on the day/month/year hour/minute/second
1196
// interval, because the timestamp has added milliseconds to the
1198
assertTrue("Dates not equal", (utilDate.getMonth() == retrUtilDate
1200
&& (utilDate.getDate() == retrUtilDate.getDate())
1201
&& (utilDate.getYear() == retrUtilDate.getYear())
1202
&& (utilDate.getHours() == retrUtilDate.getHours())
1203
&& (utilDate.getMinutes() == retrUtilDate.getMinutes())
1204
&& (utilDate.getSeconds() == retrUtilDate.getSeconds()));
1206
this.stmt.executeUpdate("DROP TABLE IF EXISTS testBug3103");
1211
* Tests fix for BUG#3520
1216
public void testBug3520() throws Exception {
1218
this.stmt.executeUpdate("DROP TABLE IF EXISTS t");
1219
this.stmt.executeUpdate("CREATE TABLE t (s1 int,primary key (s1))");
1220
this.stmt.executeUpdate("INSERT INTO t VALUES (1)");
1221
this.stmt.executeUpdate("INSERT INTO t VALUES (1)");
1222
} catch (SQLException sqlEx) {
1223
System.out.println(sqlEx.getSQLState());
1225
this.stmt.executeUpdate("DROP TABLE IF EXISTS t");
1230
* Test fix for BUG#3557 -- UpdatableResultSet not picking up default values
1235
public void testBug3557() throws Exception {
1236
boolean populateDefaults = ((com.mysql.jdbc.ConnectionProperties) this.conn)
1237
.getPopulateInsertRowWithDefaultValues();
1240
((com.mysql.jdbc.ConnectionProperties) this.conn)
1241
.setPopulateInsertRowWithDefaultValues(true);
1243
this.stmt.executeUpdate("DROP TABLE IF EXISTS testBug3557");
1245
this.stmt.executeUpdate("CREATE TABLE testBug3557 ( "
1246
+ "`a` varchar(255) NOT NULL default 'XYZ', "
1247
+ "`b` varchar(255) default '123', "
1248
+ "PRIMARY KEY (`a`))");
1250
Statement updStmt = this.conn
1251
.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
1252
ResultSet.CONCUR_UPDATABLE);
1253
this.rs = updStmt.executeQuery("SELECT * FROM testBug3557");
1255
assertTrue(this.rs.getConcurrency() == ResultSet.CONCUR_UPDATABLE);
1257
this.rs.moveToInsertRow();
1259
assertEquals("XYZ", this.rs.getObject(1));
1260
assertEquals("123", this.rs.getObject(2));
1262
((com.mysql.jdbc.ConnectionProperties) this.conn)
1263
.setPopulateInsertRowWithDefaultValues(populateDefaults);
1265
this.stmt.executeUpdate("DROP TABLE IF EXISTS testBug3557");
1270
* Tests fix for BUG#3620 -- Timezone not respected correctly.
1272
* @throws SQLException
1273
* if the test fails.
1275
public void testBug3620() throws SQLException {
1276
if (isRunningOnJRockit()) {
1277
// bug with their timezones
1281
if (isRunningOnJdk131()) {
1282
// bug with timezones, no update
1283
// for new DST in USA
1287
long epsillon = 3000; // 3 seconds time difference
1290
this.stmt.executeUpdate("DROP TABLE IF EXISTS testBug3620");
1292
.executeUpdate("CREATE TABLE testBug3620 (field1 TIMESTAMP)");
1294
PreparedStatement tsPstmt = this.conn
1295
.prepareStatement("INSERT INTO testBug3620 VALUES (?)");
1297
Calendar pointInTime = Calendar.getInstance();
1298
pointInTime.set(2004, 02, 29, 10, 0, 0);
1300
long pointInTimeOffset = pointInTime.getTimeZone().getRawOffset();
1302
java.sql.Timestamp ts = new java.sql.Timestamp(pointInTime
1303
.getTime().getTime());
1305
tsPstmt.setTimestamp(1, ts);
1306
tsPstmt.executeUpdate();
1308
String tsValueAsString = getSingleValue("testBug3620", "field1",
1311
System.out.println("Timestamp as string with no calendar: "
1312
+ tsValueAsString.toString());
1314
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
1316
this.stmt.executeUpdate("DELETE FROM testBug3620");
1318
Properties props = new Properties();
1319
props.put("useTimezone", "true");
1320
// props.put("serverTimezone", "UTC");
1322
Connection tzConn = getConnectionWithProps(props);
1324
Statement tsStmt = tzConn.createStatement();
1327
.prepareStatement("INSERT INTO testBug3620 VALUES (?)");
1329
tsPstmt.setTimestamp(1, ts, cal);
1330
tsPstmt.executeUpdate();
1332
tsValueAsString = getSingleValue("testBug3620", "field1", null)
1335
Timestamp tsValueAsTimestamp = (Timestamp) getSingleValue(
1336
"testBug3620", "field1", null);
1338
System.out.println("Timestamp as string with UTC calendar: "
1339
+ tsValueAsString.toString());
1340
System.out.println("Timestamp as Timestamp with UTC calendar: "
1341
+ tsValueAsTimestamp);
1343
this.rs = tsStmt.executeQuery("SELECT field1 FROM testBug3620");
1346
Timestamp tsValueUTC = this.rs.getTimestamp(1, cal);
1349
// We use this testcase with other vendors, JDBC spec
1350
// requires result set fields can only be read once,
1351
// although MySQL doesn't require this ;)
1353
this.rs = tsStmt.executeQuery("SELECT field1 FROM testBug3620");
1356
Timestamp tsValueStmtNoCal = this.rs.getTimestamp(1);
1359
.println("Timestamp specifying UTC calendar from normal statement: "
1360
+ tsValueUTC.toString());
1362
PreparedStatement tsPstmtRetr = tzConn
1363
.prepareStatement("SELECT field1 FROM testBug3620");
1365
this.rs = tsPstmtRetr.executeQuery();
1368
Timestamp tsValuePstmtUTC = this.rs.getTimestamp(1, cal);
1371
.println("Timestamp specifying UTC calendar from prepared statement: "
1372
+ tsValuePstmtUTC.toString());
1375
// We use this testcase with other vendors, JDBC spec
1376
// requires result set fields can only be read once,
1377
// although MySQL doesn't require this ;)
1379
this.rs = tsPstmtRetr.executeQuery();
1382
Timestamp tsValuePstmtNoCal = this.rs.getTimestamp(1);
1385
.println("Timestamp specifying no calendar from prepared statement: "
1386
+ tsValuePstmtNoCal.toString());
1388
long stmtDeltaTWithCal = (ts.getTime() - tsValueStmtNoCal.getTime());
1390
long deltaOrig = Math.abs(stmtDeltaTWithCal - pointInTimeOffset);
1393
"Difference between original timestamp and timestamp retrieved using java.sql.Statement "
1394
+ "set in database using UTC calendar is not ~= "
1395
+ epsillon + ", it is actually " + deltaOrig,
1396
(deltaOrig < epsillon));
1398
long pStmtDeltaTWithCal = (ts.getTime() - tsValuePstmtNoCal
1402
.println(Math.abs(pStmtDeltaTWithCal - pointInTimeOffset)
1405
+ (Math.abs(pStmtDeltaTWithCal - pointInTimeOffset) < epsillon));
1407
"Difference between original timestamp and timestamp retrieved using java.sql.PreparedStatement "
1408
+ "set in database using UTC calendar is not ~= "
1410
+ ", it is actually "
1411
+ pStmtDeltaTWithCal, (Math.abs(pStmtDeltaTWithCal
1412
- pointInTimeOffset) < epsillon));
1415
.println("Difference between original ts and ts with no calendar: "
1416
+ (ts.getTime() - tsValuePstmtNoCal.getTime())
1417
+ ", offset should be " + pointInTimeOffset);
1419
this.stmt.executeUpdate("DROP TABLE IF EXISTS testBug3620");
1424
* Tests that DataTruncation is thrown when data is truncated.
1427
* if the test fails.
1429
public void testBug3697() throws Exception {
1431
this.stmt.executeUpdate("DROP TABLE IF EXISTS testBug3697");
1433
.executeUpdate("CREATE TABLE testBug3697 (field1 VARCHAR(255))");
1435
StringBuffer updateBuf = new StringBuffer(
1436
"INSERT INTO testBug3697 VALUES ('");
1438
for (int i = 0; i < 512; i++) {
1439
updateBuf.append("A");
1442
updateBuf.append("')");
1445
this.stmt.executeUpdate(updateBuf.toString());
1446
} catch (DataTruncation dtEx) {
1447
// This is an expected exception....
1450
SQLWarning warningChain = this.stmt.getWarnings();
1452
System.out.println(warningChain);
1454
this.stmt.executeUpdate("DROP TABLE IF EXISTS testBug3697");
1459
* Tests fix for BUG#3804, data truncation on server should throw
1460
* DataTruncation exception.
1465
public void testBug3804() throws Exception {
1466
if (versionMeetsMinimum(4, 1)) {
1468
this.stmt.executeUpdate("DROP TABLE IF EXISTS testBug3804");
1470
.executeUpdate("CREATE TABLE testBug3804 (field1 VARCHAR(5))");
1472
boolean caughtTruncation = false;
1476
.executeUpdate("INSERT INTO testBug3804 VALUES ('1234567')");
1477
} catch (DataTruncation truncationEx) {
1478
caughtTruncation = true;
1479
System.out.println(truncationEx);
1482
assertTrue("Data truncation exception should've been thrown",
1485
this.stmt.executeUpdate("DROP TABLE IF EXISTS testBug3804");
1491
* Tests BUG#3873 - PreparedStatement.executeBatch() not returning all
1492
* generated keys (even though that's not JDBC compliant).
1497
public void testBug3873() throws Exception {
1498
if (isRunningOnJdk131()) {
1499
return; // test not valid on JDK-1.3.1
1502
PreparedStatement batchStmt = null;
1505
this.stmt.executeUpdate("DROP TABLE IF EXISTS testBug3873");
1507
.executeUpdate("CREATE TABLE testBug3873 (keyField INT NOT NULL PRIMARY KEY AUTO_INCREMENT, dataField VARCHAR(32))");
1508
batchStmt = this.conn.prepareStatement(
1509
"INSERT INTO testBug3873 (dataField) VALUES (?)",
1510
Statement.RETURN_GENERATED_KEYS);
1511
batchStmt.setString(1, "abc");
1512
batchStmt.addBatch();
1513
batchStmt.setString(1, "def");
1514
batchStmt.addBatch();
1515
batchStmt.setString(1, "ghi");
1516
batchStmt.addBatch();
1518
int[] updateCounts = batchStmt.executeBatch();
1520
this.rs = batchStmt.getGeneratedKeys();
1522
while (this.rs.next()) {
1523
System.out.println(this.rs.getInt(1));
1526
this.rs = batchStmt.getGeneratedKeys();
1527
assertTrue(this.rs.next());
1528
assertTrue(1 == this.rs.getInt(1));
1529
assertTrue(this.rs.next());
1530
assertTrue(2 == this.rs.getInt(1));
1531
assertTrue(this.rs.next());
1532
assertTrue(3 == this.rs.getInt(1));
1533
assertTrue(!this.rs.next());
1535
if (batchStmt != null) {
1539
this.stmt.executeUpdate("DROP TABLE IF EXISTS testBug3873");
1544
* Tests fix for BUG#4119 -- misbehavior in a managed environment from
1548
* if the test fails.
1550
public void testBug4119() throws Exception {
1552
this.stmt.executeUpdate("DROP TABLE IF EXISTS testBug4119");
1553
this.stmt.executeUpdate("CREATE TABLE `testBug4119` ("
1554
+ "`field1` varchar(255) NOT NULL default '',"
1555
+ "`field2` bigint(20) default NULL,"
1556
+ "`field3` int(11) default NULL,"
1557
+ "`field4` datetime default NULL,"
1558
+ "`field5` varchar(75) default NULL,"
1559
+ "`field6` varchar(75) default NULL,"
1560
+ "`field7` varchar(75) default NULL,"
1561
+ "`field8` datetime default NULL,"
1562
+ " PRIMARY KEY (`field1`)" + ")");
1564
PreparedStatement pStmt = this.conn
1565
.prepareStatement("insert into testBug4119 (field2, field3,"
1566
+ "field4, field5, field6, field7, field8, field1) values (?, ?,"
1567
+ "?, ?, ?, ?, ?, ?)");
1569
pStmt.setString(1, "0");
1570
pStmt.setString(2, "0");
1571
pStmt.setTimestamp(3, new java.sql.Timestamp(System
1572
.currentTimeMillis()));
1573
pStmt.setString(4, "ABC");
1574
pStmt.setString(5, "DEF");
1575
pStmt.setString(6, "AA");
1576
pStmt.setTimestamp(7, new java.sql.Timestamp(System
1577
.currentTimeMillis()));
1578
pStmt.setString(8, "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
1579
pStmt.executeUpdate();
1581
this.stmt.executeUpdate("DROP TABLE IF EXISTS testBug4119");
1586
* Tests fix for BUG#4311 - Error in JDBC retrieval of mediumint column when
1587
* using prepared statements and binary result sets.
1590
* if the test fails.
1592
public void testBug4311() throws Exception {
1594
int lowValue = -8388608;
1595
int highValue = 8388607;
1597
this.stmt.executeUpdate("DROP TABLE IF EXISTS testBug4311");
1599
.executeUpdate("CREATE TABLE testBug4311 (low MEDIUMINT, high MEDIUMINT)");
1600
this.stmt.executeUpdate("INSERT INTO testBug4311 VALUES ("
1601
+ lowValue + ", " + highValue + ")");
1603
PreparedStatement pStmt = this.conn
1604
.prepareStatement("SELECT low, high FROM testBug4311");
1605
this.rs = pStmt.executeQuery();
1606
assertTrue(this.rs.next());
1607
assertTrue(this.rs.getInt(1) == lowValue);
1608
assertTrue(this.rs.getInt(2) == highValue);
1610
this.stmt.executeUpdate("DROP TABLE IF EXISTS testBug4311");
1615
* Tests fix for BUG#4510 -- Statement.getGeneratedKeys() fails when key >
1621
public void testBug4510() throws Exception {
1622
if (isRunningOnJdk131()) {
1623
return; // test not valid on JDK-1.3.1
1627
this.stmt.executeUpdate("DROP TABLE IF EXISTS testBug4510");
1628
this.stmt.executeUpdate("CREATE TABLE testBug4510 ("
1629
+ "field1 INT NOT NULL PRIMARY KEY AUTO_INCREMENT,"
1630
+ "field2 VARCHAR(100))");
1632
.executeUpdate("INSERT INTO testBug4510 (field1, field2) VALUES (32767, 'bar')");
1634
PreparedStatement p = this.conn.prepareStatement(
1635
"insert into testBug4510 (field2) values (?)",
1636
Statement.RETURN_GENERATED_KEYS);
1638
p.setString(1, "blah");
1642
ResultSet rs = p.getGeneratedKeys();
1644
System.out.println("Id: " + rs.getInt(1));
1647
this.stmt.executeUpdate("DROP TABLE IF EXISTS testBug4510");
1652
* Server doesn't accept everything as a server-side prepared statement, so
1653
* by default we scan for stuff it can't handle.
1655
* @throws SQLException
1657
public void testBug4718() throws SQLException {
1658
if (versionMeetsMinimum(4, 1, 0)
1659
&& ((com.mysql.jdbc.Connection) this.conn)
1660
.getUseServerPreparedStmts()) {
1661
this.pstmt = this.conn.prepareStatement("SELECT 1 LIMIT ?");
1662
assertTrue(this.pstmt instanceof com.mysql.jdbc.PreparedStatement);
1664
this.pstmt = this.conn.prepareStatement("SELECT 1 LIMIT 1");
1665
assertTrue(this.pstmt instanceof com.mysql.jdbc.ServerPreparedStatement);
1667
this.pstmt = this.conn.prepareStatement("SELECT 1 LIMIT 1, ?");
1668
assertTrue(this.pstmt instanceof com.mysql.jdbc.PreparedStatement);
1671
this.stmt.executeUpdate("DROP TABLE IF EXISTS testBug4718");
1673
.executeUpdate("CREATE TABLE testBug4718 (field1 char(32))");
1675
this.pstmt = this.conn
1676
.prepareStatement("ALTER TABLE testBug4718 ADD INDEX (field1)");
1677
assertTrue(this.pstmt instanceof com.mysql.jdbc.PreparedStatement);
1679
this.pstmt = this.conn.prepareStatement("SELECT 1");
1680
assertTrue(this.pstmt instanceof ServerPreparedStatement);
1682
this.pstmt = this.conn
1683
.prepareStatement("UPDATE testBug4718 SET field1=1");
1684
assertTrue(this.pstmt instanceof ServerPreparedStatement);
1686
this.pstmt = this.conn
1687
.prepareStatement("UPDATE testBug4718 SET field1=1 LIMIT 1");
1688
assertTrue(this.pstmt instanceof ServerPreparedStatement);
1690
this.pstmt = this.conn
1691
.prepareStatement("UPDATE testBug4718 SET field1=1 LIMIT ?");
1692
assertTrue(this.pstmt instanceof com.mysql.jdbc.PreparedStatement);
1694
this.pstmt = this.conn
1695
.prepareStatement("UPDATE testBug4718 SET field1='Will we ignore LIMIT ?,?'");
1696
assertTrue(this.pstmt instanceof ServerPreparedStatement);
1699
this.stmt.executeUpdate("DROP TABLE IF EXISTS testBug4718");
1705
* Tests fix for BUG#5012 -- ServerPreparedStatements dealing with return of
1706
* DECIMAL type don't work.
1709
* if the test fails.
1711
public void testBug5012() throws Exception {
1712
PreparedStatement pStmt = null;
1713
String valueAsString = "12345.12";
1716
this.stmt.executeUpdate("DROP TABLE IF EXISTS testBug5012");
1718
.executeUpdate("CREATE TABLE testBug5012(field1 DECIMAL(10,2))");
1719
this.stmt.executeUpdate("INSERT INTO testBug5012 VALUES ("
1720
+ valueAsString + ")");
1723
.prepareStatement("SELECT field1 FROM testBug5012");
1724
this.rs = pStmt.executeQuery();
1725
assertTrue(this.rs.next());
1726
assertEquals(new BigDecimal(valueAsString), this.rs
1729
this.stmt.executeUpdate("DROP TABLE IF EXISTS testBug5012");
1731
if (pStmt != null) {
1738
* Tests fix for BUG#5133 -- PreparedStatement.toString() doesn't return
1739
* correct value if no parameters are present in statement.
1743
public void testBug5133() throws Exception {
1744
String query = "SELECT 1";
1745
String output = this.conn.prepareStatement(query).toString();
1746
System.out.println(output);
1748
assertTrue(output.indexOf(query) != -1);
1752
* Tests for BUG#5191 -- PreparedStatement.executeQuery() gives
1756
* if the test fails.
1758
public void testBug5191() throws Exception {
1759
PreparedStatement pStmt = null;
1762
this.stmt.executeUpdate("DROP TABLE IF EXISTS testBug5191Q");
1763
this.stmt.executeUpdate("DROP TABLE IF EXISTS testBug5191C");
1765
this.stmt.executeUpdate("CREATE TABLE testBug5191Q"
1766
+ "(QuestionId int NOT NULL AUTO_INCREMENT, "
1767
+ "Text VARCHAR(200), " + "PRIMARY KEY(QuestionId))");
1769
this.stmt.executeUpdate("CREATE TABLE testBug5191C"
1770
+ "(CategoryId int, " + "QuestionId int)");
1772
String[] questions = new String[] { "What is your name?",
1773
"What is your quest?",
1774
"What is the airspeed velocity of an unladen swollow?",
1775
"How many roads must a man walk?", "Where's the tea?", };
1777
for (int i = 0; i < questions.length; i++) {
1778
this.stmt.executeUpdate("INSERT INTO testBug5191Q(Text)"
1779
+ " VALUES (\"" + questions[i] + "\")");
1780
int catagory = (i < 3) ? 0 : i;
1782
this.stmt.executeUpdate("INSERT INTO testBug5191C"
1783
+ "(CategoryId, QuestionId) VALUES (" + catagory + ", "
1786
* this.stmt.executeUpdate("INSERT INTO testBug5191C" +
1787
* "(CategoryId, QuestionId) VALUES (" + catagory + ", (SELECT
1788
* testBug5191Q.QuestionId" + " FROM testBug5191Q " + "WHERE
1789
* testBug5191Q.Text LIKE '" + questions[i] + "'))");
1793
pStmt = this.conn.prepareStatement("SELECT qc.QuestionId, q.Text "
1794
+ "FROM testBug5191Q q, testBug5191C qc "
1795
+ "WHERE qc.CategoryId = ? "
1796
+ " AND q.QuestionId = qc.QuestionId");
1799
for (int i = 0; i < 100; i++) {
1800
execQueryBug5191(pStmt, catId);
1804
this.stmt.executeUpdate("DROP TABLE IF EXISTS testBug5191Q");
1805
this.stmt.executeUpdate("DROP TABLE IF EXISTS testBug5191C");
1807
if (pStmt != null) {
1813
public void testBug5235() throws Exception {
1814
Properties props = new Properties();
1815
props.setProperty("zeroDateTimeBehavior", "convertToNull");
1817
Connection convertToNullConn = getConnectionWithProps(props);
1818
Statement convertToNullStmt = convertToNullConn.createStatement();
1820
convertToNullStmt.executeUpdate("DROP TABLE IF EXISTS testBug5235");
1822
.executeUpdate("CREATE TABLE testBug5235(field1 DATE)");
1824
.executeUpdate("INSERT INTO testBug5235 (field1) VALUES ('0000-00-00')");
1826
PreparedStatement ps = convertToNullConn
1827
.prepareStatement("SELECT field1 FROM testBug5235");
1828
this.rs = ps.executeQuery();
1830
if (this.rs.next()) {
1831
Date d = (Date) this.rs.getObject("field1");
1832
System.out.println("date: " + d);
1835
convertToNullStmt.executeUpdate("DROP TABLE IF EXISTS testBug5235");
1839
public void testBug5450() throws Exception {
1840
if (versionMeetsMinimum(4, 1)) {
1841
String table = "testBug5450";
1842
String column = "policyname";
1845
Properties props = new Properties();
1846
props.setProperty("characterEncoding", "utf-8");
1848
Connection utf8Conn = getConnectionWithProps(props);
1849
Statement utfStmt = utf8Conn.createStatement();
1851
this.stmt.executeUpdate("DROP TABLE IF EXISTS " + table);
1853
this.stmt.executeUpdate("CREATE TABLE " + table
1854
+ "(policyid int NOT NULL AUTO_INCREMENT, " + column
1856
+ "PRIMARY KEY(policyid)) DEFAULT CHARACTER SET utf8");
1858
String pname0 = "inserted \uac00 - foo - \u4e00";
1860
utfStmt.executeUpdate("INSERT INTO " + table + "(" + column
1861
+ ")" + " VALUES (\"" + pname0 + "\")");
1863
this.rs = utfStmt.executeQuery("SELECT " + column + " FROM "
1867
String pname1 = this.rs.getString(column);
1869
assertEquals(pname0, pname1);
1870
byte[] bytes = this.rs.getBytes(column);
1872
String pname2 = new String(bytes, "utf-8");
1873
assertEquals(pname1, pname2);
1875
utfStmt.executeUpdate("delete from " + table + " where "
1876
+ column + " like 'insert%'");
1878
PreparedStatement s1 = utf8Conn.prepareStatement("insert into "
1879
+ table + "(" + column + ") values (?)");
1881
s1.setString(1, pname0);
1884
String byteesque = "byte " + pname0;
1885
byte[] newbytes = byteesque.getBytes("utf-8");
1887
s1.setBytes(1, newbytes);
1890
this.rs = utfStmt.executeQuery("select " + column + " from "
1891
+ table + " where " + column + " like 'insert%'");
1893
String pname3 = this.rs.getString(column);
1894
assertEquals(pname0, pname3);
1896
this.rs = utfStmt.executeQuery("select " + column + " from "
1897
+ table + " where " + column + " like 'byte insert%'");
1900
String pname4 = this.rs.getString(column);
1901
assertEquals(byteesque, pname4);
1904
this.stmt.executeUpdate("DROP TABLE IF EXISTS " + table);
1909
public void testBug5510() throws Exception {
1910
// This is a server bug that should be fixed by 4.1.6
1911
if (versionMeetsMinimum(4, 1, 6)) {
1913
this.stmt.executeUpdate("DROP TABLE IF EXISTS testBug5510");
1916
.executeUpdate("CREATE TABLE `testBug5510` ("
1917
+ "`a` bigint(20) NOT NULL auto_increment,"
1918
+ "`b` varchar(64) default NULL,"
1919
+ "`c` varchar(64) default NULL,"
1920
+ "`d` varchar(255) default NULL,"
1921
+ "`e` int(11) default NULL,"
1922
+ "`f` varchar(32) default NULL,"
1923
+ "`g` varchar(32) default NULL,"
1924
+ "`h` varchar(80) default NULL,"
1925
+ "`i` varchar(255) default NULL,"
1926
+ "`j` varchar(255) default NULL,"
1927
+ "`k` varchar(255) default NULL,"
1928
+ "`l` varchar(32) default NULL,"
1929
+ "`m` varchar(32) default NULL,"
1930
+ "`n` timestamp NOT NULL default CURRENT_TIMESTAMP on update"
1931
+ " CURRENT_TIMESTAMP,"
1932
+ "`o` int(11) default NULL,"
1933
+ "`p` int(11) default NULL,"
1934
+ "PRIMARY KEY (`a`)"
1935
+ ") ENGINE=InnoDB DEFAULT CHARSET=latin1");
1936
PreparedStatement pStmt = this.conn
1937
.prepareStatement("INSERT INTO testBug5510 (a) VALUES (?)");
1938
pStmt.setNull(1, 0);
1939
pStmt.executeUpdate();
1942
this.stmt.executeUpdate("DROP TABLE IF EXISTS testBug5510");
1948
* Tests fix for BUG#5874, timezone correction goes in wrong 'direction'
1949
* when useTimezone=true and server timezone differs from client timezone.
1952
* if the test fails.
1954
public void testBug5874() throws Exception {
1957
String clientTimezoneName = "America/Los_Angeles";
1958
String serverTimezoneName = "America/Chicago";
1960
TimeZone.setDefault(TimeZone.getTimeZone(clientTimezoneName));
1962
long epsillon = 3000; // 3 seconds difference
1964
long clientTimezoneOffsetMillis = TimeZone.getDefault()
1966
long serverTimezoneOffsetMillis = TimeZone.getTimeZone(
1967
serverTimezoneName).getRawOffset();
1969
long offsetDifference = clientTimezoneOffsetMillis
1970
- serverTimezoneOffsetMillis;
1972
Properties props = new Properties();
1973
props.put("useTimezone", "true");
1974
props.put("serverTimezone", serverTimezoneName);
1976
Connection tzConn = getConnectionWithProps(props);
1977
Statement tzStmt = tzConn.createStatement();
1978
tzStmt.executeUpdate("DROP TABLE IF EXISTS timeTest");
1980
.executeUpdate("CREATE TABLE timeTest (tstamp DATETIME, t TIME)");
1982
PreparedStatement pstmt = tzConn
1983
.prepareStatement("INSERT INTO timeTest VALUES (?, ?)");
1985
long now = System.currentTimeMillis(); // Time in milliseconds
1986
// since 1/1/1970 GMT
1988
Timestamp nowTstamp = new Timestamp(now);
1989
Time nowTime = new Time(now);
1991
pstmt.setTimestamp(1, nowTstamp);
1992
pstmt.setTime(2, nowTime);
1993
pstmt.executeUpdate();
1995
this.rs = tzStmt.executeQuery("SELECT * from timeTest");
1997
// Timestamps look like this: 2004-11-29 13:43:21
1998
SimpleDateFormat timestampFormat = new SimpleDateFormat(
1999
"yyyy-MM-dd HH:mm:ss");
2000
SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm:ss");
2002
while (this.rs.next()) {
2003
// Driver now converts/checks DATE/TIME/TIMESTAMP/DATETIME types
2004
// when calling getString()...
2005
String retrTimestampString = new String(this.rs.getBytes(1));
2006
Timestamp retrTimestamp = this.rs.getTimestamp(1);
2008
java.util.Date timestampOnServer = timestampFormat
2009
.parse(retrTimestampString);
2011
long retrievedOffsetForTimestamp = retrTimestamp.getTime()
2012
- timestampOnServer.getTime();
2015
"Difference between original timestamp and timestamp retrieved using client timezone is not "
2016
+ offsetDifference, (Math
2017
.abs(retrievedOffsetForTimestamp
2018
- offsetDifference) < epsillon));
2020
String retrTimeString = new String(this.rs.getBytes(2));
2021
Time retrTime = this.rs.getTime(2);
2023
java.util.Date timeOnServerAsDate = timeFormat
2024
.parse(retrTimeString);
2025
Time timeOnServer = new Time(timeOnServerAsDate.getTime());
2027
long retrievedOffsetForTime = retrTime.getTime()
2028
- timeOnServer.getTime();
2031
"Difference between original times and time retrieved using client timezone is not "
2033
(Math.abs(retrievedOffsetForTime - offsetDifference) < epsillon));
2036
this.stmt.executeUpdate("DROP TABLE IF EXISTS timeTest");
2040
public void testBug6823() throws SQLException {
2042
innerBug6823(false);
2045
public void testBug7461() throws Exception {
2046
String tableName = "testBug7461";
2049
createTable(tableName, "(field1 varchar(4))");
2050
File tempFile = File.createTempFile("mysql-test", ".txt");
2051
tempFile.deleteOnExit();
2053
FileOutputStream fOut = new FileOutputStream(tempFile);
2054
fOut.write("abcdefghijklmnop".getBytes());
2058
this.stmt.executeQuery("LOAD DATA LOCAL INFILE '"
2059
+ tempFile.toString() + "' INTO TABLE " + tableName);
2060
} catch (SQLException sqlEx) {
2061
this.stmt.getWarnings();
2065
dropTable(tableName);
2070
public void testBug8181() throws Exception {
2073
this.stmt.executeUpdate("DROP TABLE IF EXISTS testBug8181");
2075
.executeUpdate("CREATE TABLE testBug8181(col1 VARCHAR(20),col2 INT)");
2077
this.pstmt = this.conn
2078
.prepareStatement("INSERT INTO testBug8181(col1,col2) VALUES(?,?)");
2080
for (int i = 0; i < 20; i++) {
2081
this.pstmt.setString(1, "Test " + i);
2082
this.pstmt.setInt(2, i);
2083
this.pstmt.addBatch();
2086
this.pstmt.executeBatch();
2089
this.stmt.executeUpdate("DROP TABLE IF EXISTS testBug8181");
2091
if (this.pstmt != null) {
2098
* Tests fix for BUG#8487 - PreparedStatements not creating streaming result
2102
* if the test fails.
2104
public void testBug8487() throws Exception {
2106
this.pstmt = this.conn.prepareStatement("SELECT 1",
2107
ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
2109
this.pstmt.setFetchSize(Integer.MIN_VALUE);
2110
this.rs = this.pstmt.executeQuery();
2112
this.conn.createStatement().executeQuery("SELECT 2");
2113
fail("Should have caught a streaming exception here");
2114
} catch (SQLException sqlEx) {
2115
assertTrue(sqlEx.getMessage() != null
2116
&& sqlEx.getMessage().indexOf("Streaming") != -1);
2120
if (this.rs != null) {
2121
while (this.rs.next())
2127
if (this.pstmt != null) {
2134
* Tests multiple statement support with fix for BUG#9704.
2139
public void testBug9704() throws Exception {
2140
if (versionMeetsMinimum(4, 1)) {
2141
Connection multiStmtConn = null;
2142
Statement multiStmt = null;
2145
Properties props = new Properties();
2146
props.setProperty("allowMultiQueries", "true");
2148
multiStmtConn = getConnectionWithProps(props);
2150
multiStmt = multiStmtConn.createStatement();
2153
.executeUpdate("DROP TABLE IF EXISTS testMultiStatements");
2155
.executeUpdate("CREATE TABLE testMultiStatements (field1 VARCHAR(255), field2 INT, field3 DOUBLE)");
2157
.executeUpdate("INSERT INTO testMultiStatements VALUES ('abcd', 1, 2)");
2160
.execute("SELECT field1 FROM testMultiStatements WHERE field1='abcd';"
2161
+ "UPDATE testMultiStatements SET field3=3;"
2162
+ "SELECT field3 FROM testMultiStatements WHERE field3=3");
2164
this.rs = multiStmt.getResultSet();
2166
assertTrue(this.rs.next());
2168
assertTrue("abcd".equals(this.rs.getString(1)));
2171
// Next should be an update count...
2172
assertTrue(!multiStmt.getMoreResults());
2174
assertTrue("Update count was " + multiStmt.getUpdateCount()
2175
+ ", expected 1", multiStmt.getUpdateCount() == 1);
2177
assertTrue(multiStmt.getMoreResults());
2179
this.rs = multiStmt.getResultSet();
2181
assertTrue(this.rs.next());
2183
assertTrue(this.rs.getDouble(1) == 3);
2185
// End of multi results
2186
assertTrue(!multiStmt.getMoreResults());
2187
assertTrue(multiStmt.getUpdateCount() == -1);
2189
if (multiStmt != null) {
2191
.executeUpdate("DROP TABLE IF EXISTS testMultiStatements");
2196
if (multiStmtConn != null) {
2197
multiStmtConn.close();
2204
* Tests that you can close a statement twice without an NPE.
2207
* if an error occurs.
2209
public void testCloseTwice() throws Exception {
2210
Statement closeMe = this.conn.createStatement();
2215
public void testCsc4194() throws Exception {
2216
if (isRunningOnJdk131()) {
2217
return; // test not valid on JDK-1.3.1
2220
Connection sjisConn = null;
2221
Connection windows31JConn = null;
2224
String tableNameText = "testCsc4194Text";
2225
String tableNameBlob = "testCsc4194Blob";
2227
createTable(tableNameBlob, "(field1 BLOB)");
2228
String charset = "";
2230
if (versionMeetsMinimum(5, 0, 3) || versionMeetsMinimum(4, 1, 12)) {
2231
charset = " CHARACTER SET cp932";
2232
} else if (versionMeetsMinimum(4, 1, 0)) {
2233
charset = " CHARACTER SET sjis";
2236
createTable(tableNameText, "(field1 TEXT)" + charset);
2238
Properties windows31JProps = new Properties();
2239
windows31JProps.setProperty("useUnicode", "true");
2240
windows31JProps.setProperty("characterEncoding", "Windows-31J");
2242
windows31JConn = getConnectionWithProps(windows31JProps);
2243
testCsc4194InsertCheckBlob(windows31JConn, tableNameBlob);
2245
if (versionMeetsMinimum(4, 1, 0)) {
2246
testCsc4194InsertCheckText(windows31JConn, tableNameText,
2250
Properties sjisProps = new Properties();
2251
sjisProps.setProperty("useUnicode", "true");
2252
sjisProps.setProperty("characterEncoding", "sjis");
2254
sjisConn = getConnectionWithProps(sjisProps);
2255
testCsc4194InsertCheckBlob(sjisConn, tableNameBlob);
2257
if (versionMeetsMinimum(5, 0, 3)) {
2258
testCsc4194InsertCheckText(sjisConn, tableNameText,
2264
if (windows31JConn != null) {
2265
windows31JConn.close();
2268
if (sjisConn != null) {
2274
private void testCsc4194InsertCheckBlob(Connection c, String tableName)
2276
byte[] bArray = new byte[] { (byte) 0xac, (byte) 0xed, (byte) 0x00,
2279
PreparedStatement testStmt = c.prepareStatement("INSERT INTO "
2280
+ tableName + " VALUES (?)");
2281
testStmt.setBytes(1, bArray);
2282
testStmt.executeUpdate();
2284
this.rs = c.createStatement().executeQuery(
2285
"SELECT field1 FROM " + tableName);
2286
assertTrue(this.rs.next());
2287
assertEquals(getByteArrayString(bArray), getByteArrayString(this.rs
2292
private void testCsc4194InsertCheckText(Connection c, String tableName,
2293
String encoding) throws Exception {
2294
byte[] kabuInShiftJIS = { (byte) 0x87, // a double-byte
2295
// charater("kabu") in Shift JIS
2298
String expected = new String(kabuInShiftJIS, encoding);
2299
PreparedStatement testStmt = c.prepareStatement("INSERT INTO "
2300
+ tableName + " VALUES (?)");
2301
testStmt.setString(1, expected);
2302
testStmt.executeUpdate();
2304
this.rs = c.createStatement().executeQuery(
2305
"SELECT field1 FROM " + tableName);
2306
assertTrue(this.rs.next());
2307
assertEquals(expected, this.rs.getString(1));
2312
* Tests all forms of statements influencing getGeneratedKeys().
2315
* if the test fails.
2317
public void testGetGeneratedKeysAllCases() throws Exception {
2318
if (isRunningOnJdk131()) {
2319
return; // test not valid on JDK-1.3.1
2322
System.out.println("Using Statement.executeUpdate()\n");
2328
for (int i = 0; i < tests.length; i++) {
2329
doGGKTestStatement(tests[i], true);
2338
System.out.println("Using Statement.execute()\n");
2344
for (int i = 0; i < tests.length; i++) {
2345
doGGKTestStatement(tests[i], false);
2354
System.out.println("Using PreparedStatement.executeUpdate()\n");
2360
for (int i = 0; i < tests.length; i++) {
2361
doGGKTestPreparedStatement(tests[i], true);
2370
System.out.println("Using PreparedStatement.execute()\n");
2376
for (int i = 0; i < tests.length; i++) {
2377
doGGKTestPreparedStatement(tests[i], false);
2385
* Tests that max_rows and 'limit' don't cause exceptions to be thrown.
2388
* if the test fails.
2390
public void testLimitAndMaxRows() throws Exception {
2392
this.stmt.executeUpdate("DROP TABLE IF EXISTS testMaxRowsAndLimit");
2394
.executeUpdate("CREATE TABLE testMaxRowsAndLimit(limitField INT)");
2396
for (int i = 0; i < 500; i++) {
2398
.executeUpdate("INSERT INTO testMaxRowsAndLimit VALUES ("
2402
this.stmt.setMaxRows(250);
2404
.executeQuery("SELECT limitField FROM testMaxRowsAndLimit");
2406
this.stmt.setMaxRows(0);
2408
this.stmt.executeUpdate("DROP TABLE IF EXISTS testMaxRowsAndLimit");
2413
* public void testBug9595() throws Exception { double[] vals = new double[]
2414
* {52.21, 52.22, 52.23, 52.24};
2416
* createTable("testBug9595", "(field1 DECIMAL(10,2), sortField INT)");
2418
* this.pstmt = this.conn.prepareStatement("INSERT INTO testBug9595 VALUES
2419
* (?, ?)"); // Try setting as doubles for (int i = 0; i < vals.length; i++) {
2420
* this.pstmt.setDouble(1, vals[i]); this.pstmt.setInt(2, i);
2421
* this.pstmt.executeUpdate(); }
2423
* this.pstmt = this.conn.prepareStatement("SELECT field1 FROM testBug9595
2424
* ORDER BY sortField"); this.rs = this.pstmt.executeQuery();
2428
* while (this.rs.next()) { double valToTest = vals[i++];
2430
* assertEquals(this.rs.getDouble(1), valToTest, 0.001);
2431
* assertEquals(this.rs.getBigDecimal(1).doubleValue(), valToTest, 0.001); }
2433
* this.pstmt = this.conn.prepareStatement("INSERT INTO testBug9595 VALUES
2436
* this.stmt.executeUpdate("TRUNCATE TABLE testBug9595"); // Now, as
2437
* BigDecimals for (i = 0; i < vals.length; i++) { BigDecimal foo = new
2438
* BigDecimal(vals[i]);
2440
* this.pstmt.setObject(1, foo, Types.DECIMAL, 2); this.pstmt.setInt(2, i);
2441
* this.pstmt.executeUpdate(); }
2443
* this.pstmt = this.conn.prepareStatement("SELECT field1 FROM testBug9595
2444
* ORDER BY sortField"); this.rs = this.pstmt.executeQuery();
2448
* while (this.rs.next()) { double valToTest = vals[i++];
2449
* System.out.println(this.rs.getString(1));
2450
* assertEquals(this.rs.getDouble(1), valToTest, 0.001);
2451
* assertEquals(this.rs.getBigDecimal(1).doubleValue(), valToTest, 0.001); } }
2455
* Tests that 'LOAD DATA LOCAL INFILE' works
2458
* if any errors occur
2460
public void testLoadData() throws Exception {
2462
int maxAllowedPacket = 1048576;
2464
this.stmt.executeUpdate("DROP TABLE IF EXISTS loadDataRegress");
2466
.executeUpdate("CREATE TABLE loadDataRegress (field1 int, field2 int)");
2468
File tempFile = File.createTempFile("mysql", ".txt");
2470
// tempFile.deleteOnExit();
2471
System.out.println(tempFile);
2473
Writer out = new FileWriter(tempFile);
2476
int rowCount = 128; // maxAllowedPacket * 4;
2478
for (int i = 0; i < rowCount; i++) {
2479
out.write((localCount++) + "\t" + (localCount++) + "\n");
2484
StringBuffer fileNameBuf = null;
2486
if (File.separatorChar == '\\') {
2487
fileNameBuf = new StringBuffer();
2489
String fileName = tempFile.getAbsolutePath();
2490
int fileNameLength = fileName.length();
2492
for (int i = 0; i < fileNameLength; i++) {
2493
char c = fileName.charAt(i);
2496
fileNameBuf.append("/");
2498
fileNameBuf.append(c);
2502
fileNameBuf = new StringBuffer(tempFile.getAbsolutePath());
2505
int updateCount = this.stmt
2506
.executeUpdate("LOAD DATA LOCAL INFILE '"
2507
+ fileNameBuf.toString()
2508
+ "' INTO TABLE loadDataRegress");
2509
assertTrue(updateCount == rowCount);
2511
this.stmt.executeUpdate("DROP TABLE IF EXISTS loadDataRegress");
2515
public void testNullClob() throws Exception {
2516
createTable("testNullClob", "(field1 TEXT NULL)");
2518
PreparedStatement pStmt = null;
2522
.prepareStatement("INSERT INTO testNullClob VALUES (?)");
2523
pStmt.setClob(1, null);
2524
pStmt.executeUpdate();
2526
if (pStmt != null) {
2533
* Tests fix for BUG#1658
2536
* if the fix for parameter bounds checking doesn't work.
2538
public void testParameterBoundsCheck() throws Exception {
2541
.executeUpdate("DROP TABLE IF EXISTS testParameterBoundsCheck");
2543
.executeUpdate("CREATE TABLE testParameterBoundsCheck(f1 int, f2 int, f3 int, f4 int, f5 int)");
2545
PreparedStatement pstmt = this.conn
2546
.prepareStatement("UPDATE testParameterBoundsCheck SET f1=?, f2=?,f3=?,f4=? WHERE f5=?");
2548
pstmt.setString(1, "");
2549
pstmt.setString(2, "");
2552
pstmt.setString(25, "");
2553
} catch (SQLException sqlEx) {
2554
assertTrue(SQLError.SQL_STATE_ILLEGAL_ARGUMENT.equals(sqlEx
2559
.executeUpdate("DROP TABLE IF EXISTS testParameterBoundsCheck");
2563
public void testPStmtTypesBug() throws Exception {
2565
this.stmt.executeUpdate("DROP TABLE IF EXISTS testPStmtTypesBug");
2567
.executeUpdate("CREATE TABLE testPStmtTypesBug(field1 INT)");
2568
this.pstmt = this.conn
2569
.prepareStatement("INSERT INTO testPStmtTypesBug VALUES (?)");
2570
this.pstmt.setObject(1, null, Types.INTEGER);
2571
this.pstmt.addBatch();
2572
this.pstmt.setInt(1, 1);
2573
this.pstmt.addBatch();
2574
this.pstmt.executeBatch();
2577
this.stmt.executeUpdate("DROP TABLE IF EXISTS testPStmtTypesBug");
2582
* Tests fix for BUG#1511
2585
* if the quoteid parsing fix in PreparedStatement doesn't work.
2587
public void testQuotedIdRecognition() throws Exception {
2588
if (!this.versionMeetsMinimum(4, 1)) {
2590
this.stmt.executeUpdate("DROP TABLE IF EXISTS testQuotedId");
2592
.executeUpdate("CREATE TABLE testQuotedId (col1 VARCHAR(32))");
2594
PreparedStatement pStmt = this.conn
2595
.prepareStatement("SELECT * FROM testQuotedId WHERE col1='ABC`DEF' or col1=?");
2596
pStmt.setString(1, "foo");
2599
this.stmt.executeUpdate("DROP TABLE IF EXISTS testQuotedId2");
2601
.executeUpdate("CREATE TABLE testQuotedId2 (`Works?` INT)");
2603
.prepareStatement("INSERT INTO testQuotedId2 (`Works?`) VALUES (?)");
2605
pStmt.executeUpdate();
2607
this.stmt.executeUpdate("DROP TABLE IF EXISTS testQuotedId");
2608
this.stmt.executeUpdate("DROP TABLE IF EXISTS testQuotedId2");
2614
* Tests for BUG#9288, parameter index out of range if LIKE, ESCAPE '\'
2618
* if the test fails.
2621
* public void testBug9288() throws Exception { String tableName =
2622
* "testBug9288"; PreparedStatement pStmt = null;
2624
* try { createTable(tableName, "(field1 VARCHAR(32), field2 INT)"); pStmt =
2625
* ((com.mysql.jdbc.Connection)this.conn).clientPrepareStatement( "SELECT
2626
* COUNT(1) FROM " + tableName + " WHERE " + "field1 LIKE '%' ESCAPE '\\'
2627
* AND " + "field2 > ?"); pStmt.setInt(1, 0);
2629
* this.rs = pStmt.executeQuery(); } finally { if (this.rs != null) {
2630
* this.rs.close(); this.rs = null; }
2632
* if (pStmt != null) { pStmt.close(); } } }
2636
* public void testBug10999() throws Exception { if (versionMeetsMinimum(5,
2639
* String tableName = "testBug10999"; String updateTrigName =
2640
* "testBug10999Update"; String insertTrigName = "testBug10999Insert"; try {
2641
* createTable(tableName, "(pkfield INT PRIMARY KEY NOT NULL AUTO_INCREMENT,
2642
* field1 VARCHAR(32))");
2644
* try { this.stmt.executeUpdate("DROP TRIGGER " + updateTrigName); } catch
2645
* (SQLException sqlEx) { // ignore for now }
2647
* this.stmt.executeUpdate("CREATE TRIGGER " + updateTrigName + " AFTER
2648
* UPDATE ON " + tableName + " FOR EACH ROW " + "BEGIN " + "END");
2650
* try { this.stmt.executeUpdate("DROP TRIGGER " + insertTrigName); } catch
2651
* (SQLException sqlEx) { // ignore }
2653
* this.stmt.executeUpdate("CREATE TRIGGER " + insertTrigName + " AFTER
2654
* INSERT ON " + tableName + " FOR EACH ROW " + " BEGIN " + "END");
2656
* this.conn.setAutoCommit(false);
2658
* String updateSQL = "INSERT INTO " + tableName + " (field1) VALUES
2659
* ('abcdefg')"; int rowCount = this.stmt.executeUpdate(updateSQL,
2660
* Statement.RETURN_GENERATED_KEYS);
2662
* this.rs = stmt.getGeneratedKeys(); if (rs.next()) {
2663
* System.out.println(rs.getInt(1)); int id = rs.getInt(1); //if
2664
* (log.isDebugEnabled()) // log.debug("Retrieved ID = " + id); } //else {
2665
* //log.error("Can't retrieve ID with getGeneratedKeys."); // Retrieve ID
2666
* using a SELECT statement instead. // querySQL = "SELECT id from tab1
2669
* //if (log.isDebugEnabled()) // log.debug(querySQL);
2671
* //rs = stmt.executeQuery(querySQL); this.rs =
2672
* this.stmt.executeQuery("SELECT pkfield FROM " + tableName); } finally {
2673
* this.conn.setAutoCommit(true);
2675
* try { this.stmt.executeUpdate("DROP TRIGGER IF EXISTS " +
2676
* insertTrigName); } catch (SQLException sqlEx) { // ignore }
2678
* try { this.stmt.executeUpdate("DROP TRIGGER IF EXISTS " +
2679
* updateTrigName); } catch (SQLException sqlEx) { // ignore } } } }
2683
* Tests that binary dates/times are encoded/decoded correctly.
2686
* if the test fails.
2688
* @deprecated because we need to use this particular constructor for the
2689
* date class, as Calendar-constructed dates don't pass the
2692
public void testServerPrepStmtAndDate() throws Exception {
2695
.executeUpdate("DROP TABLE IF EXISTS testServerPrepStmtAndDate");
2696
this.stmt.executeUpdate("CREATE TABLE testServerPrepStmtAndDate("
2697
+ "`P_ID` int(10) NOT NULL default '0',"
2698
+ "`H_ID` int(10) NOT NULL default '0',"
2699
+ "`R_ID` int(10) NOT NULL default '0',"
2700
+ "`H_Age` int(10) default NULL,"
2701
+ "`R_Date` date NOT NULL default '0000-00-00',"
2702
+ "`Comments` varchar(255) default NULL,"
2703
+ "`Weight` int(10) default NULL,"
2704
+ "`HeadGear` char(1) NOT NULL default '',"
2705
+ "`FinPos` int(10) default NULL,"
2706
+ "`Jock_ID` int(10) default NULL,"
2707
+ "`BtnByPrev` double default NULL,"
2708
+ "`BtnByWinner` double default NULL,"
2709
+ "`Jock_All` int(10) default NULL,"
2710
+ "`Draw` int(10) default NULL,"
2711
+ "`SF` int(10) default NULL,"
2712
+ "`RHR` int(10) default NULL,"
2713
+ "`ORating` int(10) default NULL,"
2714
+ "`Odds` double default NULL,"
2715
+ "`RaceFormPlus` int(10) default NULL,"
2716
+ "`PrevPerform` int(10) default NULL,"
2717
+ "`TrainerID` int(10) NOT NULL default '0',"
2718
+ "`DaysSinceRun` int(10) default NULL,"
2719
+ "UNIQUE KEY `P_ID` (`P_ID`),"
2720
+ "UNIQUE KEY `R_H_ID` (`R_ID`,`H_ID`),"
2721
+ "KEY `R_Date` (`R_Date`)," + "KEY `H_Age` (`H_Age`),"
2722
+ "KEY `TrainerID` (`TrainerID`)," + "KEY `H_ID` (`H_ID`)"
2725
Date dt = new java.sql.Date(102, 1, 2); // Note, this represents the
2728
PreparedStatement pStmt2 = this.conn
2729
.prepareStatement("INSERT INTO testServerPrepStmtAndDate (P_ID, R_Date) VALUES (171576, ?)");
2730
pStmt2.setDate(1, dt);
2731
pStmt2.executeUpdate();
2735
.executeQuery("SELECT R_Date FROM testServerPrepStmtAndDate");
2738
System.out.println("Date that was stored (as String) "
2739
+ this.rs.getString(1)); // comes back as 2002-02-02
2741
PreparedStatement pStmt = this.conn
2742
.prepareStatement("Select P_ID,R_Date from testServerPrepStmtAndDate Where R_Date = ? and P_ID = 171576");
2743
pStmt.setDate(1, dt);
2745
this.rs = pStmt.executeQuery();
2747
assertTrue(this.rs.next());
2749
assertEquals("171576", this.rs.getString(1));
2751
assertEquals(dt, this.rs.getDate(2));
2754
.executeUpdate("DROP TABLE IF EXISTS testServerPrepStmtAndDate");
2758
public void testServerPrepStmtDeadlock() throws Exception {
2760
Connection c = getConnectionWithProps(null);
2762
Thread testThread1 = new PrepareThread(c);
2763
Thread testThread2 = new PrepareThread(c);
2764
testThread1.start();
2765
testThread2.start();
2766
Thread.sleep(30000);
2767
assertTrue(this.testServerPrepStmtDeadlockCounter >= 10);
2771
* Tests PreparedStatement.setCharacterStream() to ensure it accepts > 4K
2775
* if an error occurs.
2777
public void testSetCharacterStream() throws Exception {
2779
((com.mysql.jdbc.Connection) this.conn).setTraceProtocol(true);
2782
.executeUpdate("DROP TABLE IF EXISTS charStreamRegressTest");
2784
.executeUpdate("CREATE TABLE charStreamRegressTest(field1 text)");
2786
this.pstmt = this.conn
2787
.prepareStatement("INSERT INTO charStreamRegressTest VALUES (?)");
2789
// char[] charBuf = new char[16384];
2790
char[] charBuf = new char[32];
2792
for (int i = 0; i < charBuf.length; i++) {
2796
CharArrayReader reader = new CharArrayReader(charBuf);
2798
this.pstmt.setCharacterStream(1, reader, charBuf.length);
2799
this.pstmt.executeUpdate();
2802
.executeQuery("SELECT LENGTH(field1) FROM charStreamRegressTest");
2806
System.out.println("Character stream length: "
2807
+ this.rs.getString(1));
2810
.executeQuery("SELECT field1 FROM charStreamRegressTest");
2814
String result = this.rs.getString(1);
2816
assertTrue(result.length() == charBuf.length);
2818
this.stmt.execute("TRUNCATE TABLE charStreamRegressTest");
2820
// Test that EOF is not thrown
2821
reader = new CharArrayReader(charBuf);
2822
this.pstmt.clearParameters();
2823
this.pstmt.setCharacterStream(1, reader, charBuf.length);
2824
this.pstmt.executeUpdate();
2827
.executeQuery("SELECT LENGTH(field1) FROM charStreamRegressTest");
2831
System.out.println("Character stream length: "
2832
+ this.rs.getString(1));
2835
.executeQuery("SELECT field1 FROM charStreamRegressTest");
2839
result = this.rs.getString(1);
2841
assertTrue("Retrieved value of length " + result.length()
2842
+ " != length of inserted value " + charBuf.length, result
2843
.length() == charBuf.length);
2845
// Test single quotes inside identifers
2847
.executeUpdate("DROP TABLE IF EXISTS `charStream'RegressTest`");
2849
.executeUpdate("CREATE TABLE `charStream'RegressTest`(field1 text)");
2851
this.pstmt = this.conn
2852
.prepareStatement("INSERT INTO `charStream'RegressTest` VALUES (?)");
2854
reader = new CharArrayReader(charBuf);
2855
this.pstmt.setCharacterStream(1, reader, (charBuf.length * 2));
2856
this.pstmt.executeUpdate();
2859
.executeQuery("SELECT field1 FROM `charStream'RegressTest`");
2863
result = this.rs.getString(1);
2865
assertTrue("Retrieved value of length " + result.length()
2866
+ " != length of inserted value " + charBuf.length, result
2867
.length() == charBuf.length);
2869
((com.mysql.jdbc.Connection) this.conn).setTraceProtocol(false);
2871
if (this.rs != null) {
2874
} catch (Exception ex) {
2882
.executeUpdate("DROP TABLE IF EXISTS `charStream'RegressTest`");
2884
.executeUpdate("DROP TABLE IF EXISTS charStreamRegressTest");
2889
* Tests a bug where Statement.setFetchSize() does not work for values other
2890
* than 0 or Integer.MIN_VALUE
2893
* if any errors occur
2895
public void testSetFetchSize() throws Exception {
2896
int oldFetchSize = this.stmt.getFetchSize();
2899
this.stmt.setFetchSize(10);
2901
this.stmt.setFetchSize(oldFetchSize);
2906
* Tests fix for BUG#907
2909
* if an error occurs
2911
public void testSetMaxRows() throws Exception {
2912
Statement maxRowsStmt = null;
2915
maxRowsStmt = this.conn.createStatement();
2916
maxRowsStmt.setMaxRows(1);
2917
maxRowsStmt.executeQuery("SELECT 1");
2919
if (maxRowsStmt != null) {
2920
maxRowsStmt.close();
2926
* Tests for timestamp NPEs occuring in binary-format timestamps.
2931
* @deprecated yes, we know we are using deprecated methods here :)
2933
public void testTimestampNPE() throws Exception {
2935
Timestamp ts = new Timestamp(System.currentTimeMillis());
2937
this.stmt.executeUpdate("DROP TABLE IF EXISTS testTimestampNPE");
2939
.executeUpdate("CREATE TABLE testTimestampNPE (field1 TIMESTAMP)");
2941
this.pstmt = this.conn
2942
.prepareStatement("INSERT INTO testTimestampNPE VALUES (?)");
2943
this.pstmt.setTimestamp(1, ts);
2944
this.pstmt.executeUpdate();
2946
this.pstmt = this.conn
2947
.prepareStatement("SELECT field1 FROM testTimestampNPE");
2949
this.rs = this.pstmt.executeQuery();
2953
System.out.println(this.rs.getString(1));
2957
Timestamp rTs = this.rs.getTimestamp(1);
2958
assertTrue("Retrieved year of " + rTs.getYear()
2959
+ " does not match " + ts.getYear(), rTs.getYear() == ts
2961
assertTrue("Retrieved month of " + rTs.getMonth()
2962
+ " does not match " + ts.getMonth(), rTs.getMonth() == ts
2964
assertTrue("Retrieved date of " + rTs.getDate()
2965
+ " does not match " + ts.getDate(), rTs.getDate() == ts
2971
public void testTruncationWithChar() throws Exception {
2974
.executeUpdate("DROP TABLE IF EXISTS testTruncationWithChar");
2976
.executeUpdate("CREATE TABLE testTruncationWithChar (field1 char(2))");
2978
this.pstmt = this.conn
2979
.prepareStatement("INSERT INTO testTruncationWithChar VALUES (?)");
2980
this.pstmt.setString(1, "00");
2981
this.pstmt.executeUpdate();
2984
.executeUpdate("DROP TABLE IF EXISTS testTruncationWithChar");
2989
* Tests fix for updatable streams being supported in updatable result sets.
2992
* if the test fails.
2994
public void testUpdatableStream() throws Exception {
2996
this.stmt.executeUpdate("DROP TABLE IF EXISTS updateStreamTest");
2998
.executeUpdate("CREATE TABLE updateStreamTest (keyField INT NOT NULL AUTO_INCREMENT PRIMARY KEY, field1 BLOB)");
3000
int streamLength = 16385;
3001
byte[] streamData = new byte[streamLength];
3003
/* create an updatable statement */
3004
Statement updStmt = this.conn.createStatement(
3005
ResultSet.TYPE_SCROLL_INSENSITIVE,
3006
ResultSet.CONCUR_UPDATABLE);
3008
/* fill the resultset with some values */
3009
ResultSet updRs = updStmt
3010
.executeQuery("SELECT * FROM updateStreamTest");
3012
/* move to insertRow */
3013
updRs.moveToInsertRow();
3015
/* update the table */
3016
updRs.updateBinaryStream("field1", new ByteArrayInputStream(
3017
streamData), streamLength);
3021
this.stmt.executeUpdate("DROP TABLE IF EXISTS updateStreamTest");
3026
* Tests fix for BUG#15383 - PreparedStatement.setObject() serializes
3027
* BigInteger as object, rather than sending as numeric value (and is thus
3028
* not complementary to .getObject() on an UNSIGNED LONG type).
3031
* if the test fails.
3033
public void testBug15383() throws Exception {
3036
"(id INTEGER UNSIGNED NOT NULL "
3037
+ "AUTO_INCREMENT,value BIGINT UNSIGNED NULL DEFAULT 0,PRIMARY "
3038
+ "KEY(id))ENGINE=InnoDB;");
3040
this.stmt.executeUpdate("INSERT INTO testBug15383(value) VALUES(1)");
3042
Statement updatableStmt = this.conn.createStatement(
3043
ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE);
3046
this.rs = updatableStmt.executeQuery("SELECT * from testBug15383");
3048
assertTrue(this.rs.next());
3050
Object bigIntObj = this.rs.getObject("value");
3051
assertEquals("java.math.BigInteger", bigIntObj.getClass().getName());
3053
this.rs.updateObject("value", new BigInteger("3"));
3054
this.rs.updateRow();
3056
assertEquals("3", this.rs.getString("value"));
3058
if (this.rs != null) {
3059
ResultSet toClose = this.rs;
3064
if (updatableStmt != null) {
3065
updatableStmt.close();
3071
* Tests fix for BUG#17099 - Statement.getGeneratedKeys() throws NPE when no
3072
* query has been processed.
3077
public void testBug17099() throws Exception {
3078
if (isRunningOnJdk131()) {
3079
return; // test not valid
3082
Statement newStmt = this.conn.createStatement();
3083
assertNotNull(newStmt.getGeneratedKeys());
3085
PreparedStatement pStmt = this.conn.prepareStatement("SELECT 1");
3086
assertNotNull(pStmt.getGeneratedKeys());
3088
if (versionMeetsMinimum(4, 1)) {
3089
pStmt = ((com.mysql.jdbc.Connection) this.conn)
3090
.clientPrepareStatement("SELECT 1");
3091
assertNotNull(pStmt.getGeneratedKeys());
3096
* Tests fix for BUG#17587 - clearParameters() on a closed prepared
3097
* statement causes NPE.
3100
* if the test fails.
3102
public void testBug17587() throws Exception {
3103
createTable("testBug17857", "(field1 int)");
3104
PreparedStatement pStmt = null;
3108
.prepareStatement("INSERT INTO testBug17857 VALUES (?)");
3111
pStmt.clearParameters();
3112
} catch (SQLException sqlEx) {
3113
assertEquals("08003", sqlEx.getSQLState());
3116
pStmt = ((com.mysql.jdbc.Connection) this.conn)
3117
.clientPrepareStatement("INSERT INTO testBug17857 VALUES (?)");
3120
pStmt.clearParameters();
3121
} catch (SQLException sqlEx) {
3122
assertEquals("08003", sqlEx.getSQLState());
3126
if (pStmt != null) {
3133
* Tests fix for BUG#18740 - Data truncation and getWarnings() only returns
3134
* last warning in set.
3137
* if the test fails.
3139
public void testBug18740() throws Exception {
3140
if (!versionMeetsMinimum(5, 0, 2)) {
3141
createTable("testWarnings", "(field1 smallint(6),"
3142
+ "field2 varchar(6)," + "UNIQUE KEY field1(field1))");
3145
this.stmt.executeUpdate("INSERT INTO testWarnings VALUES "
3146
+ "(10001, 'data1')," + "(10002, 'data2 foo'),"
3147
+ "(10003, 'data3')," + "(10004999, 'data4'),"
3148
+ "(10005, 'data5')");
3149
} catch (SQLException sqlEx) {
3150
String sqlStateToCompare = "01004";
3153
sqlStateToCompare = "22001";
3156
assertEquals(sqlStateToCompare, sqlEx.getSQLState());
3157
assertEquals(sqlStateToCompare, sqlEx.getNextException().getSQLState());
3159
SQLWarning sqlWarn = this.stmt.getWarnings();
3160
assertEquals("01000", sqlWarn.getSQLState());
3161
assertEquals("01000", sqlWarn.getNextWarning().getSQLState());
3166
protected boolean isJdbc4() {
3170
Class.forName("java.sql.Wrapper");
3172
} catch (Throwable t) {
3180
* Tests fix for BUG#19615, PreparedStatement.setObject(int, Object, int)
3181
* doesn't respect scale of BigDecimals.
3184
* if the test fails.
3186
public void testBug19615() throws Exception {
3187
createTable("testBug19615", "(field1 DECIMAL(19, 12))");
3190
BigDecimal dec = new BigDecimal("1.234567");
3192
this.pstmt = this.conn
3193
.prepareStatement("INSERT INTO testBug19615 VALUES (?)");
3194
this.pstmt.setObject(1, dec, Types.DECIMAL);
3195
this.pstmt.executeUpdate();
3198
this.rs = this.stmt.executeQuery("SELECT field1 FROM testBug19615");
3200
assertEquals(dec, this.rs.getBigDecimal(1).setScale(6));
3202
this.stmt.executeUpdate("TRUNCATE TABLE testBug19615");
3204
this.pstmt = ((com.mysql.jdbc.Connection) this.conn)
3205
.clientPrepareStatement("INSERT INTO testBug19615 VALUES (?)");
3206
this.pstmt.setObject(1, dec, Types.DECIMAL);
3207
this.pstmt.executeUpdate();
3210
this.rs = this.stmt.executeQuery("SELECT field1 FROM testBug19615");
3212
assertEquals(dec, this.rs.getBigDecimal(1).setScale(6));
3215
closeMemberJDBCResources();
3220
* Tests fix for BUG#20029 - NPE thrown from executeBatch().
3224
public void testBug20029() throws Exception {
3225
createTable("testBug20029", ("(field1 int)"));
3227
long initialTimeout = 20; // may need to raise this depending on environment
3228
// we try and do this automatically in this testcase
3230
for (int i = 0; i < 10; i++) {
3231
final Connection toBeKilledConn = getConnectionWithProps(new Properties());
3232
final long timeout = initialTimeout;
3233
PreparedStatement toBeKilledPstmt = null;
3236
toBeKilledPstmt = ((com.mysql.jdbc.Connection)toBeKilledConn).clientPrepareStatement("INSERT INTO testBug20029 VALUES (?)");
3238
for (int j = 0; j < 1000; j++) {
3239
toBeKilledPstmt.setInt(1, j);
3240
toBeKilledPstmt.addBatch();
3243
Thread t = new Thread() {
3247
toBeKilledConn.close();
3248
} catch (Throwable t) {
3257
if (toBeKilledConn.isClosed()) {
3258
initialTimeout *= 2;
3262
toBeKilledPstmt.executeBatch();
3263
fail("Should've caught a SQLException for the statement being closed here");
3264
} catch (BatchUpdateException batchEx) {
3265
assertEquals("08003", batchEx.getSQLState());
3269
fail("Connection didn't close while in the middle of PreparedStatement.executeBatch()");
3271
if (toBeKilledPstmt != null) {
3272
toBeKilledPstmt.close();
3275
if (toBeKilledConn != null) {
3276
toBeKilledConn.close();
3283
* Fixes BUG#20687 - Can't pool server-side prepared statements, exception
3284
* raised when re-using them.
3286
* @throws Exception if the test fails.
3288
public void testBug20687() throws Exception {
3289
if (!isRunningOnJdk131() && versionMeetsMinimum(5, 0)) {
3290
createTable("testBug20687", "(field1 int)");
3291
Connection poolingConn = null;
3293
Properties props = new Properties();
3294
props.setProperty("cachePrepStmts", "true");
3295
props.setProperty("useServerPrepStmts", "true");
3296
PreparedStatement pstmt1 = null;
3297
PreparedStatement pstmt2 = null;
3300
poolingConn = getConnectionWithProps(props);
3301
pstmt1 = poolingConn.prepareStatement("SELECT field1 FROM testBug20687");
3302
pstmt1.executeQuery();
3305
pstmt2 = poolingConn.prepareStatement("SELECT field1 FROM testBug20687");
3306
pstmt2.executeQuery();
3307
assertTrue(pstmt1 == pstmt2);
3310
if (pstmt1 != null) {
3314
if (pstmt2 != null) {
3318
if (poolingConn != null) {
3319
poolingConn.close();
3325
public void testLikeWithBackslashes() throws Exception {
3326
if (!versionMeetsMinimum(5, 0, 0)) {
3330
Connection noBackslashEscapesConn = null;
3333
Properties props = new Properties();
3334
props.setProperty("sessionVariables",
3335
"sql_mode=NO_BACKSLASH_ESCAPES");
3337
noBackslashEscapesConn = getConnectionWithProps(props);
3341
"(userName varchar(32) not null, ivalue integer, CNAME varchar(255), bvalue CHAR(1), svalue varchar(255), ACTIVE CHAR(1), primary key (userName))");
3343
String insert_sql = "insert into X_TEST (ivalue, CNAME, bvalue, svalue, ACTIVE, userName) values (?, ?, ?, ?, ?, ?)";
3345
this.pstmt = noBackslashEscapesConn.prepareStatement(insert_sql);
3346
this.pstmt.setInt(1, 0);
3347
this.pstmt.setString(2, "c:\\jetson");
3348
this.pstmt.setInt(3, 1);
3349
this.pstmt.setString(4, "c:\\jetson");
3350
this.pstmt.setInt(5, 1);
3351
this.pstmt.setString(6, "c:\\jetson");
3352
this.pstmt.execute();
3354
String select_sql = "select user0_.userName as userName0_0_, user0_.ivalue as ivalue0_0_, user0_.CNAME as CNAME0_0_, user0_.bvalue as bvalue0_0_, user0_.svalue as svalue0_0_, user0_.ACTIVE as ACTIVE0_0_ from X_TEST user0_ where user0_.userName like ?";
3355
this.pstmt = noBackslashEscapesConn.prepareStatement(select_sql);
3356
this.pstmt.setString(1, "c:\\j%");
3357
// if we comment out the previous line and uncomment the following, the like clause matches
3358
// stmt.setString(1,"c:\\\\j%");
3359
System.out.println("about to execute query " + select_sql);
3360
this.rs = this.pstmt.executeQuery();
3361
assertTrue(this.rs.next());
3363
closeMemberJDBCResources();
3365
if (noBackslashEscapesConn != null) {
3366
noBackslashEscapesConn.close();
3372
* Tests fix for BUG#20650 - Statement.cancel() causes NullPointerException
3373
* if underlying connection has been closed due to server failure.
3375
* @throws Exception if the test fails.
3377
public void testBug20650() throws Exception {
3378
Connection closedConn = null;
3379
Statement cancelStmt = null;
3382
closedConn = getConnectionWithProps(null);
3383
cancelStmt = closedConn.createStatement();
3387
cancelStmt.cancel();
3389
if (cancelStmt != null) {
3393
if (closedConn != null && !closedConn.isClosed()) {
3400
* Tests fix for BUG#20888 - escape of quotes in client-side prepared
3401
* statements parsing not respected.
3403
* @throws Exception if the test fails.
3405
public void testBug20888() throws Exception {
3408
String s = "SELECT 'What do you think about D\\'Artanian''?', \"What do you think about D\\\"Artanian\"\"?\"";
3409
this.pstmt = ((com.mysql.jdbc.Connection)this.conn).clientPrepareStatement(s);
3411
this.rs = this.pstmt.executeQuery();
3413
assertEquals(this.rs.getString(1), "What do you think about D'Artanian'?");
3414
assertEquals(this.rs.getString(2), "What do you think about D\"Artanian\"?");
3416
closeMemberJDBCResources();
3421
* Tests Bug#21207 - Driver throws NPE when tracing prepared statements that
3422
* have been closed (in asSQL()).
3424
* @throws Exception if the test fails
3426
public void testBug21207() throws Exception {
3428
this.pstmt = this.conn.prepareStatement("SELECT 1");
3430
this.pstmt.toString(); // this used to cause an NPE
3432
closeMemberJDBCResources();
3437
* Tests BUG#21438, server-side PS fails when using jdbcCompliantTruncation.
3438
* If either is set to FALSE (&useServerPrepStmts=false or
3439
* &jdbcCompliantTruncation=false) test succedes.
3442
* if the test fails.
3445
public void testBug21438() throws Exception {
3446
createTable("testBug21438","(t_id int(10), test_date timestamp(30) NOT NULL,primary key t_pk (t_id));");
3448
assertEquals(1, this.stmt.executeUpdate("insert into testBug21438 values (1,NOW());"));
3450
if (this.versionMeetsMinimum(4, 1)) {
3451
this.pstmt = ((com.mysql.jdbc.Connection)this.conn)
3452
.serverPrepare("UPDATE testBug21438 SET test_date=ADDDATE(?,INTERVAL 1 YEAR) WHERE t_id=1;");
3455
Timestamp ts = new Timestamp(System.currentTimeMillis());
3456
ts.setNanos(999999999);
3458
this.pstmt.setTimestamp(1, ts);
3460
assertEquals(1, this.pstmt.executeUpdate());
3462
Timestamp future = (Timestamp)getSingleIndexedValueWithQuery(1, "SELECT test_date FROM testBug21438");
3463
assertEquals(future.getYear() - ts.getYear(), 1);
3466
closeMemberJDBCResources();
3472
* Tests fix for BUG#22359 - Driver was using millis for
3473
* Statement.setQueryTimeout() when spec says argument is
3476
* @throws Exception if the test fails.
3478
public void testBug22359() throws Exception {
3479
if (versionMeetsMinimum(5, 0)) {
3480
Statement timeoutStmt = null;
3483
timeoutStmt = this.conn.createStatement();
3484
timeoutStmt.setQueryTimeout(2);
3486
long begin = System.currentTimeMillis();
3489
timeoutStmt.execute("SELECT SLEEP(30)");
3490
} catch (MySQLTimeoutException timeoutEx) {
3491
long end = System.currentTimeMillis();
3493
assertTrue((end - begin) > 1000);
3496
if (timeoutStmt != null) {
3497
timeoutStmt.close();
3504
* Tests fix for BUG#22290 - Driver issues truncation on write exception when
3505
* it shouldn't (due to sending big decimal incorrectly to server with
3506
* server-side prepared statement).
3508
* @throws Exception if the test fails.
3510
public void testBug22290() throws Exception {
3511
if (!versionMeetsMinimum(5, 0)) {
3517
"(`id` int(11) NOT NULL default '1',`cost` decimal(10,2) NOT NULL,PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8");
3520
.executeUpdate("INSERT INTO testbug22290 (`id`,`cost`) VALUES (1,'1.00')"),
3523
Connection configuredConn = null;
3526
Properties props = new Properties();
3527
props.setProperty("sessionVariables", "sql_mode='STRICT_TRANS_TABLES'");
3530
configuredConn = getConnectionWithProps(props);
3532
this.pstmt = configuredConn
3533
.prepareStatement("update testbug22290 set cost = cost + ? where id = 1");
3534
this.pstmt.setBigDecimal(1, new BigDecimal("1.11"));
3535
assertEquals(this.pstmt.executeUpdate(), 1);
3537
assertEquals(this.stmt
3538
.executeUpdate("UPDATE testbug22290 SET cost='1.00'"), 1);
3539
this.pstmt = ((com.mysql.jdbc.Connection)configuredConn)
3540
.clientPrepareStatement("update testbug22290 set cost = cost + ? where id = 1");
3541
this.pstmt.setBigDecimal(1, new BigDecimal("1.11"));
3542
assertEquals(this.pstmt.executeUpdate(), 1);
3544
closeMemberJDBCResources();
3546
if (configuredConn != null) {
3547
configuredConn.close();
3552
public void testClientPreparedSetBoolean() throws Exception {
3554
this.pstmt = ((com.mysql.jdbc.Connection)this.conn).clientPrepareStatement("SELECT ?");
3555
this.pstmt.setBoolean(1, false);
3556
assertEquals("SELECT 0",
3557
this.pstmt.toString().substring(this.pstmt.toString().indexOf("SELECT")));
3558
this.pstmt.setBoolean(1, true);
3559
assertEquals("SELECT 1",
3560
this.pstmt.toString().substring(this.pstmt.toString().indexOf("SELECT")));
3562
closeMemberJDBCResources();
3567
* Tests fix for BUG#24360 .setFetchSize() breaks prepared
3568
* SHOW and other commands.
3570
* @throws Exception if the test fails
3572
public void testBug24360() throws Exception {
3573
if (!versionMeetsMinimum(5, 0)) {
3577
Connection c = null;
3579
Properties props = new Properties();
3580
props.setProperty("useServerPrepStmts", "true");
3583
c = getConnectionWithProps(props);
3585
this.pstmt = c.prepareStatement("SHOW PROCESSLIST");
3586
this.pstmt.setFetchSize(5);
3587
this.pstmt.execute();
3589
closeMemberJDBCResources();
3598
* Tests fix for BUG#24344 - useJDBCCompliantTimezoneShift with server-side prepared
3599
* statements gives different behavior than when using client-side prepared
3600
* statements. (this is now fixed if moving from server-side prepared statements
3601
* to client-side prepared statements by setting "useSSPSCompatibleTimezoneShift" to
3602
* "true", as the driver can't tell if this is a new deployment that never used
3603
* server-side prepared statements, or if it is an existing deployment that is
3604
* switching to client-side prepared statements from server-side prepared statements.
3606
* @throws Exception if the test fails
3608
public void testBug24344() throws Exception {
3610
if (!versionMeetsMinimum(4, 1)) {
3611
return; // need SSPS
3614
super.createTable("testBug24344",
3615
"(i INT AUTO_INCREMENT, t1 DATETIME, PRIMARY KEY (i)) ENGINE = MyISAM");
3617
Connection conn2 = null;
3620
Properties props = new Properties();
3621
props.setProperty("useServerPrepStmts", "true");
3622
props.setProperty("useJDBCCompliantTimezoneShift", "true");
3623
conn2 = super.getConnectionWithProps(props);
3624
this.pstmt = conn2.prepareStatement("INSERT INTO testBug24344 (t1) VALUES (?)");
3625
Calendar c = Calendar.getInstance();
3626
this.pstmt.setTimestamp(1, new Timestamp(c.getTime().getTime()));
3627
this.pstmt.execute();
3631
props.setProperty("useServerPrepStmts", "false");
3632
props.setProperty("useJDBCCompliantTimezoneShift", "true");
3633
props.setProperty("useSSPSCompatibleTimezoneShift", "true");
3635
conn2 = super.getConnectionWithProps(props);
3636
this.pstmt = conn2.prepareStatement("INSERT INTO testBug24344 (t1) VALUES (?)");
3637
this.pstmt.setTimestamp(1, new Timestamp(c.getTime().getTime()));
3638
this.pstmt.execute();
3642
props.setProperty("useServerPrepStmts", "false");
3643
props.setProperty("useJDBCCompliantTimezoneShift", "false");
3644
props.setProperty("useSSPSCompatibleTimezoneShift", "false");
3645
conn2 = super.getConnectionWithProps(props);
3646
this.pstmt = conn2.prepareStatement("INSERT INTO testBug24344 (t1) VALUES (?)");
3647
this.pstmt.setTimestamp(1, new Timestamp(c.getTime().getTime()));
3648
this.pstmt.execute();
3651
Statement s = conn2.createStatement();
3652
this.rs = s.executeQuery("SELECT t1 FROM testBug24344 ORDER BY i ASC");
3654
Timestamp[] dates = new Timestamp[3];
3659
dates[i++] = rs.getTimestamp(1);
3662
assertEquals( "Number of rows should be 3.", 3, i);
3663
assertEquals(dates[0], dates[1]);
3664
assertTrue(!dates[1].equals(dates[2]));
3666
closeMemberJDBCResources();
3668
if (conn2 != null) {
3675
* Tests fix for BUG#25073 - rewriting batched statements leaks internal statement
3676
* instances, and causes a memory leak.
3678
* @throws Exception if the test fails.
3680
public void testBug25073() throws Exception {
3681
if (isRunningOnJdk131()) {
3685
Properties props = new Properties();
3686
props.setProperty("rewriteBatchedStatements", "true");
3687
Connection multiConn = getConnectionWithProps(props);
3688
createTable("testBug25073", "(pk_field INT PRIMARY KEY NOT NULL AUTO_INCREMENT, field1 INT)");
3689
Statement multiStmt = multiConn.createStatement();
3690
multiStmt.addBatch("INSERT INTO testBug25073(field1) VALUES (1)");
3691
multiStmt.addBatch("INSERT INTO testBug25073(field1) VALUES (2)");
3692
multiStmt.addBatch("INSERT INTO testBug25073(field1) VALUES (3)");
3693
multiStmt.addBatch("INSERT INTO testBug25073(field1) VALUES (4)");
3694
multiStmt.addBatch("UPDATE testBug25073 SET field1=5 WHERE field1=1");
3695
multiStmt.addBatch("UPDATE testBug25073 SET field1=6 WHERE field1=2 OR field1=3");
3697
int beforeOpenStatementCount = ((com.mysql.jdbc.Connection)multiConn).getActiveStatementCount();
3699
multiStmt.executeBatch();
3701
int afterOpenStatementCount = ((com.mysql.jdbc.Connection)multiConn).getActiveStatementCount();
3703
assertEquals(beforeOpenStatementCount, afterOpenStatementCount);
3706
createTable("testBug25073", "(pk_field INT PRIMARY KEY NOT NULL AUTO_INCREMENT, field1 INT)");
3708
props.setProperty("rewriteBatchedStatements", "true");
3709
props.setProperty("sessionVariables", "max_allowed_packet=1024");
3710
multiConn = getConnectionWithProps(props);
3711
multiStmt = multiConn.createStatement();
3713
for (int i = 0; i < 1000; i++) {
3714
multiStmt.addBatch("INSERT INTO testBug25073(field1) VALUES (" + i + ")");
3717
beforeOpenStatementCount = ((com.mysql.jdbc.Connection)multiConn).getActiveStatementCount();
3719
multiStmt.executeBatch();
3721
afterOpenStatementCount = ((com.mysql.jdbc.Connection)multiConn).getActiveStatementCount();
3723
assertEquals(beforeOpenStatementCount, afterOpenStatementCount);
3725
createTable("testBug25073", "(pk_field INT PRIMARY KEY NOT NULL AUTO_INCREMENT, field1 INT)");
3728
props.setProperty("useServerPrepStmts", "false");
3729
props.setProperty("rewriteBatchedStatements", "true");
3730
multiConn = getConnectionWithProps(props);
3731
PreparedStatement pStmt = multiConn.prepareStatement("INSERT INTO testBug25073(field1) VALUES (?)",
3732
Statement.RETURN_GENERATED_KEYS);
3734
for (int i = 0; i < 1000; i++) {
3739
beforeOpenStatementCount = ((com.mysql.jdbc.Connection)multiConn).getActiveStatementCount();
3741
pStmt.executeBatch();
3743
afterOpenStatementCount = ((com.mysql.jdbc.Connection)multiConn).getActiveStatementCount();
3745
assertEquals(beforeOpenStatementCount, afterOpenStatementCount);
3747
createTable("testBug25073", "(pk_field INT PRIMARY KEY NOT NULL AUTO_INCREMENT, field1 INT)");
3748
props.setProperty("useServerPrepStmts", "false");
3749
props.setProperty("rewriteBatchedStatements", "true");
3750
props.setProperty("sessionVariables", "max_allowed_packet=1024");
3751
multiConn = getConnectionWithProps(props);
3752
pStmt = multiConn.prepareStatement("INSERT INTO testBug25073(field1) VALUES (?)",
3753
Statement.RETURN_GENERATED_KEYS);
3755
for (int i = 0; i < 1000; i++) {
3760
beforeOpenStatementCount = ((com.mysql.jdbc.Connection)multiConn).getActiveStatementCount();
3762
pStmt.executeBatch();
3764
afterOpenStatementCount = ((com.mysql.jdbc.Connection)multiConn).getActiveStatementCount();
3766
assertEquals(beforeOpenStatementCount, afterOpenStatementCount);
3770
* Tests fix for BUG#25009 - Results from updates not handled correctly in multi-statement
3773
* @throws Exception if the test fails.
3775
public void testBug25009() throws Exception {
3776
if (!versionMeetsMinimum(4, 1)) {
3780
Properties props = new Properties();
3781
props.setProperty("allowMultiQueries", "true");
3783
Connection multiConn = getConnectionWithProps(props);
3784
createTable("testBug25009", "(field1 INT)");
3787
Statement multiStmt = multiConn.createStatement();
3788
multiStmt.execute("SELECT 1;SET @a=1; SET @b=2; SET @c=3; INSERT INTO testBug25009 VALUES (1)");
3790
assertEquals(-1, multiStmt.getUpdateCount());
3792
this.rs = multiStmt.getResultSet();
3793
assertTrue(this.rs.next());
3794
assertEquals(multiStmt.getMoreResults(), false);
3796
for (int i = 0; i < 3; i++) {
3797
assertEquals(0, multiStmt.getUpdateCount());
3798
assertEquals(multiStmt.getMoreResults(), false);
3801
assertEquals(1, multiStmt.getUpdateCount());
3803
this.rs = multiStmt.executeQuery("SELECT field1 FROM testBug25009");
3804
assertTrue(this.rs.next());
3805
assertEquals(1, this.rs.getInt(1));
3808
closeMemberJDBCResources();
3810
if (multiConn != null) {
3817
* Tests fix for BUG#25025 - Client-side prepared statement parser gets confused by
3818
* in-line (slash-star) comments and therefore can't rewrite batched statements or
3819
* reliably detect type of statements when they're used.
3821
* @throws Exception if the test fails.
3823
public void testBug25025() throws Exception {
3825
Connection multiConn = null;
3827
createTable("testBug25025", "(field1 INT)");
3830
Properties props = new Properties();
3831
props.setProperty("rewriteBatchedStatements", "true");
3832
props.setProperty("useServerPrepStmts", "false");
3834
multiConn = getConnectionWithProps(props);
3836
this.pstmt = multiConn.prepareStatement("/* insert foo.bar.baz INSERT INTO foo VALUES (?,?,?,?) to trick parser */ INSERT into testBug25025 VALUES (?)");
3837
this.pstmt.setInt(1, 1);
3838
this.pstmt.addBatch();
3839
this.pstmt.setInt(1, 2);
3840
this.pstmt.addBatch();
3841
this.pstmt.setInt(1, 3);
3842
this.pstmt.addBatch();
3844
int[] counts = this.pstmt.executeBatch();
3846
assertEquals(3, counts.length);
3847
assertEquals(1, counts[0]);
3848
assertEquals(1, counts[1]);
3849
assertEquals(1, counts[2]);
3851
((com.mysql.jdbc.PreparedStatement)this.pstmt).canRewriteAsMultivalueInsertStatement());
3853
closeMemberJDBCResources();
3855
if (multiConn != null) {
3861
public void testBug25606() throws Exception {
3862
if (!versionMeetsMinimum(5, 0)) {
3866
createTable("testtable", "(c0 int not null) engine=myisam");
3868
.execute("alter table testtable add unique index testtable_i(c0)");
3870
Properties props = new Properties();
3871
props.setProperty("allowMultiQueries", "true");
3873
Connection multiConn = getConnectionWithProps(props);
3878
"create temporary table testtable_td(_batch int not null,c0 int not null)");
3879
multiConn.createStatement().execute(
3880
"create unique index testtable_td_b on testtable_td(_batch)");
3882
PreparedStatement ps;
3883
int num_changes = 0;
3885
ps = multiConn.prepareStatement("insert into testtable(c0) values(?)");
3886
while (num_changes < 10000) {
3887
ps.setInt(1, num_changes);
3893
if ((num_changes % 1000) == 0) {
3900
int num_deletes = 3646;
3904
.prepareStatement("insert into testtable_td(_batch,c0) values(?,?)");
3905
while (i < num_deletes) {
3913
if ((i % 1000) == 0) {
3922
String sql = "lock tables testtable write;\n"
3923
+ "delete testtable from testtable_td force index(testtable_td_b) straight_join testtable on testtable.c0=testtable_td.c0 where testtable_td._batch>=? and testtable_td._batch<?;\n"
3926
ps = multiConn.prepareStatement(sql);
3930
for (int start_index = 0, end_index = Math.min(bsize, num_deletes); start_index < num_changes && start_index < 3646; start_index = end_index, end_index = Math
3931
.min(start_index + bsize, num_deletes)) {
3932
ps.clearParameters();
3933
ps.setInt(1, start_index);
3934
ps.setInt(2, end_index);
3937
//ignore the results from the "lock_tables"
3938
int c1 = ps.getUpdateCount();
3939
boolean b1 = ps.getMoreResults();
3941
//should always be the results from the "delete"
3942
int nrows_changed = ps.getUpdateCount();
3944
if (nrows_changed == -1)
3945
throw new SQLException("nrows_changed==-1"); //????
3951
public void testBustedGGKWithPSExecute() throws Exception {
3952
if (isRunningOnJdk131()) {
3957
createTable("sequence", "(sequence_name VARCHAR(255) NOT NULL PRIMARY KEY, next_val BIGINT NOT NULL)");
3959
// Populate with the initial value
3960
stmt.executeUpdate("INSERT INTO sequence VALUES ('test-sequence', 1234)");
3962
// Atomic operation to increment and return next value
3963
PreparedStatement pStmt = null;
3966
pStmt = this.conn.prepareStatement("UPDATE sequence SET next_val=LAST_INSERT_ID(next_val + ?) WHERE sequence_name = ?",
3967
Statement.RETURN_GENERATED_KEYS);
3970
pStmt.setString(2, "test-sequence");
3973
this.rs = pStmt.getGeneratedKeys();
3975
assertEquals(1238, this.rs.getLong(1));
3977
closeMemberJDBCResources();
3979
if (pStmt != null) {
3986
* Tests fix for BUG#28469 - PreparedStatement.getMetaData()
3987
* for statements containing leading one-line comments
3988
* is not returned correctly.
3990
* As part of this fix, we also overhauled detection of
3991
* DML for executeQuery() and SELECTs for executeUpdate() in
3992
* plain and prepared statements to be aware of the same
3993
* types of comments.
3997
public void testBug28469() throws Exception {
3998
PreparedStatement commentStmt = null;
4001
String[] statementsToTest = {"-- COMMENT\nSELECT 1",
4002
"# COMMENT\nSELECT 1",
4003
"/* comment */ SELECT 1"};
4005
for (int i = 0; i < statementsToTest.length; i++) {
4006
commentStmt = this.conn.prepareStatement(statementsToTest[i]);
4008
assertNotNull(commentStmt.getMetaData());
4011
commentStmt.executeUpdate();
4012
fail("Should not be able to call executeUpdate() on a SELECT statement!");
4013
} catch (SQLException sqlEx) {
4017
this.rs = commentStmt.executeQuery();
4019
assertEquals(1, this.rs.getInt(1));
4022
createTable("testBug28469", "(field1 INT)");
4024
String[] updatesToTest = {"-- COMMENT\nUPDATE testBug28469 SET field1 = 2",
4025
"# COMMENT\nUPDATE testBug28469 SET field1 = 2",
4026
"/* comment */ UPDATE testBug28469 SET field1 = 2"};
4028
for (int i = 0; i < updatesToTest.length; i++) {
4029
commentStmt = this.conn.prepareStatement(updatesToTest[i]);
4031
assertNull(commentStmt.getMetaData());
4034
commentStmt.executeQuery();
4035
fail("Should not be able to call executeQuery() on a SELECT statement!");
4036
} catch (SQLException sqlEx) {
4041
this.stmt.executeQuery(updatesToTest[i]);
4042
fail("Should not be able to call executeQuery() on a SELECT statement!");
4043
} catch (SQLException sqlEx) {
4048
closeMemberJDBCResources();
4050
if (commentStmt != null) {
4051
commentStmt.close();
4057
* Tests error with slash-star comment at EOL
4059
* @throws Exception if the test fails.
4061
public void testCommentParsing() throws Exception {
4062
createTable("PERSON", "(NAME VARCHAR(32), PERID VARCHAR(32))");
4065
this.pstmt = this.conn.prepareStatement("SELECT NAME AS name2749_0_, PERID AS perid2749_0_ FROM PERSON WHERE PERID=? /*FOR UPDATE*/");
4067
closeMemberJDBCResources();
4071
public void testBug28505() throws Exception {
4072
createTable("testBug28505", "(id int(10) PRIMARY KEY AUTO_INCREMENT NOT NULL, " +
4073
"name char(20) NOT NULL, " +
4074
"UNIQUE INDEX name (name))");
4076
for (int i = 0; i < 2; i++) {
4078
int changed = this.stmt.executeUpdate("INSERT INTO testBug28505 (id, name) " +
4079
"VALUES (NULL, 'test') ON DUPLICATE KEY UPDATE id = last_insert_id(id)");
4081
ResultSet keysResultSet = this.stmt.getGeneratedKeys();
4083
if (keysResultSet.next()) {
4084
assertEquals(keysResultSet.getInt(1), 1);
4086
// THIS IS THE INCORRECT BEHAVIOP * * * *
4087
System.out.println(" No generated keys returned by this.stmt.getGeneratedKeys()");
4089
keysResultSet.close();
4091
System.out.println(getSingleIndexedValueWithQuery(1, "SELECT LAST_INSERT_ID()"));
4097
* Tests fix for BUG#28851 - parser in client-side prepared statements
4098
* eats character following '/' if it's not a multi-line comment.
4100
* @throws Exception if the test fails.
4102
public void testBug28851() throws Exception {
4105
this.pstmt = ((com.mysql.jdbc.Connection) this.conn)
4106
.clientPrepareStatement("SELECT 1/?");
4107
this.pstmt.setInt(1, 1);
4108
this.rs = this.pstmt.executeQuery();
4110
assertTrue(this.rs.next());
4112
assertEquals(1, this.rs.getInt(1));
4114
closeMemberJDBCResources();
4119
* Tests fix for BUG#28596 - parser in client-side prepared statements
4120
* runs to end of statement, rather than end-of-line for '#' comments.
4122
* Also added support for '--' single-line comments
4124
* @throws Exception if the test fails.
4126
public void testBug28596() throws Exception {
4127
String query = "SELECT #\n" +
4134
this.pstmt = ((com.mysql.jdbc.Connection) this.conn)
4135
.clientPrepareStatement(query);
4136
this.pstmt.setInt(1, 1);
4137
this.pstmt.setInt(2, 2);
4138
this.pstmt.setInt(3, 3);
4140
assertEquals(3, this.pstmt.getParameterMetaData().getParameterCount());
4141
this.rs = this.pstmt.executeQuery();
4143
assertTrue(this.rs.next());
4145
assertEquals(1, this.rs.getInt(1));
4146
assertEquals(2, this.rs.getInt(2));
4147
assertEquals(3, this.rs.getInt(3));
4149
closeMemberJDBCResources();
b'\\ No newline at end of file'