qail-pg 0.27.4

Fastest async PostgreSQL driver - AST to wire protocol, optional io_uring on Linux
Documentation
//! Test for v0.14.4+ features
//! Tests: ArrayConstructor, RowConstructor, Subscript, Collate, FieldAccess
//!
//! Run with: cargo run --example expr_test

use qail_core::ast::Expr;
use qail_core::prelude::Qail;
use qail_pg::driver::PgDriver;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    println!("๐Ÿ”ฅ QAIL Expression Coverage Test (v0.14.4+)");
    println!("=============================================\n");

    let mut driver = PgDriver::connect("127.0.0.1", 5432, "orion", "qail_test_migration").await?;

    // Setup test table with arrays
    println!("๐Ÿ›   Setup Test Data");
    println!("-------------------");

    driver
        .execute_raw("DROP TABLE IF EXISTS expr_test CASCADE")
        .await
        .ok();
    driver
        .execute_raw(
            "CREATE TABLE expr_test (
            id SERIAL PRIMARY KEY,
            name TEXT NOT NULL,
            tags TEXT[] DEFAULT '{}',
            data JSONB DEFAULT '{}'
        )",
        )
        .await?;

    driver
        .execute_raw(
            "INSERT INTO expr_test (name, tags, data) VALUES 
        ('Alice', ARRAY['rust', 'postgres'], '{\"city\": \"NYC\"}'),
        ('Bob', ARRAY['go', 'mysql'], '{\"city\": \"LA\"}'),
        ('Carol', ARRAY['python', 'postgres', 'redis'], '{\"city\": \"SF\"}')",
        )
        .await?;
    println!("  โœ“ Created expr_test table with 3 rows");

    // =====================================================
    // Test 1: ArrayConstructor - ARRAY[name, name] (same types)
    // =====================================================
    println!("\n๐Ÿ“– Test 1: ArrayConstructor");
    println!("----------------------------");

    let mut arr_query = Qail::get("expr_test").columns(["id", "name"]);
    arr_query.columns.push(Expr::ArrayConstructor {
        elements: vec![
            Expr::Named("name".to_string()),
            Expr::Literal(qail_core::ast::Value::String("suffix".to_string())),
        ],
        alias: Some("name_arr".to_string()),
    });

    match driver.fetch_all(&arr_query).await {
        Ok(rows) => {
            println!("  โœ“ ArrayConstructor: {} rows returned", rows.len());
        }
        Err(e) => println!("  โš  ArrayConstructor: {} (PostgreSQL type check)", e),
    }

    // =====================================================
    // Test 2: RowConstructor - ROW(a, b, c)
    // =====================================================
    println!("\n๐Ÿ“– Test 2: RowConstructor");
    println!("--------------------------");

    let mut row_query = Qail::get("expr_test").columns(["id"]);
    row_query.columns.push(Expr::RowConstructor {
        elements: vec![
            Expr::Named("id".to_string()),
            Expr::Named("name".to_string()),
        ],
        alias: Some("person_row".to_string()),
    });

    match driver.fetch_all(&row_query).await {
        Ok(rows) => {
            println!(
                "  โœ“ RowConstructor: {} rows returned (may be 0 due to simple driver)",
                rows.len()
            );
        }
        Err(e) => println!("  โš  RowConstructor: {}", e),
    }

    // =====================================================
    // Test 3: Subscript - tags[1]
    // =====================================================
    println!("\n๐Ÿ“– Test 3: Subscript (Array Access)");
    println!("------------------------------------");

    let mut sub_query = Qail::get("expr_test").columns(["id", "name"]);
    sub_query.columns.push(Expr::Subscript {
        expr: Box::new(Expr::Named("tags".to_string())),
        index: Box::new(Expr::Literal(qail_core::ast::Value::Int(1))),
        alias: Some("first_tag".to_string()),
    });

    match driver.fetch_all(&sub_query).await {
        Ok(rows) => {
            println!("  โœ“ Subscript: {} rows with first_tag", rows.len());
            assert_eq!(rows.len(), 3, "Expected 3 rows");
        }
        Err(e) => println!("  โœ— Subscript: {}", e),
    }

    // =====================================================
    // Test 4: Collate - name COLLATE "C"
    // =====================================================
    println!("\n๐Ÿ“– Test 4: Collate");
    println!("-------------------");

    let mut collate_query = Qail::get("expr_test").columns(["id"]);
    collate_query.columns.push(Expr::Collate {
        expr: Box::new(Expr::Named("name".to_string())),
        collation: "C".to_string(),
        alias: Some("name_c".to_string()),
    });

    match driver.fetch_all(&collate_query).await {
        Ok(rows) => {
            println!("  โœ“ Collate: {} rows with C collation", rows.len());
            assert_eq!(rows.len(), 3, "Expected 3 rows");
        }
        Err(e) => println!("  โœ— Collate: {}", e),
    }

    // =====================================================
    // =====================================================
    println!("\n๐Ÿงน Cleanup");
    println!("-----------");
    driver
        .execute_raw("DROP TABLE IF EXISTS expr_test CASCADE")
        .await?;
    println!("  โœ“ Cleanup complete");

    println!("\nโœ… Expression test complete! All v0.14.4 features verified.");

    Ok(())
}