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 tsvectorSELECT to_tsvector('PostgreSQL embedded database with vectors');
-- Build a querySELECT to_tsquery('postgresql & embedded');SELECT plainto_tsquery('PostgreSQL embedded'); -- plain EnglishSELECT phraseto_tsquery('embedded database'); -- phrase form
-- RankSELECT title, ts_rank_cd(to_tsvector(body), to_tsquery('helios')) AS rankFROM articlesWHERE 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 scoreFROM chunksORDER BY score DESCLIMIT 10;Fixed
- Stale version strings —
pg_catalog.version(), theserver_versionparameter-status message, and theSHOW server_versionresponse all now useenv!("CARGO_PKG_VERSION")instead of hardcoded3.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
| Component | Version |
|---|---|
| PostgreSQL wire | 14, 15, 16 |
| MySQL wire | 5.7, 8.0 |
| MCP protocol | 1.0 |