mirror of
https://github.com/DeusData/codebase-memory-mcp.git
synced 2026-11-04 10:48:20 +00:00
fix(cypher): label-filtered edge traversal silently truncates at 10 results
MATCH (c:Class)-[:DEFINES_METHOD]->(m:Method) returned at most 10 results for any class, regardless of how many methods it actually has. Root cause: bind_cap was set to scan_count (the number of nodes matched in the initial pattern — typically 1 when querying a single class by name). max_new = bind_cap * 10 = 10, so the edge expansion loop exited after collecting 10 results. No error, no warning, no truncation indicator. This is language-agnostic: any class with more than 10 methods in any language was silently truncated. The fix is two characters: bind_cap = scan_count > max_rows ? scan_count : max_rows Regression test: a Python class with 15 methods must return all 15 via MATCH (c:Class)-[:DEFINES_METHOD]->(m:Method) with label filtering. Signed-off-by: Thomas Dyar <tdyar@intersystems.com>
This commit is contained in:
1 parent
e599df1d56
commit
c43fc8df0e
2 files changed
+41
-8
No files matched your search
+1
-1
@@ -4201,7 +4201,7 @@ static int execute_single(cbm_store_t *store, cbm_query_t *q, const char *projec
|
||||
scan_pattern_nodes(store, project, max_rows, &pat0->nodes[0], &scanned, &scan_count);
|
||||
|
||||
/* Build initial bindings with early WHERE */
|
||||
int bind_cap = scan_count > 0 ? scan_count : SKIP_ONE;
|
||||
int bind_cap = scan_count > max_rows ? scan_count : (max_rows > 0 ? max_rows : SKIP_ONE);
|
||||
binding_t *bindings = malloc((bind_cap + SKIP_ONE) * sizeof(binding_t));
|
||||
int bind_count = 0;
|
||||
const char *var_name = pat0->nodes[0].variable ? pat0->nodes[0].variable : "_n0";
|
||||
|
||||
@@ -400,8 +400,8 @@ TEST(incr_modify_file) {
|
||||
|
||||
/* Single-file incremental should be faster than full */
|
||||
if ((int)ms > (int)(g_full_index_ms * 1.5)) {
|
||||
printf(" [PERF WARNING] incremental slower than 1.5x full: %.0fms vs %.0fms\n",
|
||||
ms, g_full_index_ms);
|
||||
printf(" [PERF WARNING] incremental slower than 1.5x full: %.0fms vs %.0fms\n", ms,
|
||||
g_full_index_ms);
|
||||
}
|
||||
|
||||
printf(" [perf] modify 1 file: %.0fms (full was %.0fms)\n", ms, g_full_index_ms);
|
||||
@@ -910,12 +910,12 @@ static int resp_lacks_key(const char *resp, const char *key) {
|
||||
}
|
||||
|
||||
/* Helper: assert tool call succeeds, warn if slow */
|
||||
#define TOOL_OK(resp, ms) \
|
||||
do { \
|
||||
ASSERT((resp) != NULL); \
|
||||
if ((int)(ms) > PERF_WARN_MS) { \
|
||||
#define TOOL_OK(resp, ms) \
|
||||
do { \
|
||||
ASSERT((resp) != NULL); \
|
||||
if ((int)(ms) > PERF_WARN_MS) { \
|
||||
printf(" [PERF WARNING] tool call: %.0fms (>%dms)\n", (ms), PERF_WARN_MS); \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* Helper: assert response is not an error */
|
||||
@@ -932,6 +932,38 @@ TEST(tool_list_projects_basic) {
|
||||
PASS();
|
||||
}
|
||||
|
||||
TEST(tool_qg_defines_method_more_than_10) {
|
||||
write_file_at("fastapi/big_class.py", "class BigClass:\n"
|
||||
" def m1(self): pass\n"
|
||||
" def m2(self): pass\n"
|
||||
" def m3(self): pass\n"
|
||||
" def m4(self): pass\n"
|
||||
" def m5(self): pass\n"
|
||||
" def m6(self): pass\n"
|
||||
" def m7(self): pass\n"
|
||||
" def m8(self): pass\n"
|
||||
" def m9(self): pass\n"
|
||||
" def m10(self): pass\n"
|
||||
" def m11(self): pass\n"
|
||||
" def m12(self): pass\n"
|
||||
" def m13(self): pass\n"
|
||||
" def m14(self): pass\n"
|
||||
" def m15(self): pass\n");
|
||||
char *idx = index_repo();
|
||||
ASSERT(idx != NULL);
|
||||
free(idx);
|
||||
double ms;
|
||||
char *r = call_tool_timed("query_graph", &ms,
|
||||
"{\"project\":\"%s\","
|
||||
"\"query\":\"MATCH (c:Class)-[:DEFINES_METHOD]->(m:Method)"
|
||||
" WHERE c.name = 'BigClass' RETURN count(m) AS n\"}",
|
||||
g_project);
|
||||
TOOL_OK(r, ms);
|
||||
ASSERT(strstr(r, "\"15\"") != NULL || strstr(r, "\\\"15\\\"") != NULL);
|
||||
free(r);
|
||||
PASS();
|
||||
}
|
||||
|
||||
TEST(tool_list_projects_has_current) {
|
||||
double ms;
|
||||
char *r = call_tool_timed("list_projects", &ms, "{}");
|
||||
@@ -3042,6 +3074,7 @@ SUITE(incremental) {
|
||||
RUN_TEST(tool_qg_configures);
|
||||
RUN_TEST(tool_qg_handles);
|
||||
RUN_TEST(tool_qg_defines_method);
|
||||
RUN_TEST(tool_qg_defines_method_more_than_10);
|
||||
RUN_TEST(tool_qg_no_limit);
|
||||
RUN_TEST(tool_qg_empty_result);
|
||||
|
||||
|
||||
Reference in new issue
Block a user