infiniflow / infiniflow/infinity

[Bug]: HTTP SDK explain() silently drops match_*/fusion search clauses

Open
#3,438 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
C++
Stars
4.7k
Forks
445
Avg merge
2d 2h
Merged PRs (30d)
7

Description

Is there an existing issue for the same bug?
  • I have checked the existing issues.
Version or Commit ID

main @ 4954148 (current main as of 2026-09-08)

Other environment information

Actual behavior and How to reproduce it

In the Python HTTP SDK (python/infinity_sdk/infinity/infinity_http.py), table_http_result.explain() builds its request body from self._fusion, self._knn, self._match, self._match_tensor and self._match_sparse. These five lists are initialized to [] in init and never populated anywhere else - every match_dense / match_text / match_tensor / match_sparse / fusion method appends to self._search_exprs instead (which select() sends under the "search" key).

So over HTTP:

table.output(["c1"]).match_dense("vec", [0.1, 0.2, 0.3, 0.4], "float", "l2", 10).explain()

sends only {"output": ["c1"], "explain_type": "physical"}. The server's explain handler (HTTPSearch::Explain in src/network/http/http_search_impl.cpp) only parses a "search" key - it has no "knn"/"match"/"match_tensor"/"match_sparse"/"fusion" branches - so it returns the plan for a plain table scan instead of the search query. The plan you get back silently describes a different query than the one you asked about.

Repro without a server: stub table_http.net, call match_dense(...).match_text(...).fusion("rrf", ...) then explain(), and inspect the dict passed to net.set_up_data - there is no "search" key, while select() on the same builder state sends one. The thrift client passes search_expr correctly, so the two SDKs disagree on the same call.

Expected behavior

explain() should send the same "search" payload as select(), and the returned plan should include the match operators (e.g. KNN SCAN for a match_dense query).

Additional information

Root cause: leftover fields from before the match_* methods were consolidated into _search_exprs. Fix is to build the explain request from self._search_exprs under the "search" key and drop the dead fields. PR with the fix plus a regression test (test_explain_with_match_dense asserting KNN SCAN appears in the physical plan) coming.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in python/infinity_sdk/infinity/infinity_http.py and compare table_http_result.explain() with select(), then reproduce the stubbed net.set_up_data case. Done means explain sends the search payload and test_explain_with_match_dense verifies that KNN SCAN appears in the physical plan.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
api
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.