agent_patch
runs/2026-02-28__18-27-22__gpt-5-4/flux-pr-1604/flux-pr-1604.1-of-1.2026-02-28__18-27-22__gpt-5-4/agent-logs/agent.patch
8635 bytes
diff --git a/tmp/agent-patch-flux-pr-1604.1-of-1.2026-02-28__18-27-22__gpt-5-4/app/src/ast/mod.rs b/app/src/ast/mod.rs
index 9fb2bb9..575d8de 100644
--- a/tmp/agent-patch-flux-pr-1604.1-of-1.2026-02-28__18-27-22__gpt-5-4/app/src/ast/mod.rs
+++ b/app/src/ast/mod.rs
@@ -2474,6 +2474,8 @@ pub enum Statement {
assignments: Vec<Assignment>,
/// Table which provide value to be set
from: Option<TableWithJoins>,
+ /// Whether the `FROM` clause was specified before `SET`
+ from_before_set: bool,
/// WHERE
selection: Option<Expr>,
/// RETURNING
@@ -3736,6 +3738,7 @@ impl fmt::Display for Statement {
table,
assignments,
from,
+ from_before_set,
selection,
returning,
or,
@@ -3745,11 +3748,18 @@ impl fmt::Display for Statement {
write!(f, "{or} ")?;
}
write!(f, "{table}")?;
+ if *from_before_set {
+ if let Some(from) = from {
+ write!(f, " FROM {from}")?;
+ }
+ }
if !assignments.is_empty() {
write!(f, " SET {}", display_comma_separated(assignments))?;
}
- if let Some(from) = from {
- write!(f, " FROM {from}")?;
+ if !*from_before_set {
+ if let Some(from) = from {
+ write!(f, " FROM {from}")?;
+ }
}
if let Some(selection) = selection {
write!(f, " WHERE {selection}")?;
diff --git a/tmp/agent-patch-flux-pr-1604.1-of-1.2026-02-28__18-27-22__gpt-5-4/app/src/ast/spans.rs b/app/src/ast/spans.rs
index 9ba3bdd..9755903 100644
--- a/tmp/agent-patch-flux-pr-1604.1-of-1.2026-02-28__18-27-22__gpt-5-4/app/src/ast/spans.rs
+++ b/app/src/ast/spans.rs
@@ -349,6 +349,7 @@ impl Spanned for Statement {
table,
assignments,
from,
+ from_before_set: _,
selection,
returning,
or: _,
diff --git a/tmp/agent-patch-flux-pr-1604.1-of-1.2026-02-28__18-27-22__gpt-5-4/app/src/parser/mod.rs b/app/src/parser/mod.rs
index cc0a57e..5556b08 100644
--- a/tmp/agent-patch-flux-pr-1604.1-of-1.2026-02-28__18-27-22__gpt-5-4/app/src/parser/mod.rs
+++ b/app/src/parser/mod.rs
@@ -11791,14 +11791,23 @@ impl<'a> Parser<'a> {
pub fn parse_update(&mut self) -> Result<Statement, ParserError> {
let or = self.parse_conflict_clause();
let table = self.parse_table_and_joins()?;
+ let (from, from_before_set) = if self.parse_keyword(Keyword::FROM)
+ && dialect_of!(self is SnowflakeDialect)
+ {
+ (Some(self.parse_table_and_joins()?), true)
+ } else {
+ (None, false)
+ };
self.expect_keyword(Keyword::SET)?;
let assignments = self.parse_comma_separated(Parser::parse_assignment)?;
- let from = if self.parse_keyword(Keyword::FROM)
+ let from = if from_before_set {
+ from
+ } else if self.parse_keyword(Keyword::FROM)
&& dialect_of!(self is GenericDialect | PostgreSqlDialect | DuckDbDialect | BigQueryDialect | SnowflakeDialect | RedshiftSqlDialect | MsSqlDialect | SQLiteDialect )
{
Some(self.parse_table_and_joins()?)
} else {
- None
+ from
};
let selection = if self.parse_keyword(Keyword::WHERE) {
Some(self.parse_expr()?)
@@ -11814,6 +11823,7 @@ impl<'a> Parser<'a> {
table,
assignments,
from,
+ from_before_set,
selection,
returning,
or,
diff --git a/tmp/agent-patch-flux-pr-1604.1-of-1.2026-02-28__18-27-22__gpt-5-4/app/tests/sqlparser_common.rs b/app/tests/sqlparser_common.rs
index 79f5c8d..3ee090e 100644
--- a/tmp/agent-patch-flux-pr-1604.1-of-1.2026-02-28__18-27-22__gpt-5-4/app/tests/sqlparser_common.rs
+++ b/app/tests/sqlparser_common.rs
@@ -299,9 +299,11 @@ fn parse_update() {
table,
assignments,
selection,
+ from_before_set,
..
} => {
assert_eq!(table.to_string(), "t".to_string());
+ assert!(!from_before_set);
assert_eq!(
assignments,
vec![
@@ -419,6 +421,7 @@ fn parse_update_set_from() {
},
joins: vec![],
}),
+ from_before_set: false,
selection: Some(Expr::BinaryOp {
left: Box::new(Expr::CompoundIdentifier(vec![
Ident::new("t1"),
@@ -444,10 +447,12 @@ fn parse_update_with_table_alias() {
table,
assignments,
from: _from,
+ from_before_set,
selection,
returning,
or: None,
} => {
+ assert!(!from_before_set);
assert_eq!(
TableWithJoins {
relation: TableFactor::Table {
diff --git a/tmp/agent-patch-flux-pr-1604.1-of-1.2026-02-28__18-27-22__gpt-5-4/app/tests/sqlparser_mysql.rs b/app/tests/sqlparser_mysql.rs
index 4a4e796..c2ce8f1 100644
--- a/tmp/agent-patch-flux-pr-1604.1-of-1.2026-02-28__18-27-22__gpt-5-4/app/tests/sqlparser_mysql.rs
+++ b/app/tests/sqlparser_mysql.rs
@@ -1988,10 +1988,12 @@ fn parse_update_with_joins() {
table,
assignments,
from: _from,
+ from_before_set,
selection,
returning,
or: None,
} => {
+ assert!(!from_before_set);
assert_eq!(
TableWithJoins {
relation: TableFactor::Table {
diff --git a/tmp/agent-patch-flux-pr-1604.1-of-1.2026-02-28__18-27-22__gpt-5-4/app/tests/sqlparser_snowflake.rs b/app/tests/sqlparser_snowflake.rs
index 9fe1478..c5696f1 100644
--- a/tmp/agent-patch-flux-pr-1604.1-of-1.2026-02-28__18-27-22__gpt-5-4/app/tests/sqlparser_snowflake.rs
+++ b/app/tests/sqlparser_snowflake.rs
@@ -1278,6 +1278,53 @@ fn snowflake_and_generic() -> TestedDialects {
])
}
+#[test]
+fn parse_update_from_before_set() {
+ let sql = "UPDATE t1 FROM t2 SET t1.col = t2.col WHERE t1.id = t2.id";
+ match snowflake().verified_stmt(sql) {
+ Statement::Update {
+ table,
+ assignments,
+ from,
+ from_before_set,
+ selection,
+ returning,
+ or,
+ } => {
+ assert_eq!(table.to_string(), "t1");
+ assert_eq!(from.unwrap().to_string(), "t2");
+ assert!(from_before_set);
+ assert_eq!(
+ assignments,
+ vec![Assignment {
+ target: AssignmentTarget::ColumnName(ObjectName(vec![
+ Ident::new("t1"),
+ Ident::new("col")
+ ])),
+ value: Expr::CompoundIdentifier(vec![Ident::new("t2"), Ident::new("col")]),
+ }]
+ );
+ assert_eq!(
+ selection,
+ Some(Expr::BinaryOp {
+ left: Box::new(Expr::CompoundIdentifier(vec![
+ Ident::new("t1"),
+ Ident::new("id")
+ ])),
+ op: BinaryOperator::Eq,
+ right: Box::new(Expr::CompoundIdentifier(vec![
+ Ident::new("t2"),
+ Ident::new("id")
+ ])),
+ })
+ );
+ assert_eq!(returning, None);
+ assert_eq!(or, None);
+ }
+ _ => unreachable!(),
+ }
+}
+
#[test]
fn test_select_wildcard_with_exclude() {
let select = snowflake_and_generic().verified_only_select("SELECT * EXCLUDE (col_a) FROM data");
diff --git a/tmp/agent-patch-flux-pr-1604.1-of-1.2026-02-28__18-27-22__gpt-5-4/app/tests/sqlparser_sqlite.rs b/app/tests/sqlparser_sqlite.rs
index ff0b54e..f28101a 100644
--- a/tmp/agent-patch-flux-pr-1604.1-of-1.2026-02-28__18-27-22__gpt-5-4/app/tests/sqlparser_sqlite.rs
+++ b/app/tests/sqlparser_sqlite.rs
@@ -483,6 +483,7 @@ fn parse_update_tuple_row_values() {
joins: vec![],
},
from: None,
+ from_before_set: false,
returning: None
}
);