Skip to content

Commit 095d108

Browse files
committed
Support INSERT INTO ... DEFAULT VALUES ...
1 parent 4cdaa40 commit 095d108

File tree

5 files changed

+99
-15
lines changed

5 files changed

+99
-15
lines changed

src/ast/mod.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1385,7 +1385,7 @@ pub enum Statement {
13851385
/// Overwrite (Hive)
13861386
overwrite: bool,
13871387
/// A SQL query that specifies what to insert
1388-
source: Box<Query>,
1388+
source: Option<Box<Query>>,
13891389
/// partitioned insert (Hive)
13901390
partitioned: Option<Vec<Expr>>,
13911391
/// Columns defined after PARTITION
@@ -2241,7 +2241,14 @@ impl fmt::Display for Statement {
22412241
if !after_columns.is_empty() {
22422242
write!(f, "({}) ", display_comma_separated(after_columns))?;
22432243
}
2244-
write!(f, "{source}")?;
2244+
2245+
if let Some(source) = source {
2246+
write!(f, "{source}")?;
2247+
}
2248+
2249+
if source.is_none() && columns.is_empty() {
2250+
write!(f, "DEFAULT VALUES")?;
2251+
}
22452252

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

src/parser/mod.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7090,7 +7090,14 @@ impl<'a> Parser<'a> {
70907090
let table = self.parse_keyword(Keyword::TABLE);
70917091
let table_name = self.parse_object_name()?;
70927092
let is_mysql = dialect_of!(self is MySqlDialect);
7093-
let columns = self.parse_parenthesized_column_list(Optional, is_mysql)?;
7093+
7094+
let is_default_values = self.parse_keywords(&[Keyword::DEFAULT, Keyword::VALUES]);
7095+
7096+
let columns = if is_default_values {
7097+
vec![]
7098+
} else {
7099+
self.parse_parenthesized_column_list(Optional, is_mysql)?
7100+
};
70947101

70957102
let partitioned = if self.parse_keyword(Keyword::PARTITION) {
70967103
self.expect_token(&Token::LParen)?;
@@ -7104,7 +7111,12 @@ impl<'a> Parser<'a> {
71047111
// Hive allows you to specify columns after partitions as well if you want.
71057112
let after_columns = self.parse_parenthesized_column_list(Optional, false)?;
71067113

7107-
let source = Box::new(self.parse_query()?);
7114+
let source = if is_default_values {
7115+
None
7116+
} else {
7117+
Some(Box::new(self.parse_query()?))
7118+
};
7119+
71087120
let on = if self.parse_keyword(Keyword::ON) {
71097121
if self.parse_keyword(Keyword::CONFLICT) {
71107122
let conflict_target =

tests/sqlparser_common.rs

Lines changed: 67 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,71 @@ 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+
columns,
117+
on,
118+
returning,
119+
source,
120+
table_name,
121+
..
122+
} => {
123+
assert_eq!(columns, vec![]);
124+
assert_eq!(on, None);
125+
assert_eq!(returning, None);
126+
assert_eq!(source, None);
127+
assert_eq!(table_name, ObjectName(vec!["test_table".into()]));
128+
}
129+
_ => unreachable!(),
130+
}
131+
132+
let insert_with_default_values_and_returning =
133+
verified_stmt("INSERT INTO test_table DEFAULT VALUES RETURNING test_column");
134+
135+
match insert_with_default_values_and_returning {
136+
Statement::Insert {
137+
columns,
138+
on,
139+
returning,
140+
source,
141+
table_name,
142+
..
143+
} => {
144+
assert_eq!(columns, vec![]);
145+
assert_eq!(on, None);
146+
assert!(returning.is_some());
147+
assert_eq!(source, None);
148+
assert_eq!(table_name, ObjectName(vec!["test_table".into()]));
149+
}
150+
_ => unreachable!(),
151+
}
152+
153+
let insert_with_default_values_and_on_conflict =
154+
verified_stmt("INSERT INTO test_table DEFAULT VALUES ON CONFLICT DO NOTHING");
155+
156+
match insert_with_default_values_and_on_conflict {
157+
Statement::Insert {
158+
columns,
159+
on,
160+
returning,
161+
source,
162+
table_name,
163+
..
164+
} => {
165+
assert_eq!(columns, vec![]);
166+
assert!(on.is_some());
167+
assert_eq!(returning, None);
168+
assert_eq!(source, None);
169+
assert_eq!(table_name, ObjectName(vec!["test_table".into()]));
170+
}
171+
_ => unreachable!(),
172+
}
173+
}
174+
110175
#[test]
111176
fn parse_insert_sqlite() {
112177
let dialect = SQLiteDialect {};

tests/sqlparser_mysql.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -937,7 +937,7 @@ fn parse_simple_insert() {
937937
assert_eq!(vec![Ident::new("title"), Ident::new("priority")], columns);
938938
assert!(on.is_none());
939939
assert_eq!(
940-
Box::new(Query {
940+
Some(Box::new(Query {
941941
with: None,
942942
body: Box::new(SetExpr::Values(Values {
943943
explicit_row: false,
@@ -964,7 +964,7 @@ fn parse_simple_insert() {
964964
offset: None,
965965
fetch: None,
966966
locks: vec![],
967-
}),
967+
})),
968968
source
969969
);
970970
}
@@ -990,7 +990,7 @@ fn parse_ignore_insert() {
990990
assert!(on.is_none());
991991
assert!(ignore);
992992
assert_eq!(
993-
Box::new(Query {
993+
Some(Box::new(Query {
994994
with: None,
995995
body: Box::new(SetExpr::Values(Values {
996996
explicit_row: false,
@@ -1005,7 +1005,7 @@ fn parse_ignore_insert() {
10051005
offset: None,
10061006
fetch: None,
10071007
locks: vec![]
1008-
}),
1008+
})),
10091009
source
10101010
);
10111011
}
@@ -1029,7 +1029,7 @@ fn parse_empty_row_insert() {
10291029
assert!(columns.is_empty());
10301030
assert!(on.is_none());
10311031
assert_eq!(
1032-
Box::new(Query {
1032+
Some(Box::new(Query {
10331033
with: None,
10341034
body: Box::new(SetExpr::Values(Values {
10351035
explicit_row: false,
@@ -1041,7 +1041,7 @@ fn parse_empty_row_insert() {
10411041
offset: None,
10421042
fetch: None,
10431043
locks: vec![],
1044-
}),
1044+
})),
10451045
source
10461046
);
10471047
}
@@ -1077,7 +1077,7 @@ fn parse_insert_with_on_duplicate_update() {
10771077
columns
10781078
);
10791079
assert_eq!(
1080-
Box::new(Query {
1080+
Some(Box::new(Query {
10811081
with: None,
10821082
body: Box::new(SetExpr::Values(Values {
10831083
explicit_row: false,
@@ -1100,7 +1100,7 @@ fn parse_insert_with_on_duplicate_update() {
11001100
offset: None,
11011101
fetch: None,
11021102
locks: vec![],
1103-
}),
1103+
})),
11041104
source
11051105
);
11061106
assert_eq!(

tests/sqlparser_postgres.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1372,7 +1372,7 @@ fn parse_prepare() {
13721372
Statement::Insert {
13731373
table_name,
13741374
columns,
1375-
source,
1375+
source: Some(source),
13761376
..
13771377
} => {
13781378
assert_eq!(table_name.to_string(), "customers");

0 commit comments

Comments
 (0)