Skip to content

fix(oracle): knowledge-page search with an Oracle Text index - #4804

Merged
nicoloboschi merged 2 commits into
vectorize-io:mainfrom
rodrigoedu94-png:fix/oracle-knowledge-text-search
Oct 5, 2026
Merged

nicoloboschi merged 2 commits into
vectorize-io:mainfrom
rodrigoedu94-png:fix/oracle-knowledge-text-search

Conversation

@rodrigoedu94-png

@rodrigoedu94-png rodrigoedu94-png commented Sep 26, 2026 •

Copy link
Copy Markdown
Contributor

Summary

search_knowledge_pages returns 500 on the Oracle backend on every path:

  • BM25 arm: knowledge_bm25_arm only knows PostgreSQL text-search backends, so Oracle receives ts_rank_cd(...) / @@:
    ORA-00904: "TS_RANK_CD": invalid identifier
    
  • Snippet: all three queries select LEFT(mm.content, 280); Oracle has no LEFT() (ORA-00904: "LEFT"), so even the vector-only path fails.
  • There is no text index on mental_models on Oracle (the baseline only indexes memory_units(text)).

Fix

  • Rewriter (engine/db/oracle.py): LEFT(expr, n) → DBMS_LOB.SUBSTR(expr, n, 1) (VARCHAR2 and CLOB, returns VARCHAR2). LEFT JOIN is untouched.
  • Oracle arm (knowledge_bm25_arm(..., backend_type="oracle")): CONTAINS(mm.content, …, 1) > 0 / SCORE(1) DESC, mirroring the memory-recall arm. The dialect joins terms with OR; this arm swaps it for ACCUM so pages matching more query terms rank higher (with OR, Oracle Text scores a document by its best single term, and common words in natural-language questions pulled the wrong page up in the RRF fusion). memory_engine passes the connection's backend_type. PostgreSQL behaviour is unchanged.
  • Migration c8e2f4a6b1d3: Oracle Text CTXSYS.CONTEXT index idx_mental_models_text_search on mental_models(content), SYNC (ON COMMIT), idempotent (ORA-00955 ignored); PostgreSQL no-op (the index already exists there).

Tests

  • New test_oracle_uses_oracle_text_contains_and_score and TestOracleQueryRewriter::test_left_becomes_dbms_lob_substr: without the fix 2 failed, with it 33 passed (whole test_knowledge_bm25_dispatch.py + TestOracleQueryRewriter).
  • ruff check, ruff format --check and ty check clean on the changed files.
  • Verified live: the same change applied to Hindsight 0.10.1 on Oracle Autonomous Database 26ai, index created by the migration's DDL; knowledge search returns 200 with ranked pages.

Measurements (real bank, 8 knowledge pages, 32 fixed queries)

24 lexical queries (a term that appears in exactly one page) + 8 paraphrased semantic questions, same set for every run:

vector-only hybrid, OR hybrid, ACCUM
lexical hit@1 12.5% 83.3% 87.5%
semantic hit@1 100% 37.5% 100%
overall hit@1 34% 72% 91%
overall MRR 0.52 0.81 0.92
p50 latency 563 ms 564 ms 575 ms

"vector-only" is the endpoint with LEFT() fixed but the BM25 arm skipped; before this PR it returned 500.

Related Oracle fixes: #4627, #4628, #4633–#4637, #4647.

🤖 Generated with Claude Code

rodrigoedu94-png added a commit to rodrigoedu94-png/hindsight that referenced this pull request Sep 28, 2026
OR scores a row by its best single term, so a common word ranks as high
as the rare one the question is about. ACCUM matches the same rows and
ranks the ones containing more query terms higher. Measured on Oracle AI
Database 26ai (Always Free ADB) with a BEIR SciFact sample (100 queries,
1,000 docs x 2 banks, gemini-embedding-001 @1536, RRF k=60):

| Variant                  | nDCG@10 | MRR@10 | Recall@10 |
|--------------------------|---------|--------|-----------|
| keyword, OR              | 0.348   | 0.309  | 0.487     |
| keyword, ACCUM           | 0.666   | 0.656  | 0.718     |
| hybrid RRF, OR           | 0.693   | 0.640  | 0.880     |
| hybrid RRF, ACCUM        | 0.806   | 0.784  | 0.920     |

Same conclusion as the knowledge-page arm in vectorize-io#4804.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
rodrigoedu94-png and others added 2 commits October 5, 2026 18:19
search_knowledge_pages 500'd on Oracle on every path:
- the BM25 arm sent PostgreSQL ts_rank_cd/@@ (ORA-00904 "TS_RANK_CD");
- the snippet used LEFT(), which Oracle does not have (ORA-00904 "LEFT"),
  so even the vector-only path failed.

Changes:
- rewriter: LEFT(expr, n) -> DBMS_LOB.SUBSTR(expr, n, 1) (VARCHAR2 and CLOB);
- knowledge_bm25_arm: Oracle branch (backend_type="oracle") using
  CONTAINS/SCORE over the new CTXSYS.CONTEXT index, with the dialect's
  OR-joined terms switched to ACCUM so pages matching more terms rank higher;
- migration c8e2f4a6b1d3: Oracle Text index idx_mental_models_text_search on
  mental_models(content), SYNC (ON COMMIT); PostgreSQL no-op;
- tests for the rewrite and the Oracle arm.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nowledge_pages

Review fix: the backend type was looked up three times in the same block.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants