|
41 | 41 | from pyiceberg.table.metadata import INITIAL_SPEC_ID |
42 | 42 | from pyiceberg.table.sorting import INITIAL_SORT_ORDER_ID, SortField, SortOrder |
43 | 43 | from pyiceberg.transforms import BucketTransform, DayTransform, IdentityTransform |
| 44 | +from pyiceberg.typedef import Identifier |
44 | 45 | from pyiceberg.types import IntegerType, LongType, NestedField, TimestampType, UUIDType |
45 | 46 | from tests.conftest import clean_up |
46 | 47 |
|
@@ -635,3 +636,136 @@ def test_rest_custom_namespace_separator(rest_catalog: RestCatalog, table_schema |
635 | 636 |
|
636 | 637 | loaded_table = rest_catalog.load_table(identifier=full_table_identifier_tuple) |
637 | 638 | assert loaded_table.name() == full_table_identifier_tuple |
| 639 | + |
| 640 | +def _namespace_exists(catalog: Catalog, namespace: str | Identifier) -> bool: |
| 641 | + try: |
| 642 | + catalog.load_namespace_properties(namespace) |
| 643 | + return True |
| 644 | + except NoSuchNamespaceError: |
| 645 | + return False |
| 646 | + |
| 647 | + |
| 648 | +@pytest.mark.integration |
| 649 | +@pytest.mark.parametrize("test_catalog", CATALOGS) |
| 650 | +def test_namespace_with_slash(test_catalog: Catalog) -> None: |
| 651 | + if isinstance(test_catalog, (HiveCatalog, SqlCatalog, RestCatalog)): |
| 652 | + pytest.skip(f"{type(test_catalog).__name__} does not support slash in namespace") |
| 653 | + |
| 654 | + namespace = ("new/db",) |
| 655 | + |
| 656 | + if _namespace_exists(test_catalog, namespace): |
| 657 | + test_catalog.drop_namespace(namespace) |
| 658 | + |
| 659 | + assert not _namespace_exists(test_catalog, namespace) |
| 660 | + |
| 661 | + test_catalog.create_namespace(namespace) |
| 662 | + assert _namespace_exists(test_catalog, namespace) |
| 663 | + |
| 664 | + properties = test_catalog.load_namespace_properties(namespace) |
| 665 | + assert properties is not None |
| 666 | + |
| 667 | + test_catalog.drop_namespace(namespace) |
| 668 | + assert not _namespace_exists(test_catalog, namespace) |
| 669 | + |
| 670 | + |
| 671 | +@pytest.mark.integration |
| 672 | +@pytest.mark.parametrize("test_catalog", CATALOGS) |
| 673 | +def test_namespace_with_dot(test_catalog: Catalog) -> None: |
| 674 | + if isinstance(test_catalog, (HiveCatalog, SqlCatalog, RestCatalog)): |
| 675 | + pytest.skip(f"{type(test_catalog).__name__} does not support dot in namespace") |
| 676 | + |
| 677 | + namespace = ("new.db",) |
| 678 | + |
| 679 | + if _namespace_exists(test_catalog, namespace): |
| 680 | + test_catalog.drop_namespace(namespace) |
| 681 | + |
| 682 | + assert not _namespace_exists(test_catalog, namespace) |
| 683 | + |
| 684 | + test_catalog.create_namespace(namespace) |
| 685 | + assert _namespace_exists(test_catalog, namespace) |
| 686 | + |
| 687 | + # list_namespaces returns a list of tuples |
| 688 | + assert namespace in test_catalog.list_namespaces() |
| 689 | + |
| 690 | + properties = test_catalog.load_namespace_properties(namespace) |
| 691 | + assert properties is not None |
| 692 | + |
| 693 | + test_catalog.drop_namespace(namespace) |
| 694 | + assert not _namespace_exists(test_catalog, namespace) |
| 695 | + |
| 696 | + |
| 697 | +@pytest.mark.integration |
| 698 | +@pytest.mark.parametrize("test_catalog", CATALOGS) |
| 699 | +def test_table_name_with_slash(test_catalog: Catalog, table_schema_simple: Schema) -> None: |
| 700 | + if isinstance(test_catalog, (HiveCatalog, SqlCatalog, RestCatalog)): |
| 701 | + pytest.skip(f"{type(test_catalog).__name__} does not support slash in table name") |
| 702 | + |
| 703 | + namespace = ("ns_slash",) |
| 704 | + table_ident = ("ns_slash", "tab/le") |
| 705 | + |
| 706 | + if not _namespace_exists(test_catalog, namespace): |
| 707 | + test_catalog.create_namespace(namespace) |
| 708 | + |
| 709 | + if test_catalog.table_exists(table_ident): |
| 710 | + test_catalog.drop_table(table_ident) |
| 711 | + |
| 712 | + assert not test_catalog.table_exists(table_ident) |
| 713 | + |
| 714 | + test_catalog.create_table(table_ident, table_schema_simple) |
| 715 | + assert test_catalog.table_exists(table_ident) |
| 716 | + |
| 717 | + table = test_catalog.load_table(table_ident) |
| 718 | + assert table.schema().as_struct() == table_schema_simple.as_struct() |
| 719 | + |
| 720 | + test_catalog.drop_table(table_ident) |
| 721 | + assert not test_catalog.table_exists(table_ident) |
| 722 | + |
| 723 | + |
| 724 | +@pytest.mark.integration |
| 725 | +@pytest.mark.parametrize("test_catalog", CATALOGS) |
| 726 | +def test_table_name_with_dot(test_catalog: Catalog, table_schema_simple: Schema) -> None: |
| 727 | + if isinstance(test_catalog, (HiveCatalog, SqlCatalog, RestCatalog)): |
| 728 | + pytest.skip(f"{type(test_catalog).__name__} does not support dot in table name") |
| 729 | + |
| 730 | + namespace = ("ns_dot",) |
| 731 | + table_ident = ("ns_dot", "ta.ble") |
| 732 | + |
| 733 | + if not _namespace_exists(test_catalog, namespace): |
| 734 | + test_catalog.create_namespace(namespace) |
| 735 | + |
| 736 | + if test_catalog.table_exists(table_ident): |
| 737 | + test_catalog.drop_table(table_ident) |
| 738 | + |
| 739 | + assert not test_catalog.table_exists(table_ident) |
| 740 | + |
| 741 | + test_catalog.create_table(table_ident, table_schema_simple) |
| 742 | + assert test_catalog.table_exists(table_ident) |
| 743 | + |
| 744 | + assert table_ident in test_catalog.list_tables(namespace) |
| 745 | + |
| 746 | + table = test_catalog.load_table(table_ident) |
| 747 | + assert table.schema().as_struct() == table_schema_simple.as_struct() |
| 748 | + |
| 749 | + test_catalog.drop_table(table_ident) |
| 750 | + assert not test_catalog.table_exists(table_ident) |
| 751 | + |
| 752 | + |
| 753 | +@pytest.mark.integration |
| 754 | +@pytest.mark.parametrize("test_catalog", CATALOGS) |
| 755 | +def test_drop_missing_table(test_catalog: Catalog, database_name: str) -> None: |
| 756 | + test_catalog.create_namespace_if_not_exists(database_name) |
| 757 | + table_ident = (database_name, "missing_table") |
| 758 | + assert not test_catalog.table_exists(table_ident) |
| 759 | + with pytest.raises(NoSuchTableError): |
| 760 | + test_catalog.drop_table(table_ident) |
| 761 | + |
| 762 | + |
| 763 | +@pytest.mark.integration |
| 764 | +@pytest.mark.parametrize("test_catalog", CATALOGS) |
| 765 | +def test_drop_nonexistent_namespace(test_catalog: Catalog) -> None: |
| 766 | + if isinstance(test_catalog, HiveCatalog): |
| 767 | + pytest.skip("HiveCatalog raises NoSuchObjectException instead of NoSuchNamespaceError") |
| 768 | + |
| 769 | + namespace = ("non_existent_namespace",) |
| 770 | + with pytest.raises(NoSuchNamespaceError): |
| 771 | + test_catalog.drop_namespace(namespace) |
0 commit comments