in service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalog.java [2048:2160]
private void renameTableLike(
PolarisEntitySubType subType, TableIdentifier from, TableIdentifier to) {
LOGGER.debug("Renaming tableLike from {} to {}", from, to);
PolarisResolvedPathWrapper resolvedEntities =
resolvedEntityView.getResolvedPath(from, PolarisEntityType.TABLE_LIKE, subType);
if (resolvedEntities == null) {
if (subType == PolarisEntitySubType.ICEBERG_VIEW) {
throw new NoSuchViewException("Cannot rename %s to %s. View does not exist", from, to);
} else {
throw new NoSuchTableException("Cannot rename %s to %s. Table does not exist", from, to);
}
}
List<PolarisEntity> catalogPath = resolvedEntities.getRawParentPath();
PolarisEntity leafEntity = resolvedEntities.getRawLeafEntity();
final IcebergTableLikeEntity toEntity;
List<PolarisEntity> newCatalogPath = null;
if (!from.namespace().equals(to.namespace())) {
PolarisResolvedPathWrapper resolvedNewParentEntities =
resolvedEntityView.getResolvedPath(to.namespace());
if (resolvedNewParentEntities == null) {
throw new NoSuchNamespaceException(
"Cannot rename %s to %s. Namespace does not exist: %s", from, to, to.namespace());
}
newCatalogPath = resolvedNewParentEntities.getRawFullPath();
// the "to" table has a new parent and a new name / namespace path
toEntity =
new IcebergTableLikeEntity.Builder(IcebergTableLikeEntity.of(leafEntity))
.setTableIdentifier(to)
.setParentId(resolvedNewParentEntities.getResolvedLeafEntity().getEntity().getId())
.build();
} else {
// only the name of the entity is changed
toEntity =
new IcebergTableLikeEntity.Builder(IcebergTableLikeEntity.of(leafEntity))
.setTableIdentifier(to)
.build();
}
// rename the entity now
EntityResult returnedEntityResult =
getMetaStoreManager()
.renameEntity(
getCurrentPolarisContext(),
PolarisEntity.toCoreList(catalogPath),
leafEntity,
PolarisEntity.toCoreList(newCatalogPath),
toEntity);
// handle error
if (!returnedEntityResult.isSuccess()) {
LOGGER.debug(
"Rename error {} trying to rename {} to {}. Checking existing object.",
returnedEntityResult.getReturnStatus(),
from,
to);
switch (returnedEntityResult.getReturnStatus()) {
case BaseResult.ReturnStatus.ENTITY_ALREADY_EXISTS:
{
PolarisEntitySubType existingEntitySubType =
returnedEntityResult.getAlreadyExistsEntitySubType();
if (existingEntitySubType == null) {
// this code path is unexpected
throw new AlreadyExistsException(
"Cannot rename %s to %s. Object already exists", from, to);
} else if (existingEntitySubType == PolarisEntitySubType.ICEBERG_TABLE) {
throw new AlreadyExistsException(
"Cannot rename %s to %s. Table already exists", from, to);
} else if (existingEntitySubType == PolarisEntitySubType.ICEBERG_VIEW) {
throw new AlreadyExistsException(
"Cannot rename %s to %s. View already exists", from, to);
}
throw new IllegalStateException(
String.format("Unexpected entity type '%s'", existingEntitySubType));
}
case BaseResult.ReturnStatus.ENTITY_NOT_FOUND:
throw new NotFoundException("Cannot rename %s to %s. %s does not exist", from, to, from);
// this is temporary. Should throw a special error that will be caught and retried
case BaseResult.ReturnStatus.TARGET_ENTITY_CONCURRENTLY_MODIFIED:
case BaseResult.ReturnStatus.ENTITY_CANNOT_BE_RESOLVED:
throw new RuntimeException("concurrent update detected, please retry");
// some entities cannot be renamed
case BaseResult.ReturnStatus.ENTITY_CANNOT_BE_RENAMED:
throw new BadRequestException("Cannot rename built-in object %s", leafEntity.getName());
// some entities cannot be renamed
default:
throw new IllegalStateException(
"Unknown error status " + returnedEntityResult.getReturnStatus());
}
} else {
IcebergTableLikeEntity returnedEntity =
IcebergTableLikeEntity.of(returnedEntityResult.getEntity());
if (!toEntity.getTableIdentifier().equals(returnedEntity.getTableIdentifier())) {
// As long as there are older deployments which don't support the atomic update of the
// internalProperties during rename, we can log and then patch it up explicitly
// in a best-effort way.
LOGGER
.atError()
.addKeyValue("toEntity.getTableIdentifier()", toEntity.getTableIdentifier())
.addKeyValue("returnedEntity.getTableIdentifier()", returnedEntity.getTableIdentifier())
.log("Returned entity identifier doesn't match toEntity identifier");
getMetaStoreManager()
.updateEntityPropertiesIfNotChanged(
getCurrentPolarisContext(),
PolarisEntity.toCoreList(newCatalogPath),
new IcebergTableLikeEntity.Builder(returnedEntity).setTableIdentifier(to).build());
}
}
}