agent_patch
runs/2026-02-21__03-36-16__gpt-5-1-codex-mini/flux-pr-1900/flux-pr-1900.1-of-1.2026-02-21__03-36-16__gpt-5-1-codex-mini/agent-logs/agent.patch
15274 bytes
diff --git a/tmp/agent-patch-flux-pr-1900.1-of-1.2026-02-21__03-36-16__gpt-5-1-codex-mini/app/src/ast/ddl.rs b/app/src/ast/ddl.rs
index 059c619..f5a7a52 100644
--- a/tmp/agent-patch-flux-pr-1900.1-of-1.2026-02-21__03-36-16__gpt-5-1-codex-mini/app/src/ast/ddl.rs
+++ b/app/src/ast/ddl.rs
@@ -30,11 +30,10 @@ use sqlparser_derive::{Visit, VisitMut};
use crate::ast::value::escape_single_quote_string;
use crate::ast::{
- display_comma_separated, display_separated, CommentDef, CreateFunctionBody,
- CreateFunctionUsing, DataType, Expr, FunctionBehavior, FunctionCalledOnNull,
- FunctionDeterminismSpecifier, FunctionParallel, Ident, MySQLColumnPosition, ObjectName,
- OperateFunctionArg, OrderByExpr, ProjectionSelect, SequenceOptions, SqlOption, Tag, Value,
- ValueWithSpan,
+ display_comma_separated, display_separated, CommentDef, CreateFunctionBody, CreateFunctionUsing,
+ DataType, Expr, FunctionBehavior, FunctionCalledOnNull, FunctionDeterminismSpecifier,
+ FunctionParallel, Ident, IndexColumn, MySQLColumnPosition, ObjectName, OperateFunctionArg,
+ OrderByExpr, ProjectionSelect, SequenceOptions, SqlOption, Tag, Value, ValueWithSpan,
};
use crate::keywords::Keyword;
use crate::tokenizer::Token;
@@ -978,8 +977,8 @@ pub enum TableConstraint {
///
/// [1]: IndexType
index_type: Option<IndexType>,
- /// Identifiers of the columns that are unique.
- columns: Vec<Ident>,
+ /// Index column definitions that are unique.
+ columns: Vec<IndexColumn>,
index_options: Vec<IndexOption>,
characteristics: Option<ConstraintCharacteristics>,
/// Optional Postgres nulls handling: `[ NULLS [ NOT ] DISTINCT ]`
@@ -1014,8 +1013,8 @@ pub enum TableConstraint {
///
/// [1]: IndexType
index_type: Option<IndexType>,
- /// Identifiers of the columns that form the primary key.
- columns: Vec<Ident>,
+ /// Index column definitions that form the primary key.
+ columns: Vec<IndexColumn>,
index_options: Vec<IndexOption>,
characteristics: Option<ConstraintCharacteristics>,
},
@@ -1059,8 +1058,8 @@ pub enum TableConstraint {
///
/// [1]: IndexType
index_type: Option<IndexType>,
- /// Referred column identifier list.
- columns: Vec<Ident>,
+ /// Referred index column list.
+ columns: Vec<IndexColumn>,
},
/// MySQLs [fulltext][1] definition. Since the [`SPATIAL`][2] definition is exactly the same,
/// and MySQL displays both the same way, it is part of this definition as well.
@@ -1082,8 +1081,8 @@ pub enum TableConstraint {
index_type_display: KeyOrIndexDisplay,
/// Optional index name.
opt_index_name: Option<Ident>,
- /// Referred column identifier list.
- columns: Vec<Ident>,
+ /// Referred index column list.
+ columns: Vec<IndexColumn>,
},
}
diff --git a/tmp/agent-patch-flux-pr-1900.1-of-1.2026-02-21__03-36-16__gpt-5-1-codex-mini/app/src/ast/dml.rs b/app/src/ast/dml.rs
index 292650c..bd69c9d 100644
--- a/tmp/agent-patch-flux-pr-1900.1-of-1.2026-02-21__03-36-16__gpt-5-1-codex-mini/app/src/ast/dml.rs
+++ b/app/src/ast/dml.rs
@@ -37,9 +37,9 @@ use super::{
display_comma_separated, display_separated, query::InputFormatClause, Assignment, ClusteredBy,
CommentDef, CreateTableOptions, Expr, FileFormat, FromTable, HiveDistributionStyle, HiveFormat,
HiveIOFormat, HiveRowFormat, Ident, IndexType, InsertAliases, MysqlInsertPriority, ObjectName,
- OnCommit, OnInsert, OneOrManyWithParens, OrderByExpr, Query, RowAccessPolicy, SelectItem,
- Setting, SqliteOnConflict, StorageSerializationPolicy, TableObject, TableWithJoins, Tag,
- WrappedCollection,
+ OnCommit, OnInsert, OneOrManyWithParens, OrderByExpr, OrderByOptions, Query, RowAccessPolicy,
+ SelectItem, Setting, SqliteOnConflict, StorageSerializationPolicy, TableObject, TableWithJoins,
+ Tag, WrappedCollection,
};
/// Index column type.
@@ -51,6 +51,37 @@ pub struct IndexColumn {
pub operator_class: Option<Ident>,
}
+impl IndexColumn {
+ /// Build an index column from an expression with default ordering options.
+ pub fn from_expr(expr: Expr) -> Self {
+ IndexColumn {
+ column: OrderByExpr {
+ expr,
+ options: OrderByOptions::default(),
+ with_fill: None,
+ },
+ operator_class: None,
+ }
+ }
+
+ /// Create an index column from a simple identifier.
+ pub fn from_ident(ident: Ident) -> Self {
+ Self::from_expr(Expr::Identifier(ident))
+ }
+}
+
+impl From<Expr> for IndexColumn {
+ fn from(expr: Expr) -> Self {
+ IndexColumn::from_expr(expr)
+ }
+}
+
+impl From<Ident> for IndexColumn {
+ fn from(ident: Ident) -> Self {
+ Expr::Identifier(ident).into()
+ }
+}
+
impl Display for IndexColumn {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.column)?;
diff --git a/tmp/agent-patch-flux-pr-1900.1-of-1.2026-02-21__03-36-16__gpt-5-1-codex-mini/app/src/ast/query.rs b/app/src/ast/query.rs
index 1fb93b6..22f8ba5 100644
--- a/tmp/agent-patch-flux-pr-1900.1-of-1.2026-02-21__03-36-16__gpt-5-1-codex-mini/app/src/ast/query.rs
+++ b/app/src/ast/query.rs
@@ -2493,7 +2493,7 @@ impl fmt::Display for InterpolateExpr {
}
}
-#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
+#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Default)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct OrderByOptions {
diff --git a/tmp/agent-patch-flux-pr-1900.1-of-1.2026-02-21__03-36-16__gpt-5-1-codex-mini/app/src/ast/spans.rs b/app/src/ast/spans.rs
index 14664b4..d190581 100644
--- a/tmp/agent-patch-flux-pr-1900.1-of-1.2026-02-21__03-36-16__gpt-5-1-codex-mini/app/src/ast/spans.rs
+++ b/app/src/ast/spans.rs
@@ -32,7 +32,7 @@ use super::{
InterpolateExpr, Join, JoinConstraint, JoinOperator, JsonPath, JsonPathElem, LateralView,
LimitClause, MatchRecognizePattern, Measure, NamedParenthesizedList, NamedWindowDefinition,
ObjectName, ObjectNamePart, Offset, OnConflict, OnConflictAction, OnInsert, OpenStatement,
- OrderBy, OrderByExpr, OrderByKind, Partition, PivotValueSource, ProjectionSelect, Query,
+ OrderBy, OrderByExpr, OrderByKind, Partition, PivotValueSource, IndexColumn, ProjectionSelect, Query,
RaiseStatement, RaiseStatementValue, ReferentialAction, RenameSelectItem, ReplaceSelectElement,
ReplaceSelectItem, Select, SelectInto, SelectItem, SetExpr, SqlOption, Statement, Subscript,
SymbolDefinition, TableAlias, TableAliasColumnDef, TableConstraint, TableFactor, TableObject,
@@ -717,6 +717,19 @@ impl Spanned for TableConstraint {
}
}
+impl Spanned for IndexColumn {
+ fn span(&self) -> Span {
+ let IndexColumn {
+ column,
+ operator_class,
+ } = self;
+
+ column
+ .span()
+ .union_opt(&operator_class.as_ref().map(|ident| ident.span))
+ }
+}
+
impl Spanned for CreateIndex {
fn span(&self) -> Span {
let CreateIndex {
diff --git a/tmp/agent-patch-flux-pr-1900.1-of-1.2026-02-21__03-36-16__gpt-5-1-codex-mini/app/src/parser/mod.rs b/app/src/parser/mod.rs
index 44bf58d..84abb35 100644
--- a/tmp/agent-patch-flux-pr-1900.1-of-1.2026-02-21__03-36-16__gpt-5-1-codex-mini/app/src/parser/mod.rs
+++ b/app/src/parser/mod.rs
@@ -8070,7 +8070,7 @@ impl<'a> Parser<'a> {
let index_name = self.parse_optional_ident()?;
let index_type = self.parse_optional_using_then_index_type()?;
- let columns = self.parse_parenthesized_column_list(Mandatory, false)?;
+ let columns = self.parse_parenthesized_index_column_list(Mandatory, false)?;
let index_options = self.parse_index_options()?;
let characteristics = self.parse_constraint_characteristics()?;
Ok(Some(TableConstraint::Unique {
@@ -8092,7 +8092,8 @@ impl<'a> Parser<'a> {
let index_name = self.parse_optional_ident()?;
let index_type = self.parse_optional_using_then_index_type()?;
- let columns = self.parse_parenthesized_column_list(Mandatory, false)?;
+ let columns =
+ self.parse_parenthesized_index_column_list(Mandatory, false)?;
let index_options = self.parse_index_options()?;
let characteristics = self.parse_constraint_characteristics()?;
Ok(Some(TableConstraint::PrimaryKey {
@@ -8107,7 +8108,8 @@ impl<'a> Parser<'a> {
Token::Word(w) if w.keyword == Keyword::FOREIGN => {
self.expect_keyword_is(Keyword::KEY)?;
let index_name = self.parse_optional_ident()?;
- let columns = self.parse_parenthesized_column_list(Mandatory, false)?;
+ let columns =
+ self.parse_parenthesized_column_list(Mandatory, false)?;
self.expect_keyword_is(Keyword::REFERENCES)?;
let foreign_table = self.parse_object_name(false)?;
let referred_columns = self.parse_parenthesized_column_list(Optional, false)?;
@@ -8170,7 +8172,8 @@ impl<'a> Parser<'a> {
};
let index_type = self.parse_optional_using_then_index_type()?;
- let columns = self.parse_parenthesized_column_list(Mandatory, false)?;
+ let columns =
+ self.parse_parenthesized_index_column_list(Mandatory, false)?;
Ok(Some(TableConstraint::Index {
display_as_key,
@@ -8199,7 +8202,8 @@ impl<'a> Parser<'a> {
let opt_index_name = self.parse_optional_ident()?;
- let columns = self.parse_parenthesized_column_list(Mandatory, false)?;
+ let columns =
+ self.parse_parenthesized_index_column_list(Mandatory, false)?;
Ok(Some(TableConstraint::FulltextOrSpatial {
fulltext,
@@ -10601,6 +10605,18 @@ impl<'a> Parser<'a> {
self.parse_parenthesized_column_list_inner(optional, allow_empty, |p| p.parse_identifier())
}
+ pub fn parse_parenthesized_index_column_list(
+ &mut self,
+ optional: IsOptional,
+ allow_empty: bool,
+ ) -> Result<Vec<IndexColumn>, ParserError> {
+ self.parse_parenthesized_column_list_inner(
+ optional,
+ allow_empty,
+ |p| p.parse_create_index_expr(),
+ )
+ }
+
/// Parses a parenthesized comma-separated list of qualified, possibly quoted identifiers.
/// For example: `(db1.sc1.tbl1.col1, db1.sc1.tbl1."col 2", ...)`
pub fn parse_parenthesized_qualified_column_list(
@@ -16537,7 +16553,7 @@ mod tests {
display_as_key: false,
name: None,
index_type: None,
- columns: vec![Ident::new("c1")],
+ columns: vec![Ident::new("c1").into()],
}
);
@@ -16548,7 +16564,7 @@ mod tests {
display_as_key: true,
name: None,
index_type: None,
- columns: vec![Ident::new("c1")],
+ columns: vec![Ident::new("c1").into()],
}
);
@@ -16559,7 +16575,10 @@ mod tests {
display_as_key: false,
name: Some(Ident::with_quote('\'', "index")),
index_type: None,
- columns: vec![Ident::new("c1"), Ident::new("c2")],
+ columns: vec![
+ Ident::new("c1").into(),
+ Ident::new("c2").into()
+ ],
}
);
@@ -16570,7 +16589,7 @@ mod tests {
display_as_key: false,
name: None,
index_type: Some(IndexType::BTree),
- columns: vec![Ident::new("c1")],
+ columns: vec![Ident::new("c1").into()],
}
);
@@ -16581,7 +16600,7 @@ mod tests {
display_as_key: false,
name: None,
index_type: Some(IndexType::Hash),
- columns: vec![Ident::new("c1")],
+ columns: vec![Ident::new("c1").into()],
}
);
@@ -16592,7 +16611,7 @@ mod tests {
display_as_key: false,
name: Some(Ident::new("idx_name")),
index_type: Some(IndexType::BTree),
- columns: vec![Ident::new("c1")],
+ columns: vec![Ident::new("c1").into()],
}
);
@@ -16603,7 +16622,7 @@ mod tests {
display_as_key: false,
name: Some(Ident::new("idx_name")),
index_type: Some(IndexType::Hash),
- columns: vec![Ident::new("c1")],
+ columns: vec![Ident::new("c1").into()],
}
);
}
diff --git a/tmp/agent-patch-flux-pr-1900.1-of-1.2026-02-21__03-36-16__gpt-5-1-codex-mini/app/tests/sqlparser_mysql.rs b/app/tests/sqlparser_mysql.rs
index 540348f..7c1c2f6 100644
--- a/tmp/agent-patch-flux-pr-1900.1-of-1.2026-02-21__03-36-16__gpt-5-1-codex-mini/app/tests/sqlparser_mysql.rs
+++ b/app/tests/sqlparser_mysql.rs
@@ -665,7 +665,7 @@ fn table_constraint_unique_primary_ctor(
name: Option<Ident>,
index_name: Option<Ident>,
index_type: Option<IndexType>,
- columns: Vec<Ident>,
+ columns: Vec<IndexColumn>,
index_options: Vec<IndexOption>,
characteristics: Option<ConstraintCharacteristics>,
unique_index_type_display: Option<KeyOrIndexDisplay>,
@@ -713,7 +713,7 @@ fn parse_create_table_primary_and_unique_key() {
Some(Ident::new("bar_key")),
None,
None,
- vec![Ident::new("bar")],
+ vec![Ident::new("bar").into()],
vec![],
None,
index_type_display,
@@ -776,7 +776,10 @@ fn parse_create_table_primary_and_unique_key_with_index_options() {
Some(Ident::new("constr")),
Some(Ident::new("index_name")),
None,
- vec![Ident::new("bar"), Ident::new("var")],
+ vec![
+ Ident::new("bar").into(),
+ Ident::new("var").into()
+ ],
vec![
IndexOption::Using(IndexType::Hash),
IndexOption::Comment("yes, ".into()),
@@ -814,7 +817,7 @@ fn parse_create_table_primary_and_unique_key_with_index_type() {
None,
Some(Ident::new("index_name")),
Some(IndexType::BTree),
- vec![Ident::new("bar")],
+ vec![Ident::new("bar").into()],
vec![IndexOption::Using(IndexType::Hash)],
None,
index_type_display,