query

package
v0.0.0-...-effd846 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 29, 2026 License: Apache-2.0 Imports: 14 Imported by: 0

Documentation

Overview

Package query is vec's read-path query engine: the cost-based planner that turns a bound logical query into a physical plan (spec 13) and the vectorized executor that runs that plan against the index SPI, the storage engine, and the distance kernels (spec 10).

The package sits above storage ([04]), index ([07], [08]), distance ([09]), and catalog ([02]), and below the VectorSQL frontend ([12], task 14) and the library facade ([14], task 15). The frontend produces the BoundQuery this package consumes; the planner emits a PhysicalPlan; the executor walks it.

The one defining constraint is latency: the SLO is p50 < 1 ms for 1M x 768-dim HNSW recall@10 >= 0.95 on a single node (spec 10 §intro). Late materialization, the bounded top-k heap, and the per-query scratch arena are the levers.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrDimensionMismatch is returned when the query vector length does not match
	// the collection's vector dimension (spec 10 §20.4). Caught at plan time.
	ErrDimensionMismatch = errors.New("vec: query vector dimension does not match collection")
	// ErrQueryMemoryExceeded is returned when the per-query arena exceeds its limit
	// (spec 10 §14.3).
	ErrQueryMemoryExceeded = errors.New("vec: query exceeded memory limit")
	// ErrIndexSearch wraps a failure from the Index SPI Search method (spec 10 §23.1).
	ErrIndexSearch = errors.New("vec: index search failed")
	// ErrStorageRead wraps a storage engine read failure (spec 10 §23.1).
	ErrStorageRead = errors.New("vec: storage read error")
	// ErrNoIndex is returned when no access path is available and flat scan was not
	// permitted (spec 10 §23.1).
	ErrNoIndex = errors.New("vec: no suitable index for this query")
	// ErrInvalidEfSearch is returned when ef_search is below k (spec 10 §23.1); the
	// executor normally clips it up, so this is reserved for strict mode.
	ErrInvalidEfSearch = errors.New("vec: ef_search must be >= k")
	// ErrInvalidK is returned when k < 1 (spec 10 §23.1).
	ErrInvalidK = errors.New("vec: k must be >= 1")
	// ErrNoCollection is returned when the plan references a collection the executor
	// was not given a binding for.
	ErrNoCollection = errors.New("vec: no collection binding for plan")
)

The executor's error set (spec 10 §23.1). Logic errors are caught at plan or Open time; index and storage errors bubble up from the SPI; context errors produce partial results (spec 10 §15).

Functions

This section is empty.

Types

type Batch

type Batch struct {
	NumRows int
	Sel     []uint16 // selection vector; nil means all NumRows rows are live
	NumSel  int

	Pos     []uint32          // dense internal positions (spec 10 §7.2)
	Dist    []float32         // distance (kNN) or score (hybrid), nearest/highest first
	PointID []uint64          // resolved external point ids (Project fills, spec 10 §13.1)
	Vecs    [][]float32       // full-precision vectors gathered for rerank (spec 10 §7.3)
	Meta    []storage.MetaRow // projected metadata rows (spec 10 §13.2)
}

Batch is the columnar unit that flows between operators (spec 10 §6.2). The generic spec model is a []Vector keyed by type; vec's read path only ever moves positions, distances, point ids, full-precision vectors, and metadata rows, so this is a struct-of-arrays specialization of that model. Each column is valid for the first NumRows entries, or, when Sel is non-nil, only at the indices in Sel[:NumSel] (the selection vector, spec 10 §6.3).

type BoundQuery

type BoundQuery struct {
	// Vector is the query vector (full precision). Required for a kNN query.
	Vector []float32
	// K is the LIMIT (spec 13 §4.4); the number of rows to return.
	K int
	// Metric is the distance metric resolved from the operator/opclass (spec 13 §4.3).
	Metric distance.Metric

	// Predicate is the WHERE filter over metadata columns, or nil (spec 13 §5.4).
	Predicate storage.Predicate
	// Selectivity overrides the planner's estimate when >= 0; -1 means estimate it
	// from column statistics (spec 13 §7.4).
	Selectivity float64

	// Project lists the metadata column names to return (spec 10 §13.2).
	Project []string
	// IncludeDistance asks the executor to surface the distance/score column.
	IncludeDistance bool

	// RecallTarget is the recall lower bound ef/nprobe must satisfy (spec 13 §4.5),
	// 0 falls back to the default.
	RecallTarget float64

	// EfSearch, when > 0, pins the HNSW beam width and skips recall-based selection
	// (spec 10 §4.5 per-query WITH override). NProbe does the same for IVF.
	EfSearch int
	NProbe   int
	// RerankR, when > 0, pins the rerank candidate count (spec 10 §8.2).
	RerankR int
	// AllowFlat permits a flat-scan fallback when no index matches (spec 10 §23.1).
	AllowFlat bool
	// Timeout bounds the execution; 0 uses the executor default (spec 10 §15.2).
	Timeout time.Duration
}

BoundQuery is the planner's input: a query already resolved against the catalog by the binder ([12], task 14). It names one collection, an optional metadata predicate, the kNN clause, and the projection. The planner consumes it; until the SQL frontend lands, the db layer and tests build it directly.

type Collection

type Collection struct {
	Engine *storage.Engine
	CollID uint64
	Dims   int
	Metric distance.Metric

	// Index is the primary ANN index over the vector column, or nil when only a
	// flat brute-force scan is available (spec 10 §2.4).
	Index index.Index
	// IndexKind tells the planner which cost formula applies (spec 13 §6).
	IndexKind PathKind
	// HNSW build parameters, for the analytical recall fallback (spec 13 §6.4).
	M, EfConstruction int
	// NList is the IVF cell count, for nprobe selection (spec 13 §6.5).
	NList int

	// MetaCols maps a metadata column name to its engine column id, for projection.
	MetaCols map[string]storage.ColID
}

Collection is the executor's binding to one collection's physical resources (spec 10 §18.1): the storage engine, the primary ANN index (nil for flat-only), the vector geometry, and the metadata column-id map. The db layer ([14], task 15) builds it from a catalog.Collection plus the index handle; the planner reads its shape to choose an access path and the executor reads it to run operators.

type ExecContext

type ExecContext struct {
	Ctx      context.Context
	Snapshot storage.Snapshot
	Arena    *QueryArena
	Pool     *WorkerPool
	Stats    *QueryStats
	Coll     *Collection
}

ExecContext carries everything an operator needs that is not in the plan (spec 10 §18.1): cancellation, the MVCC snapshot, the scratch arena, the shared worker pool, the stats sink, and the storage binding.

type Executor

type Executor struct {
	// contains filtered or unexported fields
}

Executor runs a PhysicalPlan against a collection (spec 10 §1.2). One executor is bound to one collection; it is safe for concurrent Execute calls because every query gets its own snapshot, arena, stats, and operator tree.

func NewExecutor

func NewExecutor(coll *Collection, opts ...ExecutorOption) *Executor

NewExecutor binds an executor to a collection (spec 10 §18.1).

func (*Executor) Execute

func (e *Executor) Execute(ctx context.Context, plan PhysicalPlan, vector []float32) (rs ResultSet, err error)

Execute runs a query end to end: pin a snapshot, derive the deadline, build the operator tree from the plan, drive it to completion, and assemble the result set (spec 10 §1.2). A cancelled or timed-out query returns the rows gathered so far with Partial set (spec 10 §15.4). A panic in an operator (including an arena overflow) is recovered into an error (spec 10 §17.2).

func (*Executor) ExecuteHybrid

func (e *Executor) ExecuteHybrid(ctx context.Context, req HybridRequest) (rs ResultSet, err error)

ExecuteHybrid runs a fused dense-plus-lexical query (spec 11 §10). It runs the dense pipeline to a ranked candidate pool, fuses it with the supplied modality lists, applies the metadata predicate to the fused result when the plan post-filters, trims to k, and assembles the rows. The non-dense lists are produced by the caller through the hybrid package, keeping this method modality-agnostic.

type ExecutorOption

type ExecutorOption func(*Executor)

ExecutorOption configures an executor.

func WithDefaultTimeout

func WithDefaultTimeout(d time.Duration) ExecutorOption

WithDefaultTimeout sets the deadline applied to queries that do not carry their own (spec 10 §15.2).

func WithMemoryLimit

func WithMemoryLimit(bytes int64) ExecutorOption

WithMemoryLimit caps per-query arena bytes; a query that exceeds it fails with ErrQueryMemoryExceeded (spec 10 §14.3).

func WithWorkers

func WithWorkers(n int) ExecutorOption

WithWorkers sets the parallelism degree for flat scans (spec 10 §12.5).

type FilterStrategy

type FilterStrategy uint8

FilterStrategy is how a metadata predicate is applied relative to ANN search (spec 13 §8.3, spec 10 §9.1).

const (
	FilterNone FilterStrategy = iota // no predicate
	FilterPre                        // build a bitmap, restrict the index walk
	FilterIn                         // ACORN-style in-graph filtering (bitmap to index)
	FilterPost                       // search unfiltered, drop non-matching candidates
)

func (FilterStrategy) String

func (f FilterStrategy) String() string

String renders a FilterStrategy for EXPLAIN.

type HybridRequest

type HybridRequest struct {
	Plan    PhysicalPlan
	Vector  []float32
	Extra   [][]hybrid.ScoredPos
	Method  hybrid.FusionMethod
	Weights []float64
	RRFK    float64
	// OverFetch multiplies k for the dense candidate pool before fusion (spec 11
	// §10.3); 0 uses 3x.
	OverFetch int
}

HybridRequest describes one fused query (spec 11 §10.3): the dense plan and vector, the extra ranked lists from the non-dense modalities (BM25, sparse, MaxSim) already scored by the hybrid package, the fusion method and weights, and the RRF constant. The dense list is always list 0 of the fusion; Weights, when set, line up with [dense, extra0, extra1, ...].

type PathKind

type PathKind uint8

PathKind is the access path an ANN search resolves to (spec 13 §8.2).

const (
	PathFlat    PathKind = iota // brute-force exact scan (spec 13 §6.3)
	PathHNSW                    // HNSW graph search (spec 13 §6.4)
	PathIVF                     // IVF / IVF-PQ search (spec 13 §6.5)
	PathDiskANN                 // disk-resident beam search (spec 13 §6.6)
)

func (PathKind) String

func (p PathKind) String() string

String renders a PathKind for EXPLAIN.

type PhysicalPlan

type PhysicalPlan struct {
	Path        PathKind
	Filter      FilterStrategy
	K           int
	EfSearch    int
	NProbe      int
	Metric      distance.Metric
	Rerank      bool
	RerankR     int
	Project     []string
	IncludeDist bool

	// Predicate is carried through for the executor to build the filter bitmap.
	Predicate storage.Predicate
	// AllowWiden permits adaptive ef widening on post-filter exhaustion (spec 10 §1.5).
	AllowWiden bool
	// MaxEfSearch bounds adaptive widening (spec 10 §4.6).
	MaxEfSearch int
	// Timeout is the query deadline (spec 10 §15.2).
	Timeout time.Duration

	// EstCost and EstRecall are the planner's estimates, surfaced by EXPLAIN
	// (spec 13 §8.2).
	EstCost   float64
	EstRecall float64
}

PhysicalPlan is the planner's output: the fully committed execution choices the executor walks without re-planning (spec 10 §1.3). It is an annotation record, not the operator tree; the executor builds operators from it at Execute time.

type Planner

type Planner struct {
	// contains filtered or unexported fields
}

Planner turns a BoundQuery into a PhysicalPlan using a cost model with a recall dimension (spec 13 §1.3). It estimates selectivity from column statistics, picks an access path (flat vs the collection's ANN index), chooses a filter strategy, and sizes ef/nprobe to the recall target. The choices are committed into the PhysicalPlan; the executor never re-plans.

func NewPlanner

func NewPlanner(coll *Collection, cacheCap int) *Planner

NewPlanner returns a planner bound to one collection with an LRU plan cache of the given capacity (spec 13 §13.2); cap <= 0 disables caching.

func (*Planner) Plan

func (pl *Planner) Plan(q BoundQuery) (PhysicalPlan, error)

Plan produces the physical plan for q. Equivalent bound queries hit the LRU cache (spec 13 §13.2); a cache miss runs the full cost-based selection.

type QueryArena

type QueryArena struct {
	// contains filtered or unexported fields
}

QueryArena is the per-query scratch allocator (spec 10 §14.2). It hands out transient backing memory for candidate slices, rerank buffers, and fusion maps, then is dropped whole at query end so the GC reclaims it in one shot rather than per object. A non-zero Limit caps total bytes and trips ErrQueryMemoryExceeded (spec 10 §14.3), which the executor recovers into an error.

func (*QueryArena) Used

func (a *QueryArena) Used() int64

Used reports the bytes handed out so far (spec 10 §18.3 ArenaUsedBytes).

type QueryStats

type QueryStats struct {
	ANNCandidatesReturned  int64
	ANNRetries             int32
	PreFilterBitmapSize    int64
	PostFilterEvaluated    int64
	PostFilterSurvived     int64
	RerankCandidates       int32
	FlatScanned            int64
	BM25CandidatesReturned int64
	FuseCombined           int64
	ArenaUsedBytes         int64
}

QueryStats accumulates per-operator counters over one execution (spec 10 §18.3). The executor returns it on the ResultSet and EXPLAIN ANALYZE renders it.

type ResultSet

type ResultSet struct {
	Rows          []Row
	Partial       bool
	PartialReason string
	Stats         QueryStats
}

ResultSet is the executor's output (spec 10 §13.3). For kNN queries all rows are known when Execute returns, so it is a materialized slice plus the partial-result flags and the collected stats.

type Row

type Row struct {
	PointID  storage.PointID
	Distance float32
	Meta     map[string]storage.Value
}

Row is one assembled result row (spec 10 §13.2): the external point id, the distance or fused score, and the projected metadata keyed by column name.

type WorkerPool

type WorkerPool struct {
	// contains filtered or unexported fields
}

WorkerPool is the shared, bounded goroutine pool for intra-query parallelism (spec 10 §12.5). Size defaults to GOMAXPROCS at the executor level.

func NewWorkerPool

func NewWorkerPool(n int) *WorkerPool

NewWorkerPool returns a pool that runs up to n concurrent jobs (spec 10 §12.5).

func (*WorkerPool) Workers

func (p *WorkerPool) Workers() int

Workers returns the configured parallelism degree.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL