Skip to content

Commit 3d2773a

Browse files
authored
Support INSERT INTO ... DEFAULT VALUES ... (#1036)
1 parent 5bdf2e6 commit 3d2773a

File tree

5 files changed

+150
-25
lines changed

5 files changed

+150
-25
lines changed

src/ast/mod.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1418,7 +1418,7 @@ pub enum Statement {
14181418
/// Overwrite (Hive)
14191419
overwrite: bool,
14201420
/// A SQL query that specifies what to insert
1421-
source: Box<Query>,
1421+
source: Option<Box<Query>>,
14221422
/// partitioned insert (Hive)
14231423
partitioned: Option<Vec<Expr>>,
14241424
/// Columns defined after PARTITION
@@ -2283,7 +2283,14 @@ impl fmt::Display for Statement {
22832283
if !after_columns.is_empty() {
22842284
write!(f, "({}) ", display_comma_separated(after_columns))?;
22852285
}
2286-
write!(f, "{source}")?;
2286+
2287+
if let Some(source) = source {
2288+
write!(f, "{source}")?;
2289+
}
2290+
2291+
if source.is_none() && columns.is_empty() {
2292+
write!(f, "DEFAULT VALUES")?;
2293+
}
22872294

22882295
if let Some(on) = on {
22892296
write!(f, "{on}")?;

src/parser/mod.rs

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7277,21 +7277,23 @@ impl<'a> Parser<'a> {
72777277
let table = self.parse_keyword(Keyword::TABLE);
72787278
let table_name = self.parse_object_name()?;
72797279
let is_mysql = dialect_of!(self is MySqlDialect);
7280-
let columns = self.parse_parenthesized_column_list(Optional, is_mysql)?;
72817280

7282-
let partitioned = if self.parse_keyword(Keyword::PARTITION) {
7283-
self.expect_token(&Token::LParen)?;
7284-
let r = Some(self.parse_comma_separated(Parser::parse_expr)?);
7285-
self.expect_token(&Token::RParen)?;
7286-
r
7287-
} else {
7288-
None
7289-
};
7281+
let (columns, partitioned, after_columns, source) =
7282+
if self.parse_keywords(&[Keyword::DEFAULT, Keyword::VALUES]) {
7283+
(vec![], None, vec![], None)
7284+
} else {
7285+
let columns = self.parse_parenthesized_column_list(Optional, is_mysql)?;
72907286

7291-
// Hive allows you to specify columns after partitions as well if you want.
7292-
let after_columns = self.parse_parenthesized_column_list(Optional, false)?;
7287+
let partitioned = self.parse_insert_partition()?;
7288+
7289+
// Hive allows you to specify columns after partitions as well if you want.
7290+
let after_columns = self.parse_parenthesized_column_list(Optional, false)?;
7291+
7292+
let source = Some(Box::new(self.parse_query()?));
7293+
7294+
(columns, partitioned, after_columns, source)
7295+
};
72937296

7294-
let source = Box::new(self.parse_query()?);
72957297
let on = if self.parse_keyword(Keyword::ON) {
72967298
if self.parse_keyword(Keyword::CONFLICT) {
72977299
let conflict_target =
@@ -7362,6 +7364,17 @@ impl<'a> Parser<'a> {
73627364
}
73637365
}
73647366

7367+
pub fn parse_insert_partition(&mut self) -> Result<Option<Vec<Expr>>, ParserError> {
7368+
if self.parse_keyword(Keyword::PARTITION) {
7369+
self.expect_token(&Token::LParen)?;
7370+
let partition_cols = Some(self.parse_comma_separated(Parser::parse_expr)?);
7371+
self.expect_token(&Token::RParen)?;
7372+
Ok(partition_cols)
7373+
} else {
7374+
Ok(None)
7375+
}
7376+
}
7377+
73657378
pub fn parse_update(&mut self) -> Result<Statement, ParserError> {
73667379
let table = self.parse_table_and_joins()?;
73677380
self.expect_keyword(Keyword::SET)?;

tests/sqlparser_common.rs

Lines changed: 107 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,15 +85,15 @@ fn parse_insert_values() {
8585
Statement::Insert {
8686
table_name,
8787
columns,
88-
source,
88+
source: Some(source),
8989
..
9090
} => {
9191
assert_eq!(table_name.to_string(), expected_table_name);
9292
assert_eq!(columns.len(), expected_columns.len());
9393
for (index, column) in columns.iter().enumerate() {
9494
assert_eq!(column, &Ident::new(expected_columns[index].clone()));
9595
}
96-
match &*source.body {
96+
match *source.body {
9797
SetExpr::Values(Values { rows, .. }) => {
9898
assert_eq!(rows.as_slice(), expected_rows)
9999
}
@@ -107,6 +107,111 @@ fn parse_insert_values() {
107107
verified_stmt("INSERT INTO customer WITH foo AS (SELECT 1) SELECT * FROM foo UNION VALUES (1)");
108108
}
109109

110+
#[test]
111+
fn parse_insert_default_values() {
112+
let insert_with_default_values = verified_stmt("INSERT INTO test_table DEFAULT VALUES");
113+
114+
match insert_with_default_values {
115+
Statement::Insert {
116+
after_columns,
117+
columns,
118+
on,
119+
partitioned,
120+
returning,
121+
source,
122+
table_name,
123+
..
124+
} => {
125+
assert_eq!(columns, vec![]);
126+
assert_eq!(after_columns, vec![]);
127+
assert_eq!(on, None);
128+
assert_eq!(partitioned, None);
129+
assert_eq!(returning, None);
130+
assert_eq!(source, None);
131+
assert_eq!(table_name, ObjectName(vec!["test_table".into()]));
132+
}
133+
_ => unreachable!(),
134+
}
135+
136+
let insert_with_default_values_and_returning =
137+
verified_stmt("INSERT INTO test_table DEFAULT VALUES RETURNING test_column");
138+
139+
match insert_with_default_values_and_returning {
140+
Statement::Insert {
141+
after_columns,
142+
columns,
143+
on,
144+
partitioned,
145+
returning,
146+
source,
147+
table_name,
148+
..
149+
} => {
150+
assert_eq!(after_columns, vec![]);
151+
assert_eq!(columns, vec![]);
152+
assert_eq!(on, None);
153+
assert_eq!(partitioned, None);
154+
assert!(returning.is_some());
155+
assert_eq!(source, None);
156+
assert_eq!(table_name, ObjectName(vec!["test_table".into()]));
157+
}
158+
_ => unreachable!(),
159+
}
160+
161+
let insert_with_default_values_and_on_conflict =
162+
verified_stmt("INSERT INTO test_table DEFAULT VALUES ON CONFLICT DO NOTHING");
163+
164+
match insert_with_default_values_and_on_conflict {
165+
Statement::Insert {
166+
after_columns,
167+
columns,
168+
on,
169+
partitioned,
170+
returning,
171+
source,
172+
table_name,
173+
..
174+
} => {
175+
assert_eq!(after_columns, vec![]);
176+
assert_eq!(columns, vec![]);
177+
assert!(on.is_some());
178+
assert_eq!(partitioned, None);
179+
assert_eq!(returning, None);
180+
assert_eq!(source, None);
181+
assert_eq!(table_name, ObjectName(vec!["test_table".into()]));
182+
}
183+
_ => unreachable!(),
184+
}
185+
186+
let insert_with_columns_and_default_values = "INSERT INTO test_table (test_col) DEFAULT VALUES";
187+
assert_eq!(
188+
ParserError::ParserError(
189+
"Expected SELECT, VALUES, or a subquery in the query body, found: DEFAULT".to_string()
190+
),
191+
parse_sql_statements(insert_with_columns_and_default_values).unwrap_err()
192+
);
193+
194+
let insert_with_default_values_and_hive_after_columns =
195+
"INSERT INTO test_table DEFAULT VALUES (some_column)";
196+
assert_eq!(
197+
ParserError::ParserError("Expected end of statement, found: (".to_string()),
198+
parse_sql_statements(insert_with_default_values_and_hive_after_columns).unwrap_err()
199+
);
200+
201+
let insert_with_default_values_and_hive_partition =
202+
"INSERT INTO test_table DEFAULT VALUES PARTITION (some_column)";
203+
assert_eq!(
204+
ParserError::ParserError("Expected end of statement, found: PARTITION".to_string()),
205+
parse_sql_statements(insert_with_default_values_and_hive_partition).unwrap_err()
206+
);
207+
208+
let insert_with_default_values_and_values_list = "INSERT INTO test_table DEFAULT VALUES (1)";
209+
assert_eq!(
210+
ParserError::ParserError("Expected end of statement, found: (".to_string()),
211+
parse_sql_statements(insert_with_default_values_and_values_list).unwrap_err()
212+
);
213+
}
214+
110215
#[test]
111216
fn parse_insert_sqlite() {
112217
let dialect = SQLiteDialect {};

tests/sqlparser_mysql.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -941,7 +941,7 @@ fn parse_simple_insert() {
941941
assert_eq!(vec![Ident::new("title"), Ident::new("priority")], columns);
942942
assert!(on.is_none());
943943
assert_eq!(
944-
Box::new(Query {
944+
Some(Box::new(Query {
945945
with: None,
946946
body: Box::new(SetExpr::Values(Values {
947947
explicit_row: false,
@@ -969,7 +969,7 @@ fn parse_simple_insert() {
969969
fetch: None,
970970
locks: vec![],
971971
for_clause: None,
972-
}),
972+
})),
973973
source
974974
);
975975
}
@@ -995,7 +995,7 @@ fn parse_ignore_insert() {
995995
assert!(on.is_none());
996996
assert!(ignore);
997997
assert_eq!(
998-
Box::new(Query {
998+
Some(Box::new(Query {
999999
with: None,
10001000
body: Box::new(SetExpr::Values(Values {
10011001
explicit_row: false,
@@ -1011,7 +1011,7 @@ fn parse_ignore_insert() {
10111011
fetch: None,
10121012
locks: vec![],
10131013
for_clause: None,
1014-
}),
1014+
})),
10151015
source
10161016
);
10171017
}
@@ -1035,7 +1035,7 @@ fn parse_empty_row_insert() {
10351035
assert!(columns.is_empty());
10361036
assert!(on.is_none());
10371037
assert_eq!(
1038-
Box::new(Query {
1038+
Some(Box::new(Query {
10391039
with: None,
10401040
body: Box::new(SetExpr::Values(Values {
10411041
explicit_row: false,
@@ -1048,7 +1048,7 @@ fn parse_empty_row_insert() {
10481048
fetch: None,
10491049
locks: vec![],
10501050
for_clause: None,
1051-
}),
1051+
})),
10521052
source
10531053
);
10541054
}
@@ -1084,7 +1084,7 @@ fn parse_insert_with_on_duplicate_update() {
10841084
columns
10851085
);
10861086
assert_eq!(
1087-
Box::new(Query {
1087+
Some(Box::new(Query {
10881088
with: None,
10891089
body: Box::new(SetExpr::Values(Values {
10901090
explicit_row: false,
@@ -1108,7 +1108,7 @@ fn parse_insert_with_on_duplicate_update() {
11081108
fetch: None,
11091109
locks: vec![],
11101110
for_clause: None,
1111-
}),
1111+
})),
11121112
source
11131113
);
11141114
assert_eq!(

tests/sqlparser_postgres.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1379,7 +1379,7 @@ fn parse_prepare() {
13791379
Statement::Insert {
13801380
table_name,
13811381
columns,
1382-
source,
1382+
source: Some(source),
13831383
..
13841384
} => {
13851385
assert_eq!(table_name.to_string(), "customers");

0 commit comments

Comments
 (0)