Skip to content

Order keys after rrf() are silently ignored #787

Description

@ragnorc

Behaviour

An rrf(...) order silently ignores the order keys after it, on both engines. With four rows whose fused scores tie, order { rrf(bm25($d.body, "needle"), bm25($d.body, "needle")), $d.rank desc } limit 2 returns d1, d2 on engine v2; the keys ask for d4, d3. The same query with bm25 alone returns d4, d3, because v2 sorts a BM25 order by score, then the trailing keys, then every binding's id.

Reproduced on main (80406fee, v2) with a logic-test probe; schema Doc { slug @key, title, body @index, rank: I64 }, four rows with identical body and rank 1 to 4.

Mechanism

  • The planner plans no Sort over a fusion: optimizer.rs sort_keys returns None for Ranking::Fused ("a fusion orders its own rows").
  • RankFuseExec (engine/graph.rs fuse_arms, a copy of v1's body) sorts entities by fused score only (partial_cmp, NaN compared equal), truncates to the limit in entities, and never reads the trailing keys. The fused score is not a column, so rrf(...) cannot be projected (T37).
  • The GQT runner already encodes the gap: ordered_refusal refuses expect ordered for an rrf-led order because "fusion sorts by score alone, with no tie-break".

Expected

One total order for every search order: the fused score as a per-row column, then the trailing keys, then the binding ids, then limit cuts rows. The fused score becomes projectable under the same rule as nearest and bm25 (T33). Tracked as RFC 0047's total-order work (#791, rollout step 5).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions