Squashed 'vendor/ruvector/' content from commit b64c2172

git-subtree-dir: vendor/ruvector
git-subtree-split: b64c21726f2bb37286d9ee36a7869fef60cc6900
This commit is contained in:
ruv
2026-02-28 14:39:40 -05:00
commit d803bfe2b1
7854 changed files with 3522914 additions and 0 deletions

View File

@@ -0,0 +1,249 @@
-- IVFFlat Access Method Tests
-- ============================================================================
-- Comprehensive test suite for IVFFlat index access method
-- Setup
\set ON_ERROR_STOP on
BEGIN;
-- Create test table
CREATE TABLE test_ivfflat (
id serial PRIMARY KEY,
embedding vector(128),
data text
);
-- Insert test data (1000 random vectors)
INSERT INTO test_ivfflat (embedding, data)
SELECT
array_to_vector(array_agg(random()::float4))::vector(128),
'Test document ' || i
FROM generate_series(1, 1000) i,
generate_series(1, 128) d
GROUP BY i;
-- ============================================================================
-- Test 1: Basic Index Creation
-- ============================================================================
\echo 'Test 1: Creating IVFFlat index with default parameters...'
CREATE INDEX test_ivfflat_l2_idx ON test_ivfflat
USING ruivfflat (embedding vector_l2_ops);
\echo 'Test 1: PASSED - Index created successfully'
-- ============================================================================
-- Test 2: Index Creation with Custom Parameters
-- ============================================================================
\echo 'Test 2: Creating IVFFlat index with custom parameters...'
CREATE INDEX test_ivfflat_custom_idx ON test_ivfflat
USING ruivfflat (embedding vector_l2_ops)
WITH (lists = 50);
\echo 'Test 2: PASSED - Custom index created successfully'
-- ============================================================================
-- Test 3: Cosine Distance Index
-- ============================================================================
\echo 'Test 3: Creating IVFFlat index with cosine distance...'
CREATE INDEX test_ivfflat_cosine_idx ON test_ivfflat
USING ruivfflat (embedding vector_cosine_ops)
WITH (lists = 100);
\echo 'Test 3: PASSED - Cosine index created successfully'
-- ============================================================================
-- Test 4: Inner Product Index
-- ============================================================================
\echo 'Test 4: Creating IVFFlat index with inner product...'
CREATE INDEX test_ivfflat_ip_idx ON test_ivfflat
USING ruivfflat (embedding vector_ip_ops)
WITH (lists = 100);
\echo 'Test 4: PASSED - Inner product index created successfully'
-- ============================================================================
-- Test 5: Basic Search Query
-- ============================================================================
\echo 'Test 5: Testing basic search query...'
-- Create a query vector
WITH query AS (
SELECT array_to_vector(array_agg(random()::float4))::vector(128) as q
FROM generate_series(1, 128)
)
SELECT COUNT(*) as result_count
FROM test_ivfflat, query
ORDER BY embedding <-> query.q
LIMIT 10;
\echo 'Test 5: PASSED - Search query executed successfully'
-- ============================================================================
-- Test 6: Probe Configuration
-- ============================================================================
\echo 'Test 6: Testing probe configuration...'
-- Set probes to 1 (fast, lower recall)
SET ruvector.ivfflat_probes = 1;
SELECT setting FROM pg_settings WHERE name = 'ruvector.ivfflat_probes';
-- Set probes to 10 (slower, higher recall)
SET ruvector.ivfflat_probes = 10;
SELECT setting FROM pg_settings WHERE name = 'ruvector.ivfflat_probes';
\echo 'Test 6: PASSED - Probe configuration working'
-- ============================================================================
-- Test 7: Insert After Index Creation
-- ============================================================================
\echo 'Test 7: Testing insert after index creation...'
INSERT INTO test_ivfflat (embedding, data)
SELECT
array_to_vector(array_agg(random()::float4))::vector(128),
'New document ' || i
FROM generate_series(1, 100) i,
generate_series(1, 128) d
GROUP BY i;
\echo 'Test 7: PASSED - Inserts after index creation working'
-- ============================================================================
-- Test 8: Search with Different Probe Values
-- ============================================================================
\echo 'Test 8: Comparing search results with different probes...'
WITH query AS (
SELECT array_to_vector(array_agg(0.5::float4))::vector(128) as q
FROM generate_series(1, 128)
)
SELECT
'probes=1' as config,
(
SELECT COUNT(*)
FROM test_ivfflat, query
WHERE pg_catalog.set_config('ruvector.ivfflat_probes', '1', true) IS NOT NULL
ORDER BY embedding <-> query.q
LIMIT 10
) as result_count
UNION ALL
SELECT
'probes=10' as config,
(
SELECT COUNT(*)
FROM test_ivfflat, query
WHERE pg_catalog.set_config('ruvector.ivfflat_probes', '10', true) IS NOT NULL
ORDER BY embedding <-> query.q
LIMIT 10
) as result_count;
\echo 'Test 8: PASSED - Different probe values tested'
-- ============================================================================
-- Test 9: Index Statistics
-- ============================================================================
\echo 'Test 9: Checking index statistics...'
SELECT * FROM ruvector_ivfflat_stats('test_ivfflat_l2_idx');
\echo 'Test 9: PASSED - Index statistics retrieved'
-- ============================================================================
-- Test 10: Index Size
-- ============================================================================
\echo 'Test 10: Checking index size...'
SELECT
indexrelname,
pg_size_pretty(pg_relation_size(indexrelid)) as index_size
FROM pg_stat_user_indexes
WHERE indexrelname LIKE 'test_ivfflat%'
ORDER BY indexrelname;
\echo 'Test 10: PASSED - Index sizes retrieved'
-- ============================================================================
-- Test 11: Explain Plan
-- ============================================================================
\echo 'Test 11: Checking query plan uses index...'
WITH query AS (
SELECT array_to_vector(array_agg(0.5::float4))::vector(128) as q
FROM generate_series(1, 128)
)
EXPLAIN (COSTS OFF)
SELECT id, data
FROM test_ivfflat, query
ORDER BY embedding <-> query.q
LIMIT 10;
\echo 'Test 11: PASSED - Query plan generated'
-- ============================================================================
-- Test 12: Concurrent Access
-- ============================================================================
\echo 'Test 12: Testing concurrent queries...'
-- Multiple simultaneous queries
WITH query1 AS (
SELECT array_to_vector(array_agg(random()::float4))::vector(128) as q
FROM generate_series(1, 128)
),
query2 AS (
SELECT array_to_vector(array_agg(random()::float4))::vector(128) as q
FROM generate_series(1, 128)
)
SELECT
(SELECT COUNT(*) FROM test_ivfflat, query1 ORDER BY embedding <-> query1.q LIMIT 10) as q1_count,
(SELECT COUNT(*) FROM test_ivfflat, query2 ORDER BY embedding <-> query2.q LIMIT 10) as q2_count;
\echo 'Test 12: PASSED - Concurrent queries working'
-- ============================================================================
-- Test 13: Reindex
-- ============================================================================
\echo 'Test 13: Testing REINDEX...'
REINDEX INDEX test_ivfflat_l2_idx;
\echo 'Test 13: PASSED - REINDEX successful'
-- ============================================================================
-- Test 14: Drop Index
-- ============================================================================
\echo 'Test 14: Testing DROP INDEX...'
DROP INDEX test_ivfflat_custom_idx;
DROP INDEX test_ivfflat_cosine_idx;
DROP INDEX test_ivfflat_ip_idx;
\echo 'Test 14: PASSED - DROP INDEX successful'
-- ============================================================================
-- Cleanup
-- ============================================================================
\echo 'Cleaning up...'
DROP TABLE test_ivfflat CASCADE;
ROLLBACK;
\echo ''
\echo '============================================'
\echo 'All IVFFlat Access Method Tests PASSED!'
\echo '============================================'