Version: codebase-memory-mcp v0.8.1
Problem
There is no statement-level signal for "an ORM/query call happens inside a loop". The only in-loop signals on Function/Method are linear_scan_in_loop, alloc_in_loop, recursion_in_loop. So any N+1 detection has to be done at function granularity: "this function has a loop AND somewhere calls .filter()". That cannot distinguish:
rows = list(qs.filter(active=True)) # materialized ONCE, outside the loop ✅ fine
for r in rows: # iterating an in-memory list — NOT N+1
do(r)
from the real N+1:
for pk in pks:
obj = Model.objects.get(pk=pk) # query INSIDE the loop ❌ N+1
Both look identical to a function-level query (loop_count>=1 + CALLS → get/filter), so the first is a false positive.
Repro
There is no property to query; get_graph_schema() shows Function props include
loop_count, loop_depth, linear_scan_in_loop, alloc_in_loop, recursion_in_loop
but no orm_call_in_loop / query_in_loop. A user N+1 query (loop + ORM call) therefore mis-flags list(qs.filter())-outside-loop patterns.
Requested
- Add a statement-scoped signal analogous to
linear_scan_in_loop, e.g. orm_call_in_loop (count of ORM/DB-query calls whose call-site is lexically inside a loop body), and/or
- A
query_in_loop boolean. ORM call recognition can mirror whatever powers route/HTTP extraction (Django objects.*, SQLAlchemy session.*, Sequelize, etc.).
- Bonus: don't count calls whose result is assigned via
list(...)/tuple(...) before the loop (materialization).
Why
linear_scan_in_loop already proves the analyzer can attribute calls to loop scope; extending it to ORM calls would make N+1 detection precise instead of heuristic.
Version: codebase-memory-mcp v0.8.1
Problem
There is no statement-level signal for "an ORM/query call happens inside a loop". The only in-loop signals on Function/Method are
linear_scan_in_loop,alloc_in_loop,recursion_in_loop. So any N+1 detection has to be done at function granularity: "this function has a loop AND somewhere calls.filter()". That cannot distinguish:from the real N+1:
Both look identical to a function-level query (
loop_count>=1+CALLS → get/filter), so the first is a false positive.Repro
There is no property to query;
get_graph_schema()shows Function props includeloop_count, loop_depth, linear_scan_in_loop, alloc_in_loop, recursion_in_loopbut no
orm_call_in_loop/query_in_loop. A user N+1 query (loop + ORM call) therefore mis-flagslist(qs.filter())-outside-loop patterns.Requested
linear_scan_in_loop, e.g.orm_call_in_loop(count of ORM/DB-query calls whose call-site is lexically inside a loop body), and/orquery_in_loopboolean. ORM call recognition can mirror whatever powers route/HTTP extraction (Djangoobjects.*, SQLAlchemysession.*, Sequelize, etc.).list(...)/tuple(...)before the loop (materialization).Why
linear_scan_in_loopalready proves the analyzer can attribute calls to loop scope; extending it to ORM calls would make N+1 detection precise instead of heuristic.