icydb-core 0.80.3

IcyDB — A type-safe, embedded ORM and schema system for the Internet Computer
Documentation
//! Module: db::query::plan::order_term
//! Responsibility: canonical index-order term rendering shared by planner boundaries.
//! Does not own: query expression parsing or executor slot resolution.
//! Boundary: keeps index-key canonicalization in one place.

use crate::model::index::{IndexKeyItem, IndexKeyItemsRef, IndexModel};

/// Return one canonical ORDER BY term list for an index key sequence.
#[must_use]
pub(in crate::db) fn index_order_terms(index: &IndexModel) -> Vec<String> {
    match index.key_items() {
        IndexKeyItemsRef::Fields(fields) => {
            fields.iter().map(|field| (*field).to_string()).collect()
        }
        IndexKeyItemsRef::Items(items) => items.iter().map(IndexKeyItem::canonical_text).collect(),
    }
}

///
/// TESTS
///

#[cfg(test)]
mod tests {
    use crate::{
        db::query::plan::{
            expr::{
                parse_supported_order_expr, render_supported_order_expr, supported_order_expr_field,
            },
            index_order_terms,
        },
        model::index::{IndexExpression, IndexKeyItem, IndexModel},
    };

    const EXPRESSION_INDEX_FIELDS: [&str; 1] = ["name"];
    const EXPRESSION_INDEX_KEY_ITEMS: [IndexKeyItem; 1] =
        [IndexKeyItem::Expression(IndexExpression::Lower("name"))];
    const EXPRESSION_INDEX_MODEL: IndexModel = IndexModel::generated_with_key_items(
        "order_term_tests::idx_name_lower",
        "order_term_tests::Store",
        &EXPRESSION_INDEX_FIELDS,
        &EXPRESSION_INDEX_KEY_ITEMS,
        false,
    );

    #[test]
    fn supported_order_expr_helpers_round_trip_casefold_terms() {
        let lower = parse_supported_order_expr("LOWER(name)")
            .expect("lower(name) should parse onto the canonical expression tree");
        assert_eq!(
            supported_order_expr_field(&lower)
                .expect("lower(name) should preserve one field leaf")
                .as_str(),
            "name"
        );
        assert_eq!(
            render_supported_order_expr(&lower),
            Some("LOWER(name)".to_string())
        );

        let upper = parse_supported_order_expr("UPPER(email)")
            .expect("upper(email) should parse onto the canonical expression tree");
        assert_eq!(
            render_supported_order_expr(&upper),
            Some("UPPER(email)".to_string())
        );
        assert_eq!(parse_supported_order_expr("TRIM(name)"), None);
    }

    #[test]
    fn index_order_terms_use_canonical_key_item_text() {
        assert_eq!(
            index_order_terms(&EXPRESSION_INDEX_MODEL),
            vec!["LOWER(name)".to_string()]
        );
    }
}