mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-12-13 00:22:23 +00:00
Fix Soft Deleted Table don't shows the Columns Data (#22991)
This commit is contained in:
parent
d5dfc458fd
commit
1fc766d7b7
@ -284,21 +284,21 @@ public class DashboardDataModelRepository extends EntityRepository<DashboardData
|
|||||||
public ResultList<Column> getDataModelColumns(
|
public ResultList<Column> getDataModelColumns(
|
||||||
UUID dataModelId, int limit, int offset, String fieldsParam, Include include) {
|
UUID dataModelId, int limit, int offset, String fieldsParam, Include include) {
|
||||||
DashboardDataModel dataModel = find(dataModelId, include);
|
DashboardDataModel dataModel = find(dataModelId, include);
|
||||||
return getDataModelColumnsInternal(dataModel, limit, offset, fieldsParam);
|
return getDataModelColumnsInternal(dataModel, limit, offset, fieldsParam, include);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResultList<Column> getDataModelColumnsByFQN(
|
public ResultList<Column> getDataModelColumnsByFQN(
|
||||||
String fqn, int limit, int offset, String fieldsParam, Include include) {
|
String fqn, int limit, int offset, String fieldsParam, Include include) {
|
||||||
DashboardDataModel dataModel = findByName(fqn, include);
|
DashboardDataModel dataModel = findByName(fqn, include);
|
||||||
return getDataModelColumnsInternal(dataModel, limit, offset, fieldsParam);
|
return getDataModelColumnsInternal(dataModel, limit, offset, fieldsParam, include);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ResultList<Column> getDataModelColumnsInternal(
|
private ResultList<Column> getDataModelColumnsInternal(
|
||||||
DashboardDataModel dataModel, int limit, int offset, String fieldsParam) {
|
DashboardDataModel dataModel, int limit, int offset, String fieldsParam, Include include) {
|
||||||
// For paginated column access, we need to load the data model with columns
|
// For paginated column access, we need to load the data model with columns
|
||||||
// but we'll optimize the field loading to only process what we need
|
// but we'll optimize the field loading to only process what we need
|
||||||
DashboardDataModel fullDataModel =
|
DashboardDataModel fullDataModel =
|
||||||
get(null, dataModel.getId(), getFields(Set.of("columns")), Include.NON_DELETED, false);
|
get(null, dataModel.getId(), getFields(Set.of("columns")), include, false);
|
||||||
|
|
||||||
List<Column> allColumns = fullDataModel.getColumns();
|
List<Column> allColumns = fullDataModel.getColumns();
|
||||||
if (allColumns == null || allColumns.isEmpty()) {
|
if (allColumns == null || allColumns.isEmpty()) {
|
||||||
|
|||||||
@ -1820,7 +1820,8 @@ public class TableRepository extends EntityRepository<Table> {
|
|||||||
Authorizer authorizer,
|
Authorizer authorizer,
|
||||||
SecurityContext securityContext) {
|
SecurityContext securityContext) {
|
||||||
Table table = find(tableId, include);
|
Table table = find(tableId, include);
|
||||||
return getTableColumnsInternal(table, limit, offset, fieldsParam, authorizer, securityContext);
|
return getTableColumnsInternal(
|
||||||
|
table, limit, offset, fieldsParam, include, authorizer, securityContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResultList<Column> getTableColumnsByFQN(
|
public ResultList<Column> getTableColumnsByFQN(
|
||||||
@ -1832,7 +1833,8 @@ public class TableRepository extends EntityRepository<Table> {
|
|||||||
Authorizer authorizer,
|
Authorizer authorizer,
|
||||||
SecurityContext securityContext) {
|
SecurityContext securityContext) {
|
||||||
Table table = findByName(fqn, include);
|
Table table = findByName(fqn, include);
|
||||||
return getTableColumnsInternal(table, limit, offset, fieldsParam, authorizer, securityContext);
|
return getTableColumnsInternal(
|
||||||
|
table, limit, offset, fieldsParam, include, authorizer, securityContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
private org.openmetadata.service.util.ResultList<Column> getTableColumnsInternal(
|
private org.openmetadata.service.util.ResultList<Column> getTableColumnsInternal(
|
||||||
@ -1840,11 +1842,12 @@ public class TableRepository extends EntityRepository<Table> {
|
|||||||
int limit,
|
int limit,
|
||||||
int offset,
|
int offset,
|
||||||
String fieldsParam,
|
String fieldsParam,
|
||||||
|
Include include,
|
||||||
Authorizer authorizer,
|
Authorizer authorizer,
|
||||||
SecurityContext securityContext) {
|
SecurityContext securityContext) {
|
||||||
// For paginated column access, we need to load the table with columns
|
// For paginated column access, we need to load the table with columns
|
||||||
// but we'll optimize the field loading to only process what we need
|
// but we'll optimize the field loading to only process what we need
|
||||||
Table fullTable = get(null, table.getId(), getFields(Set.of(COLUMN_FIELD)), NON_DELETED, false);
|
Table fullTable = get(null, table.getId(), getFields(Set.of(COLUMN_FIELD)), include, false);
|
||||||
|
|
||||||
List<Column> allColumns = fullTable.getColumns();
|
List<Column> allColumns = fullTable.getColumns();
|
||||||
if (allColumns == null || allColumns.isEmpty()) {
|
if (allColumns == null || allColumns.isEmpty()) {
|
||||||
|
|||||||
@ -5140,4 +5140,76 @@ public class TableResourceTest extends EntityResourceTest<Table, CreateTable> {
|
|||||||
// Verify table no longer exists in RDF after hard delete
|
// Verify table no longer exists in RDF after hard delete
|
||||||
RdfTestUtils.verifyEntityNotInRdf(table.getFullyQualifiedName());
|
RdfTestUtils.verifyEntityNotInRdf(table.getFullyQualifiedName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void test_getColumnsForSoftDeletedTable_200() throws IOException {
|
||||||
|
// Create database and schema with simple names for clean FQN
|
||||||
|
Database db =
|
||||||
|
dbTest.createEntity(
|
||||||
|
dbTest
|
||||||
|
.createRequest("test_soft_delete_db")
|
||||||
|
.withService(SNOWFLAKE_REFERENCE.getFullyQualifiedName()),
|
||||||
|
ADMIN_AUTH_HEADERS);
|
||||||
|
DatabaseSchema schema =
|
||||||
|
schemaTest.createEntity(
|
||||||
|
schemaTest
|
||||||
|
.createRequest("test_soft_delete_schema")
|
||||||
|
.withDatabase(db.getFullyQualifiedName()),
|
||||||
|
ADMIN_AUTH_HEADERS);
|
||||||
|
|
||||||
|
// Create a table with columns for testing soft-delete column retrieval
|
||||||
|
List<Column> columns = new ArrayList<>();
|
||||||
|
for (int i = 1; i <= 5; i++) {
|
||||||
|
columns.add(getColumn("col" + i, STRING, null).withOrdinalPosition(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
CreateTable create =
|
||||||
|
new CreateTable()
|
||||||
|
.withName("test_soft_delete_columns")
|
||||||
|
.withDatabaseSchema(schema.getFullyQualifiedName())
|
||||||
|
.withColumns(columns);
|
||||||
|
Table table = createAndCheckEntity(create, ADMIN_AUTH_HEADERS);
|
||||||
|
|
||||||
|
// Verify columns can be retrieved for active table
|
||||||
|
WebTarget target =
|
||||||
|
getResource("tables/" + table.getId() + "/columns").queryParam("include", "all");
|
||||||
|
TableResource.TableColumnList response =
|
||||||
|
TestUtils.get(target, TableResource.TableColumnList.class, ADMIN_AUTH_HEADERS);
|
||||||
|
assertEquals(5, response.getData().size());
|
||||||
|
assertEquals(5, response.getPaging().getTotal());
|
||||||
|
|
||||||
|
// Soft delete the table
|
||||||
|
deleteEntity(table.getId(), ADMIN_AUTH_HEADERS);
|
||||||
|
|
||||||
|
// Verify columns can still be retrieved for soft-deleted table using include=all
|
||||||
|
target = getResource("tables/" + table.getId() + "/columns").queryParam("include", "all");
|
||||||
|
response = TestUtils.get(target, TableResource.TableColumnList.class, ADMIN_AUTH_HEADERS);
|
||||||
|
assertEquals(5, response.getData().size());
|
||||||
|
assertEquals(5, response.getPaging().getTotal());
|
||||||
|
|
||||||
|
// Also test by FQN for soft-deleted table (now with clean FQN)
|
||||||
|
target =
|
||||||
|
getResource(
|
||||||
|
"tables/name/"
|
||||||
|
+ URLEncoder.encode(table.getFullyQualifiedName(), StandardCharsets.UTF_8)
|
||||||
|
+ "/columns")
|
||||||
|
.queryParam("include", "all");
|
||||||
|
response = TestUtils.get(target, TableResource.TableColumnList.class, ADMIN_AUTH_HEADERS);
|
||||||
|
assertEquals(5, response.getData().size());
|
||||||
|
assertEquals(5, response.getPaging().getTotal());
|
||||||
|
|
||||||
|
// Verify that without include=all parameter, it should fail
|
||||||
|
WebTarget targetWithoutInclude = getResource("tables/" + table.getId() + "/columns");
|
||||||
|
assertResponse(
|
||||||
|
() ->
|
||||||
|
TestUtils.get(
|
||||||
|
targetWithoutInclude, TableResource.TableColumnList.class, ADMIN_AUTH_HEADERS),
|
||||||
|
NOT_FOUND,
|
||||||
|
entityNotFound("table", table.getId()));
|
||||||
|
|
||||||
|
// Cleanup: Hard delete the test entities we created to avoid affecting other tests
|
||||||
|
deleteEntity(table.getId(), false, true, ADMIN_AUTH_HEADERS);
|
||||||
|
schemaTest.deleteEntity(schema.getId(), false, true, ADMIN_AUTH_HEADERS);
|
||||||
|
dbTest.deleteEntity(db.getId(), false, true, ADMIN_AUTH_HEADERS);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -35,6 +35,8 @@ import static org.openmetadata.service.util.TestUtils.assertResponse;
|
|||||||
import jakarta.ws.rs.client.WebTarget;
|
import jakarta.ws.rs.client.WebTarget;
|
||||||
import jakarta.ws.rs.core.Response.Status;
|
import jakarta.ws.rs.core.Response.Status;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@ -424,4 +426,68 @@ public class DashboardDataModelResourceTest
|
|||||||
column3.getTags() == null || column3.getTags().isEmpty(), "column3 should not have tags");
|
column3.getTags() == null || column3.getTags().isEmpty(), "column3 should not have tags");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void test_getColumnsForSoftDeletedDataModel_200() throws IOException {
|
||||||
|
// Create a dashboard data model with columns for testing soft-delete column retrieval
|
||||||
|
List<Column> columns = new ArrayList<>();
|
||||||
|
for (int i = 1; i <= 5; i++) {
|
||||||
|
columns.add(getColumn("datamodel_col" + i, INT, null));
|
||||||
|
}
|
||||||
|
|
||||||
|
CreateDashboardDataModel create =
|
||||||
|
createRequest("test_soft_delete_datamodel_columns").withColumns(columns);
|
||||||
|
DashboardDataModel dataModel = createAndCheckEntity(create, ADMIN_AUTH_HEADERS);
|
||||||
|
|
||||||
|
// Verify columns can be retrieved for active data model using the columns endpoint
|
||||||
|
WebTarget target =
|
||||||
|
getResource("dashboard/datamodels/" + dataModel.getId() + "/columns")
|
||||||
|
.queryParam("include", "all");
|
||||||
|
DashboardDataModelResource.DataModelColumnList response =
|
||||||
|
TestUtils.get(
|
||||||
|
target, DashboardDataModelResource.DataModelColumnList.class, ADMIN_AUTH_HEADERS);
|
||||||
|
assertEquals(5, response.getData().size());
|
||||||
|
assertEquals(5, response.getPaging().getTotal());
|
||||||
|
|
||||||
|
// Soft delete the data model
|
||||||
|
deleteEntity(dataModel.getId(), ADMIN_AUTH_HEADERS);
|
||||||
|
|
||||||
|
// Verify columns can still be retrieved for soft-deleted data model using include=all
|
||||||
|
target =
|
||||||
|
getResource("dashboard/datamodels/" + dataModel.getId() + "/columns")
|
||||||
|
.queryParam("include", "all");
|
||||||
|
response =
|
||||||
|
TestUtils.get(
|
||||||
|
target, DashboardDataModelResource.DataModelColumnList.class, ADMIN_AUTH_HEADERS);
|
||||||
|
assertEquals(5, response.getData().size());
|
||||||
|
assertEquals(5, response.getPaging().getTotal());
|
||||||
|
|
||||||
|
// Also test by FQN for soft-deleted data model
|
||||||
|
target =
|
||||||
|
getResource(
|
||||||
|
"dashboard/datamodels/name/"
|
||||||
|
+ URLEncoder.encode(dataModel.getFullyQualifiedName(), StandardCharsets.UTF_8)
|
||||||
|
+ "/columns")
|
||||||
|
.queryParam("include", "all");
|
||||||
|
response =
|
||||||
|
TestUtils.get(
|
||||||
|
target, DashboardDataModelResource.DataModelColumnList.class, ADMIN_AUTH_HEADERS);
|
||||||
|
assertEquals(5, response.getData().size());
|
||||||
|
assertEquals(5, response.getPaging().getTotal());
|
||||||
|
|
||||||
|
// Verify that without include=all parameter, it should fail for soft-deleted data model
|
||||||
|
WebTarget targetWithoutInclude =
|
||||||
|
getResource("dashboard/datamodels/" + dataModel.getId() + "/columns");
|
||||||
|
assertResponse(
|
||||||
|
() ->
|
||||||
|
TestUtils.get(
|
||||||
|
targetWithoutInclude,
|
||||||
|
DashboardDataModelResource.DataModelColumnList.class,
|
||||||
|
ADMIN_AUTH_HEADERS),
|
||||||
|
NOT_FOUND,
|
||||||
|
CatalogExceptionMessage.entityNotFound("dashboardDataModel", dataModel.getId()));
|
||||||
|
|
||||||
|
// Cleanup: Hard delete the test entity to avoid affecting other tests
|
||||||
|
deleteEntity(dataModel.getId(), false, true, ADMIN_AUTH_HEADERS);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user