Skip to content
Open
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 @@ -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(
Expand Down
Original file line number Diff line number Diff line change
@@ -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);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I think this should be update database?

}
}


Original file line number Diff line number Diff line change
Expand Up @@ -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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want cascading updates? dbname -> dbname2 would also be bad. Less bad, but still bad.

);
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -87,6 +88,13 @@ 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(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

package com.netflix.metacat.connector.polaris;

import com.google.common.collect.Maps;
Expand Down Expand Up @@ -167,4 +166,3 @@ public void testDeleteDb() {
Assert.assertFalse(polarisDBService.exists(requestContext, DB1_QUALIFIED_NAME));
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -182,6 +183,24 @@ public void testTableCreationAndDeletionWithParams() {
Assert.assertFalse(polarisConnector.tableExistsById(tblEntity.getTblId()));
}

/**
* Test database deletion if table exists and ON DELETE CASCADE is disabled.
*/
@Test
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be good to have a test at the PolarisConnectorDatabaseService level as well.

public void testDbDeletionNoCascade() {
final String dbName = generateDatabaseName();
final String tblName = generateTableName();
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));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Could you also add a check to make sure the table exist as well?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1

Assert.assertTrue(polarisConnector.tableExists(dbName, tblName));
}

/**
* Test to verify that table name can be updated.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Original file line number Diff line number Diff line change
Expand Up @@ -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
);
Loading