plexus-engine 0.3.4

Engine integration traits for consuming Plexus plans
Documentation
use super::*;

fn assert_readonly_tck_equivalence_for_pipeline(pipeline: &str) {
    for case in tck_readonly::load_readonly_cases() {
        let unopt_out = tck_readonly::execute_case_unoptimized_for_equivalence(&case);
        let opt_out = if pipeline == PIPELINE_CORE {
            tck_readonly::execute_case_optimized_for_equivalence(&case)
        } else {
            tck_readonly::execute_case_with_pipeline_for_equivalence(&case, pipeline)
        };

        match (unopt_out, opt_out) {
            (Ok(unopt), Ok(opt)) => {
                if case.any_order {
                    assert_eq!(
                        normalize_rows(&opt.rows),
                        normalize_rows(&unopt.rows),
                        "optimized/unoptimized mismatch (any-order) for pipeline `{pipeline}` readonly tck case: {}",
                        case.name,
                    );
                } else {
                    assert_eq!(
                        opt.rows, unopt.rows,
                        "optimized/unoptimized mismatch for pipeline `{pipeline}` readonly tck case: {}",
                        case.name,
                    );
                }
            }
            (Err(unopt_err), Err(opt_err)) => {
                if let Some(expected) = &case.expected_error_contains {
                    let expected_lower = expected.to_ascii_lowercase();
                    assert!(
                        unopt_err.to_ascii_lowercase().contains(&expected_lower),
                        "unoptimized error does not match expected substring `{expected}` for pipeline `{pipeline}` case `{}`: {unopt_err}",
                        case.name,
                    );
                    assert!(
                        opt_err.to_ascii_lowercase().contains(&expected_lower),
                        "optimized error does not match expected substring `{expected}` for pipeline `{pipeline}` case `{}`: {opt_err}",
                        case.name,
                    );
                } else {
                    assert_eq!(
                        opt_err, unopt_err,
                        "optimized/unoptimized error mismatch for pipeline `{pipeline}` readonly tck case: {}",
                        case.name,
                    );
                }
            }
            (Ok(unopt), Err(opt_err)) => {
                panic!(
                    "optimized/unoptimized mismatch for pipeline `{pipeline}` readonly tck case `{}`: unoptimized succeeded with {:?}, optimized failed with `{opt_err}`",
                    case.name, unopt.rows
                );
            }
            (Err(unopt_err), Ok(opt)) => {
                panic!(
                    "optimized/unoptimized mismatch for pipeline `{pipeline}` readonly tck case `{}`: unoptimized failed with `{unopt_err}`, optimized succeeded with {:?}",
                    case.name, opt.rows
                );
            }
        }
    }
}

#[test]
fn readonly_tck_corpus_equivalence_core_pipeline() {
    assert_readonly_tck_equivalence_for_pipeline(PIPELINE_CORE);
}

#[test]
fn readonly_tck_corpus_equivalence_full_pipeline() {
    assert_readonly_tck_equivalence_for_pipeline(PIPELINE_FULL);
}

#[test]
fn curated_query_equivalence_core_and_full_pipelines() {
    let queries = [
        "MATCH (n:Person) RETURN n.name AS name ORDER BY name",
        "MATCH (n:Person)-[r:KNOWS]->(m:Person) WHERE n.age > 25 RETURN n.name, m.name ORDER BY n.name, m.name",
        "OPTIONAL MATCH (n:Person)-[r:WORKS_AT]->(c:Company) RETURN n.name, c.name ORDER BY n.name",
        "MATCH (n:Person) WITH COLLECT(n.name) AS names UNWIND names AS name RETURN name ORDER BY name",
        "MATCH (n:Person) RETURN n.name AS name UNION MATCH (m:Person) RETURN m.name AS name",
        "MATCH (a:Person)-[p:KNOWS*1..2]->(b:Person) RETURN p",
        "MATCH (n:Person) RETURN 1 + n.age AS age ORDER BY age",
        "MATCH (n:Person) RETURN (n.age + 1) + 2 AS age ORDER BY age",
        "MATCH (n:Person) RETURN CASE WHEN false THEN 0 WHEN true THEN n.age + 0 ELSE n.age + 0 END AS age ORDER BY age",
        "MATCH (n:Person) WHERE CASE WHEN n.age > 35 THEN true WHEN n.name = \"Alice\" THEN true ELSE false END RETURN n.name AS name ORDER BY name",
    ];
    for cypher in queries {
        assert_query_equivalent_under_pipeline(cypher, PIPELINE_CORE);
        assert_query_equivalent_under_pipeline(cypher, PIPELINE_FULL);
    }
}