sqruff_lib_core/parser/segments/
from.rs

1use smol_str::SmolStr;
2
3use crate::dialects::common::AliasInfo;
4use crate::dialects::syntax::{SyntaxKind, SyntaxSet};
5use crate::parser::segments::base::ErasedSegment;
6use crate::parser::segments::join::JoinClauseSegment;
7
8pub struct FromExpressionElementSegment(pub ErasedSegment);
9pub struct FromClauseSegment(pub ErasedSegment);
10
11impl FromClauseSegment {
12    pub fn eventual_aliases(&self) -> Vec<(ErasedSegment, AliasInfo)> {
13        let mut buff = Vec::new();
14        let mut direct_table_children = Vec::new();
15        let mut join_clauses = Vec::new();
16
17        for from_expression in self
18            .0
19            .children(const { &SyntaxSet::new(&[SyntaxKind::FromExpression]) })
20        {
21            direct_table_children.extend(
22                from_expression
23                    .children(const { &SyntaxSet::new(&[SyntaxKind::FromExpressionElement]) }),
24            );
25            join_clauses.extend(
26                from_expression.children(const { &SyntaxSet::new(&[SyntaxKind::JoinClause]) }),
27            );
28        }
29
30        for &clause in &direct_table_children {
31            let tmp;
32
33            let alias = FromExpressionElementSegment(clause.clone()).eventual_alias();
34
35            let table_expr = if direct_table_children.contains(&clause) {
36                clause
37            } else {
38                tmp = clause
39                    .child(const { &SyntaxSet::new(&[SyntaxKind::FromExpressionElement]) })
40                    .unwrap();
41                &tmp
42            };
43
44            buff.push((table_expr.clone(), alias));
45        }
46
47        for clause in join_clauses {
48            let aliases = JoinClauseSegment(clause.clone()).eventual_aliases();
49
50            if !aliases.is_empty() {
51                buff.extend(aliases);
52            }
53        }
54
55        buff
56    }
57}
58
59impl FromExpressionElementSegment {
60    pub fn eventual_alias(&self) -> AliasInfo {
61        let mut tbl_expression = self
62            .0
63            .child(const { &SyntaxSet::new(&[SyntaxKind::TableExpression]) })
64            .or_else(|| {
65                self.0
66                    .child(const { &SyntaxSet::new(&[SyntaxKind::Bracketed]) })
67                    .and_then(|bracketed| {
68                        bracketed.child(const { &SyntaxSet::new(&[SyntaxKind::TableExpression]) })
69                    })
70            });
71
72        if let Some(tbl_expression_inner) = &tbl_expression {
73            if tbl_expression_inner
74                    .child(const { &SyntaxSet::new(&[SyntaxKind::ObjectReference, SyntaxKind::TableReference]) })
75                    .is_none()
76                {
77                    if let Some(bracketed) = tbl_expression_inner.child(const { &SyntaxSet::new(&[SyntaxKind::Bracketed]) }) {
78                        tbl_expression = bracketed.child(const { &SyntaxSet::new(&[SyntaxKind::TableExpression]) });
79                    }
80                }
81        }
82
83        let reference = tbl_expression.and_then(|tbl_expression| {
84            tbl_expression.child(const { &SyntaxSet::new(&[SyntaxKind::ObjectReference, SyntaxKind::TableReference]) })
85        });
86
87        let reference = reference.as_ref().map(|reference| reference.reference());
88
89        let alias_expression = self
90            .0
91            .child(const { &SyntaxSet::new(&[SyntaxKind::AliasExpression]) });
92        if let Some(alias_expression) = alias_expression {
93            let segment = alias_expression.child(
94                const { &SyntaxSet::new(&[SyntaxKind::Identifier, SyntaxKind::NakedIdentifier]) },
95            );
96            if let Some(segment) = segment {
97                return AliasInfo {
98                    ref_str: segment.raw().clone(),
99                    segment: segment.into(),
100                    aliased: true,
101                    from_expression_element: self.0.clone(),
102                    alias_expression: alias_expression.into(),
103                    object_reference: reference.map(|it| it.clone().0),
104                };
105            }
106        }
107
108        if let Some(reference) = &reference {
109            let references = reference.iter_raw_references();
110
111            if !references.is_empty() {
112                let penultimate_ref = references.last().unwrap();
113                return AliasInfo {
114                    ref_str: penultimate_ref.part.clone().into(),
115                    segment: penultimate_ref.segments[0].clone().into(),
116                    aliased: false,
117                    from_expression_element: self.0.clone(),
118                    alias_expression: None,
119                    object_reference: reference.clone().0.into(),
120                };
121            }
122        }
123
124        AliasInfo {
125            ref_str: SmolStr::new_static(""),
126            segment: None,
127            aliased: false,
128            from_expression_element: self.0.clone(),
129            alias_expression: None,
130            object_reference: reference.map(|it| it.clone().0),
131        }
132    }
133}