Skip to main content

uqa_sql/catalog/index/
stored.rs

1//
2// Unified Query Algebra
3//
4// Copyright (c) 2023-2026 Cognica, Inc.
5//
6
7//! Decode stored index metadata and inspect column references in key, included-column, then predicate order.
8use super::IndexDefinition;
9use crate::{
10    ast::{CreateIndex, IndexKey},
11    schema::dependencies::schema_expr_references_column,
12};
13
14/// Restore the complete SQL declaration for validation or a physical rebuild without changing its durable catalog identity.
15pub fn declaration(
16    row: &uqa_core::catalog_index::CatalogIndexRow,
17) -> Result<CreateIndex, serde_json::Error> {
18    let definition = index_definition(row.definition_json.as_deref())?;
19    let options: std::collections::BTreeMap<String, String> =
20        serde_json::from_str(&row.parameters_json)?;
21    Ok(CreateIndex {
22        name: Some(row.relation.name.clone()),
23        table: row.table_name.clone(),
24        access_method: row.index_type.clone(),
25        columns: serde_json::from_str(&row.columns_json)?,
26        included_columns: definition.included_columns,
27        column_order: definition.column_order,
28        predicate: definition.predicate,
29        unique: definition.unique,
30        nulls_not_distinct: definition.nulls_not_distinct,
31        if_not_exists: false,
32        options: options.into_iter().collect(),
33    })
34}
35pub fn index_definition(definition: Option<&str>) -> Result<IndexDefinition, serde_json::Error> {
36    definition.map_or_else(|| Ok(IndexDefinition::default()), serde_json::from_str)
37}
38pub fn references_column(
39    keys: &str,
40    definition: Option<&str>,
41    column: &str,
42) -> Result<bool, serde_json::Error> {
43    let keys: Vec<IndexKey> = serde_json::from_str(keys)?;
44    Ok(keys
45        .iter()
46        .any(|key| schema_expr_references_column(&key.expression(), column))
47        || index_definition(definition)?
48            .included_columns
49            .iter()
50            .any(|name| name == column)
51        || index_definition(definition)?
52            .predicate
53            .as_deref()
54            .is_some_and(|expression| schema_expr_references_column(expression, column)))
55}