This is an automated email from the ASF dual-hosted git repository.

github-bot pushed a commit to branch 
gh-readonly-queue/main/pr-2260-1da2ff779c0e71932fc882fe7ae4e6d674b8cc76
in repository https://gitbox.apache.org/repos/asf/datafusion-sqlparser-rs.git

commit 255e50cfaf56d5eb20e3dc05cfbc618ecfd4b1eb
Author: xitep <[email protected]>
AuthorDate: Wed Mar 4 11:02:34 2026 +0100

    Allow INSERT columns to be qualified (#2260)
---
 src/ast/dml.rs              |  2 +-
 src/ast/spans.rs            |  2 +-
 src/parser/mod.rs           |  3 +-
 tests/sqlparser_common.rs   |  5 +++-
 tests/sqlparser_mysql.rs    | 67 +++++++++++++++++++++++++++++++++++----------
 tests/sqlparser_oracle.rs   | 15 ++++++++++
 tests/sqlparser_postgres.rs | 24 ++++++++--------
 7 files changed, 88 insertions(+), 30 deletions(-)

diff --git a/src/ast/dml.rs b/src/ast/dml.rs
index e2c48885..446d44b2 100644
--- a/src/ast/dml.rs
+++ b/src/ast/dml.rs
@@ -61,7 +61,7 @@ pub struct Insert {
     /// `table_name foo` (for Oracle)
     pub table_alias: Option<TableAliasWithoutColumns>,
     /// COLUMNS
-    pub columns: Vec<Ident>,
+    pub columns: Vec<ObjectName>,
     /// Overwrite (Hive)
     pub overwrite: bool,
     /// A SQL query that specifies what to insert
diff --git a/src/ast/spans.rs b/src/ast/spans.rs
index 7c075197..3f73af40 100644
--- a/src/ast/spans.rs
+++ b/src/ast/spans.rs
@@ -1335,7 +1335,7 @@ impl Spanned for Insert {
             core::iter::once(insert_token.0.span)
                 .chain(core::iter::once(table.span()))
                 .chain(table_alias.iter().map(|k| k.alias.span))
-                .chain(columns.iter().map(|i| i.span))
+                .chain(columns.iter().map(|i| i.span()))
                 .chain(source.as_ref().map(|q| q.span()))
                 .chain(assignments.iter().map(|i| i.span()))
                 .chain(partitioned.iter().flat_map(|i| i.iter().map(|k| 
k.span())))
diff --git a/src/parser/mod.rs b/src/parser/mod.rs
index 2749969c..7764fab2 100644
--- a/src/parser/mod.rs
+++ b/src/parser/mod.rs
@@ -17319,7 +17319,8 @@ impl<'a> Parser<'a> {
                 (vec![], None, vec![], None, None, vec![])
             } else {
                 let (columns, partitioned, after_columns) = if 
!self.peek_subquery_start() {
-                    let columns = 
self.parse_parenthesized_column_list(Optional, is_mysql)?;
+                    let columns =
+                        
self.parse_parenthesized_qualified_column_list(Optional, is_mysql)?;
 
                     let partitioned = self.parse_insert_partition()?;
                     // Hive allows you to specify columns after partitions as 
well if you want.
diff --git a/tests/sqlparser_common.rs b/tests/sqlparser_common.rs
index 7bf27640..a59e3b96 100644
--- a/tests/sqlparser_common.rs
+++ b/tests/sqlparser_common.rs
@@ -153,7 +153,10 @@ fn parse_insert_values() {
                 assert_eq!(table_name.to_string(), expected_table_name);
                 assert_eq!(columns.len(), expected_columns.len());
                 for (index, column) in columns.iter().enumerate() {
-                    assert_eq!(column, 
&Ident::new(expected_columns[index].clone()));
+                    assert_eq!(
+                        column,
+                        
&ObjectName::from(Ident::new(expected_columns[index].clone()))
+                    );
                 }
                 match *source.body {
                     SetExpr::Values(Values {
diff --git a/tests/sqlparser_mysql.rs b/tests/sqlparser_mysql.rs
index 541f7df6..6c59997c 100644
--- a/tests/sqlparser_mysql.rs
+++ b/tests/sqlparser_mysql.rs
@@ -1913,7 +1913,13 @@ fn parse_simple_insert() {
                 
TableObject::TableName(ObjectName::from(vec![Ident::new("tasks")])),
                 table_name
             );
-            assert_eq!(vec![Ident::new("title"), Ident::new("priority")], 
columns);
+            assert_eq!(
+                vec![
+                    ObjectName::from(Ident::new("title")),
+                    ObjectName::from(Ident::new("priority"))
+                ],
+                columns
+            );
             assert!(on.is_none());
             assert_eq!(
                 Some(Box::new(Query {
@@ -1978,7 +1984,13 @@ fn parse_ignore_insert() {
                 
TableObject::TableName(ObjectName::from(vec![Ident::new("tasks")])),
                 table_name
             );
-            assert_eq!(vec![Ident::new("title"), Ident::new("priority")], 
columns);
+            assert_eq!(
+                vec![
+                    ObjectName::from(Ident::new("title")),
+                    ObjectName::from(Ident::new("priority"))
+                ],
+                columns
+            );
             assert!(on.is_none());
             assert!(ignore);
             assert_eq!(
@@ -2028,7 +2040,13 @@ fn parse_priority_insert() {
                 
TableObject::TableName(ObjectName::from(vec![Ident::new("tasks")])),
                 table_name
             );
-            assert_eq!(vec![Ident::new("title"), Ident::new("priority")], 
columns);
+            assert_eq!(
+                vec![
+                    ObjectName::from(Ident::new("title")),
+                    ObjectName::from(Ident::new("priority"))
+                ],
+                columns
+            );
             assert!(on.is_none());
             assert_eq!(priority, Some(HighPriority));
             assert_eq!(
@@ -2075,7 +2093,13 @@ fn parse_priority_insert() {
                 
TableObject::TableName(ObjectName::from(vec![Ident::new("tasks")])),
                 table_name
             );
-            assert_eq!(vec![Ident::new("title"), Ident::new("priority")], 
columns);
+            assert_eq!(
+                vec![
+                    ObjectName::from(Ident::new("title")),
+                    ObjectName::from(Ident::new("priority"))
+                ],
+                columns
+            );
             assert!(on.is_none());
             assert_eq!(priority, Some(LowPriority));
             assert_eq!(
@@ -2123,7 +2147,10 @@ fn parse_insert_as() {
                 
TableObject::TableName(ObjectName::from(vec![Ident::with_quote('`', "table")])),
                 table_name
             );
-            assert_eq!(vec![Ident::with_quote('`', "date")], columns);
+            assert_eq!(
+                vec![ObjectName::from(Ident::with_quote('`', "date"))],
+                columns
+            );
             let insert_alias = insert_alias.unwrap();
 
             assert_eq!(
@@ -2176,7 +2203,10 @@ fn parse_insert_as() {
                 table_name
             );
             assert_eq!(
-                vec![Ident::with_quote('`', "id"), Ident::with_quote('`', 
"date")],
+                vec![
+                    ObjectName::from(Ident::with_quote('`', "id")),
+                    ObjectName::from(Ident::with_quote('`', "date"))
+                ],
                 columns
             );
             let insert_alias = insert_alias.unwrap();
@@ -2238,7 +2268,13 @@ fn parse_replace_insert() {
                 
TableObject::TableName(ObjectName::from(vec![Ident::new("tasks")])),
                 table_name
             );
-            assert_eq!(vec![Ident::new("title"), Ident::new("priority")], 
columns);
+            assert_eq!(
+                vec![
+                    ObjectName::from(Ident::new("title")),
+                    ObjectName::from(Ident::new("priority"))
+                ],
+                columns
+            );
             assert!(on.is_none());
             assert!(replace_into);
             assert_eq!(priority, Some(Delayed));
@@ -2332,12 +2368,12 @@ fn parse_insert_with_on_duplicate_update() {
             );
             assert_eq!(
                 vec![
-                    Ident::new("name"),
-                    Ident::new("description"),
-                    Ident::new("perm_create"),
-                    Ident::new("perm_read"),
-                    Ident::new("perm_update"),
-                    Ident::new("perm_delete")
+                    ObjectName::from(Ident::new("name")),
+                    ObjectName::from(Ident::new("description")),
+                    ObjectName::from(Ident::new("perm_create")),
+                    ObjectName::from(Ident::new("perm_read")),
+                    ObjectName::from(Ident::new("perm_update")),
+                    ObjectName::from(Ident::new("perm_delete"))
                 ],
                 columns
             );
@@ -2651,7 +2687,10 @@ fn parse_insert_with_numeric_prefix_column_name() {
                 TableObject::TableName(ObjectName::from(vec![Ident::new("s1"), 
Ident::new("t1")])),
                 table_name
             );
-            assert_eq!(vec![Ident::new("123col_$@length123")], columns);
+            assert_eq!(
+                vec![ObjectName::from(Ident::new("123col_$@length123"))],
+                columns
+            );
         }
         _ => unreachable!(),
     }
diff --git a/tests/sqlparser_oracle.rs b/tests/sqlparser_oracle.rs
index b34a9308..35f08311 100644
--- a/tests/sqlparser_oracle.rs
+++ b/tests/sqlparser_oracle.rs
@@ -475,6 +475,21 @@ fn test_insert_with_table_alias() {
          VALUES (1, 2, 3)",
     );
     verify_table_name_with_alias(&stmt, "foo_t", "t");
+
+    let stmt =
+        oracle_dialect.verified_stmt("INSERT INTO foo_t t (t.id, t.val) SELECT 
1, 2 FROM dual");
+    verify_table_name_with_alias(&stmt, "foo_t", "t");
+    if let Statement::Insert(Insert { columns, .. }) = stmt {
+        assert_eq!(
+            vec![
+                ObjectName::from(vec![Ident::new("t"), Ident::new("id")]),
+                ObjectName::from(vec![Ident::new("t"), Ident::new("val")])
+            ],
+            columns
+        );
+    } else {
+        panic!("not an insert statement");
+    };
 }
 
 #[test]
diff --git a/tests/sqlparser_postgres.rs b/tests/sqlparser_postgres.rs
index 7dd624a2..ecf7b6bf 100644
--- a/tests/sqlparser_postgres.rs
+++ b/tests/sqlparser_postgres.rs
@@ -5493,16 +5493,16 @@ fn test_simple_postgres_insert_with_alias() {
                 }
             }),
             columns: vec![
-                Ident {
+                ObjectName::from(Ident {
                     value: "id".to_string(),
                     quote_style: None,
                     span: Span::empty(),
-                },
-                Ident {
+                }),
+                ObjectName::from(Ident {
                     value: "a".to_string(),
                     quote_style: None,
                     span: Span::empty(),
-                }
+                })
             ],
             overwrite: false,
             source: Some(Box::new(Query {
@@ -5573,16 +5573,16 @@ fn test_simple_postgres_insert_with_alias() {
                 }
             }),
             columns: vec![
-                Ident {
+                ObjectName::from(Ident {
                     value: "id".to_string(),
                     quote_style: None,
                     span: Span::empty(),
-                },
-                Ident {
+                }),
+                ObjectName::from(Ident {
                     value: "a".to_string(),
                     quote_style: None,
                     span: Span::empty(),
-                }
+                })
             ],
             overwrite: false,
             source: Some(Box::new(Query {
@@ -5655,16 +5655,16 @@ fn test_simple_insert_with_quoted_alias() {
                 }
             }),
             columns: vec![
-                Ident {
+                ObjectName::from(Ident {
                     value: "id".to_string(),
                     quote_style: None,
                     span: Span::empty(),
-                },
-                Ident {
+                }),
+                ObjectName::from(Ident {
                     value: "a".to_string(),
                     quote_style: None,
                     span: Span::empty(),
-                }
+                })
             ],
             overwrite: false,
             source: Some(Box::new(Query {


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to