grafbase_sql_ast/ast/
join.rs1use crate::ast::{ConditionTree, Table};
2
3#[derive(Debug, PartialEq, Clone)]
5pub struct JoinData<'a> {
6 pub(crate) table: Table<'a>,
7 pub(crate) conditions: ConditionTree<'a>,
8 #[cfg(feature = "postgresql")]
9 pub(crate) lateral: bool,
10}
11
12impl<'a> JoinData<'a> {
13 pub fn all_from(table: impl Into<Table<'a>>) -> Self {
15 Self {
16 table: table.into(),
17 conditions: ConditionTree::NoCondition,
18 lateral: false,
19 }
20 }
21
22 pub fn lateral(&mut self) {
24 self.lateral = true;
25 }
26}
27
28impl<'a, T> From<T> for JoinData<'a>
29where
30 T: Into<Table<'a>>,
31{
32 fn from(table: T) -> Self {
33 Self::all_from(table)
34 }
35}
36
37#[derive(Debug, PartialEq, Clone)]
39pub enum Join<'a> {
40 Inner(JoinData<'a>),
42 Left(JoinData<'a>),
44 Right(JoinData<'a>),
46 Full(JoinData<'a>),
48}
49
50pub trait Joinable<'a> {
52 fn on<T>(self, conditions: T) -> JoinData<'a>
54 where
55 T: Into<ConditionTree<'a>>;
56}
57
58impl<'a, U> Joinable<'a> for U
59where
60 U: Into<Table<'a>>,
61{
62 fn on<T>(self, conditions: T) -> JoinData<'a>
63 where
64 T: Into<ConditionTree<'a>>,
65 {
66 JoinData {
67 table: self.into(),
68 conditions: conditions.into(),
69 lateral: false,
70 }
71 }
72}
73
74impl<'a> Joinable<'a> for JoinData<'a> {
75 fn on<T>(self, conditions: T) -> JoinData<'a>
76 where
77 T: Into<ConditionTree<'a>>,
78 {
79 let conditions = match self.conditions {
80 ConditionTree::NoCondition => conditions.into(),
81 cond => cond.and(conditions.into()),
82 };
83
84 JoinData {
85 table: self.table,
86 conditions,
87 lateral: false,
88 }
89 }
90}