Line data Source code
1 : //! INSERT statements.
2 :
3 : use dashql_parser::attrs;
4 : use super::{FmtReg, Formatter, FormattingJoinPolicy, K};
5 : use dashql_buffers::parser::{Node, NodeType};
6 :
7 : impl<'a> Formatter<'a> {
8 90 : pub(super) fn format_insert(&self, node: &'a Node) -> FmtReg {
9 90 : let f = &self.fmt;
10 90 : let [target, columns, source, default_values, returning, with_ctes, with_recursive] = attrs!(self.children(node), [
11 : K::SQL_INSERT_TARGET,
12 : K::SQL_INSERT_COLUMNS,
13 : K::SQL_INSERT_SOURCE,
14 : K::SQL_INSERT_DEFAULT_VALUES,
15 : K::SQL_INSERT_RETURNING,
16 : K::SQL_SELECT_WITH_CTES,
17 : K::SQL_SELECT_WITH_RECURSIVE,
18 : ],
19 : );
20 90 : let Some(target) = target else { return self.format_unimplemented(node) };
21 90 : if source.is_none() == default_values.is_none() {
22 0 : return self.format_unimplemented(node);
23 90 : }
24 90 : let target_reg = self.reg(target);
25 90 : if target_reg == 0 {
26 0 : return self.format_unimplemented(target);
27 90 : }
28 :
29 90 : let mut clauses = Vec::new();
30 90 : let mut header = f.concat(&[f.text("insert into "), target_reg]);
31 90 : if let Some(columns) = columns.filter(|c| c.node_type() == NodeType::ARRAY && c.children_count() > 0) {
32 36 : let columns_reg = self.reg(columns);
33 36 : if columns_reg == 0 {
34 0 : return self.format_unimplemented(columns);
35 36 : }
36 36 : header = f.concat(&[header, f.parenthesized(columns_reg)]);
37 54 : }
38 90 : clauses.push(header);
39 :
40 90 : if let Some(source) = source {
41 75 : let source_reg = self.reg(source);
42 75 : if source_reg == 0 {
43 0 : return self.format_unimplemented(source);
44 75 : }
45 75 : clauses.push(source_reg);
46 15 : } else {
47 15 : clauses.push(f.text("default values"));
48 15 : }
49 :
50 90 : if let Some(returning) = returning.filter(|r| r.node_type() == NodeType::ARRAY && r.children_count() > 0) {
51 15 : let returning_reg = self.reg(returning);
52 15 : if returning_reg == 0 {
53 0 : return self.format_unimplemented(returning);
54 15 : }
55 15 : clauses.push(f.concat(&[f.text("returning "), returning_reg]));
56 75 : }
57 :
58 90 : let policy = self.pretty_policy(FormattingJoinPolicy::BreakAllOrNone);
59 90 : let mut query = self.space_join(&clauses, policy, false);
60 90 : if let Some(with_ctes) = with_ctes {
61 12 : let ctes_reg = self.reg(with_ctes);
62 12 : if ctes_reg == 0 {
63 0 : return self.format_unimplemented(with_ctes);
64 12 : }
65 12 : let keyword = if with_recursive.is_some() { "with recursive " } else { "with " };
66 12 : let with_clause = f.concat(&[f.text(keyword), ctes_reg]);
67 12 : query = self.space_join(&[with_clause, query], policy, false);
68 78 : }
69 90 : query
70 90 : }
71 : }
|