Skip to main content

laminar_core/compiler/
error.rs

1//! Error types and compiled expression wrappers for the JIT compiler.
2//!
3//! Defines [`CompileError`] for compilation failures, function pointer types
4//! for compiled filters and scalars, and the [`CompiledExpr`] / [`MaybeCompiledExpr`]
5//! wrappers used by downstream pipeline stages.
6
7use std::fmt;
8
9use super::row::FieldType;
10
11/// Errors that can occur during expression compilation.
12#[derive(Debug)]
13pub enum CompileError {
14    /// An expression node is not supported by the JIT compiler.
15    UnsupportedExpr(String),
16    /// A field type is not supported in the requested context.
17    UnsupportedType(FieldType),
18    /// A binary operation is not supported for the given type.
19    UnsupportedBinaryOp(FieldType, datafusion_expr::Operator),
20    /// A literal value type is not supported.
21    UnsupportedLiteral,
22    /// A referenced column was not found in the schema.
23    ColumnNotFound(String),
24    /// Cranelift module-level error during compilation or linking.
25    Cranelift(Box<cranelift_module::ModuleError>),
26}
27
28impl fmt::Display for CompileError {
29    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
30        match self {
31            Self::UnsupportedExpr(desc) => write!(f, "unsupported expression: {desc}"),
32            Self::UnsupportedType(ft) => write!(f, "unsupported field type: {ft:?}"),
33            Self::UnsupportedBinaryOp(ft, op) => {
34                write!(f, "unsupported binary op {op} for type {ft:?}")
35            }
36            Self::UnsupportedLiteral => write!(f, "unsupported literal value"),
37            Self::ColumnNotFound(name) => write!(f, "column not found: {name}"),
38            Self::Cranelift(e) => write!(f, "cranelift error: {e}"),
39        }
40    }
41}
42
43impl std::error::Error for CompileError {
44    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
45        match self {
46            Self::Cranelift(e) => Some(e.as_ref()),
47            _ => None,
48        }
49    }
50}
51
52impl From<cranelift_module::ModuleError> for CompileError {
53    fn from(e: cranelift_module::ModuleError) -> Self {
54        Self::Cranelift(Box::new(e))
55    }
56}
57
58/// Errors that can occur during pipeline extraction from a logical plan.
59#[derive(Debug)]
60pub enum ExtractError {
61    /// The logical plan contains a node that cannot be decomposed into pipelines.
62    UnsupportedPlan(String),
63    /// A schema-related error during extraction (e.g., unsupported column type).
64    SchemaError(String),
65}
66
67impl fmt::Display for ExtractError {
68    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
69        match self {
70            Self::UnsupportedPlan(desc) => write!(f, "unsupported plan node: {desc}"),
71            Self::SchemaError(desc) => write!(f, "schema error during extraction: {desc}"),
72        }
73    }
74}
75
76impl std::error::Error for ExtractError {}
77
78/// A compiled filter function: `fn(row_ptr: *const u8) -> u8`.
79///
80/// Returns 1 if the row passes the filter, 0 otherwise.
81/// The caller must ensure the pointer points to a valid `EventRow` byte buffer
82/// matching the schema used during compilation.
83pub type FilterFn = unsafe extern "C" fn(*const u8) -> u8;
84
85/// A compiled scalar function: `fn(row_ptr: *const u8, out_ptr: *mut u8) -> u8`.
86///
87/// Evaluates the expression and writes the result to `out_ptr`.
88/// Returns 1 if the result is null, 0 if valid.
89pub type ScalarFn = unsafe extern "C" fn(*const u8, *mut u8) -> u8;
90
91/// A successfully compiled expression, either a filter or a scalar projection.
92pub enum CompiledExpr {
93    /// A filter expression returning a boolean.
94    Filter(FilterFn),
95    /// A scalar expression writing its result to an output pointer.
96    Scalar(ScalarFn),
97}
98
99/// Result of attempting to compile an expression.
100///
101/// Falls back to interpretation when the JIT compiler encounters an
102/// unsupported expression node, preserving the reason for diagnostics.
103pub enum MaybeCompiledExpr {
104    /// Successfully compiled to native code.
105    Compiled(CompiledExpr),
106    /// Compilation failed; caller should use interpreted evaluation.
107    Interpreted {
108        /// The reason compilation failed.
109        reason: CompileError,
110    },
111}