sqruff_lib_core/parser/segments/
from.rs1use 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}