-- Copyright (C) 2026 Intel Corporation -- SPDX-License-Identifier: PostgreSQL -- Enable this database and wait for its worker before any index work, so this -- file runs standalone. Enrollment reserves the slot synchronously (the gate -- then passes), but the worker spawns asynchronously; the first INSERT would -- otherwise race its cold start and time out. Idempotent and a no-op in the -- full suite, where vamana_databases.sql (ordered first) has already warmed it. INSERT INTO vamana_databases (datname, enabled) VALUES (current_database(), true) ON CONFLICT (datname) DO NOTHING; DO $$ BEGIN FOR i IN 1 .. 300 LOOP PERFORM 1 FROM pg_stat_vamana_worker WHERE db_oid = (SELECT oid FROM pg_database WHERE datname = current_database()) AND worker_state = 'running'; EXIT WHEN FOUND; PERFORM pg_sleep(0.1); END LOOP; END $$; SET enable_seqscan = off; -- L2 CREATE TABLE t (id serial PRIMARY KEY, val vector(3)); INSERT INTO t (val) VALUES ('[0,0,0]'), ('[1,2,3]'), ('[1,1,1]'), (NULL); SET client_min_messages = error; CREATE INDEX ON t USING vamana (val vector_l2_ops); RESET client_min_messages; INSERT INTO t (val) VALUES ('[1,2,4]'); SELECT * FROM t ORDER BY val <-> '[3,3,3]', id; id | val ----+--------- 2 | [1,2,3] 5 | [1,2,4] 3 | [1,1,1] 1 | [0,0,0] (4 rows) SELECT COUNT(*) FROM (SELECT * FROM t ORDER BY val <-> (SELECT NULL::vector)) t2; count ------- 0 (1 row) SELECT COUNT(*) FROM t; count ------- 5 (1 row) TRUNCATE t; NOTICE: buffered 0 vectors for SVS index build NOTICE: no vectors to index, skipping SVS build SELECT * FROM t ORDER BY val <-> '[3,3,3]', id; id | val ----+----- (0 rows) DROP TABLE t; -- inner product CREATE TABLE t (id serial PRIMARY KEY, val vector(3)); INSERT INTO t (val) VALUES ('[0,0,0]'), ('[1,2,3]'), ('[1,1,1]'), (NULL); CREATE INDEX ON t USING vamana (val vector_ip_ops); NOTICE: buffered 3 vectors for SVS index build NOTICE: building SVS index with 3 vectors of dimension 3 NOTICE: SVS index built successfully INSERT INTO t (val) VALUES ('[1,2,4]'); SELECT * FROM t ORDER BY val <#> '[3,3,3]', id; id | val ----+--------- 5 | [1,2,4] 2 | [1,2,3] 3 | [1,1,1] 1 | [0,0,0] (4 rows) SELECT COUNT(*) FROM (SELECT * FROM t ORDER BY val <#> (SELECT NULL::vector)) t2; count ------- 0 (1 row) DROP TABLE t; -- cosine CREATE TABLE t (id serial PRIMARY KEY, val vector(3)); INSERT INTO t (val) VALUES ('[0,0,0]'), ('[1,2,3]'), ('[1,1,1]'), (NULL); CREATE INDEX ON t USING vamana (val vector_cosine_ops); NOTICE: buffered 3 vectors for SVS index build NOTICE: building SVS index with 3 vectors of dimension 3 NOTICE: SVS index built successfully INSERT INTO t (val) VALUES ('[1,2,4]'); SELECT * FROM t ORDER BY val <=> '[3,3,3]', id; id | val ----+--------- 3 | [1,1,1] 2 | [1,2,3] 5 | [1,2,4] 1 | [0,0,0] (4 rows) SELECT COUNT(*) FROM (SELECT * FROM t ORDER BY val <=> '[0,0,0]') t2; count ------- 4 (1 row) SELECT COUNT(*) FROM (SELECT * FROM t ORDER BY val <=> (SELECT NULL::vector)) t2; count ------- 0 (1 row) DROP TABLE t; -- unlogged CREATE UNLOGGED TABLE t (id serial PRIMARY KEY, val vector(3)); INSERT INTO t (val) VALUES ('[0,0,0]'), ('[1,2,3]'), ('[1,1,1]'), (NULL); CREATE INDEX ON t USING vamana (val vector_l2_ops); NOTICE: buffered 3 vectors for SVS index build NOTICE: building SVS index with 3 vectors of dimension 3 NOTICE: SVS index built successfully SELECT * FROM t ORDER BY val <-> '[3,3,3]', id; id | val ----+--------- 2 | [1,2,3] 3 | [1,1,1] 1 | [0,0,0] (3 rows) DROP TABLE t; -- options CREATE TABLE t (id serial PRIMARY KEY, val vector(3)); CREATE INDEX ON t USING vamana (val vector_l2_ops) WITH (graph_degree = 15); ERROR: value 15 out of bounds for option "graph_degree" DETAIL: Valid values are between "16" and "256". CREATE INDEX ON t USING vamana (val vector_l2_ops) WITH (graph_degree = 257); ERROR: value 257 out of bounds for option "graph_degree" DETAIL: Valid values are between "16" and "256". CREATE INDEX ON t USING vamana (val vector_l2_ops) WITH (alpha = 50); NOTICE: buffered 0 vectors for SVS index build NOTICE: no vectors to index, skipping SVS build CREATE INDEX ON t USING vamana (val vector_l2_ops) WITH (alpha = 201); ERROR: value 201 out of bounds for option "alpha" DETAIL: Valid values are between "-1" and "200". CREATE INDEX ON t USING vamana (val vector_l2_ops) WITH (graph_degree = 64, alpha = 120); NOTICE: buffered 0 vectors for SVS index build NOTICE: no vectors to index, skipping SVS build DROP TABLE t; -- compression detailed parameters -- Test compression_type enum (0=none, 1=leanvec) CREATE TABLE t (id serial PRIMARY KEY, val vector(3)); INSERT INTO t (val) VALUES ('[0,0,0]'), ('[1,2,3]'), ('[1,1,1]'); CREATE INDEX ON t USING vamana (val vector_l2_ops) WITH (compression_type = 0); NOTICE: buffered 3 vectors for SVS index build NOTICE: building SVS index with 3 vectors of dimension 3 NOTICE: SVS index built successfully SELECT * FROM t ORDER BY val <-> '[3,3,3]', id; id | val ----+--------- 2 | [1,2,3] 3 | [1,1,1] 1 | [0,0,0] (3 rows) DROP TABLE t; -- compression error cases -- Test invalid compression_type values CREATE TABLE t (id serial PRIMARY KEY, val vector(3)); CREATE INDEX ON t USING vamana (val vector_l2_ops) WITH (compression_type = 99); ERROR: value 99 out of bounds for option "compression_type" DETAIL: Valid values are between "0" and "2". CREATE INDEX ON t USING vamana (val vector_l2_ops) WITH (compression_type = -1); ERROR: value -1 out of bounds for option "compression_type" DETAIL: Valid values are between "0" and "2". CREATE INDEX ON t USING vamana (val vector_l2_ops) WITH (compression_type = 2); NOTICE: buffered 0 vectors for SVS index build NOTICE: no vectors to index, skipping SVS build DROP TABLE t; -- Test invalid compression_primary values CREATE TABLE t (id serial PRIMARY KEY, val vector(3)); CREATE INDEX ON t USING vamana (val vector_l2_ops) WITH (compression_type = 1, compression_primary = 5); ERROR: invalid compression_primary value: 5 HINT: Valid values are: 4 (UINT4), -4 (INT4), 8 (UINT8), -8 (INT8) CREATE INDEX ON t USING vamana (val vector_l2_ops) WITH (compression_type = 1, compression_primary = 10); ERROR: value 10 out of bounds for option "compression_primary" DETAIL: Valid values are between "-8" and "8". CREATE INDEX ON t USING vamana (val vector_l2_ops) WITH (compression_type = 1, compression_primary = 3); ERROR: invalid compression_primary value: 3 HINT: Valid values are: 4 (UINT4), -4 (INT4), 8 (UINT8), -8 (INT8) CREATE INDEX ON t USING vamana (val vector_l2_ops) WITH (compression_type = 1, compression_primary = 16); ERROR: value 16 out of bounds for option "compression_primary" DETAIL: Valid values are between "-8" and "8". CREATE INDEX ON t USING vamana (val vector_l2_ops) WITH (compression_type = 1, compression_primary = 0); ERROR: invalid compression_primary value: 0 HINT: Valid values are: 4 (UINT4), -4 (INT4), 8 (UINT8), -8 (INT8) DROP TABLE t; -- Test invalid compression_secondary values CREATE TABLE t (id serial PRIMARY KEY, val vector(3)); CREATE INDEX ON t USING vamana (val vector_l2_ops) WITH (compression_type = 1, compression_primary = 4, compression_secondary = 5); ERROR: invalid compression_secondary value: 5 HINT: Valid values are: 4 (UINT4), -4 (INT4), 8 (UINT8), -8 (INT8) CREATE INDEX ON t USING vamana (val vector_l2_ops) WITH (compression_type = 1, compression_primary = 4, compression_secondary = 10); ERROR: value 10 out of bounds for option "compression_secondary" DETAIL: Valid values are between "-8" and "8". CREATE INDEX ON t USING vamana (val vector_l2_ops) WITH (compression_type = 1, compression_primary = 4, compression_secondary = 3); ERROR: invalid compression_secondary value: 3 HINT: Valid values are: 4 (UINT4), -4 (INT4), 8 (UINT8), -8 (INT8) CREATE INDEX ON t USING vamana (val vector_l2_ops) WITH (compression_type = 1, compression_primary = 4, compression_secondary = 16); ERROR: value 16 out of bounds for option "compression_secondary" DETAIL: Valid values are between "-8" and "8". DROP TABLE t; -- Test invalid leanvec_dims values CREATE TABLE t (id serial PRIMARY KEY, val vector(128)); CREATE INDEX ON t USING vamana (val vector_l2_ops) WITH (compression_type = 1, leanvec_dims = 0); NOTICE: buffered 0 vectors for SVS index build NOTICE: no vectors to index, skipping SVS build CREATE INDEX ON t USING vamana (val vector_l2_ops) WITH (compression_type = 1, leanvec_dims = -2); ERROR: value -2 out of bounds for option "leanvec_dims" DETAIL: Valid values are between "-1" and "2000". CREATE INDEX ON t USING vamana (val vector_l2_ops) WITH (compression_type = 1, leanvec_dims = 200); NOTICE: buffered 0 vectors for SVS index build NOTICE: no vectors to index, skipping SVS build DROP TABLE t; -- Test compression parameters without compression_type = 1 CREATE TABLE t (id serial PRIMARY KEY, val vector(3)); CREATE INDEX ON t USING vamana (val vector_l2_ops) WITH (compression_primary = 4); NOTICE: buffered 0 vectors for SVS index build NOTICE: no vectors to index, skipping SVS build CREATE INDEX ON t USING vamana (val vector_l2_ops) WITH (compression_type = 0, compression_primary = 4); NOTICE: buffered 0 vectors for SVS index build NOTICE: no vectors to index, skipping SVS build CREATE INDEX ON t USING vamana (val vector_l2_ops) WITH (compression_type = 0, compression_secondary = 8); NOTICE: buffered 0 vectors for SVS index build NOTICE: no vectors to index, skipping SVS build DROP TABLE t; -- Test invalid build parameter values CREATE TABLE t (id serial PRIMARY KEY, val vector(3)); CREATE INDEX ON t USING vamana (val vector_l2_ops) WITH (build_window_size = 0); NOTICE: buffered 0 vectors for SVS index build NOTICE: no vectors to index, skipping SVS build CREATE INDEX ON t USING vamana (val vector_l2_ops) WITH (build_window_size = -1); NOTICE: buffered 0 vectors for SVS index build NOTICE: no vectors to index, skipping SVS build CREATE INDEX ON t USING vamana (val vector_l2_ops) WITH (search_window_size = 0); ERROR: value 0 out of bounds for option "search_window_size" DETAIL: Valid values are between "10" and "10000". CREATE INDEX ON t USING vamana (val vector_l2_ops) WITH (search_window_size = -1); ERROR: value -1 out of bounds for option "search_window_size" DETAIL: Valid values are between "10" and "10000". DROP TABLE t; -- advanced build parameters -- Test build_window_size variations CREATE TABLE t (id serial PRIMARY KEY, val vector(3)); INSERT INTO t (val) VALUES ('[0,0,0]'), ('[1,2,3]'), ('[1,1,1]'), ('[2,2,2]'), ('[3,3,3]'); CREATE INDEX ON t USING vamana (val vector_l2_ops) WITH (build_window_size = 100); NOTICE: buffered 5 vectors for SVS index build NOTICE: building SVS index with 5 vectors of dimension 3 NOTICE: SVS index built successfully SELECT * FROM t ORDER BY val <-> '[3,3,3]', id LIMIT 3; id | val ----+--------- 5 | [3,3,3] 4 | [2,2,2] 2 | [1,2,3] (3 rows) DROP TABLE t; CREATE TABLE t (id serial PRIMARY KEY, val vector(3)); INSERT INTO t (val) VALUES ('[0,0,0]'), ('[1,2,3]'), ('[1,1,1]'), ('[2,2,2]'), ('[3,3,3]'); CREATE INDEX ON t USING vamana (val vector_l2_ops) WITH (build_window_size = 150); NOTICE: buffered 5 vectors for SVS index build NOTICE: building SVS index with 5 vectors of dimension 3 NOTICE: SVS index built successfully SELECT * FROM t ORDER BY val <-> '[3,3,3]', id LIMIT 3; id | val ----+--------- 5 | [3,3,3] 4 | [2,2,2] 2 | [1,2,3] (3 rows) DROP TABLE t; CREATE TABLE t (id serial PRIMARY KEY, val vector(3)); INSERT INTO t (val) VALUES ('[0,0,0]'), ('[1,2,3]'), ('[1,1,1]'), ('[2,2,2]'), ('[3,3,3]'); CREATE INDEX ON t USING vamana (val vector_l2_ops) WITH (build_window_size = 200); NOTICE: buffered 5 vectors for SVS index build NOTICE: building SVS index with 5 vectors of dimension 3 NOTICE: SVS index built successfully SELECT * FROM t ORDER BY val <-> '[3,3,3]', id LIMIT 3; id | val ----+--------- 5 | [3,3,3] 4 | [2,2,2] 2 | [1,2,3] (3 rows) DROP TABLE t; -- Test search_window_size variations CREATE TABLE t (id serial PRIMARY KEY, val vector(3)); INSERT INTO t (val) VALUES ('[0,0,0]'), ('[1,2,3]'), ('[1,1,1]'), ('[2,2,2]'), ('[3,3,3]'); CREATE INDEX ON t USING vamana (val vector_l2_ops) WITH (search_window_size = 50); NOTICE: buffered 5 vectors for SVS index build NOTICE: building SVS index with 5 vectors of dimension 3 NOTICE: SVS index built successfully SELECT * FROM t ORDER BY val <-> '[3,3,3]', id LIMIT 3; id | val ----+--------- 5 | [3,3,3] 4 | [2,2,2] 2 | [1,2,3] (3 rows) DROP TABLE t; CREATE TABLE t (id serial PRIMARY KEY, val vector(3)); INSERT INTO t (val) VALUES ('[0,0,0]'), ('[1,2,3]'), ('[1,1,1]'), ('[2,2,2]'), ('[3,3,3]'); CREATE INDEX ON t USING vamana (val vector_l2_ops) WITH (search_window_size = 150); NOTICE: buffered 5 vectors for SVS index build NOTICE: building SVS index with 5 vectors of dimension 3 NOTICE: SVS index built successfully SELECT * FROM t ORDER BY val <-> '[3,3,3]', id LIMIT 3; id | val ----+--------- 5 | [3,3,3] 4 | [2,2,2] 2 | [1,2,3] (3 rows) DROP TABLE t; CREATE TABLE t (id serial PRIMARY KEY, val vector(3)); INSERT INTO t (val) VALUES ('[0,0,0]'), ('[1,2,3]'), ('[1,1,1]'), ('[2,2,2]'), ('[3,3,3]'); CREATE INDEX ON t USING vamana (val vector_l2_ops) WITH (search_window_size = 200); NOTICE: buffered 5 vectors for SVS index build NOTICE: building SVS index with 5 vectors of dimension 3 NOTICE: SVS index built successfully SELECT * FROM t ORDER BY val <-> '[3,3,3]', id LIMIT 3; id | val ----+--------- 5 | [3,3,3] 4 | [2,2,2] 2 | [1,2,3] (3 rows) DROP TABLE t; -- Test use_search_history boolean CREATE TABLE t (id serial PRIMARY KEY, val vector(3)); INSERT INTO t (val) VALUES ('[0,0,0]'), ('[1,2,3]'), ('[1,1,1]'), ('[2,2,2]'), ('[3,3,3]'); CREATE INDEX ON t USING vamana (val vector_l2_ops) WITH (use_search_history = true); NOTICE: buffered 5 vectors for SVS index build NOTICE: building SVS index with 5 vectors of dimension 3 NOTICE: SVS index built successfully SELECT * FROM t ORDER BY val <-> '[3,3,3]', id LIMIT 3; id | val ----+--------- 5 | [3,3,3] 4 | [2,2,2] 2 | [1,2,3] (3 rows) DROP TABLE t; CREATE TABLE t (id serial PRIMARY KEY, val vector(3)); INSERT INTO t (val) VALUES ('[0,0,0]'), ('[1,2,3]'), ('[1,1,1]'), ('[2,2,2]'), ('[3,3,3]'); CREATE INDEX ON t USING vamana (val vector_l2_ops) WITH (use_search_history = false); NOTICE: buffered 5 vectors for SVS index build NOTICE: building SVS index with 5 vectors of dimension 3 NOTICE: SVS index built successfully SELECT * FROM t ORDER BY val <-> '[3,3,3]', id LIMIT 3; id | val ----+--------- 5 | [3,3,3] 4 | [2,2,2] 2 | [1,2,3] (3 rows) DROP TABLE t; -- Test combined parameters CREATE TABLE t (id serial PRIMARY KEY, val vector(3)); INSERT INTO t (val) VALUES ('[0,0,0]'), ('[1,2,3]'), ('[1,1,1]'), ('[2,2,2]'), ('[3,3,3]'); CREATE INDEX ON t USING vamana (val vector_l2_ops) WITH (build_window_size = 150, search_window_size = 100, use_search_history = true); NOTICE: buffered 5 vectors for SVS index build NOTICE: building SVS index with 5 vectors of dimension 3 NOTICE: SVS index built successfully SELECT * FROM t ORDER BY val <-> '[3,3,3]', id LIMIT 3; id | val ----+--------- 5 | [3,3,3] 4 | [2,2,2] 2 | [1,2,3] (3 rows) DROP TABLE t; -- Test with different distance metrics CREATE TABLE t (id serial PRIMARY KEY, val vector(3)); INSERT INTO t (val) VALUES ('[0,0,0]'), ('[1,2,3]'), ('[1,1,1]'), ('[2,2,2]'), ('[3,3,3]'); CREATE INDEX ON t USING vamana (val vector_ip_ops) WITH (build_window_size = 150); NOTICE: buffered 5 vectors for SVS index build NOTICE: building SVS index with 5 vectors of dimension 3 NOTICE: SVS index built successfully SELECT * FROM t ORDER BY val <#> '[3,3,3]', id LIMIT 3; id | val ----+--------- 5 | [3,3,3] 2 | [1,2,3] 4 | [2,2,2] (3 rows) DROP TABLE t; CREATE TABLE t (id serial PRIMARY KEY, val vector(3)); INSERT INTO t (val) VALUES ('[1,0,0]'), ('[1,2,3]'), ('[1,1,1]'), ('[2,2,2]'), ('[3,3,3]'); CREATE INDEX ON t USING vamana (val vector_cosine_ops) WITH (search_window_size = 100); NOTICE: buffered 5 vectors for SVS index build NOTICE: building SVS index with 5 vectors of dimension 3 NOTICE: SVS index built successfully SELECT * FROM t ORDER BY val <=> '[3,3,3]', id LIMIT 3; id | val ----+--------- 3 | [1,1,1] 4 | [2,2,2] 5 | [3,3,3] (3 rows) DROP TABLE t; -- DML operations -- Test UPDATE of vector values CREATE TABLE t (id serial PRIMARY KEY, val vector(3)); INSERT INTO t (val) VALUES ('[0,0,0]'), ('[1,2,3]'), ('[1,1,1]'), ('[2,2,2]'); CREATE INDEX ON t USING vamana (val vector_l2_ops); NOTICE: buffered 4 vectors for SVS index build NOTICE: building SVS index with 4 vectors of dimension 3 NOTICE: SVS index built successfully -- Update a vector and verify searchability UPDATE t SET val = '[5,5,5]' WHERE id = 2; SELECT * FROM t ORDER BY val <-> '[4,4,4]', id; id | val ----+--------- 2 | [5,5,5] 4 | [2,2,2] 3 | [1,1,1] 1 | [0,0,0] (4 rows) DROP TABLE t; -- Test DELETE of rows CREATE TABLE t (id serial PRIMARY KEY, val vector(3)); INSERT INTO t (val) VALUES ('[0,0,0]'), ('[1,2,3]'), ('[1,1,1]'), ('[2,2,2]'), ('[3,3,3]'); CREATE INDEX ON t USING vamana (val vector_l2_ops); NOTICE: buffered 5 vectors for SVS index build NOTICE: building SVS index with 5 vectors of dimension 3 NOTICE: SVS index built successfully -- Delete a row and verify it's not in results DELETE FROM t WHERE id = 3; SELECT * FROM t ORDER BY val <-> '[1,1,1]', id; id | val ----+--------- 1 | [0,0,0] 4 | [2,2,2] 2 | [1,2,3] 5 | [3,3,3] (4 rows) DROP TABLE t; -- Test INSERT after index creation CREATE TABLE t (id serial PRIMARY KEY, val vector(3)); INSERT INTO t (val) VALUES ('[0,0,0]'), ('[1,2,3]'); CREATE INDEX ON t USING vamana (val vector_l2_ops); NOTICE: buffered 2 vectors for SVS index build NOTICE: building SVS index with 2 vectors of dimension 3 NOTICE: SVS index built successfully -- Insert new rows after index exists INSERT INTO t (val) VALUES ('[2,2,2]'), ('[3,3,3]'); SELECT * FROM t ORDER BY val <-> '[3,3,3]', id; id | val ----+--------- 4 | [3,3,3] 3 | [2,2,2] 2 | [1,2,3] 1 | [0,0,0] (4 rows) DROP TABLE t; -- Test mixed DML operations CREATE TABLE t (id serial PRIMARY KEY, val vector(3)); INSERT INTO t (val) VALUES ('[0,0,0]'), ('[1,1,1]'), ('[2,2,2]'), ('[3,3,3]'), ('[4,4,4]'); CREATE INDEX ON t USING vamana (val vector_l2_ops); NOTICE: buffered 5 vectors for SVS index build NOTICE: building SVS index with 5 vectors of dimension 3 NOTICE: SVS index built successfully -- Mix of UPDATE, DELETE, INSERT UPDATE t SET val = '[1.5,1.5,1.5]' WHERE id = 2; DELETE FROM t WHERE id = 4; INSERT INTO t (val) VALUES ('[5,5,5]'); SELECT * FROM t ORDER BY val <-> '[2,2,2]', id; id | val ----+--------------- 3 | [2,2,2] 2 | [1.5,1.5,1.5] 1 | [0,0,0] 5 | [4,4,4] 6 | [5,5,5] (5 rows) DROP TABLE t; -- Test DML with different distance metrics CREATE TABLE t (id serial PRIMARY KEY, val vector(3)); INSERT INTO t (val) VALUES ('[0,0,0]'), ('[1,2,3]'), ('[1,1,1]'), ('[2,2,2]'); CREATE INDEX ON t USING vamana (val vector_ip_ops); NOTICE: buffered 4 vectors for SVS index build NOTICE: building SVS index with 4 vectors of dimension 3 NOTICE: SVS index built successfully UPDATE t SET val = '[5,5,5]' WHERE id = 2; DELETE FROM t WHERE id = 1; INSERT INTO t (val) VALUES ('[3,3,3]'); SELECT * FROM t ORDER BY val <#> '[3,3,3]', id; id | val ----+--------- 2 | [5,5,5] 5 | [3,3,3] 4 | [2,2,2] 3 | [1,1,1] (4 rows) DROP TABLE t; -- index introspection -- Verify basic index metadata CREATE TABLE t (id serial PRIMARY KEY, val vector(3)); INSERT INTO t (val) VALUES ('[0,0,0]'), ('[1,2,3]'), ('[1,1,1]'); CREATE INDEX vamana_meta_idx ON t USING vamana (val vector_l2_ops); NOTICE: buffered 3 vectors for SVS index build NOTICE: building SVS index with 3 vectors of dimension 3 NOTICE: SVS index built successfully SELECT indexname, tablename FROM pg_indexes WHERE indexname = 'vamana_meta_idx'; indexname | tablename -----------------+----------- vamana_meta_idx | t (1 row) DROP TABLE t; -- Verify index parameters appear in definition CREATE TABLE t (id serial PRIMARY KEY, val vector(3)); CREATE INDEX vamana_params_idx ON t USING vamana (val vector_l2_ops) WITH (graph_degree = 64, alpha = 120); NOTICE: buffered 0 vectors for SVS index build NOTICE: no vectors to index, skipping SVS build SELECT indexname, indexdef FROM pg_indexes WHERE indexname = 'vamana_params_idx'; indexname | indexdef -------------------+------------------------------------------------------------------------------------------------------------------- vamana_params_idx | CREATE INDEX vamana_params_idx ON public.t USING vamana (val vector_l2_ops) WITH (graph_degree='64', alpha='120') (1 row) DROP TABLE t; -- Verify compression parameters in definition CREATE TABLE t (id serial PRIMARY KEY, val vector(3)); CREATE INDEX vamana_compress_idx ON t USING vamana (val vector_l2_ops) WITH (compression_type = 1, compression_primary = 8); NOTICE: buffered 0 vectors for SVS index build NOTICE: no vectors to index, skipping SVS build SELECT indexname FROM pg_indexes WHERE indexname = 'vamana_compress_idx'; indexname --------------------- vamana_compress_idx (1 row) DROP TABLE t; -- Verify operator class mappings (L2, inner product, cosine) CREATE TABLE t (id serial PRIMARY KEY, val vector(3)); CREATE INDEX vamana_l2_idx ON t USING vamana (val vector_l2_ops); NOTICE: buffered 0 vectors for SVS index build NOTICE: no vectors to index, skipping SVS build CREATE INDEX vamana_ip_idx ON t USING vamana (val vector_ip_ops); NOTICE: buffered 0 vectors for SVS index build NOTICE: no vectors to index, skipping SVS build CREATE INDEX vamana_cosine_idx ON t USING vamana (val vector_cosine_ops); NOTICE: buffered 0 vectors for SVS index build NOTICE: no vectors to index, skipping SVS build SELECT indexname FROM pg_indexes WHERE tablename = 't' AND indexname LIKE 'vamana_%_idx' ORDER BY indexname; indexname ------------------- vamana_cosine_idx vamana_ip_idx vamana_l2_idx (3 rows) DROP TABLE t; -- runtime parameter tuning CREATE TABLE t (id serial PRIMARY KEY, val vector(3)); INSERT INTO t (val) VALUES ('[0,0,0]'), ('[1,2,3]'), ('[1,1,1]'), (NULL); CREATE INDEX ON t USING vamana (val vector_l2_ops); NOTICE: buffered 3 vectors for SVS index build NOTICE: building SVS index with 3 vectors of dimension 3 NOTICE: SVS index built successfully SET svs.search_window_size = 50; SELECT * FROM t ORDER BY val <-> '[3,3,3]', id; id | val ----+--------- 2 | [1,2,3] 3 | [1,1,1] 1 | [0,0,0] (3 rows) SET svs.search_window_size = 200; SELECT * FROM t ORDER BY val <-> '[3,3,3]', id; id | val ----+--------- 2 | [1,2,3] 3 | [1,1,1] 1 | [0,0,0] (3 rows) RESET svs.search_window_size; SELECT * FROM t ORDER BY val <-> '[3,3,3]', id; id | val ----+--------- 2 | [1,2,3] 3 | [1,1,1] 1 | [0,0,0] (3 rows) DROP TABLE t; -- test with reversed insertion order (tests index robustness) CREATE TABLE t (id serial PRIMARY KEY, val vector(3)); INSERT INTO t (val) VALUES ('[1,2,4]'), ('[1,1,1]'), ('[1,2,3]'), ('[0,0,0]'), (NULL); CREATE INDEX ON t USING vamana (val vector_l2_ops); NOTICE: buffered 4 vectors for SVS index build NOTICE: building SVS index with 4 vectors of dimension 3 NOTICE: SVS index built successfully SELECT * FROM t ORDER BY val <-> '[3,3,3]', id; id | val ----+--------- 3 | [1,2,3] 1 | [1,2,4] 2 | [1,1,1] 4 | [0,0,0] (4 rows) DROP TABLE t; -- test top-K recall (verify index returns reasonable results) -- Note: Exact recall varies due to approximate nature of Vamana -- Use Perl TAP tests (test/t/*_recall.pl) for statistical recall verification CREATE TABLE t (id int, val vector(3)); INSERT INTO t VALUES (1, '[0,0,0]'), (2, '[1,1,1]'), (3, '[2,2,2]'), (4, '[3,3,3]'), (5, '[10,10,10]'); CREATE INDEX ON t USING vamana (val vector_l2_ops); NOTICE: buffered 5 vectors for SVS index build NOTICE: building SVS index with 5 vectors of dimension 3 NOTICE: SVS index built successfully -- Nearest to [3,3,3] - expect mostly ids 2,3,4 (but may vary) SELECT id FROM t ORDER BY val <-> '[3,3,3]' LIMIT 3; id ---- 4 3 2 (3 rows) DROP TABLE t; -- serialization -- CREATE INDEX persists to disk (no "not yet implemented" notice); -- INSERT invalidates the saved copy; next SELECT rebuilds from table and re-saves. CREATE TABLE t (id serial PRIMARY KEY, val vector(3)); INSERT INTO t (val) VALUES ('[0,0,0]'), ('[1,2,3]'), ('[1,1,1]'), ('[3,3,3]'); CREATE INDEX ON t USING vamana (val vector_l2_ops); NOTICE: buffered 4 vectors for SVS index build NOTICE: building SVS index with 4 vectors of dimension 3 NOTICE: SVS index built successfully INSERT INTO t (val) VALUES ('[2,2,2]'); SELECT * FROM t ORDER BY val <-> '[2,2,2]', id; id | val ----+--------- 5 | [2,2,2] 2 | [1,2,3] 3 | [1,1,1] 4 | [3,3,3] 1 | [0,0,0] (5 rows) DROP TABLE t; -- pgvector rejects NaN/Inf at parse time on tables carrying a vamana index (vector type) -- pgvector rejects NaN/Inf on INSERT CREATE TABLE t (id serial PRIMARY KEY, val vector(3)); CREATE INDEX ON t USING vamana (val vector_l2_ops); NOTICE: buffered 0 vectors for SVS index build NOTICE: no vectors to index, skipping SVS build INSERT INTO t (val) VALUES ('[1,NaN,3]'); ERROR: NaN not allowed in vector LINE 1: INSERT INTO t (val) VALUES ('[1,NaN,3]'); ^ INSERT INTO t (val) VALUES ('[1,Infinity,3]'); ERROR: infinite value not allowed in vector LINE 1: INSERT INTO t (val) VALUES ('[1,Infinity,3]'); ^ INSERT INTO t (val) VALUES ('[1,-Infinity,3]'); ERROR: infinite value not allowed in vector LINE 1: INSERT INTO t (val) VALUES ('[1,-Infinity,3]'); ^ DROP TABLE t; -- pgvector rejects NaN/Inf in query vector CREATE TABLE t (id serial PRIMARY KEY, val vector(3)); INSERT INTO t (val) VALUES ('[0,0,0]'), ('[1,1,1]'); CREATE INDEX ON t USING vamana (val vector_l2_ops); NOTICE: buffered 2 vectors for SVS index build NOTICE: building SVS index with 2 vectors of dimension 3 NOTICE: SVS index built successfully SELECT * FROM t ORDER BY val <-> '[1,NaN,3]' LIMIT 1; ERROR: NaN not allowed in vector LINE 1: SELECT * FROM t ORDER BY val <-> '[1,NaN,3]' LIMIT 1; ^ SELECT * FROM t ORDER BY val <-> '[1,Infinity,3]' LIMIT 1; ERROR: infinite value not allowed in vector LINE 1: SELECT * FROM t ORDER BY val <-> '[1,Infinity,3]' LIMIT 1; ^ DROP TABLE t; -- VamanaValidateVectorData direct coverage: bypass pgvector's input functions -- via a bytea cast so a NaN datum reaches the extension's AM boundary. -- Requires superuser (CREATE CAST is privileged DDL). -- 16-byte bytea payload: int16 dim=3, int16 unused=0, then three little-endian -- float4s where the first is 0x7FC00000 (quiet NaN). CREATE CAST (bytea AS vector) WITHOUT FUNCTION; -- insert path: index exists, NaN reaches vamanainsert CREATE TABLE t (id serial PRIMARY KEY, val vector(3)); CREATE INDEX ON t USING vamana (val vector_l2_ops); NOTICE: buffered 0 vectors for SVS index build NOTICE: no vectors to index, skipping SVS build INSERT INTO t (val) VALUES ('\x030000000000c07f0000803f0000803f'::bytea::vector); ERROR: vector contains invalid floating-point value (NaN or Infinity) at position 1 in insert DROP TABLE t; -- build path: NaN in heap before CREATE INDEX, reaches BuildCallback CREATE TABLE t (id serial PRIMARY KEY, val vector(3)); INSERT INTO t (val) VALUES ('\x030000000000c07f0000803f0000803f'::bytea::vector); CREATE INDEX ON t USING vamana (val vector_l2_ops); ERROR: vector contains invalid floating-point value (NaN or Infinity) at position 1 in build DROP TABLE t; DROP CAST (bytea AS vector);