Skip to content

fix(gfql): show_indexes reports engine usability, not just fingerprint validity - #1841

Open
lmeyerov wants to merge 2 commits into
masterfrom
fix/gfql-show-indexes-engine-usability
Open

fix(gfql): show_indexes reports engine usability, not just fingerprint validity#1841
lmeyerov wants to merge 2 commits into
masterfrom
fix/gfql-show-indexes-engine-usability

Conversation

@lmeyerov

@lmeyerov lmeyerov commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

Lineage: the one unlanded piece of #1767's disposition

#1767 was retracted after measurement showed it regressed the default path 125–534×. Its disposition comment proposed replacing it with a diagnostic instead:

Proposing instead to close this and replace it with the diagnostic: make an engine-mismatched decline loud (and stop show_indexes() reporting valid=True for an index the resolved query engine cannot use).

#1838 landed the first half — gfql_explain/index_trace now name the mismatch via _engine_mismatch_reason. This PR lands the second half: the inspection surface itself. On master today, show_indexes() still says valid=True for every index in the disposition's measured cells, including the ones being declined at query time — the user inspecting their own index state is told it is fine while paying a silent 100–500× cliff (the disposition's words, not a new measurement; no perf claims are made here).

What it does

valid keeps its fingerprint-only meaning, so nothing existing breaks. Three columns are added:

column meaning
query_engine what the engine argument (default 'auto') resolves to for THIS graph — the same resolve_engine call a query makes
usable fresh AND built for the resolved engine
reason why not — engine mismatches reuse #1838's exact wording via a shared formatter (resident edge_out_adj index engine=polars, requested engine=pandas -> scan), plus a stale-fingerprint reason

So the disposition's headline case now reads honestly: a polars-built index on a graph whose AUTO queries resolve to pandas shows valid=True, usable=False with the same reason string gfql_explain gives for the decline.

Surfaces wired through: g.show_indexes(engine=...) previews an explicit engine choice; SHOW GFQL INDEXES respects the gfql(engine=...) of the call; gfql_explain passes its engine into the resident-index table it embeds.

Mechanism reuse, not a parallel one

The per-row reason and the #1838 trace diagnostic share one formatter (_engine_mismatch_text), so the two surfaces can never drift apart in wording; the existing exact-string pins on the explain side (test_explain_reports_bidirectional_engine_mismatch) keep guarding both.

Explicitly NOT a routing change

No query planning or engine resolution is altered anywhere — reporting only. #1743 (AUTO → native routing) remains on hold, untouched.

Tests

9 new in TestShowIndexesEngineUsability:

  • positive: matching engine usable; polars index + AUTO(pandas) query not-usable with exact reason; explicit engine='polars' preview usable; cudf lane (importorskip-guarded, mirrors the suite's existing cudf gating)
  • negative: pandas index under explicit polars preview; stale-but-engine-matched is not usable (and not "usable-fresh"); stale+mismatched reports both reasons; per-kind reasons across all four index kinds; DDL SHOW GFQL INDEXES honors AUTO vs explicit engine

Local (CPU, GPU lanes deselected — box has no GPU): graphistry/tests/compute/gfql/index/ 219 passed, 1 skipped. ./bin/lint.sh (incl. type-hygiene guard) and MYPY_CMD="uvx mypy==2.3.0" ./bin/mypy.sh on the touched files: clean.

CHANGELOG: entry under Development/Fixed; docs: indexing.rst liveness section now explains usable/reason.

🤖 Generated with Claude Code

https://claude.ai/code/session_011AB4RZpph3uSFUpzKnZJcr

lmeyerov and others added 2 commits August 1, 2026 17:49
…t validity

show_indexes() claimed valid=True for an index the resolved query engine
cannot use. Indexes are engine-specific, so a fingerprint-fresh index built
for another engine (e.g. polars-built, inspected on a graph whose AUTO
queries resolve to pandas) silently declines to a scan at query time while
the inspection surface said everything was fine.

This is the follow-up proposed in #1767's disposition comment ("stop
show_indexes() reporting valid=True for an index the resolved query engine
cannot use"). #1838 made the decline loud in gfql_explain via
_engine_mismatch_reason; this completes the pair on show_indexes by reusing
the same mechanism and wording rather than inventing a parallel one.

- valid keeps its fingerprint-only meaning (backward compatible)
- new columns: query_engine (what engine= resolves to for THIS graph, the
  same resolution a query makes; default 'auto'), usable (fresh AND
  engine-matched), reason (shared #1838 mismatch wording + stale reason)
- show_indexes(engine=...) previews an explicit engine choice; SHOW GFQL
  INDEXES respects the gfql(engine=...) of the call; gfql_explain passes
  its engine through
- reporting-only: no query routing changes (#1743 AUTO-routing stays held)

Tests: 9 new (polars index vs AUTO/pandas query not-usable with exact
reason, matching-engine usable, explicit-engine preview both directions,
stale-but-engine-matched not usable, stale+mismatched combined reason,
per-kind reasons across all four index kinds, DDL surface, cudf lane with
import skip-guard). Index suite: 219 passed, 1 skipped locally (GPU lanes
deselected, no GPU on this box). Lint + scoped mypy clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011AB4RZpph3uSFUpzKnZJcr
Resolve CHANGELOG.md conflict by keeping both Fixed entries: this PR's
show_indexes engine-usability entry and master's gfql_clear_caches
registry entry (#1836).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011AB4RZpph3uSFUpzKnZJcr
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant