Skip to content

HeliosDB Nano v3.13.0 Release Notes

HeliosDB Nano v3.13.0 Release Notes

Release Date: 2026-04-19 Theme: PostgreSQL-compatible BM25 full-text search, surfaced through SQL


Highlights

BM25 has been in the engine since v3.11 (search::Bm25Index) but unreachable from SQL. v3.13.0 lights up the full PostgreSQL FTS surface — tsvector, tsquery, @@, ts_rank_cd, to_tsvector, plainto_tsquery, phraseto_tsquery, plus CREATE INDEX … USING gin for ORM/migration compatibility.

Net effect: existing PG-FTS code paths and migration scripts compile and run. EasyRAG (foor.network/easyrag) was client-side reranking with rank_bm25.BM25Okapi; that workaround can now be deleted.


What’s New

Scalar FTS Functions

-- Tokenise text into a tsvector
SELECT to_tsvector('PostgreSQL embedded database with vectors');
-- Build a query
SELECT to_tsquery('postgresql & embedded');
SELECT plainto_tsquery('PostgreSQL embedded'); -- plain English
SELECT phraseto_tsquery('embedded database'); -- phrase form
-- Rank
SELECT title, ts_rank_cd(to_tsvector(body), to_tsquery('helios')) AS rank
FROM articles
WHERE to_tsvector(body) @@ to_tsquery('helios')
ORDER BY rank DESC LIMIT 10;

All round-trip as Value::Json (array of normalised tokens) so they flow through PG wire protocol unchanged and render as JSON arrays for introspection.

@@ Operator

tsvector @@ tsquery → boolean. New BinaryOperator::TsMatch in the logical plan, wired in the planner from SqlBinaryOp::AtAt and evaluated via the shared search::tokenizer + in-memory match.

TSVECTOR / TSQUERY Column Types

Accepted in CREATE TABLE. Stored internally as DataType::Json.

CREATE TABLE articles (
id SERIAL PRIMARY KEY,
body TEXT,
body_tsv TSVECTOR
);

CREATE INDEX … USING gin | gist (col)

Accepted as DDL for ORM/migration compatibility. The index itself is a no-op currently — @@ still walks rows in the evaluator — but the syntax round-trips cleanly so Django, SQLAlchemy, and hand-written migrations load without errors.

Hybrid Search (FTS + Vector)

Combine BM25 and vector similarity in one query:

SELECT id, text,
0.7 * (1.0 - (embedding <=> $1::vector))
+ 0.3 * ts_rank_cd(to_tsvector(text), plainto_tsquery($2)) AS score
FROM chunks
ORDER BY score DESC
LIMIT 10;

Fixed

  • Stale version stringspg_catalog.version(), the server_version parameter-status message, and the SHOW server_version response all now use env!("CARGO_PKG_VERSION") instead of hardcoded 3.7.0 / 3.10.0 / 17.0 (HeliosDB Nano 2.0) strings that had drifted across releases.

Documentation

  • docs/compatibility/fts.md — honest scope: token match, BM25 rank, JSON-encoded tsvector ✅; stemming, phrase queries, setweight(), persistent GIN ❌.
  • tests/fts_tests.rs — 8 regression cases (tsvector construction, @@ match/miss, rank, GIN DDL, NULL propagation, version-string drift).

Migration

No breaking changes. Existing to_tsvector / @@ code paths from prior PG-FTS deployments work as-is. No schema migration required — tsvector columns can be added and populated in place.


Known Limitations

  • GIN/GIST indexes are accepted DDL but are no-ops; @@ walks rows. Persistent FTS index lands in a follow-up.
  • Stemming and full phrase-query semantics are out of scope for v3.13.

Compatibility Matrix

ComponentVersion
PostgreSQL wire14, 15, 16
MySQL wire5.7, 8.0
MCP protocol1.0