Skip to main content

sql_dialect_fmt_parser/
ast.rs

1//! A thin typed layer over the untyped CST: zero-cost newtypes around `SyntaxNode` with
2//! `cast`/`syntax` plus a few accessors. This bootstraps the pattern; coverage grows with the
3//! grammar (and can later be code-generated from an ungrammar).
4
5use sql_dialect_fmt_syntax::{SyntaxKind, SyntaxNode};
6
7/// A typed view of a CST node of a particular kind.
8pub trait AstNode {
9    fn can_cast(kind: SyntaxKind) -> bool
10    where
11        Self: Sized;
12    fn cast(node: SyntaxNode) -> Option<Self>
13    where
14        Self: Sized;
15    fn syntax(&self) -> &SyntaxNode;
16}
17
18macro_rules! ast_node {
19    ($name:ident, $kind:ident) => {
20        #[derive(Debug, Clone, PartialEq, Eq, Hash)]
21        pub struct $name {
22            syntax: SyntaxNode,
23        }
24        impl AstNode for $name {
25            fn can_cast(kind: SyntaxKind) -> bool {
26                kind == SyntaxKind::$kind
27            }
28            fn cast(node: SyntaxNode) -> Option<Self> {
29                if node.kind() == SyntaxKind::$kind {
30                    Some(Self { syntax: node })
31                } else {
32                    None
33                }
34            }
35            fn syntax(&self) -> &SyntaxNode {
36                &self.syntax
37            }
38        }
39        impl $name {
40            pub fn syntax(&self) -> &SyntaxNode {
41                &self.syntax
42            }
43
44            pub fn child<N: AstNode>(&self) -> Option<N> {
45                self.syntax.children().find_map(N::cast)
46            }
47
48            pub fn children<'a, N: AstNode + 'a>(&'a self) -> impl Iterator<Item = N> + 'a {
49                self.syntax.children().filter_map(N::cast)
50            }
51        }
52    };
53}
54
55macro_rules! ast_nodes {
56    ($($name:ident, $kind:ident;)*) => {
57        $(ast_node!($name, $kind);)*
58    };
59}
60
61ast_node!(SourceFile, SOURCE_FILE);
62ast_node!(ExprStmt, EXPR_STMT);
63ast_node!(SelectStmt, SELECT_STMT);
64ast_node!(SelectList, SELECT_LIST);
65ast_node!(SelectItem, SELECT_ITEM);
66ast_node!(FromClause, FROM_CLAUSE);
67ast_node!(WhereClause, WHERE_CLAUSE);
68
69ast_nodes! {
70    TableRef, TABLE_REF;
71    LateralView, LATERAL_VIEW;
72    AsOfTravel, AS_OF_TRAVEL;
73    ArgList, ARG_LIST;
74    TypeName, TYPE_NAME;
75    Name, NAME;
76    NameRef, NAME_REF;
77    Literal, LITERAL;
78    StarExpr, STAR_EXPR;
79    ParenExpr, PAREN_EXPR;
80    PrefixExpr, PREFIX_EXPR;
81    BinExpr, BIN_EXPR;
82    CallExpr, CALL_EXPR;
83    IndexExpr, INDEX_EXPR;
84    CastExpr, CAST_EXPR;
85    BindMarker, BIND_MARKER;
86    IntervalLiteral, INTERVAL_LITERAL;
87    ArrayLiteral, ARRAY_LITERAL;
88    ObjectLiteral, OBJECT_LITERAL;
89    ObjectField, OBJECT_FIELD;
90    WithQuery, WITH_QUERY;
91    WithClause, WITH_CLAUSE;
92    Cte, CTE;
93    ColumnList, COLUMN_LIST;
94    SetOp, SET_OP;
95    Subquery, SUBQUERY;
96    GroupByClause, GROUP_BY_CLAUSE;
97    HavingClause, HAVING_CLAUSE;
98    QualifyClause, QUALIFY_CLAUSE;
99    OrderByClause, ORDER_BY_CLAUSE;
100    OrderByItem, ORDER_BY_ITEM;
101    LimitClause, LIMIT_CLAUSE;
102    OffsetClause, OFFSET_CLAUSE;
103    Join, JOIN;
104    IsExpr, IS_EXPR;
105    InExpr, IN_EXPR;
106    BetweenExpr, BETWEEN_EXPR;
107    ExistsExpr, EXISTS_EXPR;
108    ExprList, EXPR_LIST;
109    WindowExpr, WINDOW_EXPR;
110    WindowSpec, WINDOW_SPEC;
111    PartitionByClause, PARTITION_BY_CLAUSE;
112    WindowFrame, WINDOW_FRAME;
113    CaseExpr, CASE_EXPR;
114    CaseWhen, CASE_WHEN;
115    JsonAccess, JSON_ACCESS;
116    LambdaExpr, LAMBDA_EXPR;
117    LambdaParams, LAMBDA_PARAMS;
118    ValuesClause, VALUES_CLAUSE;
119    ValuesRow, VALUES_ROW;
120    InsertStmt, INSERT_STMT;
121    UpdateStmt, UPDATE_STMT;
122    DeleteStmt, DELETE_STMT;
123    MergeStmt, MERGE_STMT;
124    SetClause, SET_CLAUSE;
125    Assignment, ASSIGNMENT;
126    MergeWhen, MERGE_WHEN;
127    CreateStmt, CREATE_STMT;
128    DropStmt, DROP_STMT;
129    AlterStmt, ALTER_STMT;
130    GrantStmt, GRANT_STMT;
131    RevokeStmt, REVOKE_STMT;
132    CallStmt, CALL_STMT;
133    UseStmt, USE_STMT;
134    ShowStmt, SHOW_STMT;
135    DescribeStmt, DESCRIBE_STMT;
136    TruncateStmt, TRUNCATE_STMT;
137    CommentStmt, COMMENT_STMT;
138    TransactionStmt, TRANSACTION_STMT;
139    UndropStmt, UNDROP_STMT;
140    BlockStmt, BLOCK_STMT;
141    DeclareSection, DECLARE_SECTION;
142    DeclareItem, DECLARE_ITEM;
143    StmtList, STMT_LIST;
144    ExceptionSection, EXCEPTION_SECTION;
145    ExceptionWhen, EXCEPTION_WHEN;
146    LetStmt, LET_STMT;
147    AssignStmt, ASSIGN_STMT;
148    ReturnStmt, RETURN_STMT;
149    IfStmt, IF_STMT;
150    LoopStmt, LOOP_STMT;
151    CaseStmt, CASE_STMT;
152    CaseStmtWhen, CASE_STMT_WHEN;
153    ScriptStmt, SCRIPT_STMT;
154    ColumnDefList, COLUMN_DEF_LIST;
155    ColumnDef, COLUMN_DEF;
156    RoutineReturnsClause, ROUTINE_RETURNS_CLAUSE;
157    RoutineLanguageClause, ROUTINE_LANGUAGE_CLAUSE;
158    WithinGroup, WITHIN_GROUP;
159    PivotClause, PIVOT_CLAUSE;
160    NamedArg, NAMED_ARG;
161    MatchRecognize, MATCH_RECOGNIZE;
162    MeasuresClause, MEASURES_CLAUSE;
163    RowMatchClause, ROW_MATCH_CLAUSE;
164    AfterMatchClause, AFTER_MATCH_CLAUSE;
165    PatternClause, PATTERN_CLAUSE;
166    PatternBody, PATTERN_BODY;
167    SubsetClause, SUBSET_CLAUSE;
168    DefineClause, DEFINE_CLAUSE;
169    DefineItem, DEFINE_ITEM;
170    StartWithClause, START_WITH_CLAUSE;
171    ConnectByClause, CONNECT_BY_CLAUSE;
172    FlowStmt, FLOW_STMT;
173    SetStmt, SET_STMT;
174    ExecuteStmt, EXECUTE_STMT;
175    GroupingSets, GROUPING_SETS;
176    CopyStmt, COPY_STMT;
177    StageFileStmt, STAGE_FILE_STMT;
178    CopyLocation, COPY_LOCATION;
179    CopyOption, COPY_OPTION;
180    StageRef, STAGE_REF;
181    IntoClause, INTO_CLAUSE;
182    InsertWhen, INSERT_WHEN;
183    ObjectProperty, OBJECT_PROPERTY;
184    AlterAction, ALTER_ACTION;
185    StreamSource, STREAM_SOURCE;
186    TaskAfter, TASK_AFTER;
187    SemanticViewClause, SEMANTIC_VIEW_CLAUSE;
188    SemanticViewItem, SEMANTIC_VIEW_ITEM;
189    PrivList, PRIV_LIST;
190    GrantTarget, GRANT_TARGET;
191    Grantee, GRANTEE;
192    VacuumStmt, VACUUM_STMT;
193    OptimizeStmt, OPTIMIZE_STMT;
194    ZorderClause, ZORDER_CLAUSE;
195    CacheStmt, CACHE_STMT;
196    UncacheStmt, UNCACHE_STMT;
197    RefreshStmt, REFRESH_STMT;
198    DescribeHistoryStmt, DESCRIBE_HISTORY_STMT;
199}
200
201impl SourceFile {
202    /// All top-level statement nodes (e.g. `SELECT_STMT`, `EXPR_STMT`).
203    pub fn statements(&self) -> impl Iterator<Item = SyntaxNode> + '_ {
204        self.syntax.children()
205    }
206
207    /// Top-level statements of one typed kind.
208    pub fn statements_of<'a, N: AstNode + 'a>(&'a self) -> impl Iterator<Item = N> + 'a {
209        self.children::<N>()
210    }
211}
212
213impl SelectStmt {
214    pub fn select_list(&self) -> Option<SelectList> {
215        self.child()
216    }
217    pub fn from_clause(&self) -> Option<FromClause> {
218        self.child()
219    }
220    pub fn where_clause(&self) -> Option<WhereClause> {
221        self.child()
222    }
223}
224
225impl SelectList {
226    pub fn items(&self) -> impl Iterator<Item = SelectItem> + '_ {
227        self.children()
228    }
229}