Contents
Using pgContext Alongside pgvector
pgContext and pgvector can be installed in either order. Their SQL types are separate extension-owned objects:
- pgvector owns
public.vector,public.halfvec, andpublic.sparsevec; - pgContext owns
pgcontext.vector,pgcontext.halfvec,pgcontext.sparsevec, andpgcontext.bitvec.
The type OIDs are intentionally distinct. The main pgcontext extension has no
catalog dependency on the vector extension, so installing or dropping
pgvector does not remove or disable canonical pgContext objects.
The optional pgcontext_pgvector companion is shipped as a separate extension
artifact. Its certified profile is PostgreSQL 17, pgContext 0.2.0, and pgvector
0.8.x installed in public; installation fails closed outside that profile.
CREATE EXTENSION vector;
CREATE EXTENSION pgcontext;
CREATE EXTENSION pgcontext_pgvector; -- only for existing pgvector columns
The reverse order is valid as well.
Existing pgvector columns
The main extension does not pretend that a pgvector-owned column has a
pgContext-owned type. Direct HNSW service over an existing public.vector,
public.halfvec, or public.sparsevec column requires the separately installed
pgcontext_pgvector companion extension. That privileged bridge owns only the
certified dense binary casts, validated sparse conversion casts, and
pgvector-operator-bound opclasses; it keeps the main extension’s dependency
boundary clean.
make install installs both control/SQL artifacts. If the main extension was
installed directly with cargo pgrx install, install the SQL-only companion
and upgrade artifacts with
scripts/install-pgcontext-upgrades.sh /path/to/pg_config and
scripts/install-pgvector-bridge.sh /path/to/pg_config before
running CREATE EXTENSION pgcontext_pgvector. The companion does not activate
automatically and does not create pgvector itself.
Build a pgContext index over the existing column without changing its type:
CREATE INDEX items_embedding_pgc
ON items USING pgcontext_hnsw
(embedding pgcontext.vector_hnsw_pgvector_cosine_ops);
-- Existing pgvector-spelled SQL is unchanged and selects the index above.
SELECT id
FROM items
ORDER BY embedding <=> $1::public.vector
LIMIT 10;
The bridge exact-rechecks and reranks its bounded ANN candidate set with the
pgvector heap operator. This preserves pgvector’s double precision distance
semantics; the conservative initial lower bound favors correctness over scan
work until a tighter certified bound is available.
An existing pgvector sparse column is indexed without retyping it:
CREATE INDEX items_sparse_pgc
ON items USING pgcontext_hnsw
(lexical pgcontext.sparsevec_hnsw_pgvector_cosine_ops);
SELECT id
FROM items
ORDER BY lexical <=> $1::public.sparsevec
LIMIT 10;
pgContext currently accepts at most 16,000 sparse dimensions. Bridge index builds and conversion casts validate each packed pgvector datum and fail closed when a value exceeds that limit or is malformed. The current dense graph-record format also imposes a lower index-specific single-page envelope; index builds report that bound explicitly. The roadmap’s sparse-native graph format removes both constraints for pgvector’s full coordinate range.
Without the bridge, pgcontext.migration_report() remains available
as a read-only inventory. It discovers pgvector columns and indexes by extension
ownership, reports arrays and dependency blockers, and detects both HNSW and
IVFFlat. pgcontext.adopt_pgvector(..., dry_run => true) may be used to inspect
the proposed bridge opclasses and preserved HNSW options. Executing the plan
fails closed unless pgcontext_pgvector is installed.
Canonical pgContext columns
New pgContext-owned columns should name the type explicitly:
CREATE TABLE items (
id bigint PRIMARY KEY,
embedding pgcontext.vector(768) NOT NULL
);
CREATE INDEX items_embedding_hnsw
ON items USING pgcontext_hnsw
(embedding pgcontext.vector_hnsw_cosine_ops);
These columns remain usable after DROP EXTENSION vector. Do not use
DROP EXTENSION vector CASCADE as a migration mechanism for pgvector-owned
application columns; use the inventory and ownership-conversion workflow.
Conversion boundary
Dense vector and halfvec layouts are byte-certified and support the
metadata-only fast conversion. sparsevec has a different physical layout,
so fast conversion rejects it; use restricted_online to rewrite values
through the validated packed codec in bounded batches. PostgreSQL exposes
prepared statements only for the current backend, so drain or recycle
application sessions at a type-ownership cutover.
Use pgcontext.start_pgvector_ownership_conversion plus
run_pgvector_ownership_conversion for an atomic metadata-only conversion, or
select restricted_online for bounded shadow backfill and a caller-executed
CREATE INDEX CONCURRENTLY. The online profile requires explicit INSERT column
lists; both modes require explicit review of application and string-bodied
stored-function dependencies that PostgreSQL cannot inventory. The online
profile supports at most one source ANN index with the requested metric and
requires the caller to have schema/index-build privileges. It refuses
catalog-discoverable unsupported dependencies. After its drained cutover,
rollback_pgvector_ownership_conversion restores the synchronized pgvector
column and original index; finalize_pgvector_ownership_conversion instead
removes that rollback boundary. See
Migrating from pgvector for
the complete sequence and operational restrictions.
Dropping either prerequisite is blocked while the bridge is installed. Bridge
indexes in turn block DROP EXTENSION pgcontext_pgvector under RESTRICT.
Remove or convert those indexes first; dropping the bridge then removes its
casts, support functions, and opclasses without removing either parent
extension.
IVFFlat remains an inventory-and-plan input, not a pgContext access method. A supported conversion rebuilds it as HNSW after validation rather than claiming an in-place IVFFlat implementation.