athena_rs 3.6.1

Hyper performant polyglot Database driver
Documentation
#[cfg(test)]
mod tests {
    use crate::parser::query_builder::{
        Condition, QueryBuilder, build_insert_placeholders_for_entries_with_types,
        build_where_clause,
    };
    use serde_json::json;
    use std::collections::HashMap;

    /// ## `build_where_clause_casts_uuid_comparisons_to_text_by_default`
    /// Tests that the build_where_clause function casts UUID comparisons to text by default.
    ///
    /// # Arguments
    ///
    /// * `conditions` - The conditions to build the where clause for.
    ///
    /// # Returns
    ///
    #[test]
    fn build_where_clause_casts_uuid_comparisons_to_text_by_default() {
        let conditions: Vec<Condition> = vec![Condition::eq(
            "workspace_id",
            json!("550e8400-e29b-41d4-a716-446655440000"),
        )];

        let (clause, values) = build_where_clause(&conditions, 1).expect("where clause");

        assert_eq!(clause, " WHERE t.\"workspace_id\"::text = $1::text");
        assert_eq!(values, vec![json!("550e8400-e29b-41d4-a716-446655440000")]);
    }

    /// ## `build_where_clause_can_disable_uuid_text_casts`
    /// Tests that the build_where_clause function can disable UUID text casts.
    ///
    /// # Arguments
    ///
    /// * `conditions` - The conditions to build the where clause for.
    ///
    /// # Returns
    ///
    #[test]
    fn build_where_clause_can_disable_uuid_text_casts() {
        let conditions: Vec<Condition> = vec![
            Condition::eq(
                "workspace_id",
                json!("550e8400-e29b-41d4-a716-446655440000"),
            )
            .with_uuid_value_text_cast(false),
        ];

        let (clause, values) = build_where_clause(&conditions, 1).expect("where clause");

        assert_eq!(clause, " WHERE t.\"workspace_id\" = $1");
        assert_eq!(values, vec![json!("550e8400-e29b-41d4-a716-446655440000")]);
    }

    #[test]
    fn query_builder_struct_builds_where_clause() {
        let query_builder = QueryBuilder::new()
            .with_start_index(3)
            .with_condition(Condition::eq("workspace_id", json!("workspace-1")));

        let (clause, values) = query_builder
            .build_where_clause()
            .expect("where clause from QueryBuilder");

        assert_eq!(clause, " WHERE t.\"workspace_id\" = $3");
        assert_eq!(values, vec![json!("workspace-1")]);
    }

    #[test]
    fn build_insert_placeholders_adds_jsonb_cast_with_column_types() {
        let entries = vec![
            ("\"payload\"".to_string(), json!({"source": "test"})),
            (
                "\"created_at\"".to_string(),
                json!("2024-01-15T12:00:00.000Z"),
            ),
        ];
        let column_types = HashMap::from([
            ("payload".to_string(), "jsonb".to_string()),
            (
                "created_at".to_string(),
                "timestamp with time zone".to_string(),
            ),
        ]);

        let (placeholders, bind_values) =
            build_insert_placeholders_for_entries_with_types(&entries, Some(&column_types));

        assert_eq!(placeholders, vec!["$1::jsonb", "$2::timestamptz"]);
        assert_eq!(bind_values.len(), 2);
    }

    #[test]
    fn build_where_clause_emits_pg_cast_for_string_values_against_numeric_columns() {
        let conditions: Vec<Condition> =
            vec![Condition::eq("cache_hit_ratio", json!("0.75")).with_pg_cast(Some("float8"))];

        let (clause, values) = build_where_clause(&conditions, 1).expect("where clause");

        assert_eq!(clause, " WHERE t.\"cache_hit_ratio\" = $1::float8");
        assert_eq!(values, vec![json!("0.75")]);
    }

    #[test]
    fn build_where_clause_skips_pg_cast_for_native_numbers() {
        let conditions: Vec<Condition> =
            vec![Condition::eq("cache_hit_ratio", json!(0.75)).with_pg_cast(Some("float8"))];

        let (clause, values) = build_where_clause(&conditions, 1).expect("where clause");

        // Native JSON numbers already bind with the right wire type, so no cast.
        assert_eq!(clause, " WHERE t.\"cache_hit_ratio\" = $1");
        assert_eq!(values, vec![json!(0.75)]);
    }

    #[test]
    fn build_where_clause_renders_in_list_with_pg_cast() {
        let conditions: Vec<Condition> = vec![
            Condition::new(
                "total_requests",
                crate::parser::query_builder::ConditionOperator::In,
                vec![json!("1"), json!("2"), json!(3)],
                false,
            )
            .with_pg_cast(Some("int8")),
        ];

        let (clause, values) = build_where_clause(&conditions, 1).expect("where clause");

        assert_eq!(
            clause,
            " WHERE t.\"total_requests\" IN ($1::int8, $2::int8, $3)"
        );
        assert_eq!(values, vec![json!("1"), json!("2"), json!(3)]);
    }

    #[test]
    fn build_where_clause_uuid_cast_takes_precedence_over_pg_cast() {
        let conditions: Vec<Condition> = vec![
            Condition::eq(
                "workspace_id",
                json!("550e8400-e29b-41d4-a716-446655440000"),
            )
            .with_pg_cast(Some("text")),
        ];

        let (clause, _values) = build_where_clause(&conditions, 1).expect("where clause");

        // UUID path still stamps `::text` on both sides; pg_cast must not double-cast.
        assert_eq!(clause, " WHERE t.\"workspace_id\"::text = $1::text");
    }

    #[test]
    fn build_insert_placeholders_preserves_null_without_binding() {
        let entries = vec![
            ("\"payload\"".to_string(), json!(null)),
            ("\"title\"".to_string(), json!("hello")),
        ];
        let column_types = HashMap::from([("payload".to_string(), "jsonb".to_string())]);

        let (placeholders, bind_values) =
            build_insert_placeholders_for_entries_with_types(&entries, Some(&column_types));

        assert_eq!(placeholders, vec!["NULL", "$1"]);
        assert_eq!(bind_values.len(), 1);
        assert_eq!(*bind_values[0], json!("hello"));
    }
}