Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
import org.apache.polaris.core.entity.PolarisEntityId;
import org.apache.polaris.core.entity.PolarisEntitySubType;
import org.apache.polaris.core.entity.PolarisEntityType;
import org.apache.polaris.core.entity.PolarisEntityUtils;
import org.apache.polaris.core.entity.PolarisEvent;
import org.apache.polaris.core.entity.PolarisGrantRecord;
import org.apache.polaris.core.entity.PolarisPrincipalSecrets;
Expand Down Expand Up @@ -810,11 +811,20 @@ Optional<Optional<String>> hasOverlappingSiblings(
if (!results.isEmpty()) {
StorageLocation entityLocation = StorageLocation.of(entity.getBaseLocation());
for (PolarisBaseEntity result : results) {
StorageLocation potentialSiblingLocation =
StorageLocation.of(((LocationBasedEntity) result).getBaseLocation());
if (entityLocation.isChildOf(potentialSiblingLocation)
|| potentialSiblingLocation.isChildOf(entityLocation)) {
return Optional.of(Optional.of(potentialSiblingLocation.toString()));
// JDBC materializes persisted rows as PolarisBaseEntity. Resolve the sibling location
// via PolarisEntityUtils instead of casting to LocationBasedEntity.
Optional<String> overlappingSiblingLocation =
PolarisEntityUtils.asLocationBasedEntity(PolarisEntity.of(result))
.map(LocationBasedEntity::getBaseLocation)
.filter(location -> location != null && !location.isBlank())
.map(StorageLocation::of)
.filter(
potentialSiblingLocation ->
entityLocation.isChildOf(potentialSiblingLocation)
|| potentialSiblingLocation.isChildOf(entityLocation))
.map(StorageLocation::toString);
if (overlappingSiblingLocation.isPresent()) {
return Optional.of(overlappingSiblingLocation);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,27 @@

import java.io.InputStream;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import javax.sql.DataSource;
import org.apache.polaris.core.PolarisCallContext;
import org.apache.polaris.core.PolarisDefaultDiagServiceImpl;
import org.apache.polaris.core.PolarisDiagnostics;
import org.apache.polaris.core.context.RealmContext;
import org.apache.polaris.core.entity.LocationBasedEntity;
import org.apache.polaris.core.entity.PolarisBaseEntity;
import org.apache.polaris.core.entity.PolarisEntity;
import org.apache.polaris.core.entity.PolarisEntityConstants;
import org.apache.polaris.core.entity.PolarisEntitySubType;
import org.apache.polaris.core.entity.PolarisEntityType;
import org.apache.polaris.core.persistence.AtomicOperationMetaStoreManager;
import org.apache.polaris.core.persistence.BasePolarisMetaStoreManagerTest;
import org.apache.polaris.core.persistence.PolarisTestMetaStoreManager;
import org.assertj.core.api.Assertions;
import org.assertj.core.api.Assumptions;
import org.h2.jdbcx.JdbcConnectionPool;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;

public abstract class AtomicMetastoreManagerWithJdbcBasePersistenceImplTest
Expand Down Expand Up @@ -79,6 +90,82 @@ protected PolarisTestMetaStoreManager createPolarisTestMetaStoreManager() {
return new PolarisTestMetaStoreManager(metaStoreManager, callCtx);
}

@Test
void testHasOverlappingSiblingsUsesStoredBaseLocation() {
// The optimized check relies on the location_without_scheme column added in schema v2.
Assumptions.assumeThat(schemaVersion()).isGreaterThanOrEqualTo(2);

var metaStoreManager = polarisTestMetaStoreManager.polarisMetaStoreManager();
var callContext = polarisTestMetaStoreManager.polarisCallContext();
PolarisBaseEntity catalog =
new PolarisBaseEntity(
PolarisEntityConstants.getNullId(),
metaStoreManager.generateNewEntityId(callContext).getId(),
PolarisEntityType.CATALOG,
PolarisEntitySubType.NULL_SUBTYPE,
PolarisEntityConstants.getRootEntityId(),
"overlap_test_catalog");
catalog = metaStoreManager.createCatalog(callContext, catalog, List.of()).getCatalog();

PolarisBaseEntity existingNamespace =
buildLocationBasedNamespace(
catalog,
metaStoreManager.generateNewEntityId(callContext).getId(),
"existing",
"s3://bucket/warehouse/existing/");
metaStoreManager.createEntityIfNotExists(
callContext, List.of(PolarisEntity.toCore(catalog)), existingNamespace);

TestLocationBasedEntity candidateNamespace =
new TestLocationBasedEntity(
buildLocationBasedNamespace(
catalog,
metaStoreManager.generateNewEntityId(callContext).getId(),
"candidate",
"s3://bucket/warehouse/existing/child"));

Assertions.assertThat(metaStoreManager.hasOverlappingSiblings(callContext, candidateNamespace))
.contains(Optional.of("s3://bucket/warehouse/existing/"));

TestLocationBasedEntity nonOverlappingNamespace =
new TestLocationBasedEntity(
buildLocationBasedNamespace(
catalog,
metaStoreManager.generateNewEntityId(callContext).getId(),
"non_overlapping",
"s3://bucket/warehouse/non-overlapping"));

Assertions.assertThat(
metaStoreManager.hasOverlappingSiblings(callContext, nonOverlappingNamespace))
.contains(Optional.empty());
}

private static PolarisBaseEntity buildLocationBasedNamespace(
PolarisBaseEntity catalog, long entityId, String name, String baseLocation) {
return new PolarisBaseEntity.Builder()
.catalogId(catalog.getId())
.parentId(catalog.getId())
.id(entityId)
.typeCode(PolarisEntityType.NAMESPACE.getCode())
.subTypeCode(PolarisEntitySubType.NULL_SUBTYPE.getCode())
.name(name)
.propertiesAsMap(Map.of(PolarisEntityConstants.ENTITY_BASE_LOCATION, baseLocation))
.internalPropertiesAsMap(Map.of())
.build();
}

private static class TestLocationBasedEntity extends PolarisEntity
implements LocationBasedEntity {
TestLocationBasedEntity(PolarisBaseEntity sourceEntity) {
super(sourceEntity);
}

@Override
public String getBaseLocation() {
return getPropertiesAsMap().get(PolarisEntityConstants.ENTITY_BASE_LOCATION);
}
}

private static class H2JdbcConfiguration implements RelationalJdbcConfiguration {

@Override
Expand Down