mirror of
https://github.com/aljazceru/turso.git
synced 2026-01-03 00:14:21 +01:00
impl ToSqlString for INSERT stmt + tests
This commit is contained in:
@@ -131,7 +131,7 @@ impl ToSqlString for ast::TriggerCmdInsert {
|
||||
impl ToSqlString for ast::Upsert {
|
||||
fn to_sql_string<C: crate::to_sql_string::ToSqlContext>(&self, context: &C) -> String {
|
||||
format!(
|
||||
"ON CONFLICT {}{}{}",
|
||||
"ON CONFLICT{}{}{}",
|
||||
self.index.as_ref().map_or("".to_string(), |index| format!(
|
||||
"{} ",
|
||||
index.to_sql_string(context)
|
||||
@@ -167,10 +167,10 @@ impl ToSqlString for ast::UpsertIndex {
|
||||
impl ToSqlString for ast::UpsertDo {
|
||||
fn to_sql_string<C: crate::to_sql_string::ToSqlContext>(&self, context: &C) -> String {
|
||||
match self {
|
||||
Self::Nothing => "NOTHING".to_string(),
|
||||
Self::Nothing => "DO NOTHING".to_string(),
|
||||
Self::Set { sets, where_clause } => {
|
||||
format!(
|
||||
"UPDATE SET {}{}",
|
||||
"DO UPDATE SET {}{}",
|
||||
sets.iter()
|
||||
.map(|set| set.to_sql_string(context))
|
||||
.collect::<Vec<_>>()
|
||||
|
||||
150
vendored/sqlite3-parser/src/to_sql_string/stmt/insert.rs
Normal file
150
vendored/sqlite3-parser/src/to_sql_string/stmt/insert.rs
Normal file
@@ -0,0 +1,150 @@
|
||||
use crate::{ast, to_sql_string::ToSqlString};
|
||||
|
||||
impl ToSqlString for ast::Insert {
|
||||
fn to_sql_string<C: crate::to_sql_string::ToSqlContext>(&self, context: &C) -> String {
|
||||
format!(
|
||||
"{}INSERT {}INTO {} {}{}{}",
|
||||
self.with.as_ref().map_or("".to_string(), |with| format!(
|
||||
"{} ",
|
||||
with.to_sql_string(context)
|
||||
)),
|
||||
self.or_conflict.map_or("".to_string(), |conflict| format!(
|
||||
"OR {} ",
|
||||
conflict.to_sql_string(context)
|
||||
)),
|
||||
self.tbl_name.to_sql_string(context),
|
||||
self.columns
|
||||
.as_ref()
|
||||
.map_or("".to_string(), |col_names| format!(
|
||||
"({}) ",
|
||||
col_names
|
||||
.iter()
|
||||
.map(|name| name.0.clone())
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
)),
|
||||
self.body.to_sql_string(context),
|
||||
self.returning
|
||||
.as_ref()
|
||||
.map_or("".to_string(), |returning| format!(
|
||||
" RETURNING {}",
|
||||
returning
|
||||
.iter()
|
||||
.map(|col| col.to_sql_string(context))
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
))
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToSqlString for ast::InsertBody {
|
||||
fn to_sql_string<C: crate::to_sql_string::ToSqlContext>(&self, context: &C) -> String {
|
||||
match self {
|
||||
Self::DefaultValues => "DEFAULT VALUES".to_string(),
|
||||
Self::Select(select, upsert) => format!(
|
||||
"{}{}",
|
||||
select.to_sql_string(context),
|
||||
upsert.as_ref().map_or("".to_string(), |upsert| format!(
|
||||
" {}",
|
||||
upsert.to_sql_string(context)
|
||||
)),
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::to_sql_string_test;
|
||||
|
||||
// Basic INSERT with all columns
|
||||
to_sql_string_test!(
|
||||
test_insert_basic,
|
||||
"INSERT INTO employees (id, name, salary) VALUES (1, 'John Doe', 50000);"
|
||||
);
|
||||
|
||||
// INSERT with multiple rows
|
||||
to_sql_string_test!(
|
||||
test_insert_multiple_rows,
|
||||
"INSERT INTO employees (id, name, salary) VALUES (1, 'John Doe', 50000), (2, 'Jane Smith', 60000);"
|
||||
);
|
||||
|
||||
// INSERT with specific columns
|
||||
to_sql_string_test!(
|
||||
test_insert_specific_columns,
|
||||
"INSERT INTO employees (name, salary) VALUES ('Alice Brown', 55000);"
|
||||
);
|
||||
|
||||
// INSERT with DEFAULT VALUES
|
||||
to_sql_string_test!(
|
||||
test_insert_default_values,
|
||||
"INSERT INTO employees DEFAULT VALUES;"
|
||||
);
|
||||
|
||||
// INSERT with SELECT subquery
|
||||
to_sql_string_test!(
|
||||
test_insert_select_subquery,
|
||||
"INSERT INTO employees (id, name, salary) SELECT id, name, salary FROM temp_employees WHERE salary > 40000;"
|
||||
);
|
||||
|
||||
// INSERT with ON CONFLICT IGNORE
|
||||
to_sql_string_test!(
|
||||
test_insert_on_conflict_ignore,
|
||||
"INSERT INTO employees (id, name, salary) VALUES (1, 'John Doe', 50000) ON CONFLICT(id) DO NOTHING;"
|
||||
);
|
||||
|
||||
// INSERT with ON CONFLICT REPLACE
|
||||
to_sql_string_test!(
|
||||
test_insert_on_conflict_replace,
|
||||
"INSERT INTO employees (id, name, salary) VALUES (1, 'John Doe', 50000) ON CONFLICT(id) DO UPDATE SET name = excluded.name, salary = excluded.salary;"
|
||||
);
|
||||
|
||||
// INSERT with RETURNING clause
|
||||
to_sql_string_test!(
|
||||
test_insert_with_returning,
|
||||
"INSERT INTO employees (id, name, salary) VALUES (1, 'John Doe', 50000) RETURNING id, name;"
|
||||
);
|
||||
|
||||
// INSERT with NULL values
|
||||
to_sql_string_test!(
|
||||
test_insert_with_null,
|
||||
"INSERT INTO employees (id, name, salary, department_id) VALUES (1, 'John Doe', NULL, NULL);"
|
||||
);
|
||||
|
||||
// INSERT with expression in VALUES
|
||||
to_sql_string_test!(
|
||||
test_insert_with_expression,
|
||||
"INSERT INTO employees (id, name, salary) VALUES (1, 'John Doe', 50000 * 1.1);"
|
||||
);
|
||||
|
||||
// INSERT into schema-qualified table
|
||||
to_sql_string_test!(
|
||||
test_insert_schema_qualified,
|
||||
"INSERT INTO main.employees (id, name, salary) VALUES (1, 'John Doe', 50000);"
|
||||
);
|
||||
|
||||
// INSERT with subquery and JOIN
|
||||
to_sql_string_test!(
|
||||
test_insert_subquery_join,
|
||||
"INSERT INTO employees (id, name, department_id) SELECT e.id, e.name, d.id FROM temp_employees e JOIN departments d ON e.dept_name = d.name;"
|
||||
);
|
||||
|
||||
// INSERT with all columns from SELECT
|
||||
to_sql_string_test!(
|
||||
test_insert_all_columns_select,
|
||||
"INSERT INTO employees SELECT * FROM temp_employees;"
|
||||
);
|
||||
|
||||
// INSERT with ON CONFLICT and WHERE clause
|
||||
to_sql_string_test!(
|
||||
test_insert_on_conflict_where,
|
||||
"INSERT INTO employees (id, name, salary) VALUES (1, 'John Doe', 50000) ON CONFLICT(id) DO UPDATE SET salary = excluded.salary WHERE excluded.salary > employees.salary;"
|
||||
);
|
||||
|
||||
// INSERT with quoted column names (reserved words)
|
||||
to_sql_string_test!(
|
||||
test_insert_quoted_columns,
|
||||
"INSERT INTO employees (\"select\", \"from\") VALUES (1, 'data');"
|
||||
);
|
||||
}
|
||||
@@ -7,6 +7,7 @@ mod create_table;
|
||||
mod create_trigger;
|
||||
mod create_virtual_table;
|
||||
mod delete;
|
||||
mod insert;
|
||||
mod select;
|
||||
|
||||
impl ToSqlString for ast::Stmt {
|
||||
@@ -154,6 +155,7 @@ impl ToSqlString for ast::Stmt {
|
||||
if_exists.then_some("IF EXISTS ").unwrap_or(""),
|
||||
view_name.to_sql_string(context)
|
||||
),
|
||||
Self::Insert(insert) => format!("{};", insert.to_sql_string(context)),
|
||||
Self::Select(select) => format!("{};", select.to_sql_string(context)),
|
||||
_ => todo!(),
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user