# 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`, and `public.sparsevec`; - pgContext owns `pgcontext.vector`, `pgcontext.halfvec`, `pgcontext.sparsevec`, and `pgcontext.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. ```sql 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: ```sql 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: ```sql 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: ```sql 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](pgvector_migration.md#converting-column-ownership) 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.