Class EdgeVectorSchema
- Namespace
- Qavren.Edge.VectorData
- Assembly
- Qavren.Edge.VectorData.dll
The DDL and the queries as plain strings, so a consumer can read, log or hand-execute exactly what the provider runs - the same visible-SQL contract as sub-project 1's helpers.
Nothing here opens a connection or executes anything. Every statement is emitted with
\n line endings so the text is identical on every platform.
public sealed class EdgeVectorSchema
- Inheritance
-
EdgeVectorSchema
- Inherited Members
Constructors
- EdgeVectorSchema(CollectionModel, string, EdgeVectorStoreOptions?, bool)
Builds the schema for one collection.
Fields
- FilterPlaceholder
The token BuildKnnSql(bool, bool, bool) and BuildHybridRrfSql(bool, bool) leave where the translated filter predicate goes. The caller substitutes the SQL that
EdgeFilterTranslatorproduced; the surroundingrowid IN (SELECT "_rowid" FROM <data table> WHERE ...)is already in place, which is what makes an arbitrary MEVD filter a true vec0 pre-filter.
- VectorColumnName
The vec0 vector column. Fixed, not derived from the property's storage name: a vec0 table holds exactly one vector column, and every query in this file names it.
Properties
- CollectionName
The collection name.
- DataTable
The data table - the collection name, verbatim.
- Dimensions
The declared vector width.
- FullTextColumns
The storage names of the full-text-indexed data properties, in model order.
- FullTextTable
The FTS5 sidecar, or null when the collection has no full-text property.
- KeyColumn
The storage name of the key property.
- RowIdColumn
Always
_rowid: the INTEGER PRIMARY KEY all three tables join on.
- VectorColumn
Always
embedding: the single vec0 vector column.
- VectorTable
The vec0 virtual table.
Methods
- BuildCreateSql()
Emits the create-collection statements. See the static overload for the order.
- BuildCreateSql(CollectionModel, string, EdgeVectorStoreOptions?)
The create-collection statements, in execution order: data table, key index, one index per
IsIndexedproperty, the vec0 table, the FTS5 sidecar, its three sync triggers, and the vec0 delete cascade.
- BuildDropSql()
The drop statements, in the reverse of BuildCreateSql()'s order. The triggers go first because a trigger on a dropped table is an error on some paths and a silent orphan on others; the FTS5 sidecar goes before its content table because dropping an external-content table first leaves FTS5's shadow tables referring to nothing. Dropping the vec0 virtual table also drops its four shadow tables, which is what vec0's own destructor is for, so none of them is named here.
- BuildHybridRrfSql(bool, bool)
The hybrid query: a vec0 KNN lane and an FTS5 bm25 lane, fused by reciprocal rank.
Both lanes rank ascending. FTS5's
bm25()is the standard score multiplied by -1, so a better match is numerically lower, and vec0'sdistanceis a distance. The hiddenrankcolumn is used rather than callingbm25(f), which SQLite's own docs say is faster.The keyword lane says
f."<fts table>" MATCH $keywords- the alias qualifying the table-named hidden column - and not the bare aliasf MATCH $keywords. FTS5 gives every table a hidden column named after the table, and<x> MATCH <expr>is an ordinary comparison against a column, so a bare alias resolves as a column reference and SQLite answersno such column: f. Measured against SQLite 3.53.4 + FTS5 on 2026-09-11; spec 13.3's claim that the bare alias is the only spelling that parses is wrong in both directions, and the spec is the side that is being corrected.The fused
scoreis a similarity - higher is better - the opposite polarity to BuildKnnSql(bool, bool, bool)'s distance.
- BuildKnnSql(bool, bool, bool)
The vec0 KNN query. The filter, when present, is pushed in as
v.rowid IN (SELECT "_rowid" FROM <data table> WHERE ...): vec0's BestIndex claims arowid IN (...)constraint withomit = 1and ANDs the bitmap into the chunk validity bitmap before any distance is computed, so this is a true pre-filter and never degrades to a client-side pass.
- BuildMatchExpression(ICollection<string>, KeywordCombinator, string?)
Quotes each keyword as an FTS5 string literal, doubling any embedded quote, and joins them. Quoting is what makes FTS5 treat a token as a phrase, so
AND,OR,NOT,NEAR,*,^,:and parentheses inside a keyword are inert rather than operators. This is the package's one injection surface.
- BuildUpsertSql()
The record write.
INTEGER PRIMARY KEYis a true rowid alias and is stable acrossON CONFLICT DO UPDATE, so the returned_rowidis the same integer the vec0 and FTS5 sides are keyed on.