hamelin_lib 0.15.6

Core library for Hamelin query language
Documentation
//! Options structs for parsing, type-checking, and translation pipelines.
//!
//! All Hamelin options types live here. They are re-exported from
//! [`crate::tree::ast`] and the crate root so existing import paths continue to work.
//!
//! Use `bon::Builder` to construct options, then pass them to the corresponding
//! function (e.g., [`crate::parse_with_options`], [`crate::type_check_with_options`]).

use std::collections::HashMap;
use std::sync::Arc;

use crate::err::TranslationError;
use crate::func::def::FunctionTranslationContext;
use crate::func::registry::FunctionRegistry;
use crate::interner::Interner;
use crate::provider::{EnvironmentProvider, NoOpProvider};
use crate::tree::ast::expression::Expression;
use crate::tree::ast::identifier::{Identifier, SimpleIdentifier};
use crate::tree::typed_ast::environment::TypeEnvironment;

pub use super::template::{
    template_context_from_specs, TemplateParameterKind, TemplateParameterSpecSerde,
    TemplateParameterType, TemplateParameterValue,
};

// ---------------------------------------------------------------------------
// ParseOptions
// ---------------------------------------------------------------------------

/// Options for configuring how AST nodes are parsed.
#[derive(bon::Builder, Default)]
pub struct ParseOptions {
    /// String interner for memory-efficient identifier storage.
    ///
    /// When set, all identifier strings go through the interner,
    /// deduplicating identical strings to share the same allocation.
    pub interner: Option<Arc<Interner>>,
}

// ---------------------------------------------------------------------------
// TypeCheckOptions
// ---------------------------------------------------------------------------

/// Options for type-checking a parsed AST or a Hamelin query string.
///
/// Used by both [`crate::type_check_with_options`] and
/// [`crate::parse_and_typecheck_with_options`].
#[derive(bon::Builder, Clone)]
pub struct TypeCheckOptions {
    /// Custom function registry.
    #[builder(default = Arc::new(FunctionRegistry::default()))]
    pub registry: Arc<FunctionRegistry>,

    /// Environment provider for table schema lookups.
    #[builder(default = Arc::new(NoOpProvider::default()) as Arc<dyn EnvironmentProvider>)]
    pub provider: Arc<dyn EnvironmentProvider>,

    /// String interner shared across parse and type-check passes.
    pub interner: Option<Arc<Interner>>,

    /// Time range expression to inject after the first source command (FROM, UNION, or
    /// MATCH) when the schema exposes the configured timestamp field.
    pub time_range: Option<Arc<Expression>>,

    /// Timestamp field used by `WITHIN` and time range filtering.
    /// Defaults to `"timestamp"` when not set.
    pub timestamp_field: Option<Identifier>,

    /// Message field used by `PARSE` and similar commands.
    /// Defaults to `"event.original"` when not set.
    pub message_field: Option<Identifier>,

    /// Dashboard template parameters (`${name}` in expressions and table paths).
    pub template_parameters: Option<Arc<HashMap<String, TemplateParameterKind>>>,

    /// Default space for unqualified dataset references (`FROM events` → `default:events`).
    pub default_space: Option<crate::tree::ast::identifier::SimpleIdentifier>,
}

impl Default for TypeCheckOptions {
    fn default() -> Self {
        Self {
            registry: Arc::new(FunctionRegistry::default()),
            provider: Arc::new(NoOpProvider::default()),
            interner: None,
            time_range: None,
            timestamp_field: None,
            message_field: None,
            template_parameters: None,
            default_space: None,
        }
    }
}

// ---------------------------------------------------------------------------
// ExpressionTypeCheckOptions
// ---------------------------------------------------------------------------

/// Options for type-checking Expression AST nodes.
///
/// Unlike Query/Pipeline options which take an `EnvironmentProvider`, expression options
/// take `bindings` (the already-resolved environment at the expression's location) and
/// `fctx` (function translation context for window functions, etc).
#[derive(bon::Builder, Default)]
pub struct ExpressionTypeCheckOptions {
    /// Custom function registry.
    #[builder(default = Arc::new(FunctionRegistry::default()))]
    pub registry: Arc<FunctionRegistry>,

    /// Environment bindings (available fields/variables).
    #[builder(default)]
    pub bindings: Arc<TypeEnvironment>,

    /// Function translation context (for window functions, etc.).
    #[builder(default)]
    pub fctx: FunctionTranslationContext,

    /// String interner for deduplication.
    pub interner: Option<Arc<Interner>>,

    /// Dashboard template parameters for `${name}` in standalone expression typecheck.
    pub template_parameters: Option<Arc<HashMap<String, TemplateParameterKind>>>,
}

// ---------------------------------------------------------------------------
// TranslateOptions
// ---------------------------------------------------------------------------

/// Options for translating a type-checked AST to a backend-specific representation.
///
/// This struct is shared across all backends (Trino, DataFusion, etc.).
#[derive(bon::Builder)]
pub struct TranslateOptions {
    /// Custom function registry for normalization's re-type-check pass.
    #[builder(default = Arc::new(FunctionRegistry::default()))]
    pub registry: Arc<FunctionRegistry>,

    /// Environment provider / catalog used during normalization.
    #[builder(default = Arc::new(NoOpProvider::default()) as Arc<dyn EnvironmentProvider>)]
    pub provider: Arc<dyn EnvironmentProvider>,

    /// Timestamp field used by `WITHIN` and time range filtering.
    pub timestamp_field: Option<Identifier>,

    /// Message field used by `PARSE` and similar commands.
    pub message_field: Option<Identifier>,

    /// Default space for unqualified dataset references during normalization re-type-checks.
    pub default_space: Option<SimpleIdentifier>,
}

impl Default for TranslateOptions {
    fn default() -> Self {
        Self {
            registry: Arc::new(FunctionRegistry::default()),
            provider: Arc::new(NoOpProvider::default()),
            timestamp_field: None,
            message_field: None,
            default_space: None,
        }
    }
}

/// Parse an optional default space name for unqualified dataset references.
pub fn parse_default_space(
    default_space: Option<&str>,
) -> Result<Option<SimpleIdentifier>, TranslationError> {
    default_space.map(SimpleIdentifier::parse).transpose()
}