Skip to main content

sqlrite/sql/parser/
insert.rs

1use sqlparser::ast::{Expr, Insert, SetExpr, Statement, Value, Values};
2
3use crate::error::{Result, SQLRiteError};
4
5/// The following structure represents a INSERT query already parsed
6/// and broken down into `table_name` a `Vec<String>` representing the `Columns`
7/// and `Vec<Vec<String>>` representing the list of `Rows` to be inserted
8#[derive(Debug)]
9pub struct InsertQuery {
10    pub table_name: String,
11    pub columns: Vec<String>,
12    pub rows: Vec<Vec<String>>,
13}
14
15impl InsertQuery {
16    pub fn new(statement: &Statement) -> Result<InsertQuery> {
17        let tname: Option<String>;
18        let mut columns: Vec<String> = vec![];
19        let mut all_values: Vec<Vec<String>> = vec![];
20
21        match statement {
22            Statement::Insert(Insert {
23                table,
24                columns: cols,
25                source,
26                ..
27            }) => {
28                tname = Some(table.to_string());
29                for col in cols {
30                    columns.push(col.to_string());
31                }
32
33                let source = source.as_ref().ok_or_else(|| {
34                    SQLRiteError::Internal(
35                        "INSERT statement is missing a source expression".to_string(),
36                    )
37                })?;
38
39                if let SetExpr::Values(Values { rows, .. }) = source.body.as_ref() {
40                    for row in rows {
41                        let mut value_set: Vec<String> = vec![];
42                        for e in row {
43                            match e {
44                                Expr::Value(v) => match &v.value {
45                                    Value::Number(n, _) => {
46                                        value_set.push(n.to_string());
47                                    }
48                                    Value::Boolean(b) => {
49                                        if *b {
50                                            value_set.push("true".to_string());
51                                        } else {
52                                            value_set.push("false".to_string());
53                                        }
54                                    }
55                                    Value::SingleQuotedString(sqs) => {
56                                        value_set.push(sqs.to_string());
57                                    }
58                                    Value::Null => {
59                                        value_set.push("Null".to_string());
60                                    }
61                                    _ => {}
62                                },
63                                Expr::Identifier(i) => {
64                                    // Phase 7a — sqlparser parses bracket-array
65                                    // literals like `[0.1, 0.2, 0.3]` as
66                                    // bracket-quoted identifiers (it inherits
67                                    // MSSQL-style `[name]` quoting). Detect
68                                    // that by `quote_style == Some('[')` and
69                                    // re-wrap with brackets so the
70                                    // `parse_vector_literal` helper at
71                                    // insert_row time can recognize and parse
72                                    // it. Regular unquoted identifiers (column
73                                    // refs, which don't make sense in INSERT
74                                    // VALUES anyway) keep the existing
75                                    // pass-through-as-string behavior.
76                                    if i.quote_style == Some('[') {
77                                        value_set.push(format!("[{}]", i.value));
78                                    } else {
79                                        value_set.push(i.to_string());
80                                    }
81                                }
82                                _ => {}
83                            }
84                        }
85                        all_values.push(value_set);
86                    }
87                }
88            }
89            _ => {
90                return Err(SQLRiteError::Internal(
91                    "Error parsing insert query".to_string(),
92                ));
93            }
94        }
95
96        match tname {
97            Some(t) => Ok(InsertQuery {
98                table_name: t,
99                columns,
100                rows: all_values,
101            }),
102            None => Err(SQLRiteError::Internal(
103                "Error parsing insert query".to_string(),
104            )),
105        }
106    }
107}