polyglot-sql 0.5.12

SQL parsing, validating, formatting, and dialect translation library
Documentation
use polyglot_sql::expressions::FunctionSecurity;
use polyglot_sql::{generate, parse, DialectType, Expression};

fn assert_create_view(
    sql: &str,
    dialect: DialectType,
    expected_security: Option<FunctionSecurity>,
    expected_comment: Option<&str>,
) {
    let ast = parse(sql, dialect).unwrap_or_else(|error| {
        panic!("{dialect:?} CREATE VIEW should parse for {sql:?}: {error}")
    });
    assert_eq!(ast.len(), 1);

    let Expression::CreateView(view) = &ast[0] else {
        panic!(
            "expected CreateView for {sql:?}, got {}",
            ast[0].variant_name()
        );
    };

    assert_eq!(
        view.security, expected_security,
        "security mismatch for {sql}"
    );
    assert_eq!(
        view.comment.as_deref(),
        expected_comment,
        "comment mismatch for {sql}"
    );

    let generated = generate(&ast[0], dialect).unwrap_or_else(|error| {
        panic!("{dialect:?} CREATE VIEW should generate for {sql:?}: {error}")
    });
    parse(&generated, dialect).unwrap_or_else(|error| {
        panic!("{dialect:?} generated CREATE VIEW should reparse for {generated:?}: {error}")
    });
}

#[test]
fn trino_create_view_accepts_comment_before_security() {
    assert_create_view(
        "CREATE VIEW v COMMENT 'c' SECURITY DEFINER AS SELECT 1 AS a",
        DialectType::Trino,
        Some(FunctionSecurity::Definer),
        Some("c"),
    );
    assert_create_view(
        "CREATE VIEW v COMMENT 'c' SECURITY INVOKER AS SELECT 1 AS a",
        DialectType::Trino,
        Some(FunctionSecurity::Invoker),
        Some("c"),
    );
}

#[test]
fn trino_create_view_existing_security_and_comment_orders_still_parse() {
    assert_create_view(
        "CREATE VIEW v SECURITY DEFINER AS SELECT 1 AS a",
        DialectType::Trino,
        Some(FunctionSecurity::Definer),
        None,
    );
    assert_create_view(
        "CREATE VIEW v COMMENT 'c' AS SELECT 1 AS a",
        DialectType::Trino,
        None,
        Some("c"),
    );
    assert_create_view(
        "CREATE VIEW v SECURITY DEFINER COMMENT 'c' AS SELECT 1 AS a",
        DialectType::Trino,
        Some(FunctionSecurity::Definer),
        Some("c"),
    );
}

#[test]
fn presto_create_view_accepts_comment_before_security() {
    assert_create_view(
        "CREATE VIEW v COMMENT 'c' SECURITY DEFINER AS SELECT 1 AS a",
        DialectType::Presto,
        Some(FunctionSecurity::Definer),
        Some("c"),
    );
    assert_create_view(
        "CREATE VIEW v COMMENT 'c' SECURITY INVOKER AS SELECT 1 AS a",
        DialectType::Presto,
        Some(FunctionSecurity::Invoker),
        Some("c"),
    );
}

#[test]
fn create_view_accepts_sql_security_after_comment() {
    assert_create_view(
        "CREATE VIEW v COMMENT 'c' SQL SECURITY DEFINER AS SELECT 1 AS a",
        DialectType::MySQL,
        Some(FunctionSecurity::Definer),
        Some("c"),
    );
}