|
16 | 16 | import java.sql.Statement; |
17 | 17 | import java.sql.Timestamp; |
18 | 18 | import java.sql.Types; |
| 19 | +import java.util.UUID; |
19 | 20 | import java.util.Arrays; |
20 | 21 | import java.util.Properties; |
21 | 22 | import java.util.TimeZone; |
@@ -431,6 +432,73 @@ public void testAllPreparedStatement() throws SQLException { |
431 | 432 | } |
432 | 433 | } |
433 | 434 |
|
| 435 | + @Test(groups = "IT") |
| 436 | + public void TestStageFileRemovedAfterBatchInsert() throws SQLException { |
| 437 | + String dbName = ("stage_cleanup_" + UUID.randomUUID()).replace("-", ""); |
| 438 | + try (Connection c = Utils.createConnection(); |
| 439 | + Statement s = c.createStatement()) { |
| 440 | + c.setAutoCommit(false); |
| 441 | + s.execute("create or replace database " + dbName); |
| 442 | + s.execute("use " + dbName); |
| 443 | + s.execute("create or replace table t_stage_cleanup(a int, b string)"); |
| 444 | + |
| 445 | + try (TrackingPreparedStatement ps = new TrackingPreparedStatement((DatabendConnection) c, "insert into t_stage_cleanup values")) { |
| 446 | + ps.setInt(1, 1); |
| 447 | + ps.setString(2, "hello"); |
| 448 | + ps.addBatch(); |
| 449 | + int[] counts = ps.executeBatch(); |
| 450 | + Assert.assertEquals(counts, new int[] {1}); |
| 451 | + |
| 452 | + String location = ps.getLastAttachmentLocation(); |
| 453 | + Assert.assertNotNull(location); |
| 454 | + System.out.println("[DEBUG] uploaded stage file: " + location); |
| 455 | + String dir = location.substring(0, location.lastIndexOf('/') + 1); |
| 456 | + System.out.println("location dir is:"+dir); |
| 457 | + try (ResultSet rs = s.executeQuery("LIST " + dir)) { |
| 458 | + if (rs.next()) { |
| 459 | + Assert.fail("Stage directory not empty after batch insert, unexpected entry: " + rs.getString(1)); |
| 460 | + } |
| 461 | + } catch (SQLException e) { |
| 462 | + if (e.getErrorCode() != 1003) { |
| 463 | + throw e; |
| 464 | + } |
| 465 | + } finally { |
| 466 | + try { |
| 467 | + System.out.println("[DEBUG] drop stage path: " + location); |
| 468 | + s.execute("REMOVE " + location); |
| 469 | + } catch (SQLException ignore) { |
| 470 | + // best-effort cleanup |
| 471 | + } |
| 472 | + } |
| 473 | + |
| 474 | + try (ResultSet rs = s.executeQuery("SELECT a, b FROM t_stage_cleanup")) { |
| 475 | + Assert.assertTrue(rs.next()); |
| 476 | + Assert.assertEquals(rs.getInt(1), 1); |
| 477 | + Assert.assertEquals(rs.getString(2), "hello"); |
| 478 | + Assert.assertFalse(rs.next()); |
| 479 | + } |
| 480 | + } |
| 481 | + } |
| 482 | + } |
| 483 | + |
| 484 | + private static final class TrackingPreparedStatement extends DatabendPreparedStatement { |
| 485 | + private StageAttachment lastAttachment; |
| 486 | + |
| 487 | + TrackingPreparedStatement(DatabendConnection connection, String sql) throws SQLException { |
| 488 | + super(connection, stmt -> {}, sql); |
| 489 | + } |
| 490 | + |
| 491 | + @Override |
| 492 | + boolean dropStageAttachment(StageAttachment attachment) { |
| 493 | + lastAttachment = attachment; |
| 494 | + return super.dropStageAttachment(attachment); |
| 495 | + } |
| 496 | + |
| 497 | + String getLastAttachmentLocation() { |
| 498 | + return lastAttachment == null ? null : lastAttachment.getLocation(); |
| 499 | + } |
| 500 | + } |
| 501 | + |
434 | 502 | @Test(groups = "IT") |
435 | 503 | public void shouldBuildStageAttachmentWithFileFormatOptions() throws SQLException { |
436 | 504 | Connection conn = Utils.createConnection(); |
|
0 commit comments