Skip to content
This repository was archived by the owner on Dec 25, 2019. It is now read-only.

Commit 1c1c34d

Browse files
committed
Support arbitrary INSERT sources
INSERT takes arbitrary queries as sources, not just VALUES clauses. For example, `INSERT INTO foo SELECT * FROM bar` is perfectly valid.
1 parent f34280a commit 1c1c34d

File tree

4 files changed

+22
-21
lines changed

4 files changed

+22
-21
lines changed

src/sqlast/mod.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -351,8 +351,8 @@ pub enum SQLStatement {
351351
table_name: SQLObjectName,
352352
/// COLUMNS
353353
columns: Vec<SQLIdent>,
354-
/// VALUES (vector of rows to insert)
355-
values: SQLValues,
354+
/// A SQL query that specifies what to insert
355+
source: Box<SQLQuery>,
356356
},
357357
SQLCopy {
358358
/// TABLE
@@ -439,13 +439,13 @@ impl ToString for SQLStatement {
439439
SQLStatement::SQLInsert {
440440
table_name,
441441
columns,
442-
values,
442+
source,
443443
} => {
444-
let mut s = format!("INSERT INTO {}", table_name.to_string());
444+
let mut s = format!("INSERT INTO {} ", table_name.to_string());
445445
if !columns.is_empty() {
446-
s += &format!(" ({})", columns.join(", "));
446+
s += &format!("({}) ", columns.join(", "));
447447
}
448-
s += &format!(" VALUES {}", values.to_string());
448+
s += &source.to_string();
449449
s
450450
}
451451
SQLStatement::SQLCopy {

src/sqlast/visit.rs

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -227,9 +227,9 @@ pub trait Visit<'ast> {
227227
&mut self,
228228
table_name: &'ast SQLObjectName,
229229
columns: &'ast Vec<SQLIdent>,
230-
values: &'ast SQLValues,
230+
source: &'ast SQLQuery,
231231
) {
232-
visit_insert(self, table_name, columns, values)
232+
visit_insert(self, table_name, columns, source)
233233
}
234234

235235
fn visit_values(&mut self, rows: &'ast SQLValues) {
@@ -405,8 +405,8 @@ pub fn visit_statement<'ast, V: Visit<'ast> + ?Sized>(
405405
SQLStatement::SQLInsert {
406406
table_name,
407407
columns,
408-
values,
409-
} => visitor.visit_insert(table_name, columns, values),
408+
source,
409+
} => visitor.visit_insert(table_name, columns, source),
410410
SQLStatement::SQLCopy {
411411
table_name,
412412
columns,
@@ -901,19 +901,16 @@ pub fn visit_insert<'ast, V: Visit<'ast> + ?Sized>(
901901
visitor: &mut V,
902902
table_name: &'ast SQLObjectName,
903903
columns: &'ast Vec<SQLIdent>,
904-
values: &'ast SQLValues,
904+
source: &'ast SQLQuery,
905905
) {
906906
visitor.visit_object_name(table_name);
907907
for column in columns {
908908
visitor.visit_identifier(column);
909909
}
910-
visitor.visit_values(values);
910+
visitor.visit_query(source);
911911
}
912912

913-
pub fn visit_values<'ast, V: Visit<'ast> + ?Sized>(
914-
visitor: &mut V,
915-
rows: &'ast SQLValues,
916-
) {
913+
pub fn visit_values<'ast, V: Visit<'ast> + ?Sized>(visitor: &mut V, rows: &'ast SQLValues) {
917914
for row in &rows.0 {
918915
visitor.visit_values_row(row)
919916
}

src/sqlparser.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1677,12 +1677,11 @@ impl Parser {
16771677
self.expect_keyword("INTO")?;
16781678
let table_name = self.parse_object_name()?;
16791679
let columns = self.parse_parenthesized_column_list(Optional)?;
1680-
self.expect_keyword("VALUES")?;
1681-
let values = self.parse_values()?;
1680+
let source = Box::new(self.parse_query()?);
16821681
Ok(SQLStatement::SQLInsert {
16831682
table_name,
16841683
columns,
1685-
values,
1684+
source,
16861685
})
16871686
}
16881687

tests/sqlparser_common.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,16 +71,21 @@ fn parse_insert_values() {
7171
SQLStatement::SQLInsert {
7272
table_name,
7373
columns,
74-
values,
74+
source,
7575
..
7676
} => {
7777
assert_eq!(table_name.to_string(), expected_table_name);
7878
assert_eq!(columns, expected_columns);
79-
assert_eq!(&values.0, expected_rows);
79+
match &source.body {
80+
SQLSetExpr::Values(SQLValues(values)) => assert_eq!(values, expected_rows),
81+
_ => unreachable!(),
82+
}
8083
}
8184
_ => unreachable!(),
8285
}
8386
}
87+
88+
verified_stmt("INSERT INTO customer WITH foo AS (SELECT 1) SELECT * FROM foo UNION VALUES (1)");
8489
}
8590

8691
#[test]

0 commit comments

Comments
 (0)