#![allow(clippy::unwrap_used)]
mod basic {
use insta::assert_snapshot;
#[test]
fn snapshot_postgres_basic_select() {
let sql = r#"SELECT data FROM "v_user""#;
assert_snapshot!(sql);
}
#[test]
fn snapshot_postgres_select_with_limit() {
let sql = r#"SELECT data FROM "v_user" LIMIT 10"#;
assert_snapshot!(sql);
}
#[test]
fn snapshot_postgres_select_with_offset() {
let sql = r#"SELECT data FROM "v_user" LIMIT 20 OFFSET 10"#;
assert_snapshot!(sql);
}
#[test]
fn snapshot_postgres_select_with_order_by_asc() {
let sql = r#"SELECT data FROM "v_post" ORDER BY data->>'created_at' ASC"#;
assert_snapshot!(sql);
}
#[test]
fn snapshot_postgres_select_with_order_by_desc() {
let sql = r#"SELECT data FROM "v_post" ORDER BY data->>'title' DESC LIMIT 10"#;
assert_snapshot!(sql);
}
#[test]
fn snapshot_postgres_where_eq_operator() {
let sql = r#"SELECT data FROM "v_user" WHERE data->>'email' = $1"#;
assert_snapshot!(sql);
}
#[test]
fn snapshot_postgres_where_like_operator() {
let sql = r#"SELECT data FROM "v_user" WHERE data->>'name' ILIKE $1"#;
assert_snapshot!(sql);
}
#[test]
fn snapshot_postgres_where_in_operator() {
let sql = r#"SELECT data FROM "v_user" WHERE data->>'id' = ANY($1::UUID[])"#;
assert_snapshot!(sql);
}
#[test]
fn snapshot_postgres_where_is_null() {
let sql = r#"SELECT data FROM "v_post" WHERE data->>'deleted_at' IS NULL"#;
assert_snapshot!(sql);
}
#[test]
fn snapshot_postgres_where_is_not_null() {
let sql = r#"SELECT data FROM "v_post" WHERE data->>'published_at' IS NOT NULL"#;
assert_snapshot!(sql);
}
#[test]
fn snapshot_postgres_where_gt_operator() {
let sql = r#"SELECT data FROM "v_post" WHERE (data->>'created_at')::TIMESTAMP > $1"#;
assert_snapshot!(sql);
}
#[test]
fn snapshot_postgres_multiple_where_clauses() {
let sql = r#"SELECT data FROM "v_post" WHERE data->>'published' = true AND data->>'author_id' = $1"#;
assert_snapshot!(sql);
}
#[test]
fn snapshot_postgres_with_field_projection() {
let sql = r#"SELECT jsonb_build_object('id', data->>'id', 'name', data->>'name', 'email', data->>'email') FROM "v_user" LIMIT 10"#;
assert_snapshot!(sql);
}
}
mod mutations_rls {
use insta::assert_snapshot;
#[test]
fn snapshot_postgres_function_call_create() {
let sql = r"SELECT * FROM fn_create_post($1, $2, $3, $4)";
assert_snapshot!(sql);
}
#[test]
fn snapshot_postgres_function_call_update() {
let sql = r"SELECT * FROM fn_update_post($1, $2, $3, $4, $5, $6)";
assert_snapshot!(sql);
}
#[test]
fn snapshot_postgres_function_call_delete() {
let sql = r"SELECT * FROM fn_delete_post($1, $2)";
assert_snapshot!(sql);
}
#[test]
fn snapshot_postgres_with_rls_where_clause() {
let sql = r#"SELECT data FROM "v_post" WHERE data->>'published' = true AND data->>'tenant_id' = current_setting('app.tenant_id')::UUID"#;
assert_snapshot!(sql);
}
#[test]
fn snapshot_postgres_rls_only() {
let sql = r#"SELECT data FROM "v_user" WHERE data->>'tenant_id' = current_setting('app.tenant_id')::UUID"#;
assert_snapshot!(sql);
}
}
mod edge_cases {
use insta::assert_snapshot;
#[test]
fn snapshot_null_handling_is_null() {
let sql = r#"SELECT data FROM "v_post" WHERE data->>'deleted_at' IS NULL"#;
assert_snapshot!(sql);
}
#[test]
fn snapshot_special_characters_in_like() {
let sql = r#"SELECT data FROM "v_post" WHERE data->>'title' ILIKE $1"#;
assert_snapshot!(sql);
}
#[test]
fn snapshot_reserved_keywords_quoted() {
let sql = r#"SELECT data FROM "user" WHERE data->>'from' = $1"#;
assert_snapshot!(sql);
}
#[test]
fn snapshot_type_casting_timestamp() {
let sql =
r#"SELECT data FROM "v_post" WHERE (data->>'created_at')::TIMESTAMP > $1::TIMESTAMP"#;
assert_snapshot!(sql);
}
#[test]
fn snapshot_type_casting_uuid() {
let sql = r#"SELECT data FROM "v_user" WHERE data->>'id' = ANY($1::UUID[])"#;
assert_snapshot!(sql);
}
#[test]
fn snapshot_boolean_literal() {
let sql = r#"SELECT data FROM "v_post" WHERE data->>'published' = true"#;
assert_snapshot!(sql);
}
}
mod parity {
use insta::assert_snapshot;
#[test]
fn snapshot_parity_postgres_basic_select() {
let sql = r#"SELECT data FROM "v_user""#;
assert_snapshot!(sql);
}
#[test]
fn snapshot_parity_mysql_basic_select() {
let sql = r"SELECT `data` FROM `v_user`";
assert_snapshot!(sql);
}
#[test]
fn snapshot_parity_sqlite_basic_select() {
let sql = r#"SELECT data FROM "v_user""#;
assert_snapshot!(sql);
}
#[test]
fn snapshot_parity_sqlserver_basic_select() {
let sql = r"SELECT [data] FROM [v_user]";
assert_snapshot!(sql);
}
#[test]
fn snapshot_parity_postgres_like() {
let sql = r#"SELECT data FROM "v_user" WHERE data->>'name' ILIKE $1"#;
assert_snapshot!(sql);
}
#[test]
fn snapshot_parity_mysql_like() {
let sql = r"SELECT `data` FROM `v_user` WHERE JSON_UNQUOTE(JSON_EXTRACT(`data`, '$.name')) LIKE ?";
assert_snapshot!(sql);
}
#[test]
fn snapshot_parity_sqlite_like() {
let sql = r#"SELECT data FROM "v_user" WHERE json_extract(data, '$.name') LIKE ?1"#;
assert_snapshot!(sql);
}
#[test]
fn snapshot_parity_sqlserver_like() {
let sql = r"SELECT [data] FROM [v_user] WHERE JSON_VALUE([data], '$.name') LIKE @p1";
assert_snapshot!(sql);
}
#[test]
fn snapshot_parity_postgres_function_call() {
let sql = r#"SELECT * FROM "fn_create_post"($1, $2, $3, $4)"#;
assert_snapshot!(sql);
}
#[test]
fn snapshot_parity_mysql_function_call() {
let sql = r"CALL `fn_create_post`(?, ?, ?, ?)";
assert_snapshot!(sql);
}
#[test]
fn snapshot_parity_sqlserver_function_call() {
let sql = r"EXECUTE [fn_create_post] @p1, @p2, @p3, @p4";
assert_snapshot!(sql);
}
#[test]
fn snapshot_parity_postgres_keyset_pagination() {
let sql =
r#"SELECT data FROM "v_post" WHERE data->>'id' > $1 ORDER BY data->>'id' ASC LIMIT 11"#;
assert_snapshot!(sql);
}
#[test]
fn snapshot_parity_mysql_offset_pagination() {
let sql = r"SELECT `data` FROM `v_post` ORDER BY JSON_UNQUOTE(JSON_EXTRACT(`data`, '$.id')) ASC LIMIT 11 OFFSET 10";
assert_snapshot!(sql);
}
#[test]
fn snapshot_parity_sqlserver_offset_pagination() {
let sql = r"SELECT [data] FROM [v_post] ORDER BY JSON_VALUE([data], '$.id') ASC OFFSET 10 ROWS FETCH NEXT 11 ROWS ONLY";
assert_snapshot!(sql);
}
}
mod adapters {
use insta::assert_snapshot;
#[test]
fn snapshot_mysql_basic_select() {
let sql = r"SELECT `data` FROM `v_user`";
assert_snapshot!(sql);
}
#[test]
fn snapshot_mysql_where_like() {
let sql = r"SELECT `data` FROM `v_user` WHERE JSON_UNQUOTE(JSON_EXTRACT(`data`, '$.name')) LIKE $1";
assert_snapshot!(sql);
}
#[test]
fn snapshot_mysql_function_call() {
let sql = r"CALL `fn_create_post`($1, $2, $3, $4)";
assert_snapshot!(sql);
}
#[test]
fn snapshot_sqlite_basic_select() {
let sql = r"SELECT `data` FROM `v_user`";
assert_snapshot!(sql);
}
#[test]
fn snapshot_sqlserver_basic_select() {
let sql = r"SELECT [data] FROM [v_user]";
assert_snapshot!(sql);
}
#[test]
fn snapshot_sqlserver_where_like() {
let sql = r"SELECT [data] FROM [v_user] WHERE JSON_VALUE([data], '$.name') LIKE @p1";
assert_snapshot!(sql);
}
}
mod relay_aggregation {
use insta::assert_snapshot;
#[test]
fn snapshot_relay_pagination_keyset() {
let sql =
r#"SELECT data FROM "v_post" WHERE data->>'id' > $1 ORDER BY data->>'id' ASC LIMIT 11"#;
assert_snapshot!(sql);
}
#[test]
fn snapshot_relay_pagination_offset_fallback() {
let sql = r"SELECT `data` FROM `v_post` ORDER BY `data`->>'id' ASC LIMIT 11 OFFSET 10";
assert_snapshot!(sql);
}
#[test]
fn snapshot_aggregate_query_sum() {
let sql = r#"SELECT SUM((data->>'amount')::NUMERIC) as total FROM "tf_sales""#;
assert_snapshot!(sql);
}
#[test]
fn snapshot_aggregate_query_with_group_by() {
let sql = r#"SELECT data->>'category' as category, SUM((data->>'amount')::NUMERIC) as total FROM "tf_sales" GROUP BY data->>'category'"#;
assert_snapshot!(sql);
}
}
mod generated_sql {
#[allow(unused_imports)]
use fraiseql_core::db::where_sql_generator::WhereSqlGenerator;
use fraiseql_core::db::{
PostgresDialect, WhereClause, WhereOperator, postgres::PostgresWhereGenerator,
};
use insta::assert_snapshot;
use serde_json::json;
const fn pg() -> PostgresWhereGenerator {
PostgresWhereGenerator::new(PostgresDialect)
}
#[test]
fn generated_pg_eq() {
let clause = WhereClause::Field {
path: vec!["email".to_string()],
operator: WhereOperator::Eq,
value: json!("alice@example.com"),
};
let (sql, _params) = pg().generate(&clause).unwrap();
assert_snapshot!(sql);
}
#[test]
fn generated_pg_neq() {
let clause = WhereClause::Field {
path: vec!["status".to_string()],
operator: WhereOperator::Neq,
value: json!("deleted"),
};
let (sql, _params) = pg().generate(&clause).unwrap();
assert_snapshot!(sql);
}
#[test]
fn generated_pg_gt() {
let clause = WhereClause::Field {
path: vec!["score".to_string()],
operator: WhereOperator::Gt,
value: json!(100),
};
let (sql, _params) = pg().generate(&clause).unwrap();
assert_snapshot!(sql);
}
#[test]
fn generated_pg_gte() {
let clause = WhereClause::Field {
path: vec!["score".to_string()],
operator: WhereOperator::Gte,
value: json!(100),
};
let (sql, _params) = pg().generate(&clause).unwrap();
assert_snapshot!(sql);
}
#[test]
fn generated_pg_lt() {
let clause = WhereClause::Field {
path: vec!["age".to_string()],
operator: WhereOperator::Lt,
value: json!(18),
};
let (sql, _params) = pg().generate(&clause).unwrap();
assert_snapshot!(sql);
}
#[test]
fn generated_pg_lte() {
let clause = WhereClause::Field {
path: vec!["age".to_string()],
operator: WhereOperator::Lte,
value: json!(65),
};
let (sql, _params) = pg().generate(&clause).unwrap();
assert_snapshot!(sql);
}
#[test]
fn generated_pg_like() {
let clause = WhereClause::Field {
path: vec!["title".to_string()],
operator: WhereOperator::Like,
value: json!("%rust%"),
};
let (sql, _params) = pg().generate(&clause).unwrap();
assert_snapshot!(sql);
}
#[test]
fn generated_pg_ilike() {
let clause = WhereClause::Field {
path: vec!["title".to_string()],
operator: WhereOperator::Ilike,
value: json!("%rust%"),
};
let (sql, _params) = pg().generate(&clause).unwrap();
assert_snapshot!(sql);
}
#[test]
fn generated_pg_contains() {
let clause = WhereClause::Field {
path: vec!["name".to_string()],
operator: WhereOperator::Contains,
value: json!("alice"),
};
let (sql, _params) = pg().generate(&clause).unwrap();
assert_snapshot!(sql);
}
#[test]
fn generated_pg_icontains() {
let clause = WhereClause::Field {
path: vec!["name".to_string()],
operator: WhereOperator::Icontains,
value: json!("alice"),
};
let (sql, _params) = pg().generate(&clause).unwrap();
assert_snapshot!(sql);
}
#[test]
fn generated_pg_in_operator() {
let clause = WhereClause::Field {
path: vec!["status".to_string()],
operator: WhereOperator::In,
value: json!(["active", "pending", "review"]),
};
let (sql, _params) = pg().generate(&clause).unwrap();
assert_snapshot!(sql);
}
#[test]
fn generated_pg_nin_operator() {
let clause = WhereClause::Field {
path: vec!["status".to_string()],
operator: WhereOperator::Nin,
value: json!(["deleted", "banned"]),
};
let (sql, _params) = pg().generate(&clause).unwrap();
assert_snapshot!(sql);
}
#[test]
fn generated_pg_is_null_true() {
let clause = WhereClause::Field {
path: vec!["deleted_at".to_string()],
operator: WhereOperator::IsNull,
value: json!(true),
};
let (sql, _params) = pg().generate(&clause).unwrap();
assert_snapshot!(sql);
}
#[test]
fn generated_pg_is_null_false() {
let clause = WhereClause::Field {
path: vec!["published_at".to_string()],
operator: WhereOperator::IsNull,
value: json!(false),
};
let (sql, _params) = pg().generate(&clause).unwrap();
assert_snapshot!(sql);
}
#[test]
fn generated_pg_startswith() {
let clause = WhereClause::Field {
path: vec!["username".to_string()],
operator: WhereOperator::Startswith,
value: json!("admin"),
};
let (sql, _params) = pg().generate(&clause).unwrap();
assert_snapshot!(sql);
}
#[test]
fn generated_pg_endswith() {
let clause = WhereClause::Field {
path: vec!["email".to_string()],
operator: WhereOperator::Endswith,
value: json!("@example.com"),
};
let (sql, _params) = pg().generate(&clause).unwrap();
assert_snapshot!(sql);
}
#[test]
fn generated_pg_and_two_fields() {
let clause = WhereClause::And(vec![
WhereClause::Field {
path: vec!["published".to_string()],
operator: WhereOperator::Eq,
value: json!(true),
},
WhereClause::Field {
path: vec!["author_id".to_string()],
operator: WhereOperator::Eq,
value: json!("00000000-0000-0000-0000-000000000001"),
},
]);
let (sql, _params) = pg().generate(&clause).unwrap();
assert_snapshot!(sql);
}
#[test]
fn generated_pg_or_two_fields() {
let clause = WhereClause::Or(vec![
WhereClause::Field {
path: vec!["role".to_string()],
operator: WhereOperator::Eq,
value: json!("admin"),
},
WhereClause::Field {
path: vec!["role".to_string()],
operator: WhereOperator::Eq,
value: json!("superuser"),
},
]);
let (sql, _params) = pg().generate(&clause).unwrap();
assert_snapshot!(sql);
}
#[test]
fn generated_pg_nested_and_or() {
let clause = WhereClause::And(vec![
WhereClause::Field {
path: vec!["active".to_string()],
operator: WhereOperator::Eq,
value: json!(true),
},
WhereClause::Or(vec![
WhereClause::Field {
path: vec!["role".to_string()],
operator: WhereOperator::Eq,
value: json!("admin"),
},
WhereClause::Field {
path: vec!["role".to_string()],
operator: WhereOperator::Eq,
value: json!("mod"),
},
]),
]);
let (sql, _params) = pg().generate(&clause).unwrap();
assert_snapshot!(sql);
}
#[test]
fn generated_pg_deep_nested_path() {
let clause = WhereClause::Field {
path: vec!["address".to_string(), "city".to_string()],
operator: WhereOperator::Eq,
value: json!("Paris"),
};
let (sql, _params) = pg().generate(&clause).unwrap();
assert_snapshot!(sql);
}
#[cfg(feature = "mysql")]
#[test]
fn generated_mysql_eq() {
use fraiseql_core::db::{MySqlDialect, mysql::MySqlWhereGenerator};
let clause = WhereClause::Field {
path: vec!["email".to_string()],
operator: WhereOperator::Eq,
value: json!("alice@example.com"),
};
let (sql, _params) = MySqlWhereGenerator::new(MySqlDialect).generate(&clause).unwrap();
assert_snapshot!(sql);
}
#[cfg(feature = "mysql")]
#[test]
fn generated_mysql_like() {
use fraiseql_core::db::{MySqlDialect, mysql::MySqlWhereGenerator};
let clause = WhereClause::Field {
path: vec!["name".to_string()],
operator: WhereOperator::Like,
value: json!("%alice%"),
};
let (sql, _params) = MySqlWhereGenerator::new(MySqlDialect).generate(&clause).unwrap();
assert_snapshot!(sql);
}
#[cfg(feature = "mysql")]
#[test]
fn generated_mysql_in_operator() {
use fraiseql_core::db::{MySqlDialect, mysql::MySqlWhereGenerator};
let clause = WhereClause::Field {
path: vec!["status".to_string()],
operator: WhereOperator::In,
value: json!(["active", "pending"]),
};
let (sql, _params) = MySqlWhereGenerator::new(MySqlDialect).generate(&clause).unwrap();
assert_snapshot!(sql);
}
#[cfg(feature = "sqlite")]
#[test]
fn generated_sqlite_eq() {
use fraiseql_core::db::{SqliteDialect, sqlite::SqliteWhereGenerator};
let clause = WhereClause::Field {
path: vec!["email".to_string()],
operator: WhereOperator::Eq,
value: json!("alice@example.com"),
};
let (sql, _params) = SqliteWhereGenerator::new(SqliteDialect).generate(&clause).unwrap();
assert_snapshot!(sql);
}
#[cfg(feature = "sqlite")]
#[test]
fn generated_sqlite_like() {
use fraiseql_core::db::{SqliteDialect, sqlite::SqliteWhereGenerator};
let clause = WhereClause::Field {
path: vec!["name".to_string()],
operator: WhereOperator::Like,
value: json!("%alice%"),
};
let (sql, _params) = SqliteWhereGenerator::new(SqliteDialect).generate(&clause).unwrap();
assert_snapshot!(sql);
}
#[cfg(feature = "sqlite")]
#[test]
fn generated_sqlite_gt() {
use fraiseql_core::db::{SqliteDialect, sqlite::SqliteWhereGenerator};
let clause = WhereClause::Field {
path: vec!["score".to_string()],
operator: WhereOperator::Gt,
value: json!(50),
};
let (sql, _params) = SqliteWhereGenerator::new(SqliteDialect).generate(&clause).unwrap();
assert_snapshot!(sql);
}
#[test]
fn generated_pg_param_offset_two() {
let clause = WhereClause::Field {
path: vec!["name".to_string()],
operator: WhereOperator::Eq,
value: json!("Alice"),
};
let gen = PostgresWhereGenerator::new(PostgresDialect);
let (sql, _params) = gen.generate_with_param_offset(&clause, 2).unwrap();
assert_snapshot!(sql);
}
}
mod sqlserver_relay {
use insta::assert_snapshot;
#[test]
fn snapshot_sqlserver_relay_forward_no_cursor_no_order() {
let sql = "SELECT data FROM [v_relay_item] \
ORDER BY [id] ASC \
OFFSET 0 ROWS FETCH NEXT @p1 ROWS ONLY";
assert_snapshot!(sql);
}
#[test]
fn snapshot_sqlserver_relay_forward_uuid_cursor() {
let sql = "SELECT data FROM [v_relay_item] \
WHERE [id] > CONVERT(UNIQUEIDENTIFIER, @p1) \
ORDER BY [id] ASC \
OFFSET 0 ROWS FETCH NEXT @p2 ROWS ONLY";
assert_snapshot!(sql);
}
#[test]
fn snapshot_sqlserver_relay_forward_int64_cursor() {
let sql = "SELECT data FROM [v_relay_item] \
WHERE [id] > @p1 \
ORDER BY [id] ASC \
OFFSET 0 ROWS FETCH NEXT @p2 ROWS ONLY";
assert_snapshot!(sql);
}
#[test]
fn snapshot_sqlserver_relay_forward_custom_order_by() {
let sql = "SELECT data FROM [v_relay_item] \
ORDER BY JSON_VALUE(data, '$.score') ASC, [id] ASC \
OFFSET 0 ROWS FETCH NEXT @p1 ROWS ONLY";
assert_snapshot!(sql);
}
#[test]
fn snapshot_sqlserver_relay_forward_where_clause() {
let sql = "SELECT data FROM [v_relay_item] \
WHERE (CAST(JSON_VALUE(data, '$.score') AS FLOAT) >= @p1) \
ORDER BY [id] ASC \
OFFSET 0 ROWS FETCH NEXT @p2 ROWS ONLY";
assert_snapshot!(sql);
}
#[test]
fn snapshot_sqlserver_relay_backward_no_cursor_no_order() {
let sql = "SELECT data FROM (\
SELECT data, [id] AS _relay_cursor \
FROM [v_relay_item] \
ORDER BY [id] DESC \
OFFSET 0 ROWS FETCH NEXT @p1 ROWS ONLY\
) AS _relay_page \
ORDER BY _relay_cursor ASC";
assert_snapshot!(sql);
}
#[test]
fn snapshot_sqlserver_relay_backward_uuid_cursor() {
let sql = "SELECT data FROM (\
SELECT data, [id] AS _relay_cursor \
FROM [v_relay_item] \
WHERE [id] < CONVERT(UNIQUEIDENTIFIER, @p1) \
ORDER BY [id] DESC \
OFFSET 0 ROWS FETCH NEXT @p2 ROWS ONLY\
) AS _relay_page \
ORDER BY _relay_cursor ASC";
assert_snapshot!(sql);
}
#[test]
fn snapshot_sqlserver_relay_backward_int64_cursor() {
let sql = "SELECT data FROM (\
SELECT data, [id] AS _relay_cursor \
FROM [v_relay_item] \
WHERE [id] < @p1 \
ORDER BY [id] DESC \
OFFSET 0 ROWS FETCH NEXT @p2 ROWS ONLY\
) AS _relay_page \
ORDER BY _relay_cursor ASC";
assert_snapshot!(sql);
}
#[test]
fn snapshot_sqlserver_relay_backward_custom_order_by_asc() {
let sql = "SELECT data FROM (\
SELECT data, [id] AS _relay_cursor, JSON_VALUE(data, '$.score') AS _relay_sort_0 \
FROM [v_relay_item] \
WHERE [id] < CONVERT(UNIQUEIDENTIFIER, @p1) \
ORDER BY JSON_VALUE(data, '$.score') DESC, [id] DESC \
OFFSET 0 ROWS FETCH NEXT @p2 ROWS ONLY\
) AS _relay_page \
ORDER BY _relay_sort_0 ASC, _relay_cursor ASC";
assert_snapshot!(sql);
}
#[test]
fn snapshot_sqlserver_relay_backward_custom_order_by_multi_column() {
let sql = "SELECT data FROM (\
SELECT data, [id] AS _relay_cursor, \
JSON_VALUE(data, '$.score') AS _relay_sort_0, \
JSON_VALUE(data, '$.created_at') AS _relay_sort_1 \
FROM [v_relay_item] \
WHERE [id] < CONVERT(UNIQUEIDENTIFIER, @p1) \
ORDER BY JSON_VALUE(data, '$.score') DESC, JSON_VALUE(data, '$.created_at') ASC, [id] DESC \
OFFSET 0 ROWS FETCH NEXT @p2 ROWS ONLY\
) AS _relay_page \
ORDER BY _relay_sort_0 ASC, _relay_sort_1 DESC, _relay_cursor ASC";
assert_snapshot!(sql);
}
#[test]
fn snapshot_sqlserver_relay_count_query_no_where() {
let sql = "SELECT COUNT_BIG(*) AS cnt FROM [v_relay_item]";
assert_snapshot!(sql);
}
#[test]
fn snapshot_sqlserver_relay_count_query_with_where() {
let sql = "SELECT COUNT_BIG(*) AS cnt FROM [v_relay_item] \
WHERE (CAST(JSON_VALUE(data, '$.score') AS FLOAT) >= @p1)";
assert_snapshot!(sql);
}
}
mod mysql_relay {
use insta::assert_snapshot;
#[test]
fn snapshot_mysql_relay_forward_no_cursor() {
let sql = "SELECT data FROM `v_user` ORDER BY `pk_user` ASC LIMIT ?";
assert_snapshot!(sql);
}
#[test]
fn snapshot_mysql_relay_forward_bigint_cursor() {
let sql = "SELECT data FROM `v_user` WHERE `pk_user` > ? ORDER BY `pk_user` ASC LIMIT ?";
assert_snapshot!(sql);
}
#[test]
fn snapshot_mysql_relay_forward_uuid_cursor() {
let sql = "SELECT data FROM `v_user` WHERE `pk_user` > ? ORDER BY `pk_user` ASC LIMIT ?";
assert_snapshot!(sql);
}
#[test]
fn snapshot_mysql_relay_forward_cursor_with_where() {
let sql = "SELECT data FROM `v_user` \
WHERE `pk_user` > ? \
AND (JSON_UNQUOTE(JSON_EXTRACT(data, '$.status')) = ?) \
ORDER BY `pk_user` ASC LIMIT ?";
assert_snapshot!(sql);
}
#[test]
fn snapshot_mysql_relay_forward_custom_order_by() {
let sql = "SELECT data FROM `v_post` \
WHERE `pk_post` > ? \
ORDER BY JSON_UNQUOTE(JSON_EXTRACT(data, '$.created_at')) ASC, `pk_post` ASC \
LIMIT ?";
assert_snapshot!(sql);
}
#[test]
fn snapshot_mysql_relay_backward_no_cursor() {
let sql = "SELECT data FROM (\
SELECT data, `pk_user` AS _relay_cursor \
FROM `v_user` \
ORDER BY `pk_user` DESC LIMIT ?\
) _relay_page ORDER BY _relay_cursor ASC";
assert_snapshot!(sql);
}
#[test]
fn snapshot_mysql_relay_backward_bigint_cursor() {
let sql = "SELECT data FROM (\
SELECT data, `pk_user` AS _relay_cursor \
FROM `v_user` \
WHERE `pk_user` < ? \
ORDER BY `pk_user` DESC LIMIT ?\
) _relay_page ORDER BY _relay_cursor ASC";
assert_snapshot!(sql);
}
#[test]
fn snapshot_mysql_relay_backward_cursor_with_where() {
let sql = "SELECT data FROM (\
SELECT data, `pk_user` AS _relay_cursor \
FROM `v_user` \
WHERE `pk_user` < ? \
AND (JSON_UNQUOTE(JSON_EXTRACT(data, '$.active')) = ?) \
ORDER BY `pk_user` DESC LIMIT ?\
) _relay_page ORDER BY _relay_cursor ASC";
assert_snapshot!(sql);
}
#[test]
fn snapshot_mysql_relay_backward_custom_order_by() {
let sql = "SELECT data FROM (\
SELECT data, `pk_post` AS _relay_cursor \
FROM `v_post` \
WHERE `pk_post` < ? \
ORDER BY JSON_UNQUOTE(JSON_EXTRACT(data, '$.created_at')) DESC, `pk_post` DESC \
LIMIT ?\
) _relay_page ORDER BY _relay_cursor ASC";
assert_snapshot!(sql);
}
#[test]
fn snapshot_mysql_relay_count_no_where() {
let sql = "SELECT COUNT(*) FROM `v_user`";
assert_snapshot!(sql);
}
#[test]
fn snapshot_mysql_relay_count_with_where() {
let sql = "SELECT COUNT(*) FROM `v_user` \
WHERE (JSON_UNQUOTE(JSON_EXTRACT(data, '$.status')) = ?)";
assert_snapshot!(sql);
}
}
mod window_functions {
use insta::assert_snapshot;
#[test]
fn snapshot_mysql_window_rank() {
let sql = "SELECT category, score, label, \
RANK() OVER (PARTITION BY category ORDER BY score DESC) AS rnk \
FROM `v_score` \
ORDER BY category, rnk";
assert_snapshot!(sql);
}
#[test]
fn snapshot_sqlserver_window_rank() {
let sql = "SELECT [category], [score], [label], \
RANK() OVER (PARTITION BY [category] ORDER BY [score] DESC) AS [rnk] \
FROM [v_score] \
ORDER BY [category], [rnk]";
assert_snapshot!(sql);
}
#[test]
fn snapshot_mysql_window_row_number() {
let sql = "SELECT id, label, \
ROW_NUMBER() OVER (ORDER BY score DESC) AS row_num \
FROM `v_score`";
assert_snapshot!(sql);
}
#[test]
fn snapshot_sqlserver_window_row_number() {
let sql = "SELECT [id], [label], \
ROW_NUMBER() OVER (ORDER BY [score] DESC) AS [row_num] \
FROM [v_score]";
assert_snapshot!(sql);
}
}
mod cte_queries {
use insta::assert_snapshot;
#[test]
fn snapshot_postgres_cte_basic() {
let sql = "WITH top_scores AS (\
SELECT data FROM \"v_score\" WHERE (data->>'score')::numeric >= 80\
) \
SELECT data FROM top_scores ORDER BY data->>'score' DESC";
assert_snapshot!(sql);
}
#[test]
fn snapshot_postgres_cte_recursive() {
let sql = "WITH RECURSIVE counter(n) AS (\
SELECT 1 \
UNION ALL \
SELECT n + 1 FROM counter WHERE n < 5\
) \
SELECT n FROM counter";
assert_snapshot!(sql);
}
#[test]
fn snapshot_postgres_cte_multiple() {
let sql = "WITH active_users AS (\
SELECT data FROM \"v_user\" WHERE data->>'active' = 'true'\
), user_posts AS (\
SELECT data FROM \"v_post\" WHERE data->>'author_id' IN (SELECT data->>'id' FROM active_users)\
) \
SELECT data FROM user_posts ORDER BY data->>'created_at' DESC";
assert_snapshot!(sql);
}
#[test]
fn snapshot_postgres_cte_with_aggregation() {
let sql = "WITH category_totals AS (\
SELECT data->>'category' AS category, SUM((data->>'amount')::NUMERIC) AS total \
FROM \"tf_sales\" GROUP BY data->>'category'\
) \
SELECT * FROM category_totals WHERE total > 1000 ORDER BY total DESC";
assert_snapshot!(sql);
}
#[test]
fn snapshot_mysql_cte_basic() {
let sql = "WITH top_scores AS (\
SELECT id, label, score FROM `v_score` WHERE score >= 80\
) \
SELECT * FROM top_scores ORDER BY score DESC";
assert_snapshot!(sql);
}
#[test]
fn snapshot_mysql_cte_recursive() {
let sql = "WITH RECURSIVE counter(n) AS (\
SELECT 1 \
UNION ALL \
SELECT n + 1 FROM counter WHERE n < 5\
) \
SELECT n FROM counter";
assert_snapshot!(sql);
}
#[test]
fn snapshot_mysql_cte_multiple() {
let sql = "WITH active_users AS (\
SELECT `data` FROM `v_user` WHERE JSON_UNQUOTE(JSON_EXTRACT(`data`, '$.active')) = 'true'\
), user_posts AS (\
SELECT `data` FROM `v_post` WHERE JSON_UNQUOTE(JSON_EXTRACT(`data`, '$.author_id')) IN (SELECT JSON_UNQUOTE(JSON_EXTRACT(`data`, '$.id')) FROM active_users)\
) \
SELECT `data` FROM user_posts ORDER BY JSON_UNQUOTE(JSON_EXTRACT(`data`, '$.created_at')) DESC";
assert_snapshot!(sql);
}
#[test]
fn snapshot_sqlite_cte_basic() {
let sql = "WITH top_scores AS (\
SELECT data FROM \"v_score\" WHERE CAST(json_extract(data, '$.score') AS REAL) >= 80\
) \
SELECT data FROM top_scores ORDER BY json_extract(data, '$.score') DESC";
assert_snapshot!(sql);
}
#[test]
fn snapshot_sqlite_cte_recursive() {
let sql = "WITH RECURSIVE counter(n) AS (\
SELECT 1 \
UNION ALL \
SELECT n + 1 FROM counter WHERE n < 5\
) \
SELECT n FROM counter";
assert_snapshot!(sql);
}
#[test]
fn snapshot_sqlite_cte_multiple() {
let sql = "WITH active_users AS (\
SELECT data FROM \"v_user\" WHERE json_extract(data, '$.active') = 'true'\
), user_posts AS (\
SELECT data FROM \"v_post\" WHERE json_extract(data, '$.author_id') IN (SELECT json_extract(data, '$.id') FROM active_users)\
) \
SELECT data FROM user_posts ORDER BY json_extract(data, '$.created_at') DESC";
assert_snapshot!(sql);
}
#[test]
fn snapshot_sqlserver_cte_basic() {
let sql = "WITH top_scores AS (\
SELECT [id], [label], [score] FROM [v_score] WHERE [score] >= 80\
) \
SELECT * FROM top_scores ORDER BY [score] DESC";
assert_snapshot!(sql);
}
#[test]
fn snapshot_sqlserver_cte_recursive() {
let sql = "WITH counter(n) AS (\
SELECT 1 \
UNION ALL \
SELECT n + 1 FROM counter WHERE n < 5\
) \
SELECT n FROM counter";
assert_snapshot!(sql);
}
#[test]
fn snapshot_sqlserver_cte_multiple() {
let sql = "WITH active_users AS (\
SELECT [data] FROM [v_user] WHERE JSON_VALUE([data], '$.active') = 'true'\
), user_posts AS (\
SELECT [data] FROM [v_post] WHERE JSON_VALUE([data], '$.author_id') IN (SELECT JSON_VALUE([data], '$.id') FROM active_users)\
) \
SELECT [data] FROM user_posts ORDER BY JSON_VALUE([data], '$.created_at') DESC";
assert_snapshot!(sql);
}
}
mod aggregation_parity {
use insta::assert_snapshot;
#[test]
fn snapshot_mysql_group_by_aggregation() {
let sql = "SELECT category, COUNT(*) AS cnt, MAX(score) AS max_score \
FROM `v_score` \
GROUP BY category \
ORDER BY category";
assert_snapshot!(sql);
}
#[test]
fn snapshot_sqlserver_group_by_aggregation() {
let sql = "SELECT [category], COUNT(*) AS [cnt], MAX([score]) AS [max_score] \
FROM [v_score] \
GROUP BY [category] \
ORDER BY [category]";
assert_snapshot!(sql);
}
#[test]
fn snapshot_mysql_full_aggregates() {
let sql = "SELECT COUNT(*) AS cnt, SUM(score) AS total, \
AVG(score) AS avg_score, MIN(score) AS min_score, MAX(score) AS max_score \
FROM `v_score`";
assert_snapshot!(sql);
}
#[test]
fn snapshot_sqlserver_full_aggregates() {
let sql = "SELECT COUNT(*) AS [cnt], SUM([score]) AS [total], \
AVG(CAST([score] AS FLOAT)) AS [avg_score], \
MIN([score]) AS [min_score], MAX([score]) AS [max_score] \
FROM [v_score]";
assert_snapshot!(sql);
}
}
mod mysql_keyset_pagination {
use insta::assert_snapshot;
#[test]
fn snapshot_mysql_pagination_keyset_forward_first() {
let sql = "SELECT data FROM (\
SELECT data, `id` AS _relay_cursor \
FROM `v_relay_item` \
ORDER BY `id` ASC LIMIT ?\
) _relay_page ORDER BY _relay_cursor ASC";
assert_snapshot!(sql);
}
#[test]
fn snapshot_mysql_pagination_keyset_forward_after() {
let sql = "SELECT data FROM (\
SELECT data, `id` AS _relay_cursor \
FROM `v_relay_item` \
WHERE `id` > ? \
ORDER BY `id` ASC LIMIT ?\
) _relay_page ORDER BY _relay_cursor ASC";
assert_snapshot!(sql);
}
#[test]
fn snapshot_mysql_pagination_keyset_backward_before() {
let sql = "SELECT data FROM (\
SELECT data, `id` AS _relay_cursor \
FROM `v_relay_item` \
WHERE `id` < ? \
ORDER BY `id` DESC LIMIT ?\
) _relay_page ORDER BY _relay_cursor ASC";
assert_snapshot!(sql);
}
}
mod sqlserver_keyset_pagination {
use insta::assert_snapshot;
#[test]
fn snapshot_sqlserver_pagination_keyset_forward_first() {
let sql = "SELECT [data] FROM (\
SELECT [data], [id] AS _relay_cursor \
FROM [v_relay_item] \
ORDER BY [id] ASC \
OFFSET 0 ROWS FETCH NEXT ? ROWS ONLY\
) AS _relay_page ORDER BY _relay_cursor ASC";
assert_snapshot!(sql);
}
#[test]
fn snapshot_sqlserver_pagination_keyset_forward_after() {
let sql = "SELECT [data] FROM (\
SELECT [data], [id] AS _relay_cursor \
FROM [v_relay_item] \
WHERE [id] > @p1 \
ORDER BY [id] ASC \
OFFSET 0 ROWS FETCH NEXT @p2 ROWS ONLY\
) AS _relay_page ORDER BY _relay_cursor ASC";
assert_snapshot!(sql);
}
#[test]
fn snapshot_sqlserver_pagination_keyset_backward_before() {
let sql = "SELECT [data] FROM (\
SELECT [data], [id] AS _relay_cursor \
FROM [v_relay_item] \
WHERE [id] < @p1 \
ORDER BY [id] DESC \
OFFSET 0 ROWS FETCH NEXT @p2 ROWS ONLY\
) AS _relay_page ORDER BY _relay_cursor ASC";
assert_snapshot!(sql);
}
}
mod mutation_calls {
use insta::assert_snapshot;
#[test]
fn snapshot_mysql_function_call_create() {
let sql = "CALL `fn_create_post`(?, ?, ?, ?)";
assert_snapshot!(sql);
}
#[test]
fn snapshot_mysql_function_call_update() {
let sql = "CALL `fn_update_post`(?, ?, ?, ?, ?, ?)";
assert_snapshot!(sql);
}
#[test]
fn snapshot_mysql_function_call_delete() {
let sql = "CALL `fn_delete_post`(?, ?)";
assert_snapshot!(sql);
}
#[test]
fn snapshot_sqlserver_function_call_create() {
let sql = "SELECT * FROM [fn_create_post](@p1, @p2, @p3, @p4)";
assert_snapshot!(sql);
}
#[test]
fn snapshot_sqlserver_function_call_update() {
let sql = "SELECT * FROM [fn_update_post](@p1, @p2, @p3, @p4, @p5, @p6)";
assert_snapshot!(sql);
}
#[test]
fn snapshot_sqlserver_function_call_delete() {
let sql = "SELECT * FROM [fn_delete_post](@p1, @p2)";
assert_snapshot!(sql);
}
}
mod rls_injection {
use insta::assert_snapshot;
#[test]
fn snapshot_mysql_rls_only() {
let sql = "SELECT `data` FROM `v_user` WHERE JSON_EXTRACT(`data`, '$.tenant_id') = ?";
assert_snapshot!(sql);
}
#[test]
fn snapshot_mysql_rls_with_app_where() {
let sql = "SELECT `data` FROM `v_post` WHERE JSON_EXTRACT(`data`, '$.tenant_id') = ? \
AND (JSON_UNQUOTE(JSON_EXTRACT(`data`, '$.published')) = ?)";
assert_snapshot!(sql);
}
#[test]
fn snapshot_sqlite_rls_only() {
let sql = r#"SELECT "data" FROM "v_user" WHERE json_extract("data", '$.tenant_id') = ?"#;
assert_snapshot!(sql);
}
#[test]
fn snapshot_sqlite_rls_with_app_where() {
let sql = r#"SELECT "data" FROM "v_post" WHERE json_extract("data", '$.tenant_id') = ? AND (json_extract("data", '$.published') = ?)"#;
assert_snapshot!(sql);
}
#[test]
fn snapshot_sqlserver_rls_only() {
let sql = "SELECT [data] FROM [v_user] WHERE JSON_VALUE([data], '$.tenant_id') = @p1";
assert_snapshot!(sql);
}
#[test]
fn snapshot_sqlserver_rls_with_app_where() {
let sql = "SELECT [data] FROM [v_post] WHERE JSON_VALUE([data], '$.tenant_id') = @p1 \
AND (JSON_VALUE([data], '$.published') = @p2)";
assert_snapshot!(sql);
}
}
mod mutation_rls_combined {
use insta::assert_snapshot;
#[test]
fn snapshot_postgres_mutation_create_with_rls_context() {
let sql = r#"SELECT * FROM "fn_create_post"($1, $2, $3, $4, $5)"#;
assert_snapshot!(sql);
}
#[test]
fn snapshot_postgres_mutation_update_with_rls_context() {
let sql = r#"SELECT * FROM "fn_update_post"($1, $2, $3, $4, $5, $6, $7)"#;
assert_snapshot!(sql);
}
#[test]
fn snapshot_postgres_mutation_delete_with_rls_context() {
let sql = r#"SELECT * FROM "fn_delete_post"($1, $2, $3)"#;
assert_snapshot!(sql);
}
#[test]
fn snapshot_mysql_mutation_create_with_rls_context() {
let sql = "CALL `fn_create_post`(?, ?, ?, ?, ?)";
assert_snapshot!(sql);
}
#[test]
fn snapshot_mysql_mutation_delete_with_rls_context() {
let sql = "CALL `fn_delete_post`(?, ?, ?)";
assert_snapshot!(sql);
}
#[test]
fn snapshot_sqlserver_mutation_create_with_rls_context() {
let sql = "SELECT * FROM [fn_create_post](@p1, @p2, @p3, @p4, @p5)";
assert_snapshot!(sql);
}
#[test]
fn snapshot_sqlserver_mutation_delete_with_rls_context() {
let sql = "SELECT * FROM [fn_delete_post](@p1, @p2, @p3)";
assert_snapshot!(sql);
}
}
mod json_access_parity {
use insta::assert_snapshot;
#[test]
fn snapshot_postgres_json_single_level() {
let sql = r#"SELECT data->>'email' FROM "v_user" WHERE data->>'email' = $1"#;
assert_snapshot!(sql);
}
#[test]
fn snapshot_mysql_json_single_level() {
let sql = "SELECT JSON_UNQUOTE(JSON_EXTRACT(`data`, '$.email')) FROM `v_user` \
WHERE JSON_UNQUOTE(JSON_EXTRACT(`data`, '$.email')) = ?";
assert_snapshot!(sql);
}
#[test]
fn snapshot_sqlite_json_single_level() {
let sql = r#"SELECT json_extract(data, '$.email') FROM "v_user" WHERE json_extract(data, '$.email') = ?"#;
assert_snapshot!(sql);
}
#[test]
fn snapshot_sqlserver_json_single_level() {
let sql = "SELECT JSON_VALUE([data], '$.email') FROM [v_user] \
WHERE JSON_VALUE([data], '$.email') = @p1";
assert_snapshot!(sql);
}
#[test]
fn snapshot_postgres_json_nested() {
let sql =
r#"SELECT data->'address'->>'city' FROM "v_user" WHERE data->'address'->>'city' = $1"#;
assert_snapshot!(sql);
}
#[test]
fn snapshot_mysql_json_nested() {
let sql = "SELECT JSON_UNQUOTE(JSON_EXTRACT(`data`, '$.address.city')) FROM `v_user` \
WHERE JSON_UNQUOTE(JSON_EXTRACT(`data`, '$.address.city')) = ?";
assert_snapshot!(sql);
}
#[test]
fn snapshot_sqlite_json_nested() {
let sql = r#"SELECT json_extract(data, '$.address.city') FROM "v_user" WHERE json_extract(data, '$.address.city') = ?"#;
assert_snapshot!(sql);
}
#[test]
fn snapshot_sqlserver_json_nested() {
let sql = "SELECT JSON_VALUE([data], '$.address.city') FROM [v_user] \
WHERE JSON_VALUE([data], '$.address.city') = @p1";
assert_snapshot!(sql);
}
#[test]
fn snapshot_postgres_json_deep_nested() {
let sql = r#"SELECT data->'profile'->'social'->>'twitter' FROM "v_user""#;
assert_snapshot!(sql);
}
#[test]
fn snapshot_mysql_json_deep_nested() {
let sql =
"SELECT JSON_UNQUOTE(JSON_EXTRACT(`data`, '$.profile.social.twitter')) FROM `v_user`";
assert_snapshot!(sql);
}
#[test]
fn snapshot_sqlite_json_deep_nested() {
let sql = r#"SELECT json_extract(data, '$.profile.social.twitter') FROM "v_user""#;
assert_snapshot!(sql);
}
#[test]
fn snapshot_sqlserver_json_deep_nested() {
let sql = "SELECT JSON_VALUE([data], '$.profile.social.twitter') FROM [v_user]";
assert_snapshot!(sql);
}
#[test]
fn snapshot_postgres_jsonb_contains() {
let sql = r#"SELECT data FROM "v_user" WHERE data::jsonb @> $1::jsonb"#;
assert_snapshot!(sql);
}
#[test]
fn snapshot_postgres_jsonb_contained_by() {
let sql = r#"SELECT data FROM "v_user" WHERE data::jsonb <@ $1::jsonb"#;
assert_snapshot!(sql);
}
#[test]
fn snapshot_postgres_jsonb_overlap() {
let sql = r#"SELECT data FROM "v_user" WHERE data->'tags'::jsonb && $1::jsonb"#;
assert_snapshot!(sql);
}
}
mod fts_parity {
use insta::assert_snapshot;
#[test]
fn snapshot_postgres_fts_matches() {
let sql =
r#"SELECT data FROM "v_post" WHERE to_tsvector(data->>'content') @@ to_tsquery($1)"#;
assert_snapshot!(sql);
}
#[test]
fn snapshot_postgres_fts_plain_query() {
let sql = r#"SELECT data FROM "v_post" WHERE to_tsvector(data->>'content') @@ plainto_tsquery($1)"#;
assert_snapshot!(sql);
}
#[test]
fn snapshot_postgres_fts_phrase_query() {
let sql = r#"SELECT data FROM "v_post" WHERE to_tsvector(data->>'content') @@ phraseto_tsquery($1)"#;
assert_snapshot!(sql);
}
#[test]
fn snapshot_postgres_fts_websearch_query() {
let sql = r#"SELECT data FROM "v_post" WHERE to_tsvector(data->>'content') @@ websearch_to_tsquery($1)"#;
assert_snapshot!(sql);
}
#[test]
fn snapshot_mysql_fts_natural_language() {
let sql = "SELECT `data` FROM `v_post` \
WHERE MATCH(JSON_UNQUOTE(JSON_EXTRACT(`data`, '$.content'))) AGAINST(? IN NATURAL LANGUAGE MODE)";
assert_snapshot!(sql);
}
#[test]
fn snapshot_mysql_fts_boolean_mode() {
let sql = "SELECT `data` FROM `v_post` \
WHERE MATCH(JSON_UNQUOTE(JSON_EXTRACT(`data`, '$.content'))) AGAINST(? IN BOOLEAN MODE)";
assert_snapshot!(sql);
}
#[test]
fn snapshot_sqlserver_fts_contains() {
let sql =
"SELECT [data] FROM [v_post] WHERE CONTAINS(JSON_VALUE([data], '$.content'), @p1)";
assert_snapshot!(sql);
}
#[test]
fn snapshot_sqlserver_fts_freetext() {
let sql =
"SELECT [data] FROM [v_post] WHERE FREETEXT(JSON_VALUE([data], '$.content'), @p1)";
assert_snapshot!(sql);
}
}
mod aggregate_dialect_variants {
use insta::assert_snapshot;
#[test]
fn snapshot_postgres_stddev() {
let sql = "SELECT STDDEV_SAMP(revenue) AS stddev_revenue FROM \"tf_sales\"";
assert_snapshot!(sql);
}
#[test]
fn snapshot_mysql_stddev() {
let sql = "SELECT STDDEV_SAMP(revenue) AS stddev_revenue FROM `tf_sales`";
assert_snapshot!(sql);
}
#[test]
fn snapshot_sqlite_stddev_unsupported() {
let sql =
"SELECT NULL /* STDDEV not supported in SQLite */ AS stddev_revenue FROM \"tf_sales\"";
assert_snapshot!(sql);
}
#[test]
fn snapshot_sqlserver_stdev() {
let sql = "SELECT STDEV(revenue) AS stddev_revenue FROM [tf_sales]";
assert_snapshot!(sql);
}
#[test]
fn snapshot_postgres_variance() {
let sql = "SELECT VAR_SAMP(revenue) AS var_revenue FROM \"tf_sales\"";
assert_snapshot!(sql);
}
#[test]
fn snapshot_mysql_variance() {
let sql = "SELECT VAR_SAMP(revenue) AS var_revenue FROM `tf_sales`";
assert_snapshot!(sql);
}
#[test]
fn snapshot_sqlite_variance_unsupported() {
let sql =
"SELECT NULL /* VARIANCE not supported in SQLite */ AS var_revenue FROM \"tf_sales\"";
assert_snapshot!(sql);
}
#[test]
fn snapshot_sqlserver_var() {
let sql = "SELECT VAR(revenue) AS var_revenue FROM [tf_sales]";
assert_snapshot!(sql);
}
#[test]
fn snapshot_postgres_string_agg() {
let sql = "SELECT STRING_AGG(name, ', ') AS names FROM \"v_user\"";
assert_snapshot!(sql);
}
#[test]
fn snapshot_mysql_group_concat() {
let sql = "SELECT GROUP_CONCAT(name SEPARATOR ', ') AS names FROM `v_user`";
assert_snapshot!(sql);
}
#[test]
fn snapshot_sqlite_group_concat() {
let sql = "SELECT GROUP_CONCAT(name, ', ') AS names FROM \"v_user\"";
assert_snapshot!(sql);
}
#[test]
fn snapshot_sqlserver_string_agg() {
let sql = "SELECT STRING_AGG(CAST(name AS NVARCHAR(MAX)), ', ') AS names FROM [v_user]";
assert_snapshot!(sql);
}
#[test]
fn snapshot_postgres_array_agg() {
let sql = "SELECT ARRAY_AGG(tag) AS tags FROM \"v_post\"";
assert_snapshot!(sql);
}
#[test]
fn snapshot_mysql_json_arrayagg() {
let sql = "SELECT JSON_ARRAYAGG(tag) AS tags FROM `v_post`";
assert_snapshot!(sql);
}
#[test]
fn snapshot_sqlite_array_agg_emulated() {
let sql =
"SELECT '[' || GROUP_CONCAT('\"' || tag || '\"', ',') || ']' AS tags FROM \"v_post\"";
assert_snapshot!(sql);
}
#[test]
fn snapshot_sqlserver_array_agg_emulated() {
let sql = "SELECT '[' + STRING_AGG('\"' + CAST(tag AS NVARCHAR(MAX)) + '\"', ',') + ']' AS tags FROM [v_post]";
assert_snapshot!(sql);
}
#[test]
fn snapshot_postgres_bool_and() {
let sql = "SELECT BOOL_AND(active) AS all_active FROM \"v_user\"";
assert_snapshot!(sql);
}
#[test]
fn snapshot_mysql_bool_and_emulated() {
let sql = "SELECT MIN(active) = 1 AS all_active FROM `v_user`";
assert_snapshot!(sql);
}
#[test]
fn snapshot_sqlserver_bool_and_emulated() {
let sql = "SELECT MIN(CAST(active AS BIT)) = 1 AS all_active FROM [v_user]";
assert_snapshot!(sql);
}
#[test]
fn snapshot_postgres_date_trunc_day() {
let sql = "SELECT DATE_TRUNC('day', occurred_at) AS day, COUNT(*) FROM \"tf_sales\" GROUP BY DATE_TRUNC('day', occurred_at)";
assert_snapshot!(sql);
}
#[test]
fn snapshot_mysql_date_format_day() {
let sql = "SELECT DATE_FORMAT(occurred_at, '%Y-%m-%d') AS day, COUNT(*) FROM `tf_sales` GROUP BY DATE_FORMAT(occurred_at, '%Y-%m-%d')";
assert_snapshot!(sql);
}
#[test]
fn snapshot_sqlite_strftime_day() {
let sql = "SELECT strftime('%Y-%m-%d', occurred_at) AS day, COUNT(*) FROM \"tf_sales\" GROUP BY strftime('%Y-%m-%d', occurred_at)";
assert_snapshot!(sql);
}
#[test]
fn snapshot_sqlserver_datepart_day() {
let sql = "SELECT CAST(occurred_at AS DATE) AS day, COUNT(*) FROM [tf_sales] GROUP BY CAST(occurred_at AS DATE)";
assert_snapshot!(sql);
}
}