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}