STET

agent_patch

runs/2026-02-28__18-27-22__gpt-5-4/flux-pr-1839/flux-pr-1839.1-of-1.2026-02-28__18-27-22__gpt-5-4/agent-logs/agent.patch

13926 bytes

Back to adjudication
diff --git a/tmp/agent-patch-flux-pr-1839.1-of-1.2026-02-28__18-27-22__gpt-5-4/app/src/ast/ddl.rs b/app/src/ast/ddl.rs
index a8a1fdb..0ee8e67 100644
--- a/tmp/agent-patch-flux-pr-1839.1-of-1.2026-02-28__18-27-22__gpt-5-4/app/src/ast/ddl.rs
+++ b/app/src/ast/ddl.rs
@@ -2258,6 +2258,8 @@ pub struct CreateFunction {
     pub if_not_exists: bool,
     pub name: ObjectName,
     pub args: Option<Vec<OperateFunctionArg>>,
+    /// Named return table variable for MSSQL multi-statement table-valued functions.
+    pub return_table_name: Option<Ident>,
     pub return_type: Option<DataType>,
     /// The expression that defines the function.
     ///
@@ -2330,7 +2332,11 @@ impl fmt::Display for CreateFunction {
             write!(f, "({})", display_comma_separated(args))?;
         }
         if let Some(return_type) = &self.return_type {
-            write!(f, " RETURNS {return_type}")?;
+            write!(f, " RETURNS")?;
+            if let Some(return_table_name) = &self.return_table_name {
+                write!(f, " {return_table_name}")?;
+            }
+            write!(f, " {return_type}")?;
         }
         if let Some(determinism_specifier) = &self.determinism_specifier {
             write!(f, " {determinism_specifier}")?;
@@ -2372,6 +2378,9 @@ impl fmt::Display for CreateFunction {
         if let Some(CreateFunctionBody::AsBeginEnd(bes)) = &self.function_body {
             write!(f, " AS {bes}")?;
         }
+        if let Some(CreateFunctionBody::AsReturnQuery(query)) = &self.function_body {
+            write!(f, " AS RETURN {query}")?;
+        }
         Ok(())
     }
 }
diff --git a/tmp/agent-patch-flux-pr-1839.1-of-1.2026-02-28__18-27-22__gpt-5-4/app/src/ast/mod.rs b/app/src/ast/mod.rs
index e18251e..c982c4f 100644
--- a/tmp/agent-patch-flux-pr-1839.1-of-1.2026-02-28__18-27-22__gpt-5-4/app/src/ast/mod.rs
+++ b/app/src/ast/mod.rs
@@ -8769,6 +8769,16 @@ pub enum CreateFunctionBody {
     ///
     /// [MsSql]: https://learn.microsoft.com/en-us/sql/t-sql/statements/create-function-transact-sql
     AsBeginEnd(BeginEndStatements),
+    /// MSSQL inline table-valued function body using `RETURN <query>`.
+    ///
+    /// Example:
+    /// ```sql
+    /// CREATE FUNCTION my_inline_tvf()
+    /// RETURNS TABLE
+    /// AS
+    /// RETURN SELECT 1 AS id
+    /// ```
+    AsReturnQuery(Box<Query>),
     /// Function body expression using the 'RETURN' keyword.
     ///
     /// Example:
diff --git a/tmp/agent-patch-flux-pr-1839.1-of-1.2026-02-28__18-27-22__gpt-5-4/app/src/parser/mod.rs b/app/src/parser/mod.rs
index 47b321d..923802e 100644
--- a/tmp/agent-patch-flux-pr-1839.1-of-1.2026-02-28__18-27-22__gpt-5-4/app/src/parser/mod.rs
+++ b/app/src/parser/mod.rs
@@ -5069,6 +5069,7 @@ impl<'a> Parser<'a> {
             temporary,
             name,
             args: Some(args),
+            return_table_name: None,
             return_type,
             behavior: body.behavior,
             called_on_null: body.called_on_null,
@@ -5106,6 +5107,7 @@ impl<'a> Parser<'a> {
             using,
             if_not_exists: false,
             args: None,
+            return_table_name: None,
             return_type: None,
             behavior: None,
             called_on_null: None,
@@ -5179,6 +5181,7 @@ impl<'a> Parser<'a> {
             if_not_exists,
             name,
             args: Some(args),
+            return_table_name: None,
             return_type,
             function_body,
             language,
@@ -5204,19 +5207,31 @@ impl<'a> Parser<'a> {
         let (name, args) = self.parse_create_function_name_and_params()?;
 
         self.expect_keyword(Keyword::RETURNS)?;
+        let return_table_name = match &self.peek_token().token {
+            Token::AtSign => Some(self.parse_identifier()?),
+            Token::Word(word) if word.value.starts_with('@') => Some(self.parse_identifier()?),
+            _ => None,
+        };
         let return_type = Some(self.parse_data_type()?);
 
-        self.expect_keyword_is(Keyword::AS)?;
+        let _ = self.parse_keyword(Keyword::AS);
 
-        let begin_token = self.expect_keyword(Keyword::BEGIN)?;
-        let statements = self.parse_statement_list(&[Keyword::END])?;
-        let end_token = self.expect_keyword(Keyword::END)?;
+        let function_body = if self.peek_keyword(Keyword::BEGIN) {
+            let begin_token = self.expect_keyword(Keyword::BEGIN)?;
+            let statements = self.parse_statement_list(&[Keyword::END])?;
+            let end_token = self.expect_keyword(Keyword::END)?;
 
-        let function_body = Some(CreateFunctionBody::AsBeginEnd(BeginEndStatements {
-            begin_token: AttachedToken(begin_token),
-            statements,
-            end_token: AttachedToken(end_token),
-        }));
+            Some(CreateFunctionBody::AsBeginEnd(BeginEndStatements {
+                begin_token: AttachedToken(begin_token),
+                statements,
+                end_token: AttachedToken(end_token),
+            }))
+        } else {
+            self.expect_keyword_is(Keyword::RETURN)?;
+            Some(CreateFunctionBody::AsReturnQuery(
+                self.parse_mssql_inline_function_return_query()?.into(),
+            ))
+        };
 
         Ok(Statement::CreateFunction(CreateFunction {
             or_alter,
@@ -5225,6 +5240,7 @@ impl<'a> Parser<'a> {
             if_not_exists: false,
             name,
             args: Some(args),
+            return_table_name,
             return_type,
             function_body,
             language: None,
@@ -5238,6 +5254,16 @@ impl<'a> Parser<'a> {
         }))
     }
 
+    fn parse_mssql_inline_function_return_query(&mut self) -> Result<Query, ParserError> {
+        if self.consume_token(&Token::LParen) {
+            let query = self.parse_query()?;
+            self.expect_token(&Token::RParen)?;
+            Ok(query)
+        } else {
+            self.parse_query()
+        }
+    }
+
     fn parse_create_function_name_and_params(
         &mut self,
     ) -> Result<(ObjectName, Vec<OperateFunctionArg>), ParserError> {
@@ -9841,10 +9867,28 @@ impl<'a> Parser<'a> {
     fn parse_returns_table_column(&mut self) -> Result<ColumnDef, ParserError> {
         let name = self.parse_identifier()?;
         let data_type = self.parse_data_type()?;
+        let mut options = vec![];
+        loop {
+            if self.parse_keyword(Keyword::CONSTRAINT) {
+                let name = Some(self.parse_identifier()?);
+                if let Some(option) = self.parse_optional_column_option()? {
+                    options.push(ColumnOptionDef { name, option });
+                } else {
+                    return self.expected(
+                        "constraint details after CONSTRAINT <name>",
+                        self.peek_token(),
+                    );
+                }
+            } else if let Some(option) = self.parse_optional_column_option()? {
+                options.push(ColumnOptionDef { name: None, option });
+            } else {
+                break;
+            };
+        }
         Ok(ColumnDef {
             name,
             data_type,
-            options: Vec::new(), // No constraints expected here
+            options,
         })
     }
 
diff --git a/tmp/agent-patch-flux-pr-1839.1-of-1.2026-02-28__18-27-22__gpt-5-4/app/tests/sqlparser_bigquery.rs b/app/tests/sqlparser_bigquery.rs
index 8f54f3c..8aa8ca2 100644
--- a/tmp/agent-patch-flux-pr-1839.1-of-1.2026-02-28__18-27-22__gpt-5-4/app/tests/sqlparser_bigquery.rs
+++ b/app/tests/sqlparser_bigquery.rs
@@ -2144,6 +2144,7 @@ fn test_bigquery_create_function() {
                 Ident::new("myfunction"),
             ]),
             args: Some(vec![OperateFunctionArg::with_name("x", DataType::Float64),]),
+            return_table_name: None,
             return_type: Some(DataType::Float64),
             function_body: Some(CreateFunctionBody::AsAfterOptions(Expr::Value(
                 number("42").with_empty_span()
diff --git a/tmp/agent-patch-flux-pr-1839.1-of-1.2026-02-28__18-27-22__gpt-5-4/app/tests/sqlparser_hive.rs b/app/tests/sqlparser_hive.rs
index 14dcbff..ccdb0c3 100644
--- a/tmp/agent-patch-flux-pr-1839.1-of-1.2026-02-28__18-27-22__gpt-5-4/app/tests/sqlparser_hive.rs
+++ b/app/tests/sqlparser_hive.rs
@@ -399,6 +399,7 @@ fn parse_create_function() {
             name,
             function_body,
             using,
+            return_table_name: _,
             ..
         }) => {
             assert!(temporary);
diff --git a/tmp/agent-patch-flux-pr-1839.1-of-1.2026-02-28__18-27-22__gpt-5-4/app/tests/sqlparser_mssql.rs b/app/tests/sqlparser_mssql.rs
index 7b3769e..55efc28 100644
--- a/tmp/agent-patch-flux-pr-1839.1-of-1.2026-02-28__18-27-22__gpt-5-4/app/tests/sqlparser_mssql.rs
+++ b/app/tests/sqlparser_mssql.rs
@@ -222,6 +222,7 @@ fn parse_create_function() {
                     default_expr: None,
                 },
             ]),
+            return_table_name: None,
             return_type: Some(DataType::Int(None)),
             function_body: Some(CreateFunctionBody::AsBeginEnd(BeginEndStatements {
                 begin_token: AttachedToken::empty(),
@@ -288,6 +289,59 @@ fn parse_create_function() {
         END\
     ";
     let _ = ms().verified_stmt(create_function_with_return_expression);
+
+    let inline_table_valued_function = "\
+        CREATE FUNCTION some_inline_tvf(@foo INT) \
+        RETURNS TABLE \
+        RETURN SELECT @foo AS foo\
+    ";
+    match ms().verified_stmt(inline_table_valued_function) {
+        Statement::CreateFunction(CreateFunction {
+            name,
+            args,
+            return_table_name,
+            return_type: Some(DataType::Table(columns)),
+            function_body: Some(CreateFunctionBody::AsReturnQuery(query)),
+            ..
+        }) => {
+            assert_eq!(name, ObjectName::from(vec![Ident::new("some_inline_tvf")]));
+            assert_eq!(args, Some(vec![OperateFunctionArg::with_name("@foo", DataType::Int(None))]));
+            assert_eq!(return_table_name, None);
+            assert!(columns.is_empty());
+            assert_eq!(query.to_string(), "SELECT @foo AS foo");
+        }
+        _ => unreachable!(),
+    }
+
+    let multi_statement_table_valued_function = "\
+        CREATE FUNCTION some_multi_tvf(@foo INT) \
+        RETURNS @result TABLE (id INT PRIMARY KEY, name NVARCHAR(50) NOT NULL) \
+        BEGIN \
+            INSERT INTO @result SELECT @foo, 'x'; \
+            RETURN; \
+        END\
+    ";
+    match ms().verified_stmt(multi_statement_table_valued_function) {
+        Statement::CreateFunction(CreateFunction {
+            return_table_name,
+            return_type: Some(DataType::Table(columns)),
+            function_body: Some(CreateFunctionBody::AsBeginEnd(_)),
+            ..
+        }) => {
+            assert_eq!(return_table_name, Some(Ident::new("@result")));
+            assert_eq!(columns.len(), 2);
+            assert_eq!(columns[0].to_string(), "id INT PRIMARY KEY");
+            assert_eq!(columns[1].to_string(), "name NVARCHAR(50) NOT NULL");
+        }
+        _ => unreachable!(),
+    }
+
+    let inline_table_valued_function_with_as = "\
+        CREATE FUNCTION some_inline_tvf_with_as() \
+        RETURNS TABLE \
+        AS RETURN (SELECT 1 AS id)\
+    ";
+    let _ = ms().verified_stmt(inline_table_valued_function_with_as);
 }
 
 #[test]
diff --git a/tmp/agent-patch-flux-pr-1839.1-of-1.2026-02-28__18-27-22__gpt-5-4/app/tests/sqlparser_postgres.rs b/app/tests/sqlparser_postgres.rs
index 682c0d6..ea81744 100644
--- a/tmp/agent-patch-flux-pr-1839.1-of-1.2026-02-28__18-27-22__gpt-5-4/app/tests/sqlparser_postgres.rs
+++ b/app/tests/sqlparser_postgres.rs
@@ -4135,6 +4135,7 @@ $$"#;
                     DataType::Varchar(None),
                 ),
             ]),
+            return_table_name: None,
             return_type: Some(DataType::Boolean),
             language: Some("plpgsql".into()),
             behavior: None,
@@ -4173,6 +4174,7 @@ $$"#;
                     DataType::Int(None)
                 )
             ]),
+            return_table_name: None,
             return_type: Some(DataType::Boolean),
             language: Some("plpgsql".into()),
             behavior: None,
@@ -4215,6 +4217,7 @@ $$"#;
                     DataType::Int(None)
                 ),
             ]),
+            return_table_name: None,
             return_type: Some(DataType::Boolean),
             language: Some("plpgsql".into()),
             behavior: None,
@@ -4257,6 +4260,7 @@ $$"#;
                     DataType::Int(None)
                 ),
             ]),
+            return_table_name: None,
             return_type: Some(DataType::Boolean),
             language: Some("plpgsql".into()),
             behavior: None,
@@ -4292,6 +4296,7 @@ $$"#;
                 ),
                 OperateFunctionArg::with_name("b", DataType::Varchar(None)),
             ]),
+            return_table_name: None,
             return_type: Some(DataType::Boolean),
             language: Some("plpgsql".into()),
             behavior: None,
@@ -4330,6 +4335,7 @@ fn parse_create_function() {
                 OperateFunctionArg::unnamed(DataType::Integer(None)),
                 OperateFunctionArg::unnamed(DataType::Integer(None)),
             ]),
+            return_table_name: None,
             return_type: Some(DataType::Integer(None)),
             language: Some("SQL".into()),
             behavior: Some(FunctionBehavior::Immutable),
@@ -5873,6 +5879,7 @@ fn parse_trigger_related_functions() {
             if_not_exists: false,
             name: ObjectName::from(vec![Ident::new("emp_stamp")]),
             args: Some(vec![]),
+            return_table_name: None,
             return_type: Some(DataType::Trigger),
             function_body: Some(
                 CreateFunctionBody::AsBeforeOptions(