opendeviationbar-streaming 13.70.3

Real-time streaming engine for open deviation bar processing
Documentation
//! Plugin column discovery via ClickHouse `system.columns`.
//!
//! Issue #318: Rust-native ClickHouse writer -- schema discovery.

use std::collections::HashSet;

/// Discover plugin-added columns by querying `system.columns`
/// and filtering out `CORE_COLUMNS`.
pub async fn discover_plugin_columns(
    client: &clickhouse::Client,
    database: &str,
    table: &str,
) -> Result<Vec<String>, clickhouse::error::Error> {
    #[derive(clickhouse::Row, serde::Deserialize)]
    struct ColumnRow {
        name: String,
    }

    let query = format!(
        "SELECT name FROM system.columns WHERE database = '{}' AND table = '{}' ORDER BY position",
        database, table
    );
    let rows: Vec<ColumnRow> = client.query(&query).fetch_all().await?;

    let core_set: HashSet<&str> = super::row::CORE_COLUMNS.iter().copied().collect();
    // Exclude CH-computed columns (DEFAULT expressions)
    let exclude: HashSet<&str> = ["is_liquidation_cascade", "computed_at"]
        .iter()
        .copied()
        .collect();

    Ok(rows
        .into_iter()
        .map(|r| r.name)
        .filter(|name| !core_set.contains(name.as_str()) && !exclude.contains(name.as_str()))
        .collect())
}