This repository has been archived on 2026-04-03. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
core/docs/DESIGN-vector-column.md
Jeffrey Smith 190905b3e6
All checks were successful
CI/CD / detect-changes (push) Successful in 4s
CI/CD / test-runners (push) Has been skipped
CI/CD / test-frontend (push) Has been skipped
CI/CD / e2e-smoke (push) Has been skipped
CI/CD / test-sqlite (push) Successful in 2m59s
CI/CD / test-go-pg (push) Successful in 2m58s
CI/CD / build-and-deploy (push) Successful in 1m14s
Feat v0.8.3 vector column (#70)
Co-authored-by: Jeffrey Smith <jasafpro@gmail.com>
Co-committed-by: Jeffrey Smith <jasafpro@gmail.com>
2026-04-03 09:41:32 +00:00

2.7 KiB

Design: Vector Column Type (v0.8.3)

Problem

Extensions building semantic search, RAG, or recommendation features need to store and query high-dimensional vectors (embeddings). Without kernel-level support, each extension would need to reinvent storage, serialization, and similarity search — duplicating effort and missing the pgvector optimization path.

Design

Three-tier progressive enhancement

Backend Column DDL Storage Search
Postgres + pgvector vector(N) + HNSW index Native vector type <=> operator (index-backed)
Postgres (no pgvector) JSONB JSON array Go-side cosine distance
SQLite TEXT JSON string Go-side cosine distance

Extensions declare "vector(N)" in their manifest db_tables block. The kernel maps this to the appropriate SQL type at install time based on detected capabilities.

Manifest example

{
  "db_tables": {
    "documents": {
      "columns": {
        "title": "text",
        "embedding": "vector(384)"
      }
    }
  },
  "capabilities": {
    "optional": ["pgvector"]
  }
}

API surface

# Insert (vector as list)
db.insert("documents", {"title": "hello", "embedding": [0.1, 0.2, ...]})

# Similarity search
rows = db.query_similar(
    "documents", "embedding",
    vector=[0.1, 0.2, ...],
    limit=10,
    filters={"active": True},
    metric="cosine"
)
# → [{..., "_distance": 0.023}, ...]

Dispatch paths

pgvector path — SQL-side computation with index:

SELECT *, (embedding <=> $1::vector) AS _distance
FROM ext_pkg_documents
WHERE ... ORDER BY embedding <=> $1::vector LIMIT $2

Fallback path — Go-side computation:

  1. SELECT * FROM table WHERE filters LIMIT 1000
  2. Parse each row's vector column from JSON
  3. Compute cosine distance in Go
  4. Sort by distance, return top N with _distance injected

Dimension validation

  • Manifest: 1 ≤ N ≤ 4096 (validated by parseVectorDim)
  • Insert-time: no dimension validation (store whatever list is given)
  • Query-time: dimension mismatches produce distance = 1.0 (treated as unrelated)

Performance characteristics

Path 1K rows 10K rows 100K rows
pgvector (HNSW) <1ms <5ms <10ms
Fallback (Go) <10ms ~100ms Not recommended

Fallback caps at 1000 rows fetched. Extensions needing large-scale similarity search should declare capabilities.optional: ["pgvector"] and degrade gracefully.

Limitations

  • Only cosine distance metric (v0.8.3). L2 / inner product can be added later.
  • No dimension validation at insert time.
  • Fallback path fetches at most 1000 rows — not suitable for large datasets.
  • HNSW index is only created for pgvector backends.