athena-gateway 3.18.0

Portable gateway request contracts and normalization primitives for Athena
Documentation
use super::*;

fn relation_request_body(query: &str) -> Value {
    try_rewrite_relation_select_query(query, None)
        .expect("rewrite should parse")
        .expect("rewrite should apply")
        .request_body
}

#[test]
fn relation_select_compatibility_rewrites_uuid_text_fallback_query() {
    let query = r#"SELECT user_id,users:athena.users(id) FROM "public"."chat_subscriptions" WHERE "user_id"::text = 'ef7a4c74-cc35-4d32-945a-a5271279ecdb' ORDER BY "user_id" DESC LIMIT 1 OFFSET 2"#;
    let rewrite = try_rewrite_relation_select_query(query, None)
        .expect("rewrite should parse")
        .expect("rewrite should apply");

    assert_eq!(rewrite.select, "user_id,users:athena.users(id)");
    assert_eq!(
        rewrite.table,
        GatewayRelationSelectTableRef {
            schema_name: Some("public".to_string()),
            table_name: "chat_subscriptions".to_string(),
        }
    );
    assert_eq!(
        rewrite.request_body,
        json!({
            "table_name": "chat_subscriptions",
            "schema_name": "public",
            "select": [
                {
                    "kind": "column",
                    "name": "user_id"
                },
                {
                    "kind": "relation",
                    "name": "athena.users",
                    "alias": "users",
                    "query": {
                        "select": "id"
                    }
                }
            ],
            "where_filters": [
                {
                    "column": "user_id",
                    "operator": "eq",
                    "value": "ef7a4c74-cc35-4d32-945a-a5271279ecdb",
                    "column_cast": "text"
                }
            ],
            "orderBy": [
                {
                    "column": "user_id",
                    "direction": "desc"
                }
            ],
            "limit": 1,
            "offset": 2
        })
    );
}

#[test]
fn relation_select_compatibility_rewrites_request_schema_for_unqualified_tables() {
    let query = r#"SELECT user_id,users:athena.users(id) FROM chat_subscriptions WHERE user_id = 'ef7a4c74-cc35-4d32-945a-a5271279ecdb'::uuid"#;
    let rewrite = try_rewrite_relation_select_query(query, Some("private"))
        .expect("rewrite should parse")
        .expect("rewrite should apply");

    assert_eq!(rewrite.table.schema_name.as_deref(), Some("private"));
    assert_eq!(rewrite.table.table_name, "chat_subscriptions");
    assert_eq!(rewrite.request_body["schema_name"], json!("private"));
    assert_eq!(
        rewrite.request_body["where_filters"],
        json!([
            {
                "column": "user_id",
                "operator": "eq",
                "value": "ef7a4c74-cc35-4d32-945a-a5271279ecdb",
                "column_cast": "text"
            }
        ])
    );
}

#[test]
fn relation_select_compatibility_preserves_multi_column_order() {
    let query = r#"SELECT user_id,users:athena.users(id) FROM chat_subscriptions ORDER BY created_at DESC, user_id ASC"#;
    let rewrite = try_rewrite_relation_select_query(query, None)
        .expect("rewrite should parse")
        .expect("rewrite should apply");

    assert_eq!(
        rewrite.request_body["orderBy"],
        json!([
            {
                "column": "created_at",
                "direction": "desc"
            },
            {
                "column": "user_id",
                "direction": "asc"
            }
        ])
    );
}

#[test]
fn relation_select_compatibility_parses_root_aliases() {
    let body = relation_request_body(
        r#"SELECT cs.user_id,users:athena.users(id) FROM public.chat_subscriptions AS cs WHERE cs.user_id = '1'"#,
    );

    assert_eq!(
        body["select"],
        json!([
            {
                "kind": "column",
                "name": "user_id"
            },
            {
                "kind": "relation",
                "name": "athena.users",
                "alias": "users",
                "query": {
                    "select": "id"
                }
            }
        ])
    );
    assert_eq!(
        body["where_filters"],
        json!([
            {
                "column": "user_id",
                "operator": "eq",
                "value": "1"
            }
        ])
    );
}

#[test]
fn relation_select_compatibility_rewrites_inner_join_to_relation_modifier() {
    let body = relation_request_body(
        r#"SELECT cs.user_id,member:athena.users(id,username) FROM public.chat_subscriptions cs INNER JOIN athena.users u ON u.id = cs.user_id WHERE u.username = 'alice' ORDER BY u.username DESC"#,
    );

    assert_eq!(
        body,
        json!({
            "table_name": "chat_subscriptions",
            "schema_name": "public",
            "select": [
                {
                    "kind": "column",
                    "name": "user_id"
                },
                {
                    "kind": "relation",
                    "name": "athena.users",
                    "alias": "member",
                    "join": "inner",
                    "foreign_key": "parent.user_id",
                    "query": {
                        "select": "id,username",
                        "where_filters": [
                            {
                                "column": "username",
                                "operator": "eq",
                                "value": "alice"
                            }
                        ],
                        "orderBy": [
                            {
                                "column": "username",
                                "direction": "desc"
                            }
                        ]
                    }
                }
            ]
        })
    );
}

#[test]
fn relation_select_compatibility_rewrites_left_join_to_relation_metadata() {
    let body = relation_request_body(
        r#"SELECT cs.user_id,users:athena.users(id) FROM public.chat_subscriptions cs LEFT JOIN athena.users users ON cs.user_id = users.id"#,
    );

    assert_eq!(
        body["select"][1],
        json!({
            "kind": "relation",
            "name": "athena.users",
            "alias": "users",
            "foreign_key": "parent.user_id",
            "query": {
                "select": "id"
            }
        })
    );
}

#[test]
fn relation_select_compatibility_rejects_mismatched_join_target() {
    let err = try_rewrite_relation_select_query(
            r#"SELECT user_id,users:athena.users(id) FROM public.chat_subscriptions cs INNER JOIN athena.accounts a ON a.id = cs.user_id"#,
            None,
        )
        .expect_err("mismatched join target should fail");

    assert!(err.contains("does not match any projected relation token"));
}

#[test]
fn relation_select_compatibility_rejects_using_joins() {
    let err = try_rewrite_relation_select_query(
            r#"SELECT user_id,users:athena.users(id) FROM public.chat_subscriptions cs INNER JOIN athena.users u USING (user_id)"#,
            None,
        )
        .expect_err("USING join should fail");

    assert!(err.contains("JOIN USING"));
}

#[test]
fn relation_select_compatibility_rejects_multi_predicate_on_clauses() {
    let err = try_rewrite_relation_select_query(
            r#"SELECT user_id,users:athena.users(id) FROM public.chat_subscriptions cs INNER JOIN athena.users u ON u.id = cs.user_id AND u.username = 'alice'"#,
            None,
        )
        .expect_err("multi predicate ON should fail");

    assert!(err.contains("single equality predicate"));
}

#[test]
fn relation_select_compatibility_rejects_unsupported_join_types() {
    let err = try_rewrite_relation_select_query(
            r#"SELECT user_id,users:athena.users(id) FROM public.chat_subscriptions cs RIGHT JOIN athena.users u ON u.id = cs.user_id"#,
            None,
        )
        .expect_err("RIGHT JOIN should fail");

    assert!(err.contains("RIGHT JOIN"));
}

#[test]
fn relation_select_compatibility_ignores_plain_sql_queries() {
    let query = r#"SELECT id, now() AS generated_at FROM "public"."users" WHERE "id" = '123'"#;
    let rewrite =
        try_rewrite_relation_select_query(query, None).expect("plain SQL should not error");

    assert!(rewrite.is_none());
}