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::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 && tbl_expression_inner
74 .child(const { &SyntaxSet::new(&[SyntaxKind::ObjectReference, SyntaxKind::TableReference]) })
75 .is_none()
76 && let Some(bracketed) = tbl_expression_inner.child(const { &SyntaxSet::new(&[SyntaxKind::Bracketed]) }) {
77 tbl_expression = bracketed.child(const { &SyntaxSet::new(&[SyntaxKind::TableExpression]) });
78 }
79
80 let reference = tbl_expression.and_then(|tbl_expression| {
81 tbl_expression.child(const { &SyntaxSet::new(&[SyntaxKind::ObjectReference, SyntaxKind::TableReference]) })
82 });
83
84 let reference = reference.as_ref().map(|reference| reference.reference());
85
86 let alias_expression = self
87 .0
88 .child(const { &SyntaxSet::new(&[SyntaxKind::AliasExpression]) });
89 if let Some(alias_expression) = alias_expression {
90 let segment = alias_expression.child(
91 const { &SyntaxSet::new(&[SyntaxKind::Identifier, SyntaxKind::NakedIdentifier]) },
92 );
93 if let Some(segment) = segment {
94 return AliasInfo {
95 ref_str: segment.raw().clone(),
96 segment: segment.into(),
97 aliased: true,
98 from_expression_element: self.0.clone(),
99 alias_expression: alias_expression.into(),
100 object_reference: reference.map(|it| it.clone().0),
101 };
102 }
103 }
104
105 if let Some(reference) = &reference {
106 let references = reference.iter_raw_references();
107
108 if !references.is_empty() {
109 let penultimate_ref = references.last().unwrap();
110 return AliasInfo {
111 ref_str: penultimate_ref.part.clone().into(),
112 segment: penultimate_ref.segments[0].clone().into(),
113 aliased: false,
114 from_expression_element: self.0.clone(),
115 alias_expression: None,
116 object_reference: reference.clone().0.into(),
117 };
118 }
119 }
120
121 AliasInfo {
122 ref_str: SmolStr::new_static(""),
123 segment: None,
124 aliased: false,
125 from_expression_element: self.0.clone(),
126 alias_expression: None,
127 object_reference: reference.map(|it| it.clone().0),
128 }
129 }
130}