Skip to main content

oxigdal_query/executor/join/
mod.rs

1//! Join executor with proper condition evaluation.
2
3use crate::error::Result;
4use crate::executor::scan::RecordBatch;
5use crate::parser::ast::{Expr, JoinType};
6
7// Submodules
8mod expression;
9mod hash_join;
10mod nested_loop;
11mod value;
12
13// Re-exports
14pub use value::JoinValue;
15
16/// Join execution context containing the left and right inputs and join condition.
17///
18/// This context is used by join executors to perform various join algorithms
19/// (nested loop, hash join, sort-merge join) on the input data streams.
20pub struct JoinContext<'a> {
21    /// Left record batch.
22    pub left: &'a RecordBatch,
23    /// Right record batch.
24    pub right: &'a RecordBatch,
25    /// Current left row index.
26    pub left_row: usize,
27    /// Current right row index.
28    pub right_row: usize,
29    /// Left table alias (if any).
30    pub left_alias: Option<&'a str>,
31    /// Right table alias (if any).
32    pub right_alias: Option<&'a str>,
33}
34
35/// Join operator with proper condition evaluation.
36pub struct Join {
37    /// Join type.
38    pub join_type: JoinType,
39    /// Join condition.
40    pub on_condition: Option<Expr>,
41    /// Left table alias.
42    pub left_alias: Option<String>,
43    /// Right table alias.
44    pub right_alias: Option<String>,
45}
46
47impl Join {
48    /// Create a new join.
49    pub fn new(join_type: JoinType, on_condition: Option<Expr>) -> Self {
50        Self {
51            join_type,
52            on_condition,
53            left_alias: None,
54            right_alias: None,
55        }
56    }
57
58    /// Set left table alias.
59    pub fn with_left_alias(mut self, alias: impl Into<String>) -> Self {
60        self.left_alias = Some(alias.into());
61        self
62    }
63
64    /// Set right table alias.
65    pub fn with_right_alias(mut self, alias: impl Into<String>) -> Self {
66        self.right_alias = Some(alias.into());
67        self
68    }
69
70    /// Execute the join.
71    pub fn execute(&self, left: &RecordBatch, right: &RecordBatch) -> Result<RecordBatch> {
72        match self.join_type {
73            JoinType::Inner => self.inner_join(left, right),
74            JoinType::Left => self.left_join(left, right),
75            JoinType::Right => self.right_join(left, right),
76            JoinType::Full => self.full_join(left, right),
77            JoinType::Cross => self.cross_join(left, right),
78        }
79    }
80}
81
82#[cfg(test)]
83mod tests;