finchxxia commented on code in PR #2148:
URL:
https://github.com/apache/datafusion-sqlparser-rs/pull/2148#discussion_r2719679405
##########
src/dialect/snowflake.rs:
##########
@@ -1628,3 +1654,173 @@ fn parse_show_objects(terse: bool, parser: &mut Parser)
-> Result<Statement, Par
show_options,
}))
}
+
+/// Parse multi-table INSERT statement.
+///
+/// Syntax:
+/// ```sql
+/// -- Unconditional multi-table insert
+/// INSERT [ OVERWRITE ] ALL
+/// intoClause [ ... ]
+/// <subquery>
+///
+/// -- Conditional multi-table insert
+/// INSERT [ OVERWRITE ] { FIRST | ALL }
+/// { WHEN <condition> THEN intoClause [ ... ] }
+/// [ ... ]
+/// [ ELSE intoClause ]
+/// <subquery>
+/// ```
+///
+/// See: <https://docs.snowflake.com/en/sql-reference/sql/insert-multi-table>
+fn parse_multi_table_insert(
+ parser: &mut Parser,
+ insert_token: TokenWithSpan,
+ overwrite: bool,
+ insert_first: bool,
+) -> Result<Statement, ParserError> {
+ // Check if this is conditional (has WHEN clauses) or unconditional
(direct INTO clauses)
+ let is_conditional = parser.peek_keyword(Keyword::WHEN);
+
+ let (multi_table_into_clauses, multi_table_when_clauses,
multi_table_else_clause) =
+ if is_conditional {
+ // Conditional multi-table insert: WHEN clauses
+ let (when_clauses, else_clause) =
parse_multi_table_insert_when_clauses(parser)?;
+ (vec![], when_clauses, else_clause)
+ } else {
+ // Unconditional multi-table insert: direct INTO clauses
+ let into_clauses = parse_multi_table_insert_into_clauses(parser)?;
+ (into_clauses, vec![], None)
+ };
+
+ // Parse the source query
+ let source = parser.parse_query()?;
+
+ Ok(Statement::Insert(Insert {
+ insert_token: insert_token.into(),
+ or: None,
+ ignore: false,
+ into: false,
+ table: TableObject::TableName(ObjectName(vec![])), // Not used for
multi-table insert
+ table_alias: None,
+ columns: vec![],
+ overwrite,
+ source: Some(source),
+ assignments: vec![],
+ partitioned: None,
+ after_columns: vec![],
+ has_table_keyword: false,
+ on: None,
+ returning: None,
+ replace_into: false,
+ priority: None,
+ insert_alias: None,
+ settings: None,
+ format_clause: None,
+ insert_first,
+ multi_table_into_clauses,
+ multi_table_when_clauses,
+ multi_table_else_clause,
+ }))
+}
+
+/// Parse one or more INTO clauses for multi-table INSERT.
+fn parse_multi_table_insert_into_clauses(
+ parser: &mut Parser,
+) -> Result<Vec<MultiTableInsertIntoClause>, ParserError> {
+ let mut into_clauses = vec![];
+ while parser.parse_keyword(Keyword::INTO) {
+ into_clauses.push(parse_multi_table_insert_into_clause(parser)?);
+ }
+ if into_clauses.is_empty() {
+ return parser.expected("INTO clause in multi-table INSERT",
parser.peek_token());
+ }
+ Ok(into_clauses)
+}
+
+/// Parse a single INTO clause for multi-table INSERT.
+///
+/// Syntax: `INTO <table> [ ( <columns> ) ] [ VALUES ( <values> ) ]`
+fn parse_multi_table_insert_into_clause(
+ parser: &mut Parser,
+) -> Result<MultiTableInsertIntoClause, ParserError> {
+ let table_name = parser.parse_object_name(false)?;
+
+ // Parse optional column list
+ let columns = if parser.peek_token() == Token::LParen &&
!parser.peek_keyword(Keyword::VALUES) {
Review Comment:
> It looks like this and the nested if statement can be collapsed to `if
self.consume_token(LParen)`?
I found another function `parse_parenthesized_column_list` which can be
simplier to solve it.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]