From f3038f83320a934f93c5a482b73a533c2fbe53f5 Mon Sep 17 00:00:00 2001 From: Giorgio Trettenero Date: Mon, 2 Dec 2024 23:02:42 -0800 Subject: [PATCH 1/2] Disable ON DELETE CASCADE + TESTS fix checkstyle fix checkstyle see if the test error is due to schema change check tests check tests checkstyle test test test test test test test test hopefully last test checkstyle already exists checkstyle test move test fix moved test fix test final --- .../exception/ConnectorException.java | 2 +- .../DatabasePreconditionFailedException.java | 48 +++++++++++++++++++ .../src/functionalTest/resources/schema.sql | 2 +- .../PolarisConnectorDatabaseService.java | 9 ++++ .../PolarisConnectorDatabaseServiceTest.java | 2 - .../store/PolarisStoreConnectorTest.java | 16 +++++++ .../src/test/resources/h2db/schema.sql | 2 +- .../datastores/crdb/sql/schema.sql | 2 +- 8 files changed, 77 insertions(+), 6 deletions(-) create mode 100644 metacat-common-server/src/main/java/com/netflix/metacat/common/server/connectors/exception/DatabasePreconditionFailedException.java diff --git a/metacat-common-server/src/main/java/com/netflix/metacat/common/server/connectors/exception/ConnectorException.java b/metacat-common-server/src/main/java/com/netflix/metacat/common/server/connectors/exception/ConnectorException.java index ed4125774..d45dec070 100644 --- a/metacat-common-server/src/main/java/com/netflix/metacat/common/server/connectors/exception/ConnectorException.java +++ b/metacat-common-server/src/main/java/com/netflix/metacat/common/server/connectors/exception/ConnectorException.java @@ -50,7 +50,7 @@ public ConnectorException(final String message, @Nullable final Throwable cause) * * @param message message * @param cause cause - * @param enableSuppression eable suppression + * @param enableSuppression enable suppression * @param writableStackTrace stacktrace */ public ConnectorException( diff --git a/metacat-common-server/src/main/java/com/netflix/metacat/common/server/connectors/exception/DatabasePreconditionFailedException.java b/metacat-common-server/src/main/java/com/netflix/metacat/common/server/connectors/exception/DatabasePreconditionFailedException.java new file mode 100644 index 000000000..54b153ffe --- /dev/null +++ b/metacat-common-server/src/main/java/com/netflix/metacat/common/server/connectors/exception/DatabasePreconditionFailedException.java @@ -0,0 +1,48 @@ +package com.netflix.metacat.common.server.connectors.exception; + +/* + * + * Copyright 2024 Netflix, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import com.netflix.metacat.common.QualifiedName; +import lombok.Getter; + +import javax.annotation.Nullable; + +/** + * Exception when database can't be deleted because ON DELETE CASCADE is + * disabled and a table still exists in the database. + * + * @author gtret + */ +@Getter +public class DatabasePreconditionFailedException extends ConnectorException { + /** + * Constructor. + * + * @param name qualified name of the database + * @param message error description + * @param error stacktrace + */ + public DatabasePreconditionFailedException(final QualifiedName name, + @Nullable final String message, + @Nullable final Throwable error) { + super(String.format("Precondition failed to update table %s. %s", name, message), error); + } +} + + diff --git a/metacat-connector-polaris/src/functionalTest/resources/schema.sql b/metacat-connector-polaris/src/functionalTest/resources/schema.sql index 9b91312fd..5a4a32738 100644 --- a/metacat-connector-polaris/src/functionalTest/resources/schema.sql +++ b/metacat-connector-polaris/src/functionalTest/resources/schema.sql @@ -25,5 +25,5 @@ create table TBLS ( created_date TIMESTAMP not null, last_updated_by STRING(255), last_updated_date TIMESTAMP not null, - foreign key (db_name) references DBS(name) ON DELETE CASCADE ON UPDATE CASCADE + foreign key (db_name) references DBS(name) ON DELETE RESTRICT ON UPDATE CASCADE ); diff --git a/metacat-connector-polaris/src/main/java/com/netflix/metacat/connector/polaris/PolarisConnectorDatabaseService.java b/metacat-connector-polaris/src/main/java/com/netflix/metacat/connector/polaris/PolarisConnectorDatabaseService.java index 94d67780e..7b3a41ce3 100644 --- a/metacat-connector-polaris/src/main/java/com/netflix/metacat/connector/polaris/PolarisConnectorDatabaseService.java +++ b/metacat-connector-polaris/src/main/java/com/netflix/metacat/connector/polaris/PolarisConnectorDatabaseService.java @@ -10,6 +10,7 @@ import com.netflix.metacat.common.server.connectors.exception.ConnectorException; import com.netflix.metacat.common.server.connectors.exception.DatabaseAlreadyExistsException; import com.netflix.metacat.common.server.connectors.exception.DatabaseNotFoundException; +import com.netflix.metacat.common.server.connectors.exception.DatabasePreconditionFailedException; import com.netflix.metacat.common.server.connectors.exception.InvalidMetaException; import com.netflix.metacat.common.server.connectors.model.DatabaseInfo; import com.netflix.metacat.connector.polaris.common.PolarisUtils; @@ -87,11 +88,19 @@ public void delete(final ConnectorRequestContext context, final QualifiedName na try { this.polarisStoreService.deleteDatabase(name.getDatabaseName()); } catch (DataIntegrityViolationException exception) { + if (exception.getCause() instanceof org.hibernate.exception.ConstraintViolationException) { + throw new DatabasePreconditionFailedException( + name, + String.format("Cannot delete database %s because it is not empty.", name.getDatabaseName()), + exception + ); + } throw new InvalidMetaException(name, exception); } catch (Exception exception) { throw new ConnectorException( String.format("Failed deleting polaris database %s", name), exception); } + System.out.println("DID NOT CATCH THE DB DELETE ERROR"); } /** diff --git a/metacat-connector-polaris/src/test/java/com/netflix/metacat/connector/polaris/PolarisConnectorDatabaseServiceTest.java b/metacat-connector-polaris/src/test/java/com/netflix/metacat/connector/polaris/PolarisConnectorDatabaseServiceTest.java index e297704f8..b765e7735 100644 --- a/metacat-connector-polaris/src/test/java/com/netflix/metacat/connector/polaris/PolarisConnectorDatabaseServiceTest.java +++ b/metacat-connector-polaris/src/test/java/com/netflix/metacat/connector/polaris/PolarisConnectorDatabaseServiceTest.java @@ -1,4 +1,3 @@ - package com.netflix.metacat.connector.polaris; import com.google.common.collect.Maps; @@ -167,4 +166,3 @@ public void testDeleteDb() { Assert.assertFalse(polarisDBService.exists(requestContext, DB1_QUALIFIED_NAME)); } } - diff --git a/metacat-connector-polaris/src/test/java/com/netflix/metacat/connector/polaris/store/PolarisStoreConnectorTest.java b/metacat-connector-polaris/src/test/java/com/netflix/metacat/connector/polaris/store/PolarisStoreConnectorTest.java index d36e92270..f820f490e 100644 --- a/metacat-connector-polaris/src/test/java/com/netflix/metacat/connector/polaris/store/PolarisStoreConnectorTest.java +++ b/metacat-connector-polaris/src/test/java/com/netflix/metacat/connector/polaris/store/PolarisStoreConnectorTest.java @@ -19,6 +19,7 @@ import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.boot.test.mock.mockito.SpyBean; import org.springframework.dao.DataAccessException; +import org.springframework.dao.DataIntegrityViolationException; import org.springframework.dao.OptimisticLockingFailureException; import org.springframework.data.auditing.AuditingHandler; import org.springframework.data.auditing.DateTimeProvider; @@ -182,6 +183,21 @@ public void testTableCreationAndDeletionWithParams() { Assert.assertFalse(polarisConnector.tableExistsById(tblEntity.getTblId())); } + /** + * Test database deletion if table exists and ON DELETE CASCADE is disabled. + */ + @Test + public void testDbDeletionNoCascade() { + final String dbName = generateDatabaseName(); + final String tblName = generateTableName(); + final PolarisDatabaseEntity dbEntity = createDB(dbName); + final PolarisTableEntity tblEntity = createTable(dbName, tblName); + + Assertions.assertThrows(DataIntegrityViolationException.class, () -> + polarisConnector.deleteDatabase(dbName)); + Assert.assertTrue(polarisConnector.databaseExists(dbName)); + } + /** * Test to verify that table name can be updated. */ diff --git a/metacat-connector-polaris/src/test/resources/h2db/schema.sql b/metacat-connector-polaris/src/test/resources/h2db/schema.sql index 1470b9548..e050e4ee6 100644 --- a/metacat-connector-polaris/src/test/resources/h2db/schema.sql +++ b/metacat-connector-polaris/src/test/resources/h2db/schema.sql @@ -25,7 +25,7 @@ create table TBLS ( created_date TIMESTAMP not null, last_updated_by varchar(255), last_updated_date TIMESTAMP not null, - foreign key (db_name) references DBS(name) ON DELETE CASCADE ON UPDATE CASCADE + foreign key (db_name) references DBS(name) ON DELETE RESTRICT ON UPDATE CASCADE ); CREATE INDEX DB_NAME_IDX ON TBLS(db_name); diff --git a/metacat-functional-tests/metacat-test-cluster/datastores/crdb/sql/schema.sql b/metacat-functional-tests/metacat-test-cluster/datastores/crdb/sql/schema.sql index 9f580ebe0..96d599863 100644 --- a/metacat-functional-tests/metacat-test-cluster/datastores/crdb/sql/schema.sql +++ b/metacat-functional-tests/metacat-test-cluster/datastores/crdb/sql/schema.sql @@ -25,5 +25,5 @@ create table TBLS ( last_updated_by STRING(255), last_updated_date TIMESTAMP not null, constraint uniq_name unique(db_name, tbl_name), - foreign key (db_name) references DBS(name) ON DELETE CASCADE ON UPDATE CASCADE + foreign key (db_name) references DBS(name) ON DELETE RESTRICT ON UPDATE CASCADE ); From 15f37b7b41295edea7b49bf142128376d76f974b Mon Sep 17 00:00:00 2001 From: Giorgio Trettenero Date: Wed, 7 May 2025 14:42:43 -0700 Subject: [PATCH 2/2] add tableExists --- .../connector/polaris/PolarisConnectorDatabaseService.java | 1 - .../connector/polaris/store/PolarisStoreConnectorTest.java | 3 +++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/metacat-connector-polaris/src/main/java/com/netflix/metacat/connector/polaris/PolarisConnectorDatabaseService.java b/metacat-connector-polaris/src/main/java/com/netflix/metacat/connector/polaris/PolarisConnectorDatabaseService.java index 7b3a41ce3..51e4e31ee 100644 --- a/metacat-connector-polaris/src/main/java/com/netflix/metacat/connector/polaris/PolarisConnectorDatabaseService.java +++ b/metacat-connector-polaris/src/main/java/com/netflix/metacat/connector/polaris/PolarisConnectorDatabaseService.java @@ -100,7 +100,6 @@ public void delete(final ConnectorRequestContext context, final QualifiedName na throw new ConnectorException( String.format("Failed deleting polaris database %s", name), exception); } - System.out.println("DID NOT CATCH THE DB DELETE ERROR"); } /** diff --git a/metacat-connector-polaris/src/test/java/com/netflix/metacat/connector/polaris/store/PolarisStoreConnectorTest.java b/metacat-connector-polaris/src/test/java/com/netflix/metacat/connector/polaris/store/PolarisStoreConnectorTest.java index f820f490e..fd1f4ab06 100644 --- a/metacat-connector-polaris/src/test/java/com/netflix/metacat/connector/polaris/store/PolarisStoreConnectorTest.java +++ b/metacat-connector-polaris/src/test/java/com/netflix/metacat/connector/polaris/store/PolarisStoreConnectorTest.java @@ -193,9 +193,12 @@ public void testDbDeletionNoCascade() { final PolarisDatabaseEntity dbEntity = createDB(dbName); final PolarisTableEntity tblEntity = createTable(dbName, tblName); + Assert.assertTrue(polarisConnector.databaseExists(dbName)); + Assert.assertTrue(polarisConnector.tableExists(dbName, tblName)); Assertions.assertThrows(DataIntegrityViolationException.class, () -> polarisConnector.deleteDatabase(dbName)); Assert.assertTrue(polarisConnector.databaseExists(dbName)); + Assert.assertTrue(polarisConnector.tableExists(dbName, tblName)); } /**