diff --git a/src/graph_buffer/graph_buffer.c b/src/graph_buffer/graph_buffer.c index 61b4bbbc1..e5dbc213b 100644 --- a/src/graph_buffer/graph_buffer.c +++ b/src/graph_buffer/graph_buffer.c @@ -1534,13 +1534,21 @@ int cbm_gbuf_dump_to_sqlite(cbm_gbuf_t *gb, const char *path) { * intermittently emit a structurally-corrupt .db (gbuf-data corruption that * is ASan/TSan-invisible). Detect it with the fast projects-table check * (O(1), not a full integrity_check) and remove the corrupt DB so neither - * queries nor tests ever read garbage — the next access re-indexes. */ + * queries nor tests ever read garbage — the next access re-indexes. + * + * Use the _full variant so a path-only defect (root_path the check considers + * non-absolute, e.g. a relative repo_path like ".") is RETAINED, not deleted + * — the node/edge data is intact and queries key off project name, not + * root_path. Deleting on path-only would drop valid DBs whenever a relative + * path is indexed (caught by self-indexing the repo with repo_path="."). + * Consistent with #557 resolve_store. */ if (rc == 0) { cbm_store_t *verify = cbm_store_open_path((const char *)path); if (verify) { - bool intact = cbm_store_check_integrity(verify); + bool path_only = false; + bool intact = cbm_store_check_integrity_full(verify, &path_only); cbm_store_close(verify); - if (!intact) { + if (!intact && !path_only) { /* genuine structural corruption only */ char nodes_str[CBM_SZ_16]; char edges_str[CBM_SZ_16]; snprintf(nodes_str, sizeof(nodes_str), "%d", node_idx); diff --git a/tests/test_graph_buffer.c b/tests/test_graph_buffer.c index 543e597b1..7d2bb3810 100644 --- a/tests/test_graph_buffer.c +++ b/tests/test_graph_buffer.c @@ -1047,6 +1047,35 @@ TEST(gbuf_dump_pipeline_path_integrity) { PASS(); } +/* Regression: a RELATIVE root_path (e.g. ".") must not cause the post-dump + * verify to delete a valid DB. The integrity check flags non-absolute + * root_paths as bad_root_path, but that's a cosmetic project-row defect + * (path_only) — the node/edge data is intact. The dump-verify must RETAIN + * (path_only) like #557, not delete. Caught by self-indexing the repo with + * repo_path="." (which failed with status=error before the fix). */ +TEST(gbuf_dump_relative_root_path_retained) { + char path[256]; + ASSERT_EQ(gbuf_make_temp_db(path, sizeof(path)), 0); + + cbm_gbuf_t *gb = cbm_gbuf_new("proj", "."); + ASSERT_NOT_NULL(gb); + cbm_gbuf_upsert_node(gb, "Function", "main", "proj.main", "main.c", 1, 2, "{}"); + + /* Must succeed (DB retained) despite the relative "." root_path. */ + ASSERT_EQ(cbm_gbuf_dump_to_sqlite(gb, path), 0); + + /* The DB file must still exist (not deleted by the verify). */ + FILE *f = fopen(path, "rb"); + ASSERT_NOT_NULL(f); + if (f) { + fclose(f); + } + + unlink(path); + cbm_gbuf_free(gb); + PASS(); +} + SUITE(graph_buffer) { /* Original tests */ RUN_TEST(gbuf_create_free); @@ -1110,4 +1139,6 @@ SUITE(graph_buffer) { /* B1 pipeline-path isolation (#23) */ RUN_TEST(gbuf_dump_pipeline_path_integrity); + /* Relative root_path retain regression (#57 self-index finding) */ + RUN_TEST(gbuf_dump_relative_root_path_retained); }