velesdb-core 3.1.0

High-performance vector database engine written in Rust
Documentation
//! Tests for USING FUSION clause (EPIC-040 US-005).
//!
//! Covers:
//! - USING FUSION parsing with default RRF
//! - USING FUSION with explicit strategy (rrf, weighted, maximum)
//! - USING FUSION with parameters (k, weights)

use crate::velesql::Parser;

#[test]
fn test_using_fusion_default() {
    // USING FUSION without parameters - default RRF strategy
    let sql = "SELECT * FROM docs USING FUSION";
    let result = Parser::parse(sql);
    assert!(
        result.is_ok(),
        "Failed to parse USING FUSION: {:?}",
        result.err()
    );

    let query = result.unwrap();
    let fusion = query
        .select
        .fusion_clause
        .as_ref()
        .expect("FUSION clause should be present");

    // Default strategy is RRF
    assert_eq!(fusion.strategy, crate::velesql::FusionStrategyType::Rrf);
}

#[test]
fn test_using_fusion_rrf_with_k() {
    let sql = "SELECT * FROM docs USING FUSION(strategy = 'rrf', k = 30)";
    let result = Parser::parse(sql);
    assert!(
        result.is_ok(),
        "Failed to parse FUSION with k: {:?}",
        result.err()
    );

    let query = result.unwrap();
    let fusion = query
        .select
        .fusion_clause
        .as_ref()
        .expect("FUSION clause should be present");

    assert_eq!(fusion.strategy, crate::velesql::FusionStrategyType::Rrf);
    assert_eq!(fusion.k, Some(30));
}

#[test]
fn test_using_fusion_weighted() {
    let sql = "SELECT * FROM docs USING FUSION(strategy = 'weighted', vector_weight = 0.7, graph_weight = 0.3)";
    let result = Parser::parse(sql);
    assert!(
        result.is_ok(),
        "Failed to parse FUSION weighted: {:?}",
        result.err()
    );

    let query = result.unwrap();
    let fusion = query
        .select
        .fusion_clause
        .as_ref()
        .expect("FUSION clause should be present");

    assert_eq!(
        fusion.strategy,
        crate::velesql::FusionStrategyType::Weighted
    );
    assert!((fusion.vector_weight.unwrap_or(0.0) - 0.7).abs() < 0.01);
    assert!((fusion.graph_weight.unwrap_or(0.0) - 0.3).abs() < 0.01);
}

#[test]
fn test_using_fusion_maximum() {
    let sql = "SELECT * FROM docs USING FUSION(strategy = 'maximum')";
    let result = Parser::parse(sql);
    assert!(
        result.is_ok(),
        "Failed to parse FUSION maximum: {:?}",
        result.err()
    );

    let query = result.unwrap();
    let fusion = query
        .select
        .fusion_clause
        .as_ref()
        .expect("FUSION clause should be present");

    assert_eq!(fusion.strategy, crate::velesql::FusionStrategyType::Maximum);
}

#[test]
fn test_using_fusion_average() {
    let sql = "SELECT * FROM docs USING FUSION(strategy = 'average')";
    let result = Parser::parse(sql);
    assert!(
        result.is_ok(),
        "Failed to parse FUSION average: {:?}",
        result.err()
    );

    let query = result.unwrap();
    let fusion = query
        .select
        .fusion_clause
        .as_ref()
        .expect("FUSION clause should be present");

    assert_eq!(fusion.strategy, crate::velesql::FusionStrategyType::Average);
}

#[test]
fn test_fusion_with_where_clause() {
    // USING FUSION combined with WHERE clause
    let sql = "SELECT * FROM docs WHERE category = 'tech' USING FUSION(strategy = 'rrf', k = 60)";
    let result = Parser::parse(sql);
    assert!(
        result.is_ok(),
        "Failed to parse FUSION with WHERE: {:?}",
        result.err()
    );

    let query = result.unwrap();
    let fusion = query
        .select
        .fusion_clause
        .as_ref()
        .expect("FUSION clause should be present");
    assert_eq!(fusion.strategy, crate::velesql::FusionStrategyType::Rrf);
    assert_eq!(fusion.k, Some(60));

    match query.select.where_clause {
        Some(crate::velesql::Condition::Comparison(c)) => {
            assert_eq!(c.column, "category");
            assert_eq!(c.operator, crate::velesql::CompareOp::Eq);
            assert_eq!(c.value, crate::velesql::Value::String("tech".to_string()));
        }
        other => panic!("Expected comparison WHERE clause, got {other:?}"),
    }
}