Skip to content

Commit 588f143

Browse files
Fix recursively dumping a group with a nonexistent subgroup. (#4582)
[SC-38499](https://app.shortcut.com/tiledb-inc/story/38499/recursively-dumping-a-group-fails-when-a-subgroup-does-not-exist) --- TYPE: BUG DESC: Fix recursively dumping a group with a nonexistent subgroup.
1 parent 7902e8b commit 588f143

File tree

2 files changed

+66
-4
lines changed

2 files changed

+66
-4
lines changed

test/src/unit-capi-group.cc

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1490,6 +1490,54 @@ TEST_CASE_METHOD(
14901490
remove_temp_dir(temp_dir);
14911491
}
14921492

1493+
TEST_CASE_METHOD(GroupFx, "C API: Group, dump", "[capi][group][dump]") {
1494+
// Create and open group in write mode
1495+
// TODO: refactor for each supported FS.
1496+
std::string temp_dir = fs_vec_[0]->temp_dir();
1497+
create_temp_dir(temp_dir);
1498+
1499+
tiledb::sm::URI group1_uri(temp_dir + "group1");
1500+
REQUIRE(tiledb_group_create(ctx_, group1_uri.c_str()) == TILEDB_OK);
1501+
1502+
tiledb::sm::URI group2_uri(temp_dir + "group2");
1503+
REQUIRE(tiledb_group_create(ctx_, group2_uri.c_str()) == TILEDB_OK);
1504+
1505+
tiledb_group_t* group1;
1506+
int rc = tiledb_group_alloc(ctx_, group1_uri.c_str(), &group1);
1507+
REQUIRE(rc == TILEDB_OK);
1508+
set_group_timestamp(group1, 1);
1509+
rc = tiledb_group_open(ctx_, group1, TILEDB_WRITE);
1510+
REQUIRE(rc == TILEDB_OK);
1511+
1512+
rc = tiledb_group_add_member(ctx_, group1, group2_uri.c_str(), 0, "group2");
1513+
REQUIRE(rc == TILEDB_OK);
1514+
rc = tiledb_group_close(ctx_, group1);
1515+
REQUIRE(rc == TILEDB_OK);
1516+
1517+
// Delete the subgroup to test that recursively dumping its parent will not
1518+
// fail.
1519+
rc = tiledb_object_remove(ctx_, group2_uri.c_str());
1520+
REQUIRE(rc == TILEDB_OK);
1521+
1522+
rc = tiledb_group_open(ctx_, group1, TILEDB_READ);
1523+
REQUIRE(rc == TILEDB_OK);
1524+
1525+
char* group_dump;
1526+
rc = tiledb_group_dump_str(ctx_, group1, &group_dump, 1);
1527+
REQUIRE(rc == TILEDB_OK);
1528+
REQUIRE(group_dump != nullptr);
1529+
REQUIRE(
1530+
std::string(group_dump) ==
1531+
"group1 GROUP\n|-- group2 GROUP (does not exist)\n");
1532+
free(group_dump);
1533+
1534+
rc = tiledb_group_close(ctx_, group1);
1535+
REQUIRE(rc == TILEDB_OK);
1536+
1537+
tiledb_group_free(&group1);
1538+
remove_temp_dir(temp_dir);
1539+
}
1540+
14931541
#ifdef TILEDB_SERIALIZATION
14941542
TEST_CASE_METHOD(
14951543
GroupFx,

tiledb/sm/group/group.cc

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -669,13 +669,27 @@ std::string Group::dump(
669669

670670
for (const auto& member_entry : members()) {
671671
const auto& it = member_entry.second;
672-
ss << "|" << indent << l_indent << " " << *it << std::endl;
672+
URI member_uri = it->uri();
673+
if (it->relative()) {
674+
member_uri = group_uri_.join_path(it->uri().to_string());
675+
}
676+
677+
ss << "|" << indent << l_indent << " " << *it;
678+
bool do_recurse = false;
673679
if (it->type() == ObjectType::GROUP && recursive) {
674-
URI member_uri = it->uri();
675-
if (it->relative()) {
676-
member_uri = group_uri_.join_path(it->uri().to_string());
680+
// Before listing the group's members, check if the group exists in
681+
// storage. If it does not, leave a message in the string.
682+
ObjectType member_type = ObjectType::INVALID;
683+
throw_if_not_ok(storage_manager_->object_type(member_uri, &member_type));
684+
if (member_type == ObjectType::GROUP) {
685+
do_recurse = true;
686+
} else {
687+
ss << " (does not exist)";
677688
}
689+
}
690+
ss << std::endl;
678691

692+
if (do_recurse) {
679693
Group group_rec(member_uri, storage_manager_);
680694
throw_if_not_ok(group_rec.open(QueryType::READ));
681695
ss << group_rec.dump(indent_size, num_indents + 2, recursive, false);

0 commit comments

Comments
 (0)