Parse `INSERT` with subquery when lacking column names (#1586)
diff --git a/src/parser/mod.rs b/src/parser/mod.rs
index e47e71b..04d6edc 100644
--- a/src/parser/mod.rs
+++ b/src/parser/mod.rs
@@ -11329,14 +11329,19 @@
if self.parse_keywords(&[Keyword::DEFAULT, Keyword::VALUES]) {
(vec![], None, vec![], None)
} else {
- let columns = self.parse_parenthesized_column_list(Optional, is_mysql)?;
+ let (columns, partitioned, after_columns) = if !self.peek_subquery_start() {
+ let columns = self.parse_parenthesized_column_list(Optional, is_mysql)?;
- let partitioned = self.parse_insert_partition()?;
- // Hive allows you to specify columns after partitions as well if you want.
- let after_columns = if dialect_of!(self is HiveDialect) {
- self.parse_parenthesized_column_list(Optional, false)?
+ let partitioned = self.parse_insert_partition()?;
+ // Hive allows you to specify columns after partitions as well if you want.
+ let after_columns = if dialect_of!(self is HiveDialect) {
+ self.parse_parenthesized_column_list(Optional, false)?
+ } else {
+ vec![]
+ };
+ (columns, partitioned, after_columns)
} else {
- vec![]
+ Default::default()
};
let source = Some(self.parse_query()?);
@@ -11431,6 +11436,14 @@
}
}
+ /// Returns true if the immediate tokens look like the
+ /// beginning of a subquery. `(SELECT ...`
+ fn peek_subquery_start(&mut self) -> bool {
+ let [maybe_lparen, maybe_select] = self.peek_tokens();
+ Token::LParen == maybe_lparen
+ && matches!(maybe_select, Token::Word(w) if w.keyword == Keyword::SELECT)
+ }
+
fn parse_conflict_clause(&mut self) -> Option<SqliteOnConflict> {
if self.parse_keywords(&[Keyword::OR, Keyword::REPLACE]) {
Some(SqliteOnConflict::Replace)
diff --git a/tests/sqlparser_common.rs b/tests/sqlparser_common.rs
index 42616d5..f76516e 100644
--- a/tests/sqlparser_common.rs
+++ b/tests/sqlparser_common.rs
@@ -10964,6 +10964,8 @@
Box::new(GenericDialect {}),
]);
dialects.verified_stmt("INSERT INTO t1 (id, name) (SELECT t2.id, t2.name FROM t2)");
+ dialects.verified_stmt("INSERT INTO t1 (SELECT t2.id, t2.name FROM t2)");
+ dialects.verified_stmt(r#"INSERT INTO t1 ("select", name) (SELECT t2.name FROM t2)"#);
}
#[test]