| 1 25 package testsuite.regression; 26 27 import java.io.ByteArrayInputStream ; 28 import java.io.CharArrayReader ; 29 import java.io.File ; 30 import java.io.FileOutputStream ; 31 import java.io.FileWriter ; 32 import java.io.Writer ; 33 import java.math.BigDecimal ; 34 import java.sql.BatchUpdateException ; 35 import java.sql.Blob ; 36 import java.sql.Clob ; 37 import java.sql.Connection ; 38 import java.sql.DataTruncation ; 39 import java.sql.Date ; 40 import java.sql.PreparedStatement ; 41 import java.sql.ResultSet ; 42 import java.sql.SQLException ; 43 import java.sql.SQLWarning ; 44 import java.sql.Statement ; 45 import java.sql.Time ; 46 import java.sql.Timestamp ; 47 import java.sql.Types ; 48 import java.text.SimpleDateFormat ; 49 import java.util.Calendar ; 50 import java.util.Properties ; 51 import java.util.TimeZone ; 52 53 import testsuite.BaseTestCase; 54 55 import com.mysql.jdbc.SQLError; 56 import com.mysql.jdbc.ServerPreparedStatement; 57 58 63 public class StatementRegressionTest extends BaseTestCase { 64 class PrepareThread extends Thread { 65 Connection c; 66 67 PrepareThread(Connection cn) { 68 c = cn; 69 } 70 71 public void run() { 72 for (int i = 0; i < 20; i++) { 74 try { 75 c.prepareStatement("SELECT 1"); 76 testServerPrepStmtDeadlockCounter++; 77 Thread.sleep(400); 78 } catch (SQLException sqlEx) { 79 throw new RuntimeException (sqlEx); 80 } catch (InterruptedException e) { 81 e.printStackTrace(); 82 } 83 } 84 } 85 } 86 87 95 static final int[][] tests = { { 0 }, { 1, 0, 0 }, { 2, 0, 0, }, }; 99 100 static int nextID = 1; 102 static int count = 0; 103 104 private int testServerPrepStmtDeadlockCounter = 0; 105 106 112 public StatementRegressionTest(String name) { 113 super(name); 114 } 115 116 121 public static void main(String [] args) { 122 junit.textui.TestRunner.run(StatementRegressionTest.class); 123 } 124 125 131 public void testBug1774() throws Exception { 132 try { 133 this.stmt.executeUpdate("DROP TABLE IF EXISTS testBug1774"); 134 this.stmt 135 .executeUpdate("CREATE TABLE testBug1774 (field1 VARCHAR(255))"); 136 137 PreparedStatement pStmt = this.conn 138 .prepareStatement("INSERT INTO testBug1774 VALUES (?)"); 139 140 String testString = "The word contains \" character"; 141 142 pStmt.setString(1, testString); 143 pStmt.executeUpdate(); 144 145 this.rs = this.stmt.executeQuery("SELECT * FROM testBug1774"); 146 this.rs.next(); 147 assertTrue(this.rs.getString(1).equals(testString)); 148 } finally { 149 this.stmt.executeUpdate("DROP TABLE IF EXISTS testBug1774"); 150 } 151 } 152 153 160 public void testBug1901() throws Exception { 161 try { 162 this.stmt.executeUpdate("DROP TABLE IF EXISTS testBug1901"); 163 this.stmt 164 .executeUpdate("CREATE TABLE testBug1901 (field1 VARCHAR(255))"); 165 this.stmt.executeUpdate("INSERT INTO testBug1901 VALUES ('aaa')"); 166 167 this.rs = this.stmt.executeQuery("SELECT field1 FROM testBug1901"); 168 this.rs.next(); 169 170 Clob valueAsClob = this.rs.getClob(1); 171 Blob valueAsBlob = this.rs.getBlob(1); 172 173 PreparedStatement pStmt = this.conn 174 .prepareStatement("INSERT INTO testBug1901 VALUES (?)"); 175 pStmt.setObject(1, valueAsClob, java.sql.Types.CLOB, 0); 176 pStmt.executeUpdate(); 177 pStmt.setObject(1, valueAsBlob, java.sql.Types.BLOB, 0); 178 pStmt.executeUpdate(); 179 } finally { 180 this.stmt.executeUpdate("DROP TABLE IF EXISTS testBug1901"); 181 } 182 } 183 184 190 public void testBug1933() throws Exception { 191 if (versionMeetsMinimum(4, 0)) { 192 Connection maxRowsConn = null; 193 PreparedStatement maxRowsPrepStmt = null; 194 Statement maxRowsStmt = null; 195 196 try { 197 Properties props = new Properties (); 198 199 props.setProperty("maxRows", "1"); 200 201 maxRowsConn = getConnectionWithProps(props); 202 203 maxRowsStmt = maxRowsConn.createStatement(); 204 205 assertTrue(maxRowsStmt.getMaxRows() == 1); 206 207 this.rs = maxRowsStmt.executeQuery("SELECT 1 UNION SELECT 2"); 208 209 this.rs.next(); 210 211 maxRowsPrepStmt = maxRowsConn 212 .prepareStatement("SELECT 1 UNION SELECT 2"); 213 214 assertTrue(maxRowsPrepStmt.getMaxRows() == 1); 215 216 this.rs = maxRowsPrepStmt.executeQuery(); 217 218 this.rs.next(); 219 220 assertTrue(!this.rs.next()); 221 222 props.setProperty("useServerPrepStmts", "false"); 223 224 maxRowsConn = getConnectionWithProps(props); 225 226 maxRowsPrepStmt = maxRowsConn 227 .prepareStatement("SELECT 1 UNION SELECT 2"); 228 229 assertTrue(maxRowsPrepStmt.getMaxRows() == 1); 230 231 this.rs = maxRowsPrepStmt.executeQuery(); 232 233 this.rs.next(); 234 235 assertTrue(!this.rs.next()); 236 } finally { 237 maxRowsConn.close(); 238 } 239 } 240 } 241 242 249 public void testBug1934() throws Exception { 250 try { 251 this.stmt.executeUpdate("DROP TABLE IF EXISTS testBug1934"); 252 this.stmt.executeUpdate("CREATE TABLE testBug1934 (field1 INT)"); 253 254 System.out.println("Before prepareStatement()"); 255 256 this.pstmt = this.conn.prepareStatement( 257 "INSERT INTO testBug1934 VALUES (?)", 258 java.sql.Statement.RETURN_GENERATED_KEYS); 259 260 assertTrue(this.pstmt != null); 261 262 System.out.println("After prepareStatement() - " + this.pstmt); 263 } finally { 264 this.stmt.executeUpdate("DROP TABLE IF EXISTS testBug1934"); 265 } 266 } 267 268 275 public void testBug1958() throws Exception { 276 PreparedStatement pStmt = null; 277 278 try { 279 this.stmt.executeUpdate("DROP TABLE IF EXISTS testBug1958"); 280 this.stmt.executeUpdate("CREATE TABLE testBug1958 (field1 int)"); 281 282 pStmt = this.conn 283 .prepareStatement("SELECT * FROM testBug1958 WHERE field1 IN (?, ?, ?)"); 284 285 try { 286 pStmt.setInt(4, 1); 287 } catch (SQLException sqlEx) { 288 assertTrue(SQLError.SQL_STATE_ILLEGAL_ARGUMENT.equals(sqlEx 289 .getSQLState())); 290 } 291 } finally { 292 if (pStmt != null) { 293 pStmt.close(); 294 } 295 296 this.stmt.executeUpdate("DROP TABLE IF EXISTS testBug1958"); 297 } 298 } 299 300 307 public void testBug2606() throws Exception { 308 try { 309 this.stmt.executeUpdate("DROP TABLE IF EXISTS testBug2606"); 310 this.stmt 311 .executeUpdate("CREATE TABLE testBug2606(year_field YEAR)"); 312 this.stmt.executeUpdate("INSERT INTO testBug2606 VALUES (2004)"); 313 314 PreparedStatement yrPstmt = this.conn 315 .prepareStatement("SELECT year_field FROM testBug2606"); 316 317 this.rs = yrPstmt.executeQuery(); 318 319 assertTrue(this.rs.next()); 320 321 assertEquals(2004, this.rs.getInt(1)); 322 } finally { 323 this.stmt.executeUpdate("DROP TABLE IF EXISTS testBug2606"); 324 } 325 } 326 327 334 public void testBug2671() throws Exception { 335 if (versionMeetsMinimum(4, 1)) { 336 try { 337 this.stmt.executeUpdate("DROP TABLE IF EXISTS test3"); 338 this.stmt 339 .executeUpdate("CREATE TABLE test3 (" 340 + " `field1` int(8) NOT NULL auto_increment," 341 + " `field2` int(8) unsigned zerofill default NULL," 342 + " `field3` varchar(30) binary NOT NULL default ''," 343 + " `field4` varchar(100) default NULL," 344 + " `field5` datetime NOT NULL default '0000-00-00 00:00:00'," 345 + " PRIMARY KEY (`field1`)," 346 + " UNIQUE KEY `unq_id` (`field2`)," 347 + " UNIQUE KEY (`field3`)," 348 + " UNIQUE KEY (`field2`)" 349 + " ) TYPE=InnoDB CHARACTER SET utf8"); 350 351 this.stmt 352 .executeUpdate("insert into test3 (field1, field3, field4) values (1,'blewis','Bob Lewis')"); 353 354 String query = " " + "UPDATE " 355 + " test3 " 356 + "SET " 357 + " field2=? " + " ,field3=? " 358 + " ,field4=? " + " ,field5=? " 359 + "WHERE " 360 + " field1 = ? "; 361 362 java.sql.Date mydate = null; 363 364 this.pstmt = this.conn.prepareStatement(query); 365 366 this.pstmt.setInt(1, 13); 367 this.pstmt.setString(2, "abc"); 368 this.pstmt.setString(3, "def"); 369 this.pstmt.setDate(4, mydate); 370 this.pstmt.setInt(5, 1); 371 372 int retval = this.pstmt.executeUpdate(); 373 assertTrue(retval == 1); 374 } finally { 375 this.stmt.executeUpdate("DROP TABLE IF EXISTS test3"); 376 } 377 } 378 } 379 380 389 public void testBug3103() throws Exception { 390 try { 391 this.stmt.executeUpdate("DROP TABLE IF EXISTS testBug3103"); 392 this.stmt 393 .executeUpdate("CREATE TABLE testBug3103 (field1 DATETIME)"); 394 395 PreparedStatement pStmt = this.conn 396 .prepareStatement("INSERT INTO testBug3103 VALUES (?)"); 397 398 java.util.Date utilDate = new java.util.Date (); 399 400 pStmt.setObject(1, utilDate); 401 pStmt.executeUpdate(); 402 403 this.rs = this.stmt.executeQuery("SELECT field1 FROM testBug3103"); 404 this.rs.next(); 405 406 java.util.Date retrUtilDate = new java.util.Date (this.rs 407 .getTimestamp(1).getTime()); 408 409 assertTrue("Dates not equal", (utilDate.getMonth() == retrUtilDate 413 .getMonth()) 414 && (utilDate.getDate() == retrUtilDate.getDate()) 415 && (utilDate.getYear() == retrUtilDate.getYear()) 416 && (utilDate.getHours() == retrUtilDate.getHours()) 417 && (utilDate.getMinutes() == retrUtilDate.getMinutes()) 418 && (utilDate.getSeconds() == retrUtilDate.getSeconds())); 419 } finally { 420 this.stmt.executeUpdate("DROP TABLE IF EXISTS testBug3103"); 421 } 422 } 423 424 430 public void testBug3520() throws Exception { 431 try { 432 this.stmt.executeUpdate("DROP TABLE IF EXISTS t"); 433 this.stmt.executeUpdate("CREATE TABLE t (s1 int,primary key (s1))"); 434 this.stmt.executeUpdate("INSERT INTO t VALUES (1)"); 435 this.stmt.executeUpdate("INSERT INTO t VALUES (1)"); 436 } catch (SQLException sqlEx) { 437 System.out.println(sqlEx.getSQLState()); 438 } finally { 439 this.stmt.executeUpdate("DROP TABLE IF EXISTS t"); 440 } 441 } 442 443 449 public void testBug3557() throws Exception { 450 try { 451 this.stmt.executeUpdate("DROP TABLE IF EXISTS testBug3557"); 452 453 this.stmt.executeUpdate("CREATE TABLE testBug3557 ( " 454 + "`a` varchar(255) NOT NULL default 'XYZ', " 455 + "`b` varchar(255) default '123', " 456 + "PRIMARY KEY (`a`))"); 457 458 Statement updStmt = this.conn 459 .createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, 460 ResultSet.CONCUR_UPDATABLE); 461 this.rs = updStmt.executeQuery("SELECT * FROM testBug3557"); 462 463 assertTrue(this.rs.getConcurrency() == ResultSet.CONCUR_UPDATABLE); 464 465 this.rs.moveToInsertRow(); 466 467 assertEquals("XYZ", this.rs.getObject(1)); 468 assertEquals("123", this.rs.getObject(2)); 469 } finally { 470 this.stmt.executeUpdate("DROP TABLE IF EXISTS testBug3557"); 471 } 472 } 473 474 480 public void testBug3620() throws SQLException { 481 long epsillon = 3000; 483 try { 484 this.stmt.executeUpdate("DROP TABLE IF EXISTS testBug3620"); 485 this.stmt 486 .executeUpdate("CREATE TABLE testBug3620 (field1 TIMESTAMP)"); 487 488 PreparedStatement tsPstmt = this.conn 489 .prepareStatement("INSERT INTO testBug3620 VALUES (?)"); 490 491 Calendar pointInTime = Calendar.getInstance(); 492 pointInTime.set(2004, 02, 29, 10, 0, 0); 493 494 long pointInTimeOffset = pointInTime.getTimeZone().getRawOffset(); 495 496 java.sql.Timestamp ts = new java.sql.Timestamp (pointInTime 497 .getTime().getTime()); 498 499 tsPstmt.setTimestamp(1, ts); 500 tsPstmt.executeUpdate(); 501 502 String tsValueAsString = getSingleValue("testBug3620", "field1", 503 null).toString(); 504 505 System.out.println("Timestamp as string with no calendar: " 506 + tsValueAsString.toString()); 507 508 Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC")); 509 510 this.stmt.executeUpdate("DELETE FROM testBug3620"); 511 512 Properties props = new Properties (); 513 props.put("useTimezone", "true"); 514 516 Connection tzConn = getConnectionWithProps(props); 517 518 Statement tsStmt = tzConn.createStatement(); 519 520 tsPstmt = tzConn 521 .prepareStatement("INSERT INTO testBug3620 VALUES (?)"); 522 523 tsPstmt.setTimestamp(1, ts, cal); 524 tsPstmt.executeUpdate(); 525 526 tsValueAsString = getSingleValue("testBug3620", "field1", null) 527 .toString(); 528 529 Timestamp tsValueAsTimestamp = (Timestamp ) getSingleValue( 530 "testBug3620", "field1", null); 531 532 System.out.println("Timestamp as string with UTC calendar: " 533 + tsValueAsString.toString()); 534 System.out.println("Timestamp as Timestamp with UTC calendar: " 535 + tsValueAsTimestamp); 536 537 this.rs = tsStmt.executeQuery("SELECT field1 FROM testBug3620"); 538 this.rs.next(); 539 540 Timestamp tsValueUTC = this.rs.getTimestamp(1, cal); 541 542 this.rs = tsStmt.executeQuery("SELECT field1 FROM testBug3620"); 548 this.rs.next(); 549 550 Timestamp tsValueStmtNoCal = this.rs.getTimestamp(1); 551 552 System.out 553 .println("Timestamp specifying UTC calendar from normal statement: " 554 + tsValueUTC.toString()); 555 556 PreparedStatement tsPstmtRetr = tzConn 557 .prepareStatement("SELECT field1 FROM testBug3620"); 558 559 this.rs = tsPstmtRetr.executeQuery(); 560 this.rs.next(); 561 562 Timestamp tsValuePstmtUTC = this.rs.getTimestamp(1, cal); 563 564 System.out 565 .println("Timestamp specifying UTC calendar from prepared statement: " 566 + tsValuePstmtUTC.toString()); 567 568 this.rs = tsPstmtRetr.executeQuery(); 574 this.rs.next(); 575 576 Timestamp tsValuePstmtNoCal = this.rs.getTimestamp(1); 577 578 System.out 579 .println("Timestamp specifying no calendar from prepared statement: " 580 + tsValuePstmtNoCal.toString()); 581 582 long stmtDeltaTWithCal = (ts.getTime() - tsValueStmtNoCal.getTime()); 583 584 long deltaOrig = Math.abs(stmtDeltaTWithCal - pointInTimeOffset); 585 586 assertTrue( 587 "Difference between original timestamp and timestamp retrieved using java.sql.Statement " 588 + "set in database using UTC calendar is not ~= " 589 + epsillon + ", it is actually " + deltaOrig, 590 (deltaOrig < epsillon)); 591 592 long pStmtDeltaTWithCal = (ts.getTime() - tsValuePstmtNoCal 593 .getTime()); 594 595 System.out 596 .println(Math.abs(pStmtDeltaTWithCal - pointInTimeOffset) 597 + " < " 598 + epsillon 599 + (Math.abs(pStmtDeltaTWithCal - pointInTimeOffset) < epsillon)); 600 assertTrue( 601 "Difference between original timestamp and timestamp retrieved using java.sql.PreparedStatement " 602 + "set in database using UTC calendar is not ~= " 603 + epsillon 604 + ", it is actually " 605 + pStmtDeltaTWithCal, (Math.abs(pStmtDeltaTWithCal 606 - pointInTimeOffset) < epsillon)); 607 608 System.out 609 .println("Difference between original ts and ts with no calendar: " 610 + (ts.getTime() - tsValuePstmtNoCal.getTime()) 611 + ", offset should be " + pointInTimeOffset); 612 } finally { 613 this.stmt.executeUpdate("DROP TABLE IF EXISTS testBug3620"); 614 } 615 } 616 617 623 public void testBug3697() throws Exception { 624 try { 625 this.stmt.executeUpdate("DROP TABLE IF EXISTS testBug3697"); 626 this.stmt 627 .executeUpdate("CREATE TABLE testBug3697 (field1 VARCHAR(255))"); 628 629 StringBuffer updateBuf = new StringBuffer ( 630 "INSERT INTO testBug3697 VALUES ('"); 631 632 for (int i = 0; i < 512; i++) { 633 updateBuf.append("A"); 634 } 635 636 updateBuf.append("')"); 637 638 try { 639 this.stmt.executeUpdate(updateBuf.toString()); 640 } catch (DataTruncation dtEx) { 641 } 643 644 SQLWarning warningChain = this.stmt.getWarnings(); 645 646 System.out.println(warningChain); 647 } finally { 648 this.stmt.executeUpdate("DROP TABLE IF EXISTS testBug3697"); 649 } 650 } 651 652 659 public void testBug3804() throws Exception { 660 if (versionMeetsMinimum(4, 1)) { 661 try { 662 this.stmt.executeUpdate("DROP TABLE IF EXISTS testBug3804"); 663 this.stmt 664 .executeUpdate("CREATE TABLE testBug3804 (field1 VARCHAR(5))"); 665 666 boolean caughtTruncation = false; 667 668 try { 669 this.stmt 670 .executeUpdate("INSERT INTO testBug3804 VALUES ('1234567')"); 671 } catch (DataTruncation truncationEx) { 672 caughtTruncation = true; 673 System.out.println(truncationEx); 674 } 675 676 assertTrue("Data truncation exception should've been thrown", 677 caughtTruncation); 678 } finally { 679 this.stmt.executeUpdate("DROP TABLE IF EXISTS testBug3804"); 680 } 681 } 682 } 683 684 691 public void testBug3873() throws Exception { 692 PreparedStatement batchStmt = null; 693 694 try { 695 this.stmt.executeUpdate("DROP TABLE IF EXISTS testBug3873"); 696 this.stmt 697 .executeUpdate("CREATE TABLE testBug3873 (keyField INT NOT NULL PRIMARY KEY AUTO_INCREMENT, dataField VARCHAR(32))"); 698 batchStmt = this.conn.prepareStatement( 699 "INSERT INTO testBug3873 (dataField) VALUES (?)", 700 Statement.RETURN_GENERATED_KEYS); 701 batchStmt.setString(1, "abc"); 702 batchStmt.addBatch(); 703 batchStmt.setString(1, "def"); 704 batchStmt.addBatch(); 705 batchStmt.setString(1, "ghi"); 706 batchStmt.addBatch(); 707 708 int[] updateCounts = batchStmt.executeBatch(); 709 710 this.rs = batchStmt.getGeneratedKeys(); 711 712 while (this.rs.next()) { 713 System.out.println(this.rs.getInt(1)); 714 } 715 716 this.rs = batchStmt.getGeneratedKeys(); 717 assertTrue(this.rs.next()); 718 assertTrue(1 == this.rs.getInt(1)); 719 assertTrue(this.rs.next()); 720 assertTrue(2 == this.rs.getInt(1)); 721 assertTrue(this.rs.next()); 722 assertTrue(3 == this.rs.getInt(1)); 723 assertTrue(!this.rs.next()); 724 } finally { 725 if (batchStmt != null) { 726 batchStmt.close(); 727 } 728 729 this.stmt.executeUpdate("DROP TABLE IF EXISTS testBug3873"); 730 } 731 } 732 733 739 public void testCloseTwice() throws Exception { 740 Statement closeMe = this.conn.createStatement(); 741 closeMe.close(); 742 closeMe.close(); 743 } 744 745 751 public void testGetGeneratedKeysAllCases() throws Exception { 752 System.out.println("Using Statement.executeUpdate()\n"); 753 754 try { 755 createGGKTables(); 756 757 for (int i = 0; i < tests.length; i++) { 759 doGGKTestStatement(tests[i], true); 760 } 761 } finally { 762 dropGGKTables(); 763 } 764 765 nextID = 1; 766 count = 0; 767 768 System.out.println("Using Statement.execute()\n"); 769 770 try { 771 createGGKTables(); 772 773 for (int i = 0; i < tests.length; i++) { 775 doGGKTestStatement(tests[i], false); 776 } 777 } finally { 778 dropGGKTables(); 779 } 780 781 nextID = 1; 782 count = 0; 783 784 System.out.println("Using PreparedStatement.executeUpdate()\n"); 785 786 try { 787 createGGKTables(); 788 789 for (int i = 0; i < tests.length; i++) { 791 doGGKTestPreparedStatement(tests[i], true); 792 } 793 } finally { 794 dropGGKTables(); 795
|