1use crate::{SqlElementType, SqlLanguage, SqlParser, ast, ast::*, lexer::token_type::SqlTokenType};
2use oak_core::{Builder, BuilderCache, GreenNode, OakDiagnostics, OakError, Parser, Range, RedNode, RedTree, SourceText, TextEdit, builder::BuildOutput, source::Source};
3use std::sync::Arc;
4
5mod build_expression_tree;
6
7#[derive(Clone)]
24pub struct SqlBuilder<'config> {
25 config: &'config SqlLanguage,
26}
27
28impl<'config> SqlBuilder<'config> {
29 pub fn new(config: &'config SqlLanguage) -> Self {
31 Self { config }
32 }
33}
34
35impl<'config> Builder<SqlLanguage> for SqlBuilder<'config> {
36 fn build<'a, S: Source + ?Sized>(&self, source: &S, edits: &[TextEdit], cache: &'a mut impl BuilderCache<SqlLanguage>) -> BuildOutput<SqlLanguage> {
65 let parser = SqlParser::new(self.config);
66 let parse_result = parser.parse(source, edits, cache);
67 let OakDiagnostics { result, diagnostics } = parse_result;
68
69 match result {
70 Ok(green_tree) => {
71 let source_text = SourceText::new(source.get_text_in((0..source.length()).into()).into_owned());
72 match self.build_root(green_tree, &source_text) {
73 Ok(ast_root) => OakDiagnostics { result: Ok(ast_root), diagnostics },
74 Err(build_error) => {
75 let mut diagnostics = diagnostics;
76 diagnostics.push(build_error.clone());
77 OakDiagnostics { result: Err(build_error), diagnostics }
78 }
79 }
80 }
81 Err(parse_error) => OakDiagnostics { result: Err(parse_error), diagnostics },
82 }
83 }
84}
85
86impl<'config> SqlBuilder<'config> {
87 pub(crate) fn build_root<'a>(&self, green_tree: &'a GreenNode<'a, SqlLanguage>, source: &SourceText) -> Result<SqlRoot, OakError> {
93 let root_node = RedNode::new(green_tree, 0);
94 let mut statements = Vec::new();
95
96 for child in root_node.children() {
97 if let RedTree::Node(n) = child {
98 let res = match n.green.kind {
99 SqlElementType::SelectStatement => self.build_select_statement(n, source).map(SqlStatement::Select),
100 SqlElementType::InsertStatement => self.build_insert_statement(n, source).map(SqlStatement::Insert),
101 SqlElementType::UpdateStatement => self.build_update_statement(n, source).map(SqlStatement::Update),
102 SqlElementType::DeleteStatement => self.build_delete_statement(n, source).map(SqlStatement::Delete),
103 SqlElementType::CreateStatement => self.build_create_statement(n, source).map(SqlStatement::Create),
104 SqlElementType::DropStatement => self.build_drop_statement(n, source).map(SqlStatement::Drop),
105 SqlElementType::AlterStatement => self.build_alter_statement(n, source).map(SqlStatement::Alter),
106 _ => continue,
107 };
108
109 match res {
110 Ok(stmt) => statements.push(stmt),
111 Err(e) => {
112 statements.push(SqlStatement::Error { message: Arc::from(e.to_string()), span: n.span() });
113 }
114 }
115 }
116 }
117
118 Ok(SqlRoot { statements, span: root_node.span() })
119 }
120
121 fn build_select_statement<'a>(&self, node: RedNode<'a, SqlLanguage>, source: &SourceText) -> Result<SelectStatement, OakError> {
123 let mut items = Vec::new();
124 let mut from = None;
125 let mut joins = Vec::new();
126 let mut expr = None;
127 let mut group_by = None;
128 let mut having = None;
129 let mut order_by = None;
130 let mut limit = None;
131
132 let mut where_found = false;
133
134 for child in node.children() {
135 match child {
136 RedTree::Node(n) => match n.green.kind {
137 SqlElementType::SelectItem => items.push(self.build_select_item(n, source)?),
138 SqlElementType::TableName => from = Some(self.build_table_name(n, source)?),
139 SqlElementType::JoinClause => joins.push(self.build_join_clause(n, source)?),
140 SqlElementType::GroupByClause => group_by = Some(self.build_group_by_clause(n, source)?),
141 SqlElementType::HavingClause => having = Some(self.build_having_clause(n, source)?),
142 SqlElementType::OrderByClause => order_by = Some(self.build_order_by_clause(n, source)?),
143 SqlElementType::LimitClause => limit = Some(self.build_limit_clause(n, source)?),
144 SqlElementType::Expression => {
145 if where_found && expr.is_none() {
146 expr = Some(self.build_expression(n, source)?);
147 }
148 }
149 _ => {}
150 },
151 RedTree::Leaf(t) => {
152 if t.kind == SqlTokenType::Where {
153 where_found = true;
154 }
155 }
156 }
157 }
158
159 Ok(SelectStatement { items, from, joins, expr, group_by, having, order_by, limit, span: node.span() })
160 }
161
162 fn build_select_item<'a>(&self, node: RedNode<'a, SqlLanguage>, source: &SourceText) -> Result<SelectItem, OakError> {
164 let mut expr = None;
165 let mut alias = None;
166 let mut is_star = false;
167
168 for child in node.children() {
169 match child {
170 RedTree::Leaf(t) => match t.kind {
171 SqlTokenType::Star => is_star = true,
172 SqlTokenType::Identifier_ => {
173 if expr.is_none() {
174 expr = Some(Expression::Identifier(Identifier { name: self.get_text(t.span.clone(), source), span: t.span.clone() }));
175 }
176 else {
177 alias = Some(Identifier { name: self.get_text(t.span.clone(), source), span: t.span.clone() });
178 }
179 }
180 _ => {}
181 },
182 RedTree::Node(n) => match n.green.kind {
183 SqlElementType::Expression => expr = Some(self.build_expression(n, source)?),
184 SqlElementType::Identifier => {
185 if expr.is_none() {
186 expr = Some(Expression::Identifier(self.build_identifier(n, source)?));
187 }
188 else {
189 alias = Some(self.build_identifier(n, source)?);
190 }
191 }
192 SqlElementType::Alias => alias = Some(self.build_identifier(n, source)?),
193 _ => {}
194 },
195 }
196 }
197
198 if is_star { Ok(SelectItem::Star { span: node.span() }) } else { Ok(SelectItem::Expression { expr: expr.ok_or_else(|| OakError::custom_error("Missing expression in select item"))?, alias, span: node.span() }) }
199 }
200
201 fn build_insert_statement<'a>(&self, node: RedNode<'a, SqlLanguage>, source: &SourceText) -> Result<InsertStatement, OakError> {
203 let mut table_name = None;
204 let mut columns = Vec::new();
205 let mut values = Vec::new();
206
207 for child in node.children() {
208 if let RedTree::Node(n) = child {
209 match n.green.kind {
210 SqlElementType::TableName => table_name = Some(self.build_table_name(n, source)?),
211 SqlElementType::ColumnName => {
212 for sub in n.children() {
213 match sub {
214 RedTree::Node(sn) if sn.green.kind == SqlElementType::Identifier => {
215 columns.push(self.build_identifier(sn, source)?);
216 }
217 RedTree::Leaf(st) if st.kind == SqlTokenType::Identifier_ => {
218 columns.push(Identifier { name: self.get_text(st.span.clone(), source), span: st.span.clone() });
219 }
220 _ => {}
221 }
222 }
223 }
224 SqlElementType::ValueList => {
225 self.collect_expressions(n, source, &mut values)?;
226 }
227 _ => {}
228 }
229 }
230 }
231
232 Ok(InsertStatement { table_name: table_name.ok_or_else(|| OakError::custom_error("Missing table name in INSERT"))?, columns, values, span: node.span() })
233 }
234
235 fn collect_expressions<'a>(&self, node: RedNode<'a, SqlLanguage>, source: &SourceText, out: &mut Vec<Expression>) -> Result<(), OakError> {
237 for child in node.children() {
238 if let RedTree::Node(n) = child {
239 match n.green.kind {
240 SqlElementType::Expression => out.push(self.build_expression(n, source)?),
241 SqlElementType::Identifier => out.push(Expression::Identifier(self.build_identifier(n, source)?)),
242 SqlElementType::ValueList => self.collect_expressions(n, source, out)?,
243 _ => {}
244 }
245 }
246 }
247 Ok(())
248 }
249
250 fn build_update_statement<'a>(&self, node: RedNode<'a, SqlLanguage>, source: &SourceText) -> Result<UpdateStatement, OakError> {
252 let mut table_name: Option<TableName> = None;
253 let mut assignments = Vec::new();
254 let mut selection = None;
255
256 for child in node.children() {
257 match child {
258 RedTree::Leaf(t) => match t.kind {
259 SqlTokenType::Set => {}
260 SqlTokenType::Identifier_ => {
261 if table_name.is_none() {
262 let ident = Identifier { name: self.get_text(t.span.clone(), source), span: t.span.clone() };
263 table_name = Some(TableName { name: ident, span: t.span.clone() });
264 }
265 }
266 _ => {}
267 },
268 RedTree::Node(n) => match n.green.kind {
269 SqlElementType::TableName => table_name = Some(self.build_table_name(n, source)?),
270 SqlElementType::Assignment => assignments.push(self.build_assignment(n, source)?),
271 SqlElementType::Expression => selection = Some(self.build_expression(n, source)?),
272 _ => {}
273 },
274 }
275 }
276
277 Ok(UpdateStatement { table_name: table_name.ok_or_else(|| OakError::custom_error("Missing table name in UPDATE"))?, assignments, selection, span: node.span() })
278 }
279
280 fn build_assignment<'a>(&self, node: RedNode<'a, SqlLanguage>, source: &SourceText) -> Result<Assignment, OakError> {
282 let mut column = None;
283 let mut value = None;
284
285 for child in node.children() {
286 if let RedTree::Node(n) = child {
287 match n.green.kind {
288 SqlElementType::ColumnName => column = Some(self.build_identifier(n, source)?),
289 SqlElementType::Expression => value = Some(self.build_expression(n, source)?),
290 _ => {}
291 }
292 }
293 }
294
295 Ok(Assignment { column: column.ok_or_else(|| OakError::custom_error("Missing column in assignment"))?, value: value.ok_or_else(|| OakError::custom_error("Missing value in assignment"))?, span: node.span() })
296 }
297
298 fn build_delete_statement<'a>(&self, node: RedNode<'a, SqlLanguage>, source: &SourceText) -> Result<DeleteStatement, OakError> {
300 let mut table_name = None;
301 let mut selection = None;
302
303 for child in node.children() {
304 match child {
305 RedTree::Leaf(t) => {
306 if t.kind == SqlTokenType::From {
307 }
309 }
310 RedTree::Node(n) => match n.green.kind {
311 SqlElementType::TableName => table_name = Some(self.build_table_name(n, source)?),
312 SqlElementType::Expression => selection = Some(self.build_expression(n, source)?),
313 _ => {}
314 },
315 }
316 }
317
318 Ok(DeleteStatement { table_name: table_name.ok_or_else(|| OakError::custom_error("Missing table name in DELETE"))?, selection, span: node.span() })
319 }
320
321 fn build_create_statement<'a>(&self, node: RedNode<'a, SqlLanguage>, source: &SourceText) -> Result<CreateStatement, OakError> {
323 let mut object_type = CreateObjectType::Table;
324 let mut name = None;
325 let mut if_not_exists = false;
326 let mut columns = Vec::new();
327 let mut query = None;
328 let mut table_name = None;
329 let mut index_columns = Vec::new();
330 let mut unique = false;
331
332 for child in node.children() {
333 match child {
334 RedTree::Leaf(t) => match t.kind {
335 SqlTokenType::Table => object_type = CreateObjectType::Table,
336 SqlTokenType::View => object_type = CreateObjectType::View,
337 SqlTokenType::Index => object_type = CreateObjectType::Index,
338 SqlTokenType::Database => object_type = CreateObjectType::Database,
339 SqlTokenType::Exists => if_not_exists = true,
340 SqlTokenType::Unique => unique = true,
341 _ => {
342 if object_type == CreateObjectType::Index && name.is_some() && table_name.is_some() && t.kind == SqlTokenType::Identifier_ {
343 index_columns.push(ast::Identifier { name: self.get_text(t.span.clone(), source), span: t.span.clone() });
344 }
345 }
346 },
347 RedTree::Node(n) => match n.green.kind {
348 SqlElementType::TableName => {
349 if object_type == CreateObjectType::Index && name.is_some() {
350 table_name = Some(self.build_table_name(n, source)?);
351 }
352 else {
353 name = Some(self.build_identifier(n, source)?);
354 }
355 }
356 SqlElementType::Identifier => {
357 if object_type == CreateObjectType::Index && name.is_some() && table_name.is_none() {
358 table_name = Some(ast::TableName { name: self.build_identifier(n, source)?, span: n.span() });
359 }
360 else if name.is_none() {
361 name = Some(self.build_identifier(n, source)?);
362 }
363 else if object_type == CreateObjectType::Index {
364 index_columns.push(self.build_identifier(n, source)?);
365 }
366 }
367 SqlElementType::ColumnDefinition => {
368 columns.push(self.build_column_definition(n, source)?);
369 }
370 SqlElementType::SelectStatement => {
371 query = Some(self.build_select_statement(n, source)?);
372 }
373 _ => {}
374 },
375 }
376 }
377
378 let body = match object_type {
379 CreateObjectType::Table => CreateBody::Table { columns, span: node.span() },
380 CreateObjectType::View => CreateBody::View { query: Box::new(query.ok_or_else(|| OakError::custom_error("Missing query in CREATE VIEW"))?), span: node.span() },
381 CreateObjectType::Index => CreateBody::Index { table_name: table_name.ok_or_else(|| OakError::custom_error("Missing table name in CREATE INDEX"))?, columns: index_columns, unique, span: node.span() },
382 CreateObjectType::Database => CreateBody::Database { span: node.span() },
383 };
384
385 let result = CreateStatement { object_type, name: name.ok_or_else(|| OakError::custom_error("Missing name in CREATE"))?, if_not_exists, body, span: node.span() };
386 Ok(result)
387 }
388
389 fn build_column_definition<'a>(&self, node: RedNode<'a, SqlLanguage>, source: &SourceText) -> Result<ColumnDefinition, OakError> {
390 let mut name = None;
391 let mut data_type_str = String::new();
392 let mut constraints = Vec::new();
393
394 let mut parsing_data_type = false;
396
397 for child in node.children() {
398 match child {
399 RedTree::Node(n) => match n.green.kind {
400 SqlElementType::ColumnName | SqlElementType::Identifier => {
401 if name.is_none() {
402 name = Some(self.build_identifier(n, source)?);
403 parsing_data_type = true;
404 }
405 else if parsing_data_type {
406 if !data_type_str.is_empty() {
407 data_type_str.push(' ');
408 }
409 data_type_str.push_str(self.get_text(n.span(), source).trim());
410 }
411 }
412 _ => {}
413 },
414 RedTree::Leaf(t) => {
415 match t.kind {
416 SqlTokenType::Primary => {
417 constraints.push(ColumnConstraint::PrimaryKey { span: t.span.clone() });
418 parsing_data_type = false;
419 }
420 SqlTokenType::Key => {
421 parsing_data_type = false;
423 }
424 SqlTokenType::Not => {
425 constraints.push(ColumnConstraint::NotNull { span: t.span.clone() });
426 parsing_data_type = false;
427 }
428 SqlTokenType::Null => {
429 let mut is_not_null = false;
431 if let Some(ColumnConstraint::NotNull { .. }) = constraints.last() {
432 is_not_null = true;
433 }
434
435 if !is_not_null {
436 constraints.push(ColumnConstraint::Nullable { span: t.span.clone() });
437 }
438 parsing_data_type = false;
439 }
440 SqlTokenType::Unique => {
441 constraints.push(ColumnConstraint::Unique { span: t.span.clone() });
442 parsing_data_type = false;
443 }
444 SqlTokenType::AutoIncrement => {
445 constraints.push(ColumnConstraint::AutoIncrement { span: t.span.clone() });
446 parsing_data_type = false;
447 }
448 SqlTokenType::Default => {
449 parsing_data_type = false;
450 if let Some(expr_node) = self.find_next_node_in_parent(node.clone(), SqlElementType::Expression, t.span.end) {
452 constraints.push(ColumnConstraint::Default(self.build_expression(expr_node, source)?, t.span.clone()));
453 }
454 }
455 SqlTokenType::Check => {
456 parsing_data_type = false;
457 if let Some(expr_node) = self.find_next_node_in_parent(node.clone(), SqlElementType::Expression, t.span.end) {
459 constraints.push(ColumnConstraint::Check(self.build_expression(expr_node, source)?, t.span.clone()));
460 }
461 }
462 _ if parsing_data_type => {
463 if !data_type_str.is_empty() {
464 data_type_str.push(' ');
465 }
466 data_type_str.push_str(self.get_text(t.span.clone(), source).trim());
467 }
468 _ => {}
469 }
470 }
471 }
472 }
473
474 Ok(ColumnDefinition { name: name.ok_or_else(|| OakError::custom_error("Missing name in column definition"))?, data_type: Arc::from(data_type_str), constraints, span: node.span() })
475 }
476
477 fn find_next_node_in_parent<'a>(&self, parent: RedNode<'a, SqlLanguage>, kind: SqlElementType, after_pos: usize) -> Option<RedNode<'a, SqlLanguage>> {
479 for child in parent.children() {
480 if let RedTree::Node(n) = child {
481 if n.green.kind == kind && n.span().start >= after_pos {
482 return Some(n);
483 }
484 }
485 }
486 None
487 }
488
489 fn build_drop_statement<'a>(&self, node: RedNode<'a, SqlLanguage>, source: &SourceText) -> Result<DropStatement, OakError> {
490 let mut object_type = DropObjectType::Table;
491 let mut name = None;
492 let mut if_exists = false;
493
494 for child in node.children() {
495 match child {
496 RedTree::Leaf(t) => match t.kind {
497 SqlTokenType::Table => object_type = DropObjectType::Table,
498 SqlTokenType::View => object_type = DropObjectType::View,
499 SqlTokenType::Index => object_type = DropObjectType::Index,
500 SqlTokenType::Database => object_type = DropObjectType::Database,
501 SqlTokenType::Exists => if_exists = true,
502 _ => {}
503 },
504 RedTree::Node(n) => {
505 if n.green.kind == SqlElementType::TableName || n.green.kind == SqlElementType::Identifier {
506 name = Some(self.build_identifier(n, source)?);
507 }
508 }
509 }
510 }
511
512 let result = DropStatement { object_type, name: name.ok_or_else(|| OakError::custom_error("Missing name in DROP"))?, if_exists, span: node.span() };
513 Ok(result)
514 }
515
516 fn build_alter_statement<'a>(&self, node: RedNode<'a, SqlLanguage>, source: &SourceText) -> Result<AlterStatement, OakError> {
517 let mut table_name = None;
518 let mut action = None;
519
520 for child in node.children() {
521 if let RedTree::Node(n) = child {
522 if n.green.kind == SqlElementType::TableName {
523 table_name = Some(self.build_table_name(n, source)?);
524 }
525 else if n.green.kind == SqlElementType::AlterAction {
526 action = Some(self.build_alter_action(n, source)?);
527 }
528 }
529 }
530
531 let result = AlterStatement { table_name: table_name.ok_or_else(|| OakError::custom_error("Missing table name in ALTER"))?, action, span: node.span() };
532 Ok(result)
533 }
534
535 fn build_alter_action<'a>(&self, node: RedNode<'a, SqlLanguage>, source: &SourceText) -> Result<ast::AlterAction, OakError> {
536 use SqlTokenType::*;
537 let mut is_add = false;
538 let mut is_drop = false;
539 let mut is_rename = false;
540 let mut identifier: Option<ast::Identifier> = None;
541 let mut data_type_tokens = Vec::new();
542
543 for child in node.children() {
544 match child {
545 RedTree::Leaf(t) => match t.kind {
546 Add => is_add = true,
547 Drop => is_drop = true,
548 Rename => is_rename = true,
549 Identifier_ => {
550 if identifier.is_none() {
551 identifier = Some(ast::Identifier { name: self.get_text(t.span.clone(), source), span: t.span.clone() });
552 }
553 else if is_add {
554 data_type_tokens.push(t.span.clone());
555 }
556 }
557 LeftParen | RightParen | NumberLiteral | Comma | Int | Integer | Varchar | Char | Text | Date | Time | Timestamp | Decimal | Float | Double | Boolean => {
558 if is_add && identifier.is_some() {
559 data_type_tokens.push(t.span.clone());
560 }
561 }
562 _ => {}
563 },
564 RedTree::Node(n) if n.green.kind == SqlElementType::Identifier => {
565 identifier = Some(self.build_identifier(n, source)?);
566 }
567 _ => {}
568 }
569 }
570
571 let data_type = if data_type_tokens.is_empty() {
572 None
573 }
574 else {
575 let start = data_type_tokens[0].start;
576 let end = data_type_tokens.last().unwrap().end;
577 Some(self.get_text(Range { start, end }, source))
578 };
579
580 if is_add {
581 Ok(ast::AlterAction::AddColumn { name: identifier.ok_or_else(|| OakError::custom_error("Missing column name in ALTER TABLE ADD"))?, data_type, span: node.span() })
582 }
583 else if is_drop {
584 Ok(ast::AlterAction::DropColumn { name: identifier.ok_or_else(|| OakError::custom_error("Missing column name in ALTER TABLE DROP"))?, span: node.span() })
585 }
586 else if is_rename {
587 Ok(ast::AlterAction::RenameTo { new_name: identifier.ok_or_else(|| OakError::custom_error("Missing new name in ALTER TABLE RENAME"))?, span: node.span() })
588 }
589 else {
590 Err(OakError::custom_error("Unknown ALTER action"))
591 }
592 }
593
594 fn build_table_name<'a>(&self, node: RedNode<'a, SqlLanguage>, source: &SourceText) -> Result<TableName, OakError> {
595 let mut name = None;
596 for child in node.children() {
597 match child {
598 RedTree::Leaf(t) if t.kind == SqlTokenType::Identifier_ => {
599 name = Some(Identifier { name: self.get_text(t.span.clone(), source), span: t.span.clone() });
600 }
601 RedTree::Node(n) if n.green.kind == SqlElementType::Identifier => {
602 name = Some(self.build_identifier(n, source)?);
603 }
604 _ => {}
605 }
606 }
607 Ok(TableName { name: name.ok_or_else(|| OakError::custom_error("Missing table name"))?, span: node.span() })
608 }
609
610 fn build_identifier<'a>(&self, node: RedNode<'a, SqlLanguage>, source: &SourceText) -> Result<Identifier, OakError> {
611 Ok(Identifier { name: self.get_text(node.span(), source), span: node.span() })
612 }
613
614 fn build_join_clause<'a>(&self, node: RedNode<'a, SqlLanguage>, source: &SourceText) -> Result<JoinClause, OakError> {
615 let mut join_type = JoinType::Inner;
616 let mut table = None;
617 let mut on = None;
618
619 for child in node.children() {
620 match child {
621 RedTree::Leaf(t) => match t.kind {
622 SqlTokenType::Inner => join_type = JoinType::Inner,
623 SqlTokenType::Left => join_type = JoinType::Left,
624 SqlTokenType::Right => join_type = JoinType::Right,
625 SqlTokenType::Full => join_type = JoinType::Full,
626 _ => {}
627 },
628 RedTree::Node(n) => match n.green.kind {
629 SqlElementType::TableName => table = Some(self.build_table_name(n, source)?),
630 SqlElementType::Expression => on = Some(self.build_expression(n, source)?),
631 _ => {}
632 },
633 }
634 }
635
636 Ok(JoinClause { join_type, table: table.ok_or_else(|| OakError::custom_error("Missing table in JOIN"))?, on, span: node.span() })
637 }
638
639 fn build_group_by_clause<'a>(&self, node: RedNode<'a, SqlLanguage>, source: &SourceText) -> Result<GroupByClause, OakError> {
640 let mut columns = Vec::new();
641 for child in node.children() {
642 if let RedTree::Node(n) = child {
643 if n.green.kind == SqlElementType::Expression {
644 columns.push(self.build_expression(n, source)?);
645 }
646 }
647 }
648 Ok(GroupByClause { columns, span: node.span() })
649 }
650
651 fn build_having_clause<'a>(&self, node: RedNode<'a, SqlLanguage>, source: &SourceText) -> Result<HavingClause, OakError> {
652 let mut condition = None;
653 for child in node.children() {
654 if let RedTree::Node(n) = child {
655 if n.green.kind == SqlElementType::Expression {
656 condition = Some(self.build_expression(n, source)?);
657 }
658 }
659 }
660 Ok(HavingClause { condition: condition.ok_or_else(|| OakError::custom_error("Missing condition in HAVING"))?, span: node.span() })
661 }
662
663 fn build_order_by_clause<'a>(&self, node: RedNode<'a, SqlLanguage>, source: &SourceText) -> Result<OrderByClause, OakError> {
664 let mut items = Vec::new();
665 let mut current_expr: Option<(Expression, Range<usize>)> = None;
666
667 for child in node.children() {
668 match child {
669 RedTree::Node(n) => {
670 if n.green.kind == SqlElementType::Expression {
671 if let Some((expr, span)) = current_expr.take() {
672 items.push(OrderByItem { expr, direction: OrderDirection::Asc, span });
673 }
674 current_expr = Some((self.build_expression(n.clone(), source)?, n.span()));
675 }
676 }
677 RedTree::Leaf(t) => match t.kind {
678 SqlTokenType::Asc => {
679 if let Some((expr, span)) = current_expr.take() {
680 let total_span = Range { start: span.start, end: t.span.end };
681 items.push(OrderByItem { expr, direction: OrderDirection::Asc, span: total_span });
682 }
683 }
684 SqlTokenType::Desc => {
685 if let Some((expr, span)) = current_expr.take() {
686 let total_span = Range { start: span.start, end: t.span.end };
687 items.push(OrderByItem { expr, direction: OrderDirection::Desc, span: total_span });
688 }
689 }
690 _ => {}
691 },
692 }
693 }
694
695 if let Some((expr, span)) = current_expr {
696 items.push(OrderByItem { expr, direction: OrderDirection::Asc, span });
697 }
698
699 Ok(OrderByClause { items, span: node.span() })
700 }
701
702 fn build_limit_clause<'a>(&self, node: RedNode<'a, SqlLanguage>, source: &SourceText) -> Result<LimitClause, OakError> {
703 let mut limit = None;
704 let mut offset = None;
705
706 for child in node.children() {
707 if let RedTree::Leaf(t) = child {
708 if t.kind == SqlTokenType::NumberLiteral {
709 let expr = Expression::Literal(Literal::Number(self.get_text(t.span.clone(), source), t.span.clone()));
710 if limit.is_none() {
711 limit = Some(expr);
712 }
713 else {
714 offset = Some(expr);
715 }
716 }
717 }
718 else if let RedTree::Node(n) = child {
719 if n.green.kind == SqlElementType::Expression {
720 let expr = self.build_expression(n, source)?;
721 if limit.is_none() {
722 limit = Some(expr);
723 }
724 else {
725 offset = Some(expr);
726 }
727 }
728 }
729 }
730
731 Ok(LimitClause { limit: limit.ok_or_else(|| OakError::custom_error("Missing limit value"))?, offset, span: node.span() })
732 }
733
734 fn build_statement<'a>(&self, node: RedNode<'a, SqlLanguage>, source: &SourceText) -> Result<SqlStatement, OakError> {
735 match node.green.kind {
736 SqlElementType::SelectStatement => Ok(SqlStatement::Select(self.build_select_statement(node, source)?)),
737 SqlElementType::InsertStatement => Ok(SqlStatement::Insert(self.build_insert_statement(node, source)?)),
738 SqlElementType::UpdateStatement => Ok(SqlStatement::Update(self.build_update_statement(node, source)?)),
739 SqlElementType::DeleteStatement => Ok(SqlStatement::Delete(self.build_delete_statement(node, source)?)),
740 SqlElementType::CreateStatement => Ok(SqlStatement::Create(self.build_create_statement(node, source)?)),
741 SqlElementType::DropStatement => Ok(SqlStatement::Drop(self.build_drop_statement(node, source)?)),
742 SqlElementType::AlterStatement => Ok(SqlStatement::Alter(self.build_alter_statement(node, source)?)),
743 _ => Err(OakError::custom_error("Unknown statement type")),
744 }
745 }
746
747 fn get_text(&self, span: core::range::Range<usize>, source: &SourceText) -> Arc<str> {
748 Arc::from(source.get_text_in(span))
749 }
750
751 fn map_unary_op(&self, kind: SqlTokenType) -> Option<UnaryOperator> {
752 match kind {
753 SqlTokenType::Plus => Some(UnaryOperator::Plus),
754 SqlTokenType::Minus => Some(UnaryOperator::Minus),
755 SqlTokenType::Not => Some(UnaryOperator::Not),
756 _ => None,
757 }
758 }
759
760 fn map_binary_op(&self, kind: SqlTokenType) -> Option<BinaryOperator> {
761 match kind {
762 SqlTokenType::Plus => Some(BinaryOperator::Plus),
763 SqlTokenType::Minus => Some(BinaryOperator::Minus),
764 SqlTokenType::Star => Some(BinaryOperator::Star),
765 SqlTokenType::Slash => Some(BinaryOperator::Slash),
766 SqlTokenType::Equal => Some(BinaryOperator::Equal),
767 SqlTokenType::NotEqual => Some(BinaryOperator::NotEqual),
768 SqlTokenType::Less => Some(BinaryOperator::Less),
769 SqlTokenType::LessEqual => Some(BinaryOperator::LessEqual),
770 SqlTokenType::Greater => Some(BinaryOperator::Greater),
771 SqlTokenType::GreaterEqual => Some(BinaryOperator::GreaterEqual),
772 SqlTokenType::And => Some(BinaryOperator::And),
773 SqlTokenType::Or => Some(BinaryOperator::Or),
774 _ => None,
775 }
776 }
777}