agent_patch
runs/2026-02-28__18-27-22__gpt-5-1-codex-mini/flux-pr-1441/flux-pr-1441.1-of-1.2026-02-28__18-27-22__gpt-5-1-codex-mini/agent-logs/agent.patch
9816 bytes
diff --git a/tmp/agent-patch-flux-pr-1441.1-of-1.2026-02-28__18-27-22__gpt-5-1-codex-mini/app/src/ast/ddl.rs b/app/src/ast/ddl.rs
index 4578ae8..7c637db 100644
--- a/tmp/agent-patch-flux-pr-1441.1-of-1.2026-02-28__18-27-22__gpt-5-1-codex-mini/app/src/ast/ddl.rs
+++ b/app/src/ast/ddl.rs
@@ -1049,6 +1049,7 @@ pub struct ViewColumnDef {
pub name: Ident,
pub data_type: Option<DataType>,
pub options: Option<Vec<SqlOption>>,
+ pub comment: Option<String>,
}
impl fmt::Display for ViewColumnDef {
@@ -1064,6 +1065,13 @@ impl fmt::Display for ViewColumnDef {
display_comma_separated(options.as_slice())
)?;
}
+ if let Some(comment) = self.comment.as_ref() {
+ write!(
+ f,
+ " COMMENT '{}'",
+ escape_single_quote_string(comment)
+ )?;
+ }
Ok(())
}
}
diff --git a/tmp/agent-patch-flux-pr-1441.1-of-1.2026-02-28__18-27-22__gpt-5-1-codex-mini/app/src/ast/mod.rs b/app/src/ast/mod.rs
index 8c4bc25..1879794 100644
--- a/tmp/agent-patch-flux-pr-1441.1-of-1.2026-02-28__18-27-22__gpt-5-1-codex-mini/app/src/ast/mod.rs
+++ b/app/src/ast/mod.rs
@@ -3917,44 +3917,44 @@ impl fmt::Display for Statement {
temporary,
to,
} => {
+ write!(
+ f,
+ "CREATE {or_replace}{materialized}{temporary}VIEW {if_not_exists}{name}{to}",
+ or_replace = if *or_replace { "OR REPLACE " } else { "" },
+ materialized = if *materialized { "MATERIALIZED " } else { "" },
+ name = name,
+ temporary = if *temporary { "TEMPORARY " } else { "" },
+ if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" },
+ to = to
+ .as_ref()
+ .map(|to| format!(" TO {to}"))
+ .unwrap_or_default()
+ )?;
+ if matches!(options, CreateTableOptions::With(_)) {
+ write!(f, " {options}")?;
+ }
+ if !columns.is_empty() {
+ write!(f, " ({})", display_comma_separated(columns))?;
+ }
+ if !cluster_by.is_empty() {
+ write!(f, " CLUSTER BY ({})", display_comma_separated(cluster_by))?;
+ }
+ if matches!(options, CreateTableOptions::Options(_)) {
+ write!(f, " {options}")?;
+ }
+ if let Some(comment) = comment {
write!(
f,
- "CREATE {or_replace}{materialized}{temporary}VIEW {if_not_exists}{name}{to}",
- or_replace = if *or_replace { "OR REPLACE " } else { "" },
- materialized = if *materialized { "MATERIALIZED " } else { "" },
- name = name,
- temporary = if *temporary { "TEMPORARY " } else { "" },
- if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" },
- to = to
- .as_ref()
- .map(|to| format!(" TO {to}"))
- .unwrap_or_default()
+ " COMMENT = '{}'",
+ value::escape_single_quote_string(comment)
)?;
- if let Some(comment) = comment {
- write!(
- f,
- " COMMENT = '{}'",
- value::escape_single_quote_string(comment)
- )?;
- }
- if matches!(options, CreateTableOptions::With(_)) {
- write!(f, " {options}")?;
- }
- if !columns.is_empty() {
- write!(f, " ({})", display_comma_separated(columns))?;
- }
- if !cluster_by.is_empty() {
- write!(f, " CLUSTER BY ({})", display_comma_separated(cluster_by))?;
- }
- if matches!(options, CreateTableOptions::Options(_)) {
- write!(f, " {options}")?;
- }
- write!(f, " AS {query}")?;
- if *with_no_schema_binding {
- write!(f, " WITH NO SCHEMA BINDING")?;
- }
- Ok(())
}
+ write!(f, " AS {query}")?;
+ if *with_no_schema_binding {
+ write!(f, " WITH NO SCHEMA BINDING")?;
+ }
+ Ok(())
+ }
Statement::CreateTable(create_table) => create_table.fmt(f),
Statement::CreateVirtualTable {
name,
diff --git a/tmp/agent-patch-flux-pr-1441.1-of-1.2026-02-28__18-27-22__gpt-5-1-codex-mini/app/src/parser/mod.rs b/app/src/parser/mod.rs
index 88c3bd1..e6df157 100644
--- a/tmp/agent-patch-flux-pr-1441.1-of-1.2026-02-28__18-27-22__gpt-5-1-codex-mini/app/src/parser/mod.rs
+++ b/app/src/parser/mod.rs
@@ -8374,10 +8374,23 @@ impl<'a> Parser<'a> {
} else {
None
};
+ let comment = if dialect_of!(self is SnowflakeDialect | GenericDialect)
+ && self.parse_keyword(Keyword::COMMENT)
+ {
+ let _ = self.consume_token(&Token::Eq);
+ let next_token = self.next_token();
+ match next_token.token {
+ Token::SingleQuotedString(value, ..) => Some(value),
+ _ => return self.expected("string literal", next_token),
+ }
+ } else {
+ None
+ };
Ok(ViewColumnDef {
name,
data_type,
options,
+ comment,
})
}
diff --git a/tmp/agent-patch-flux-pr-1441.1-of-1.2026-02-28__18-27-22__gpt-5-1-codex-mini/app/tests/sqlparser_bigquery.rs b/app/tests/sqlparser_bigquery.rs
index 55afe47..873422f 100644
--- a/tmp/agent-patch-flux-pr-1441.1-of-1.2026-02-28__18-27-22__gpt-5-1-codex-mini/app/tests/sqlparser_bigquery.rs
+++ b/app/tests/sqlparser_bigquery.rs
@@ -268,6 +268,7 @@ fn parse_create_view_with_options() {
name: Ident::new("name"),
data_type: None,
options: None,
+ comment: None,
},
ViewColumnDef {
name: Ident::new("age"),
@@ -275,7 +276,8 @@ fn parse_create_view_with_options() {
options: Some(vec![SqlOption::KeyValue {
key: Ident::new("description"),
value: Expr::Value(Value::DoubleQuotedString("field age".to_string())),
- }])
+ }]),
+ comment: None,
},
],
columns
diff --git a/tmp/agent-patch-flux-pr-1441.1-of-1.2026-02-28__18-27-22__gpt-5-1-codex-mini/app/tests/sqlparser_clickhouse.rs b/app/tests/sqlparser_clickhouse.rs
index e30c336..6cc3091 100644
--- a/tmp/agent-patch-flux-pr-1441.1-of-1.2026-02-28__18-27-22__gpt-5-1-codex-mini/app/tests/sqlparser_clickhouse.rs
+++ b/app/tests/sqlparser_clickhouse.rs
@@ -904,7 +904,8 @@ fn parse_create_view_with_fields_data_types() {
}]),
vec![]
)),
- options: None
+ options: None,
+ comment: None,
},
ViewColumnDef {
name: "f".into(),
@@ -915,7 +916,8 @@ fn parse_create_view_with_fields_data_types() {
}]),
vec![]
)),
- options: None
+ options: None,
+ comment: None,
},
]
);
diff --git a/tmp/agent-patch-flux-pr-1441.1-of-1.2026-02-28__18-27-22__gpt-5-1-codex-mini/app/tests/sqlparser_common.rs b/app/tests/sqlparser_common.rs
index 5d5a17c..8761f9d 100644
--- a/tmp/agent-patch-flux-pr-1441.1-of-1.2026-02-28__18-27-22__gpt-5-1-codex-mini/app/tests/sqlparser_common.rs
+++ b/app/tests/sqlparser_common.rs
@@ -6867,7 +6867,8 @@ fn parse_create_view_with_columns() {
.map(|name| ViewColumnDef {
name,
data_type: None,
- options: None
+ options: None,
+ comment: None,
})
.collect::<Vec<_>>()
);
diff --git a/tmp/agent-patch-flux-pr-1441.1-of-1.2026-02-28__18-27-22__gpt-5-1-codex-mini/app/tests/sqlparser_snowflake.rs b/app/tests/sqlparser_snowflake.rs
index 50c5f74..164b923 100644
--- a/tmp/agent-patch-flux-pr-1441.1-of-1.2026-02-28__18-27-22__gpt-5-1-codex-mini/app/tests/sqlparser_snowflake.rs
+++ b/app/tests/sqlparser_snowflake.rs
@@ -576,6 +576,25 @@ fn parse_sf_create_or_replace_with_comment_for_snowflake() {
}
}
+#[test]
+fn parse_sf_create_view_column_with_comment() {
+ let sql = "CREATE VIEW v (total_price COMMENT 'line item') AS SELECT 1";
+ match snowflake().verified_stmt(sql) {
+ Statement::CreateView { columns, .. } => {
+ assert_eq!(
+ columns,
+ vec![ViewColumnDef {
+ name: Ident::new("total_price"),
+ data_type: None,
+ options: None,
+ comment: Some("line item".to_string()),
+ }]
+ );
+ }
+ _ => unreachable!(),
+ }
+}
+
#[test]
fn test_sf_derived_table_in_parenthesis() {
// Nesting a subquery in an extra set of parentheses is non-standard,