Skip to content

Commit 4f334bd

Browse files
committed
Fix bug where columns could be listed after DEFAULT VALUES
Fix a bug where parsing `DEFAULT VALUES` in inserts didn't consider Hive syntax for partitions and columns. Also add tests for syntax errors when using `DEFAULT VALUES`.
1 parent 095d108 commit 4f334bd

File tree

2 files changed

+62
-21
lines changed

2 files changed

+62
-21
lines changed

src/parser/mod.rs

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -7091,31 +7091,21 @@ impl<'a> Parser<'a> {
70917091
let table_name = self.parse_object_name()?;
70927092
let is_mysql = dialect_of!(self is MySqlDialect);
70937093

7094-
let is_default_values = self.parse_keywords(&[Keyword::DEFAULT, Keyword::VALUES]);
7094+
let (columns, partitioned, after_columns, source) =
7095+
if self.parse_keywords(&[Keyword::DEFAULT, Keyword::VALUES]) {
7096+
(vec![], None, vec![], None)
7097+
} else {
7098+
let columns = self.parse_parenthesized_column_list(Optional, is_mysql)?;
70957099

7096-
let columns = if is_default_values {
7097-
vec![]
7098-
} else {
7099-
self.parse_parenthesized_column_list(Optional, is_mysql)?
7100-
};
7100+
let partitioned = self.parse_insert_partition()?;
71017101

7102-
let partitioned = if self.parse_keyword(Keyword::PARTITION) {
7103-
self.expect_token(&Token::LParen)?;
7104-
let r = Some(self.parse_comma_separated(Parser::parse_expr)?);
7105-
self.expect_token(&Token::RParen)?;
7106-
r
7107-
} else {
7108-
None
7109-
};
7102+
// Hive allows you to specify columns after partitions as well if you want.
7103+
let after_columns = self.parse_parenthesized_column_list(Optional, false)?;
71107104

7111-
// Hive allows you to specify columns after partitions as well if you want.
7112-
let after_columns = self.parse_parenthesized_column_list(Optional, false)?;
7105+
let source = Some(Box::new(self.parse_query()?));
71137106

7114-
let source = if is_default_values {
7115-
None
7116-
} else {
7117-
Some(Box::new(self.parse_query()?))
7118-
};
7107+
(columns, partitioned, after_columns, source)
7108+
};
71197109

71207110
let on = if self.parse_keyword(Keyword::ON) {
71217111
if self.parse_keyword(Keyword::CONFLICT) {
@@ -7187,6 +7177,17 @@ impl<'a> Parser<'a> {
71877177
}
71887178
}
71897179

7180+
pub fn parse_insert_partition(&mut self) -> Result<Option<Vec<Expr>>, ParserError> {
7181+
if self.parse_keyword(Keyword::PARTITION) {
7182+
self.expect_token(&Token::LParen)?;
7183+
let partition_cols = Some(self.parse_comma_separated(Parser::parse_expr)?);
7184+
self.expect_token(&Token::RParen)?;
7185+
Ok(partition_cols)
7186+
} else {
7187+
Ok(None)
7188+
}
7189+
}
7190+
71907191
pub fn parse_update(&mut self) -> Result<Statement, ParserError> {
71917192
let table = self.parse_table_and_joins()?;
71927193
self.expect_keyword(Keyword::SET)?;

tests/sqlparser_common.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,15 +113,19 @@ fn parse_insert_default_values() {
113113

114114
match insert_with_default_values {
115115
Statement::Insert {
116+
after_columns,
116117
columns,
117118
on,
119+
partitioned,
118120
returning,
119121
source,
120122
table_name,
121123
..
122124
} => {
123125
assert_eq!(columns, vec![]);
126+
assert_eq!(after_columns, vec![]);
124127
assert_eq!(on, None);
128+
assert_eq!(partitioned, None);
125129
assert_eq!(returning, None);
126130
assert_eq!(source, None);
127131
assert_eq!(table_name, ObjectName(vec!["test_table".into()]));
@@ -134,15 +138,19 @@ fn parse_insert_default_values() {
134138

135139
match insert_with_default_values_and_returning {
136140
Statement::Insert {
141+
after_columns,
137142
columns,
138143
on,
144+
partitioned,
139145
returning,
140146
source,
141147
table_name,
142148
..
143149
} => {
150+
assert_eq!(after_columns, vec![]);
144151
assert_eq!(columns, vec![]);
145152
assert_eq!(on, None);
153+
assert_eq!(partitioned, None);
146154
assert!(returning.is_some());
147155
assert_eq!(source, None);
148156
assert_eq!(table_name, ObjectName(vec!["test_table".into()]));
@@ -155,21 +163,53 @@ fn parse_insert_default_values() {
155163

156164
match insert_with_default_values_and_on_conflict {
157165
Statement::Insert {
166+
after_columns,
158167
columns,
159168
on,
169+
partitioned,
160170
returning,
161171
source,
162172
table_name,
163173
..
164174
} => {
175+
assert_eq!(after_columns, vec![]);
165176
assert_eq!(columns, vec![]);
166177
assert!(on.is_some());
178+
assert_eq!(partitioned, None);
167179
assert_eq!(returning, None);
168180
assert_eq!(source, None);
169181
assert_eq!(table_name, ObjectName(vec!["test_table".into()]));
170182
}
171183
_ => unreachable!(),
172184
}
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+
);
173213
}
174214

175215
#[test]

0 commit comments

Comments
 (0)