|
54 | 54 | import org.apache.iceberg.FileScanTask; |
55 | 55 | import org.apache.iceberg.PartitionSpec; |
56 | 56 | import org.apache.iceberg.Schema; |
| 57 | +import org.apache.iceberg.Snapshot; |
57 | 58 | import org.apache.iceberg.Table; |
58 | 59 | import org.apache.iceberg.TableMetadata; |
59 | 60 | import org.apache.iceberg.TableOperations; |
|
115 | 116 | import static com.facebook.presto.tests.sql.TestTable.randomTableSuffix; |
116 | 117 | import static java.lang.String.format; |
117 | 118 | import static java.util.Objects.requireNonNull; |
| 119 | +import static org.apache.iceberg.SnapshotSummary.TOTAL_DATA_FILES_PROP; |
| 120 | +import static org.apache.iceberg.SnapshotSummary.TOTAL_DELETE_FILES_PROP; |
118 | 121 | import static org.testng.Assert.assertNotEquals; |
119 | 122 | import static org.testng.Assert.assertTrue; |
120 | 123 |
|
@@ -460,6 +463,35 @@ public void testTruncate() |
460 | 463 | assertUpdate("DROP TABLE test_truncate"); |
461 | 464 | } |
462 | 465 |
|
| 466 | + @Test |
| 467 | + public void testTruncateTableWithDeleteFiles() |
| 468 | + { |
| 469 | + String tableName = "test_v2_row_delete_" + randomTableSuffix(); |
| 470 | + try { |
| 471 | + assertUpdate("CREATE TABLE " + tableName + "(a int, b varchar) WITH (format_version = '2', delete_mode = 'merge-on-read')"); |
| 472 | + assertUpdate("INSERT INTO " + tableName + " VALUES (1, '1001'), (2, '1002'), (3, '1003')", 3); |
| 473 | + |
| 474 | + // execute row level deletion |
| 475 | + assertUpdate("DELETE FROM " + tableName + " WHERE b in ('1002', '1003')", 2); |
| 476 | + assertQuery("SELECT * FROM " + tableName, "VALUES (1, '1001')"); |
| 477 | + |
| 478 | + Table icebergTable = loadTable(tableName); |
| 479 | + assertHasDataFiles(icebergTable.currentSnapshot(), 1); |
| 480 | + assertHasDeleteFiles(icebergTable.currentSnapshot(), 1); |
| 481 | + |
| 482 | + // execute truncate table |
| 483 | + assertUpdate("TRUNCATE TABLE " + tableName); |
| 484 | + assertQuery("SELECT count(*) FROM " + tableName, "VALUES 0"); |
| 485 | + |
| 486 | + icebergTable = loadTable(tableName); |
| 487 | + assertHasDataFiles(icebergTable.currentSnapshot(), 0); |
| 488 | + assertHasDeleteFiles(icebergTable.currentSnapshot(), 0); |
| 489 | + } |
| 490 | + finally { |
| 491 | + assertUpdate("DROP TABLE IF EXISTS " + tableName); |
| 492 | + } |
| 493 | + } |
| 494 | + |
463 | 495 | @Override |
464 | 496 | public void testShowColumns() |
465 | 497 | { |
@@ -1308,6 +1340,72 @@ public void testPartShowStatsWithFilters() |
1308 | 1340 | assertQuerySucceeds("DROP TABLE showstatsfilters"); |
1309 | 1341 | } |
1310 | 1342 |
|
| 1343 | + @Test |
| 1344 | + public void testMetadataDeleteOnUnPartitionedTableWithDeleteFiles() |
| 1345 | + { |
| 1346 | + String tableName = "test_v2_row_delete_" + randomTableSuffix(); |
| 1347 | + try { |
| 1348 | + assertUpdate("CREATE TABLE " + tableName + "(a int, b varchar) WITH (format_version = '2', delete_mode = 'merge-on-read')"); |
| 1349 | + assertUpdate("INSERT INTO " + tableName + " VALUES (1, '1001'), (2, '1002'), (3, '1003')", 3); |
| 1350 | + |
| 1351 | + // execute row level deletion |
| 1352 | + assertUpdate("DELETE FROM " + tableName + " WHERE b in ('1002', '1003')", 2); |
| 1353 | + assertQuery("SELECT * FROM " + tableName, "VALUES (1, '1001')"); |
| 1354 | + |
| 1355 | + Table icebergTable = loadTable(tableName); |
| 1356 | + assertHasDataFiles(icebergTable.currentSnapshot(), 1); |
| 1357 | + assertHasDeleteFiles(icebergTable.currentSnapshot(), 1); |
| 1358 | + |
| 1359 | + // execute whole table metadata deletion |
| 1360 | + assertUpdate("DELETE FROM " + tableName, 1); |
| 1361 | + assertQuery("SELECT count(*) FROM " + tableName, "VALUES 0"); |
| 1362 | + |
| 1363 | + icebergTable = loadTable(tableName); |
| 1364 | + assertHasDataFiles(icebergTable.currentSnapshot(), 0); |
| 1365 | + assertHasDeleteFiles(icebergTable.currentSnapshot(), 0); |
| 1366 | + } |
| 1367 | + finally { |
| 1368 | + assertUpdate("DROP TABLE IF EXISTS " + tableName); |
| 1369 | + } |
| 1370 | + } |
| 1371 | + |
| 1372 | + @Test |
| 1373 | + public void testMetadataDeleteOnPartitionedTableWithDeleteFiles() |
| 1374 | + { |
| 1375 | + String tableName = "test_v2_row_delete_" + randomTableSuffix(); |
| 1376 | + try { |
| 1377 | + assertUpdate("CREATE TABLE " + tableName + "(a int, b varchar) WITH (format_version = '2', delete_mode = 'merge-on-read', partitioning = ARRAY['a'])"); |
| 1378 | + assertUpdate("INSERT INTO " + tableName + " VALUES (1, '1001'), (2, '1002'), (3, '1003')", 3); |
| 1379 | + |
| 1380 | + // execute row level deletion |
| 1381 | + assertUpdate("DELETE FROM " + tableName + " WHERE b in ('1002', '1003')", 2); |
| 1382 | + assertQuery("SELECT * FROM " + tableName, "VALUES (1, '1001')"); |
| 1383 | + |
| 1384 | + Table icebergTable = loadTable(tableName); |
| 1385 | + assertHasDataFiles(icebergTable.currentSnapshot(), 3); |
| 1386 | + assertHasDeleteFiles(icebergTable.currentSnapshot(), 2); |
| 1387 | + |
| 1388 | + // execute metadata deletion with filter |
| 1389 | + assertUpdate("DELETE FROM " + tableName + " WHERE a in (2, 3)", 0); |
| 1390 | + assertQuery("SELECT * FROM " + tableName, "VALUES (1, '1001')"); |
| 1391 | + |
| 1392 | + icebergTable = loadTable(tableName); |
| 1393 | + assertHasDataFiles(icebergTable.currentSnapshot(), 1); |
| 1394 | + assertHasDeleteFiles(icebergTable.currentSnapshot(), 0); |
| 1395 | + |
| 1396 | + // execute whole table metadata deletion |
| 1397 | + assertUpdate("DELETE FROM " + tableName, 1); |
| 1398 | + assertQuery("SELECT count(*) FROM " + tableName, "VALUES 0"); |
| 1399 | + |
| 1400 | + icebergTable = loadTable(tableName); |
| 1401 | + assertHasDataFiles(icebergTable.currentSnapshot(), 0); |
| 1402 | + assertHasDeleteFiles(icebergTable.currentSnapshot(), 0); |
| 1403 | + } |
| 1404 | + finally { |
| 1405 | + assertUpdate("DROP TABLE IF EXISTS " + tableName); |
| 1406 | + } |
| 1407 | + } |
| 1408 | + |
1311 | 1409 | private void testCheckDeleteFiles(Table icebergTable, int expectedSize, List<FileContent> expectedFileContent) |
1312 | 1410 | { |
1313 | 1411 | // check delete file list |
@@ -1450,4 +1548,18 @@ private void testWithAllFileFormats(Session session, BiConsumer<Session, FileFor |
1450 | 1548 | test.accept(session, FileFormat.PARQUET); |
1451 | 1549 | test.accept(session, FileFormat.ORC); |
1452 | 1550 | } |
| 1551 | + |
| 1552 | + private void assertHasDataFiles(Snapshot snapshot, int dataFilesCount) |
| 1553 | + { |
| 1554 | + Map<String, String> map = snapshot.summary(); |
| 1555 | + int totalDataFiles = Integer.valueOf(map.get(TOTAL_DATA_FILES_PROP)); |
| 1556 | + assertEquals(totalDataFiles, dataFilesCount); |
| 1557 | + } |
| 1558 | + |
| 1559 | + private void assertHasDeleteFiles(Snapshot snapshot, int deleteFilesCount) |
| 1560 | + { |
| 1561 | + Map<String, String> map = snapshot.summary(); |
| 1562 | + int totalDeleteFiles = Integer.valueOf(map.get(TOTAL_DELETE_FILES_PROP)); |
| 1563 | + assertEquals(totalDeleteFiles, deleteFilesCount); |
| 1564 | + } |
1453 | 1565 | } |
0 commit comments