STET

agent_patch

runs/2026-02-28__18-27-22__gpt-5-3-codex/flux-pr-1628/flux-pr-1628.1-of-1.2026-02-28__18-27-22__gpt-5-3-codex/agent-logs/agent.patch

10320 bytes

Back to adjudication
diff --git a/tmp/agent-patch-flux-pr-1628.1-of-1.2026-02-28__18-27-22__gpt-5-3-codex/app/src/ast/dml.rs b/app/src/ast/dml.rs
index d68a227..1da8121 100644
--- a/tmp/agent-patch-flux-pr-1628.1-of-1.2026-02-28__18-27-22__gpt-5-3-codex/app/src/ast/dml.rs
+++ b/app/src/ast/dml.rs
@@ -33,10 +33,10 @@ pub use super::ddl::{ColumnDef, TableConstraint};
 
 use super::{
     display_comma_separated, display_separated, Assignment, ClusteredBy, CommentDef, Expr,
-    FileFormat, FromTable, HiveDistributionStyle, HiveFormat, HiveIOFormat, HiveRowFormat, Ident,
-    InsertAliases, MysqlInsertPriority, ObjectName, OnCommit, OnInsert, OneOrManyWithParens,
-    OrderByExpr, Query, RowAccessPolicy, SelectItem, SqlOption, SqliteOnConflict, TableEngine,
-    TableObject, TableWithJoins, Tag, WrappedCollection,
+    FileFormat, FormatClause, FromTable, HiveDistributionStyle, HiveFormat, HiveIOFormat,
+    HiveRowFormat, Ident, InsertAliases, MysqlInsertPriority, ObjectName, OnCommit, OnInsert,
+    OneOrManyWithParens, OrderByExpr, Query, RowAccessPolicy, SelectItem, Setting, SqlOption,
+    SqliteOnConflict, TableEngine, TableObject, TableWithJoins, Tag, WrappedCollection,
 };
 
 /// CREATE INDEX statement.
@@ -479,6 +479,10 @@ pub struct Insert {
     pub overwrite: bool,
     /// A SQL query that specifies what to insert
     pub source: Option<Box<Query>>,
+    /// ClickHouse `SETTINGS` clause.
+    pub settings: Option<Vec<Setting>>,
+    /// ClickHouse `FORMAT` clause.
+    pub format_clause: Option<FormatClause>,
     /// MySQL `INSERT INTO ... SET`
     /// See: <https://dev.mysql.com/doc/refman/8.4/en/insert.html>
     pub assignments: Vec<Assignment>,
@@ -544,6 +548,9 @@ impl Display for Insert {
         if !self.after_columns.is_empty() {
             write!(f, "({}) ", display_comma_separated(&self.after_columns))?;
         }
+        if let Some(ref settings) = self.settings {
+            write!(f, "SETTINGS {} ", display_comma_separated(settings))?;
+        }
 
         if let Some(source) = &self.source {
             write!(f, "{source}")?;
@@ -553,6 +560,9 @@ impl Display for Insert {
         } else if self.source.is_none() && self.columns.is_empty() {
             write!(f, "DEFAULT VALUES")?;
         }
+        if let Some(ref format) = self.format_clause {
+            write!(f, " {}", format)?;
+        }
 
         if let Some(insert_alias) = &self.insert_alias {
             write!(f, " AS {0}", insert_alias.row_alias)?;
diff --git a/tmp/agent-patch-flux-pr-1628.1-of-1.2026-02-28__18-27-22__gpt-5-3-codex/app/src/ast/spans.rs b/app/src/ast/spans.rs
index 8a27c4a..452fecd 100644
--- a/tmp/agent-patch-flux-pr-1628.1-of-1.2026-02-28__18-27-22__gpt-5-3-codex/app/src/ast/spans.rs
+++ b/app/src/ast/spans.rs
@@ -1136,6 +1136,8 @@ impl Spanned for AlterIndexOperation {
 ///
 /// Missing spans:ever
 /// - [Insert::insert_alias]
+/// - [Insert::settings]
+/// - [Insert::format_clause]
 impl Spanned for Insert {
     fn span(&self) -> Span {
         let Insert {
@@ -1147,6 +1149,8 @@ impl Spanned for Insert {
             columns,
             overwrite: _, // bool
             source,
+            settings: _,
+            format_clause: _,
             partitioned,
             after_columns,
             has_table_keyword: _, // bool
diff --git a/tmp/agent-patch-flux-pr-1628.1-of-1.2026-02-28__18-27-22__gpt-5-3-codex/app/src/parser/mod.rs b/app/src/parser/mod.rs
index b6e3fd1..206636e 100644
--- a/tmp/agent-patch-flux-pr-1628.1-of-1.2026-02-28__18-27-22__gpt-5-3-codex/app/src/parser/mod.rs
+++ b/app/src/parser/mod.rs
@@ -9699,18 +9699,7 @@ impl<'a> Parser<'a> {
                     locks.push(self.parse_lock()?);
                 }
             }
-            let format_clause = if dialect_of!(self is ClickHouseDialect | GenericDialect)
-                && self.parse_keyword(Keyword::FORMAT)
-            {
-                if self.parse_keyword(Keyword::NULL) {
-                    Some(FormatClause::Null)
-                } else {
-                    let ident = self.parse_identifier()?;
-                    Some(FormatClause::Identifier(ident))
-                }
-            } else {
-                None
-            };
+            let format_clause = self.parse_format_clause()?;
 
             Ok(Query {
                 with,
@@ -9746,6 +9735,22 @@ impl<'a> Parser<'a> {
         Ok(settings)
     }
 
+    fn parse_format_clause(&mut self) -> Result<Option<FormatClause>, ParserError> {
+        let format_clause = if dialect_of!(self is ClickHouseDialect | GenericDialect)
+            && self.parse_keyword(Keyword::FORMAT)
+        {
+            if self.parse_keyword(Keyword::NULL) {
+                Some(FormatClause::Null)
+            } else {
+                let ident = self.parse_identifier()?;
+                Some(FormatClause::Identifier(ident))
+            }
+        } else {
+            None
+        };
+        Ok(format_clause)
+    }
+
     /// Parse a mssql `FOR [XML | JSON | BROWSE]` clause
     pub fn parse_for_clause(&mut self) -> Result<Option<ForClause>, ParserError> {
         if self.parse_keyword(Keyword::XML) {
@@ -12033,9 +12038,9 @@ impl<'a> Parser<'a> {
 
             let is_mysql = dialect_of!(self is MySqlDialect);
 
-            let (columns, partitioned, after_columns, source, assignments) =
+            let (columns, partitioned, after_columns, source, settings, format_clause, assignments) =
                 if self.parse_keywords(&[Keyword::DEFAULT, Keyword::VALUES]) {
-                    (vec![], None, vec![], None, vec![])
+                    (vec![], None, vec![], None, None, None, vec![])
                 } else {
                     let (columns, partitioned, after_columns) = if !self.peek_subquery_start() {
                         let columns = self.parse_parenthesized_column_list(Optional, is_mysql)?;
@@ -12052,14 +12057,30 @@ impl<'a> Parser<'a> {
                         Default::default()
                     };
 
-                    let (source, assignments) =
-                        if self.dialect.supports_insert_set() && self.parse_keyword(Keyword::SET) {
-                            (None, self.parse_comma_separated(Parser::parse_assignment)?)
+                    let (source, settings, format_clause, assignments) = if self
+                        .dialect
+                        .supports_insert_set()
+                        && self.parse_keyword(Keyword::SET)
+                    {
+                        (None, None, None, self.parse_comma_separated(Parser::parse_assignment)?)
+                    } else {
+                        let settings = self.parse_settings()?;
+                        if let Some(format_clause) = self.parse_format_clause()? {
+                            (None, settings, Some(format_clause), vec![])
                         } else {
-                            (Some(self.parse_query()?), vec![])
-                        };
+                            (Some(self.parse_query()?), settings, None, vec![])
+                        }
+                    };
 
-                    (columns, partitioned, after_columns, source, assignments)
+                    (
+                        columns,
+                        partitioned,
+                        after_columns,
+                        source,
+                        settings,
+                        format_clause,
+                        assignments,
+                    )
                 };
 
             let insert_alias = if dialect_of!(self is MySqlDialect | GenericDialect)
@@ -12139,6 +12160,8 @@ impl<'a> Parser<'a> {
                 columns,
                 after_columns,
                 source,
+                settings,
+                format_clause,
                 assignments,
                 has_table_keyword: table,
                 on,
diff --git a/tmp/agent-patch-flux-pr-1628.1-of-1.2026-02-28__18-27-22__gpt-5-3-codex/app/tests/sqlparser_clickhouse.rs b/app/tests/sqlparser_clickhouse.rs
index 4fa657b..bcea6bd 100644
--- a/tmp/agent-patch-flux-pr-1628.1-of-1.2026-02-28__18-27-22__gpt-5-3-codex/app/tests/sqlparser_clickhouse.rs
+++ b/app/tests/sqlparser_clickhouse.rs
@@ -228,6 +228,61 @@ fn parse_insert_into_function() {
     clickhouse().verified_stmt(r#"INSERT INTO FUNCTION remote('localhost', default.simple_table) VALUES (100, 'inserted via remote()')"#);
 }
 
+#[test]
+fn parse_insert_with_settings_and_format_clause() {
+    let sql = "INSERT INTO tbl SETTINGS max_threads = 4, input_format_skip_unknown_fields = 1 FORMAT JSONEachRow";
+    match clickhouse_and_generic().verified_stmt(sql) {
+        Statement::Insert(Insert {
+            table,
+            source,
+            settings,
+            format_clause,
+            ..
+        }) => {
+            assert_eq!(table.to_string(), "tbl");
+            assert_eq!(source, None);
+            assert_eq!(
+                settings,
+                Some(vec![
+                    Setting {
+                        key: Ident::new("max_threads"),
+                        value: Value::Number("4".parse().unwrap(), false),
+                    },
+                    Setting {
+                        key: Ident::new("input_format_skip_unknown_fields"),
+                        value: Value::Number("1".parse().unwrap(), false),
+                    }
+                ])
+            );
+            assert_eq!(
+                format_clause,
+                Some(FormatClause::Identifier(Ident::new("JSONEachRow")))
+            );
+        }
+        _ => unreachable!(),
+    }
+}
+
+#[test]
+fn parse_insert_with_settings_before_values() {
+    let sql = "INSERT INTO tbl SETTINGS max_threads = 4 VALUES (1)";
+    match clickhouse_and_generic().verified_stmt(sql) {
+        Statement::Insert(Insert {
+            source, settings, ..
+        }) => {
+            assert!(source.is_some());
+            assert_eq!(
+                settings,
+                Some(vec![Setting {
+                    key: Ident::new("max_threads"),
+                    value: Value::Number("4".parse().unwrap(), false),
+                }])
+            );
+        }
+        _ => unreachable!(),
+    }
+}
+
 #[test]
 fn parse_alter_table_attach_and_detach_partition() {
     for operation in &["ATTACH", "DETACH"] {