Skip to content

v1.2.0

Latest

Choose a tag to compare

@Vonng Vonng released this 05 Nov 05:28

vchord 1.2.0 is the first release of the PGSTY-maintained vchord, based on VectorChord 1.1.1. It focuses on correctness, crash safety and security fixes, and supports PostgreSQL 14–18. This fork is distributed under AGPL-3.0-only.

Upgrading

  1. Install the new packages and restart PostgreSQL (vchord must stay in shared_preload_libraries).
  2. In each database: ALTER EXTENSION vchord UPDATE TO '1.2.0';

Upgrades from 0.5.3, 1.0.0, 1.1.0 and 1.1.1 produce the same schema as a fresh 1.2.0 install. The index on-disk format is unchanged, so existing indexes keep working without a rebuild. REINDEX is recommended in these cases:

  • halfvec indexes built on fp16-capable CPUs (ARM with fp16, or x86 with AVX512-FP16) whose values have large magnitudes. Distance reductions used to accumulate in binary16 and overflow, which degraded recall (for example 0.13 instead of 1.00 for halfvec(784) with values 0–255).
  • Indexes containing zero vectors or 1-dimensional vectors. Their RaBitQ metadata was NaN; on ARM a vchordrq index never returned a stored zero vector.
  • vchordg cosine indexes containing zero vectors. Normalizing a zero vector produced NaN, so they ranked first.

Security

  • vchordrq_sampled_values, vchordrq_sampled_queries and the prewarm functions opened an index without any privilege check, so any role could read other users' sampled query vectors once query sampling was enabled. They now require table ownership or SELECT on the table (or pg_read_all_stats for sampled data), and the vchordrq_sampled_queries view hides indexes the caller cannot read.
  • External index build quotes the pgvector schema and table identifiers.

Crash and resource fixes

  • Scans abandoned by an aborted subtransaction (SAVEPOINT, PL/pgSQL exception blocks, cursors in failed portals) no longer release PostgreSQL resources twice; Rust-owned objects are freed without touching released resources.
  • Cleanup during error unwinding and after aborted scans no longer raises ResourceOwnerForget errors.
  • External build: a centroid table with a long parent chain overflowed the stack and crashed the server; tree depth is now limited and cycles are reported.
  • Internal build: the sample buffer was sized from option upper bounds and an allocation failure aborted the process. It is now capped by the row count, reserved fallibly (ERROR instead of abort), and builds whose centroid working set exceeds maintenance_work_mem are refused.
  • vchordg rejects an empty alpha list instead of panicking.

Wrong results

  • PostgreSQL 17+: with the default io_rerank = read_stream, an item that stopped early (for example a vector freed by a concurrent VACUUM) left its buffers queued, and later items were silently dropped. A cursor paused across a VACUUM returned 3 of 1,999 remaining rows.
  • vchordg returned deleted rows (and permanently the start vertex) after VACUUM, pointing at reused heap TIDs.
  • vchordg sphere predicates (<<->>, <<=>>) compared the internal distance with the radius.
  • Internal k-means sampling now uses an MVCC snapshot, so dead tuples with reclaimed TOAST values are not read.
  • rabitq8/rabitq4: v <-> v returned NaN for about a third of inputs; NaN distances now sort last on every CPU.
  • MaxSim with partial probes and the default maxsim_refine = 0: documents missing from a query vector's candidates scored -inf and sorted first; they now get the worst candidate distance.
  • rabitq4 accepted 65,536–131,070 dimensions and stored rows that could not be read back (breaking SELECT, COPY and pg_dump).

Durability, statistics and planning

  • New vchordg pages and vchordrq tape pages are initialized and WAL-logged before they are linked; a crash in between could leave a chain pointing at an all-zero page.
  • A stale free space map hit no longer writes an empty WAL record and full-page image.
  • CREATE INDEX / REINDEX report real statistics instead of resetting the table's reltuples to 0.
  • ANALYZE no longer runs index cleanup, which rewrote the whole index to WAL.
  • A vchordg index (partial, or full after VACUUM ANALYZE through an index-only scan) is no longer chosen for queries without a vector clause such as count(*).
  • vchordrq cost estimation accounts for LIMIT and for filtered scans.
  • A probes count that does not match the index disables the index path at planning time, so other plans remain usable; the error is raised only if the index scan runs.

Behaviour changes

  • probes is validated when it is set: each value must be in 1..=4294967295, empty entries and spaces inside a value are rejected, and one trailing comma is accepted for compatibility with 1.1.1.
  • rabitq4/rabitq8 text and binary input reject rabitq4 codes above 15, trailing garbage and truncated binary input. Everything earlier versions produced is still accepted, including non-finite metadata, so existing dumps restore. quantize_to_rabitq* raises an overflow error instead of storing non-finite metadata.
  • Parallel index builds follow PostgreSQL's planner (plan_create_index_workers); previously any table reloption disabled them.
  • vchordrq_evaluate_query_recall no longer leaks its SET LOCAL settings into the caller's transaction, and derives ground-truth probes from the index.
  • sphere() is bound at creation time and no longer resolves types through the caller's search_path.
  • halfvec squared L2 distance on ARM is about 2× slower than in 1.1.1, in exchange for exact accumulation.

Upgrade and packaging fixes

  • The compatibility stubs for the 0.2.0–1.0.0 scripts were exported under the wrong names, so pg_upgrade of such databases failed. All C symbols referenced by shipped SQL scripts are exported again.
  • sql/install/vchord--1.1.1.sql is restored to the published 1.1.1 script, so fresh and upgraded 1.1.1 installs match.
  • Debian packages declare the pgvector dependency; release assets ship with .sha256 files.

Also included

  • Upstream VectorChord changes since 1.1.1: more f16 SIMD routines, WHPG compatibility, deferred creation of the stats database, and dependency updates.
  • pgrx 0.19.3.
  • PostgreSQL 19 RC1 builds from source with the pg19 feature for development validation. It is not part of the CI or release matrix.

Known issues

  • MaxSim accuracy is low with the default maxsim_refine = 0; raise it for multi-vector retrieval.
  • vchordrq VACUUM holds a lock that can block the table during index maintenance.
  • Query sampling can delay a query by up to 5 seconds.
  • Upgrading from 1.0.0 or earlier drops scalar8 columns.
  • The rewritten SVE-512 kernels are not dispatched until validated on SVE-512 hardware; the AVX512-FP16 and SVE paths are tested under emulation only.
  • Index scans can return rows out of distance order. vchordg keeps searching while it returns rows; a larger vchordg.ef_search makes this rarer but does not rule it out. halfvec indexes can swap rows whose distances differ by about 0.0001 (vchordrq with halfvec_cosine_ops, and every vchordg halfvec opclass). When strict order matters, re-sort the ANN candidates in an outer query (#17).

Full changelog: 5b87b88...1.2.0