Skip to content

Commit 197423f

Browse files
authored
Add namespace check on rename_table for REST Catalog (#2588)
<!-- Thanks for opening a pull request! --> <!-- In the case this PR will resolve an issue, please replace ${GITHUB_ISSUE_ID} below with the actual Github issue id. --> rename_table should throw NoSuchNamespaceError if the source / destination namespace does not exist. # Rationale for this change Better conformance with spec. ## Are these changes tested? Unit tests added. ## Are there any user-facing changes? <!-- In the case of user-facing changes, please add the changelog label. -->
1 parent b7f4e94 commit 197423f

File tree

2 files changed

+62
-0
lines changed

2 files changed

+62
-0
lines changed

pyiceberg/catalog/rest/__init__.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -654,6 +654,16 @@ def rename_table(self, from_identifier: Union[str, Identifier], to_identifier: U
654654
"source": self._split_identifier_for_json(from_identifier),
655655
"destination": self._split_identifier_for_json(to_identifier),
656656
}
657+
658+
# Ensure that namespaces exist on source and destination.
659+
source_namespace = self._split_identifier_for_json(from_identifier)["namespace"]
660+
if not self.namespace_exists(source_namespace):
661+
raise NoSuchNamespaceError(f"Source namespace does not exist: {source_namespace}")
662+
663+
destination_namespace = self._split_identifier_for_json(to_identifier)["namespace"]
664+
if not self.namespace_exists(destination_namespace):
665+
raise NoSuchNamespaceError(f"Destination namespace does not exist: {destination_namespace}")
666+
657667
response = self._session.post(self.url(Endpoints.rename_table), json=payload)
658668
try:
659669
response.raise_for_status()

tests/catalog/test_rest.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1353,6 +1353,11 @@ def test_rename_table_200(rest_mock: Mocker, example_table_metadata_with_snapsho
13531353
status_code=200,
13541354
request_headers=TEST_HEADERS,
13551355
)
1356+
rest_mock.head(
1357+
f"{TEST_URI}v1/namespaces/pdames",
1358+
status_code=200,
1359+
request_headers=TEST_HEADERS,
1360+
)
13561361
catalog = RestCatalog("rest", uri=TEST_URI, token=TEST_TOKEN)
13571362
from_identifier = ("pdames", "source")
13581363
to_identifier = ("pdames", "destination")
@@ -1396,6 +1401,11 @@ def test_rename_table_from_self_identifier_200(
13961401
status_code=200,
13971402
request_headers=TEST_HEADERS,
13981403
)
1404+
rest_mock.head(
1405+
f"{TEST_URI}v1/namespaces/pdames",
1406+
status_code=200,
1407+
request_headers=TEST_HEADERS,
1408+
)
13991409
actual = catalog.rename_table(table.name(), to_identifier)
14001410
expected = Table(
14011411
identifier=("pdames", "destination"),
@@ -1408,6 +1418,48 @@ def test_rename_table_from_self_identifier_200(
14081418
assert actual == expected
14091419

14101420

1421+
def test_rename_table_source_namespace_does_not_exist(rest_mock: Mocker) -> None:
1422+
catalog = RestCatalog("rest", uri=TEST_URI, token=TEST_TOKEN)
1423+
from_identifier = ("invalid", "source")
1424+
to_identifier = ("pdames", "destination")
1425+
1426+
rest_mock.head(
1427+
f"{TEST_URI}v1/namespaces/invalid",
1428+
status_code=404,
1429+
request_headers=TEST_HEADERS,
1430+
)
1431+
rest_mock.head(
1432+
f"{TEST_URI}v1/namespaces/pdames",
1433+
status_code=200,
1434+
request_headers=TEST_HEADERS,
1435+
)
1436+
1437+
with pytest.raises(NoSuchNamespaceError) as e:
1438+
catalog.rename_table(from_identifier, to_identifier)
1439+
assert "Source namespace does not exist" in str(e.value)
1440+
1441+
1442+
def test_rename_table_destination_namespace_does_not_exist(rest_mock: Mocker) -> None:
1443+
catalog = RestCatalog("rest", uri=TEST_URI, token=TEST_TOKEN)
1444+
from_identifier = ("pdames", "source")
1445+
to_identifier = ("invalid", "destination")
1446+
1447+
rest_mock.head(
1448+
f"{TEST_URI}v1/namespaces/pdames",
1449+
status_code=200,
1450+
request_headers=TEST_HEADERS,
1451+
)
1452+
rest_mock.head(
1453+
f"{TEST_URI}v1/namespaces/invalid",
1454+
status_code=404,
1455+
request_headers=TEST_HEADERS,
1456+
)
1457+
1458+
with pytest.raises(NoSuchNamespaceError) as e:
1459+
catalog.rename_table(from_identifier, to_identifier)
1460+
assert "Destination namespace does not exist" in str(e.value)
1461+
1462+
14111463
def test_delete_table_404(rest_mock: Mocker) -> None:
14121464
rest_mock.delete(
14131465
f"{TEST_URI}v1/namespaces/example/tables/fokko",

0 commit comments

Comments
 (0)