All Rust source code (maintenance queries, scan functions, tenancy SQL)
references the access method as `ruhnsw`, but the SQL registration files
had it as `hnsw`, causing `CREATE INDEX USING ruhnsw` to fail with
"access method not found". Historical migration files left unchanged.
Closes#48
Co-authored-by: ruvnet <ruvnet@gmail.com>
AVX-512 intrinsics (_mm512_*, _mm512_reduce_add_ps, _mm512_abs_ps) are
stable since Rust 1.72. The comment saying "requires nightly Rust" was
misleading — callers would skip the feature unnecessarily.
CI: add a compile-check build step with --features simd-avx512 on the
stable toolchain so regressions are caught. Runtime dispatch is already
in place (is_x86_feature_detected!("avx512f")); the build step verifies
the code at least compiles on runners that may lack AVX-512 hardware.
Closes#47
Co-authored-by: ruvnet <ruvnet@gmail.com>
- Wrap run_enhanced_training_cycle in tokio::task::spawn_blocking to
prevent CPU-intensive cognitive cycles from starving HTTP handlers
(root cause of 504 upstream timeouts, closes#305)
- Derive Default for EnhancedTrainingResult so spawn_blocking JoinError
can be handled cleanly
- Bump ruvector-postgres version 0.3.0 → 2.0.1 to match the Docker
image tag convention (closes#271)
Co-authored-by: ruvnet <ruvnet@gmail.com>
`CREATE EXTENSION ruvector` was failing when the extension was built
without optional feature flags (solver, math-distances, tda,
attention-extended, sona-learning, domain-expansion) because the SQL
migration unconditionally registered C functions whose symbols didn't
exist in the compiled .so file.
Wrap all 6 optional-feature sections in DO $ BEGIN ... EXCEPTION WHEN
OTHERS THEN RAISE NOTICE ... END $ blocks so PostgreSQL gracefully skips
missing C function symbols and logs an informational notice instead of
aborting the entire extension load.
Fixes#325
Co-authored-by: ruvnet <ruvnet@gmail.com>
- ruvector-postgres: Add EdgeType import in mincut tests, remove
incorrect Some() wrapping on pgrx default!() test params
- ruvllm: Make ane_ops module available on all platforms (not just macOS)
so tests can reference it unconditionally; fix unused variable warnings
- sona: Add explicit lifetime annotations on RwLockReadGuard/WriteGuard
to fix clippy mismatched_lifetime_syntaxes errors
Co-Authored-By: claude-flow <ruv@ruv.net>
- Add #[allow(unreachable_code)] for NEON fallback in distance/mod.rs (ARM
always returns before the Scalar fallback, causing clippy error on macOS)
- Restructure standalone Dockerfile to use workspace layout so dependency
crates with workspace inheritance (edition.workspace, version.workspace)
can resolve correctly during Docker builds
Co-Authored-By: claude-flow <ruv@ruv.net>
- Run cargo fmt --all to fix formatting in 362 files across the entire workspace
- Add PGDG repository for PostgreSQL 17 in CI test-all-features and benchmark jobs
- Add missing rvf dependency crates to standalone Dockerfile for domain-expansion
- Add sona-learning and domain-expansion features to standalone Dockerfile build
- Create npu.rs stub for ruvector-sparse-inference (fixes rustfmt resolution error)
Co-Authored-By: claude-flow <ruv@ruv.net>
Published ruvector-postgres@2.0.4 to crates.io with SPARQL parser
backtrack fix, executor memory leak fix, and catch_unwind safety.
Co-Authored-By: claude-flow <ruv@ruv.net>
Resolve conflicts in hnsw_am.rs:
- Keep metric_from_index() (PR Fix#3) AND dimension extraction from atttypmod (main)
- Use atttypmod dimensions to initialize meta.dimensions instead of 0
- Combine sorted result comments from both branches
Co-Authored-By: claude-flow <ruv@ruv.net>
Six bugs fixed in the HNSW access method:
1. SIGSEGV on repeated queries: beginscan must allocate xs_orderbyvals
and xs_orderbynulls arrays (like GiST/SP-GiST do). Without this,
the executor writes distance values to stale palloc memory, causing
segfaults on the second+ query in the same backend.
2. Empty HNSW graph: connect_node_to_neighbors was a no-op TODO stub.
Implemented bidirectional connections (new→neighbors, neighbor→new)
with pruning at M/M0 capacity limits.
3. Wrong distance metric: hnsw_build hardcoded DistanceMetric::Euclidean
regardless of the operator class used (e.g. ruvector_cosine_ops).
Added metric_from_index() to read the metric from the opclass
support function via index_getprocid + get_func_name.
4. Wrong result ordering: BinaryHeap::into_iter().take(k) returns k
arbitrary items, not the k closest. Removed .take(k) before sort.
5. xs_recheckorderby must be false: setting it to true triggers PG17's
IndexNextWithReorder distance comparison, which errors on harmless
floating-point differences between index-stored and heap vectors.
6. Use-after-free in endscan: added null check and null-out of
scan->opaque to prevent double-free across rescans.
Also applied the same xs_orderbyvals fix to ivfflat_ambeginscan.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Three additional hardening fixes for the SPARQL subsystem, building on
PR #172:
1. Parser: replace hardcoded saturating_sub(6) with saved_pos variable.
The old backtrack assumed all update keywords are 6 chars, but LOAD,
DROP, and CLEAR are 4-5 chars, causing incorrect parse positions.
2. Executor: change default_graph from Option<&'a str> to Option<String>
and remove Box::leak calls in the GraphPattern::Graph handler. Each
GRAPH clause previously leaked a String allocation that was never freed.
3. Operators: wrap ruvector_sparql parse/execute/format in catch_unwind
so that panics from non-empty but malformed queries are converted to
PostgreSQL ERROR messages instead of crashing the backend.
Closes#167
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix BackendSpec.as_ref() error: backend is a struct, not Option; access options.early_exit directly
- Fix ii_IndexAttrNumbers array indexing: use [0] instead of .offset(0) for fixed-size [i16; 32]
- Bump rvf-cli deps to match rvf-launch 0.2.0 and rvf-server 0.2.0
- Update Docker image version label to 2.0.2
Co-Authored-By: claude-flow <ruv@ruv.net>
HNSW fixes:
- Extract vector dimensions from column atttypmod instead of hardcoding 128,
which caused corrupted indexes for non-128-dim embeddings (#171, #164)
- Add page boundary checks in read_vector/read_neighbors to prevent
segfaults on large tables with >100K rows (#164)
- Use BinaryHeap::into_sorted_vec() for deterministic result ordering
instead of into_iter() which yields arbitrary order (#171)
- Handle non-kNN scans (COUNT, WHERE IS NOT NULL) gracefully by returning
false from hnsw_gettuple when no ORDER BY operator is present (#152)
Agent/SPARQL fixes:
- Fix SQL type mismatch: ruvector_list_agents() and
ruvector_find_agents_by_capability() now use RETURNS TABLE(...)
matching the Rust TableIterator signatures instead of RETURNS SETOF jsonb (#167)
- Add empty query validation to ruvector_sparql() and
ruvector_sparql_json() to prevent panics on invalid input (#167)
- Change workspace panic profile from "abort" to "unwind" so pgrx can
convert Rust panics to PostgreSQL errors instead of killing the backend (#167)
Security:
- Bump lru dependency from 0.12 to 0.16 in ruvector-graph, ruvector-cli,
and ruvLLM to resolve GHSA-xpfx-fvgv-hgqp Stacked Borrows violation (#148)
Version bumps: workspace 2.0.3, ruvector-postgres 2.0.2
Co-Authored-By: claude-flow <ruv@ruv.net>
- Move datum and false arguments to same line in from_polymorphic_datum
- Join split let text_len = ... assignment to single line
These changes fix CI rustfmt check failures.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit fixes a critical P0 bug where HNSW indexes on ruvector
columns would crash PostgreSQL with a segmentation fault when using
parameterized queries (prepared statements, ORMs, application drivers).
Root Cause:
- Query vector extraction failed for parameterized queries
- Code fell back to zero vector without validation
- Zero vector caused segfault during HNSW search
Changes:
- Add multi-method query vector extraction pipeline
1. Direct RuVector::from_polymorphic_datum()
2. Text parameter conversion for parameterized queries
3. Validated varlena fallback with dimension checking
- Add query_valid flag to track extraction success
- Add validation before search execution:
- Reject empty/invalid query vectors with clear errors
- Reject all-zero vectors (invalid for similarity search)
- Validate dimension match between query and index
- Apply same fixes to IVFFlat for consistency
Testing:
- Added regression tests for parameterized queries
- Added tests for zero vector error handling
- Added tests for dimension mismatch errors
- Added 384-dimension production-scale tests
Fixes: #141
See: docs/adr/ADR-0027-hnsw-parameterized-query-fix.md
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add chrono dependency to Cargo.toml
- Replace pgrx::TimestampWithTimeZone with chrono::Utc strings
- Fix temporary reference error in analysis.rs
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add README.md to patches/ explaining the critical hnsw_rs patch
- Run cargo fmt on ruvector-postgres to fix formatting issues
The patches/hnsw_rs directory is REQUIRED for builds as it provides
a WASM-compatible version of hnsw_rs (using rand 0.8 instead of 0.9).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Copy ruvector-mincut-gated-transformer crate to Docker builds
- Enable gated-transformer feature in all Docker builds
- Update workflow labels to include new features
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix dual cfg attributes causing linker errors in test builds
- Remove unused EarlyExitDecision import from gated_transformer
- Update intelligence layer data
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The Rust example files (learning_demo.rs, simd_distance_benchmark.rs)
were causing linker errors during pgrx tests because they use pgrx
functions without proper PostgreSQL library context.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The standalone test files in tests/ directory were causing linker errors
when running cargo pgrx test. These tests referenced non-existent functions
and tried to link against pgrx symbols without PostgreSQL libraries.
The actual pg_test tests are in src/operators.rs and other source modules.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Use fully-qualified pgrx::pg_schema and import pg_test explicitly
in the test module to fix "cannot find attribute" errors during
pgrx test compilation.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Keep comment on separate line to match main branch format
and avoid merge conflict in CI.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Combine split comment with its directive.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix attention/operators.rs tests: use to_json() for JsonB parameters
- Fix learning/operators.rs tests: correct parameter types for enable_learning, auto_tune, extract_patterns
- Remove cargo test --lib from CI: pg_test tests require pgrx runtime and cause linker errors (undefined PostgreSQL symbols) when compiled outside pgrx test harness
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Fix test_empty_inputs and test_weighted_gcn to properly:
- Convert Vec to JsonB using to_json helper
- Parse JsonB result using parse_result helper
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>