agent_patch
runs/2026-02-21__03-36-16__gpt-5-1-codex-mini/flux-pr-2172/flux-pr-2172.1-of-1.2026-02-21__03-36-16__gpt-5-1-codex-mini/agent-logs/agent.patch
33423 bytes
diff --git a/tmp/agent-patch-flux-pr-2172.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 08448ca..279e4ce 100644
--- a/tmp/agent-patch-flux-pr-2172.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
@@ -348,8 +348,10 @@ pub struct Select {
/// [MySQL](https://dev.mysql.com/doc/refman/8.4/en/optimizer-hints.html)
/// [Oracle](https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/Comments.html#GUID-D316D545-89E2-4D54-977F-FC97815CD62E)
pub optimizer_hint: Option<OptimizerHint>,
- /// `SELECT [DISTINCT] ...`
+ /// `SELECT [ALL | DISTINCT | DISTINCTROW] ...`
+ pub all: bool,
pub distinct: Option<Distinct>,
+ pub modifiers: Vec<SelectModifier>,
/// MSSQL syntax: `TOP (<N>) [ PERCENT ] [ WITH TIES ]`
pub top: Option<Top>,
/// Whether the top was located before `ALL`/`DISTINCT`
@@ -401,6 +403,45 @@ pub struct Select {
pub flavor: SelectFlavor,
}
+/// MySQL-specific modifiers that can appear after `SELECT`.
+#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
+#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
+#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
+pub enum SelectModifier {
+ /// HIGH_PRIORITY
+ HighPriority,
+ /// STRAIGHT_JOIN
+ StraightJoin,
+ /// SQL_SMALL_RESULT
+ SqlSmallResult,
+ /// SQL_BIG_RESULT
+ SqlBigResult,
+ /// SQL_BUFFER_RESULT
+ SqlBufferResult,
+ /// SQL_NO_CACHE
+ SqlNoCache,
+ /// SQL_CALC_FOUND_ROWS
+ SqlCalcFoundRows,
+ /// DISTINCTROW
+ DistinctRow,
+}
+
+impl fmt::Display for SelectModifier {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ use SelectModifier::*;
+ f.write_str(match self {
+ HighPriority => "HIGH_PRIORITY",
+ StraightJoin => "STRAIGHT_JOIN",
+ SqlSmallResult => "SQL_SMALL_RESULT",
+ SqlBigResult => "SQL_BIG_RESULT",
+ SqlBufferResult => "SQL_BUFFER_RESULT",
+ SqlNoCache => "SQL_NO_CACHE",
+ SqlCalcFoundRows => "SQL_CALC_FOUND_ROWS",
+ DistinctRow => "DISTINCTROW",
+ })
+ }
+}
+
impl fmt::Display for Select {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self.flavor {
@@ -431,10 +472,22 @@ impl fmt::Display for Select {
top.fmt(f)?;
}
}
- if let Some(ref distinct) = self.distinct {
+
+ if self.all {
+ f.write_str(" ALL")?;
+ }
+
+ let has_distinct_row = self
+ .modifiers
+ .iter()
+ .any(|modifier| matches!(modifier, SelectModifier::DistinctRow));
+ if has_distinct_row {
+ f.write_str(" DISTINCTROW")?;
+ } else if let Some(ref distinct) = self.distinct {
f.write_str(" ")?;
distinct.fmt(f)?;
}
+
if let Some(ref top) = self.top {
if !self.top_before_distinct {
f.write_str(" ")?;
@@ -442,6 +495,14 @@ impl fmt::Display for Select {
}
}
+ for modifier in &self.modifiers {
+ if matches!(modifier, SelectModifier::DistinctRow) {
+ continue;
+ }
+ f.write_str(" ")?;
+ modifier.fmt(f)?;
+ }
+
if !self.projection.is_empty() {
indented_list(f, &self.projection)?;
}
diff --git a/tmp/agent-patch-flux-pr-2172.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 60c983f..dcac6ec 100644
--- a/tmp/agent-patch-flux-pr-2172.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
@@ -2237,7 +2237,9 @@ impl Spanned for Select {
let Select {
select_token,
optimizer_hint: _,
+ all: _,
distinct: _, // todo
+ modifiers: _,
top: _, // todo, mysql specific
projection,
exclude: _,
diff --git a/tmp/agent-patch-flux-pr-2172.1-of-1.2026-02-21__03-36-16__gpt-5-1-codex-mini/app/src/dialect/mod.rs b/app/src/dialect/mod.rs
index 477d60f..2ad9472 100644
--- a/tmp/agent-patch-flux-pr-2172.1-of-1.2026-02-21__03-36-16__gpt-5-1-codex-mini/app/src/dialect/mod.rs
+++ b/app/src/dialect/mod.rs
@@ -691,6 +691,12 @@ pub trait Dialect: Debug + Any {
false
}
+ /// Returns true if the dialect supports MySQL-style SELECT modifiers such as
+ /// HIGH_PRIORITY, STRAIGHT_JOIN, etc.
+ fn supports_select_modifiers(&self) -> bool {
+ false
+ }
+
/// Returns true if the dialect supports specifying multiple options
/// in a `CREATE TABLE` statement for the structure of the new table. For example:
/// `CREATE TABLE t (a INT, b INT) AS SELECT 1 AS b, 2 AS a`
diff --git a/tmp/agent-patch-flux-pr-2172.1-of-1.2026-02-21__03-36-16__gpt-5-1-codex-mini/app/src/dialect/mysql.rs b/app/src/dialect/mysql.rs
index ad3ba6f..cc89547 100644
--- a/tmp/agent-patch-flux-pr-2172.1-of-1.2026-02-21__03-36-16__gpt-5-1-codex-mini/app/src/dialect/mysql.rs
+++ b/app/src/dialect/mysql.rs
@@ -186,6 +186,10 @@ impl Dialect for MySqlDialect {
fn supports_comment_optimizer_hint(&self) -> bool {
true
}
+
+ fn supports_select_modifiers(&self) -> bool {
+ true
+ }
}
/// `LOCK TABLES`
diff --git a/tmp/agent-patch-flux-pr-2172.1-of-1.2026-02-21__03-36-16__gpt-5-1-codex-mini/app/src/keywords.rs b/app/src/keywords.rs
index 964e4b3..2e26bda 100644
--- a/tmp/agent-patch-flux-pr-2172.1-of-1.2026-02-21__03-36-16__gpt-5-1-codex-mini/app/src/keywords.rs
+++ b/app/src/keywords.rs
@@ -333,6 +333,7 @@ define_keywords!(
DISCARD,
DISCONNECT,
DISTINCT,
+ DISTINCTROW,
DISTRIBUTE,
DIV,
DO,
@@ -956,6 +957,11 @@ define_keywords!(
SQLEXCEPTION,
SQLSTATE,
SQLWARNING,
+ SQL_BIG_RESULT,
+ SQL_BUFFER_RESULT,
+ SQL_CALC_FOUND_ROWS,
+ SQL_NO_CACHE,
+ SQL_SMALL_RESULT,
SQRT,
SRID,
STABLE,
diff --git a/tmp/agent-patch-flux-pr-2172.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 5fa224f..1a92d72 100644
--- a/tmp/agent-patch-flux-pr-2172.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
@@ -4925,19 +4925,19 @@ impl<'a> Parser<'a> {
/// Parse either `ALL`, `DISTINCT` or `DISTINCT ON (...)`. Returns [`None`] if `ALL` is parsed
/// and results in a [`ParserError`] if both `ALL` and `DISTINCT` are found.
- pub fn parse_all_or_distinct(&mut self) -> Result<Option<Distinct>, ParserError> {
+ pub fn parse_all_or_distinct(&mut self) -> Result<(bool, Option<Distinct>), ParserError> {
let loc = self.peek_token().span.start;
let all = self.parse_keyword(Keyword::ALL);
let distinct = self.parse_keyword(Keyword::DISTINCT);
if !distinct {
- return Ok(None);
+ return Ok((all, None));
}
if all {
return parser_err!("Cannot specify both ALL and DISTINCT".to_string(), loc);
}
let on = self.parse_keyword(Keyword::ON);
if !on {
- return Ok(Some(Distinct::Distinct));
+ return Ok((false, Some(Distinct::Distinct)));
}
self.expect_token(&Token::LParen)?;
@@ -4948,7 +4948,7 @@ impl<'a> Parser<'a> {
self.parse_comma_separated(Parser::parse_expr)?
};
self.expect_token(&Token::RParen)?;
- Ok(Some(Distinct::On(col_names)))
+ Ok((false, Some(Distinct::On(col_names))))
}
/// Parse a SQL CREATE statement
@@ -13860,6 +13860,8 @@ impl<'a> Parser<'a> {
return Ok(Select {
select_token: AttachedToken(from_token),
optimizer_hint: None,
+ all: false,
+ modifiers: vec![],
distinct: None,
top: None,
top_before_distinct: false,
@@ -13896,7 +13898,13 @@ impl<'a> Parser<'a> {
top = Some(self.parse_top()?);
top_before_distinct = true;
}
- let distinct = self.parse_all_or_distinct()?;
+ let (all, distinct, modifiers) = if self.dialect.supports_select_modifiers() {
+ let state = self.parse_select_mysql_modifiers()?;
+ (state.all, state.distinct, state.modifiers)
+ } else {
+ let (all, distinct) = self.parse_all_or_distinct()?;
+ (all, distinct, vec![])
+ };
if !self.dialect.supports_top_before_distinct() && self.parse_keyword(Keyword::TOP) {
top = Some(self.parse_top()?);
}
@@ -14043,6 +14051,8 @@ impl<'a> Parser<'a> {
Ok(Select {
select_token: AttachedToken(select_token),
optimizer_hint,
+ all,
+ modifiers,
distinct,
top,
top_before_distinct,
@@ -14071,6 +14081,93 @@ impl<'a> Parser<'a> {
})
}
+ struct SelectModifierState {
+ all: bool,
+ distinct: Option<Distinct>,
+ modifiers: Vec<SelectModifier>,
+ }
+
+ fn parse_select_mysql_modifiers(&mut self) -> Result<SelectModifierState, ParserError> {
+ let mut state = SelectModifierState {
+ all: false,
+ distinct: None,
+ modifiers: Vec::new(),
+ };
+
+ loop {
+ let loc = self.peek_token().span.start;
+ if self.parse_keyword(Keyword::ALL) {
+ if state.distinct.is_some() {
+ return parser_err!("Cannot specify both ALL and DISTINCT".to_string(), loc);
+ }
+ state.all = true;
+ continue;
+ }
+ if self.parse_keyword(Keyword::DISTINCT) {
+ if state.all {
+ return parser_err!("Cannot specify both ALL and DISTINCT".to_string(), loc);
+ }
+ if state.distinct.is_some() {
+ return parser_err!("Cannot specify DISTINCT twice".to_string(), loc);
+ }
+
+ let distinct_value = if self.parse_keyword(Keyword::ON) {
+ self.expect_token(&Token::LParen)?;
+ let col_names = if self.consume_token(&Token::RParen) {
+ self.prev_token();
+ Vec::new()
+ } else {
+ self.parse_comma_separated(Parser::parse_expr)?
+ };
+ self.expect_token(&Token::RParen)?;
+ Distinct::On(col_names)
+ } else {
+ Distinct::Distinct
+ };
+ state.distinct = Some(distinct_value);
+ continue;
+ }
+ if self.parse_keyword(Keyword::DISTINCTROW) {
+ if state.all {
+ return parser_err!("Cannot specify both ALL and DISTINCT".to_string(), loc);
+ }
+ if state.distinct.is_some() {
+ return parser_err!("Cannot specify DISTINCT twice".to_string(), loc);
+ }
+ state.distinct = Some(Distinct::Distinct);
+ state.modifiers.push(SelectModifier::DistinctRow);
+ continue;
+ }
+ if let Some(modifier) = self.parse_mysql_select_modifier_keyword() {
+ state.modifiers.push(modifier);
+ continue;
+ }
+ break;
+ }
+
+ Ok(state)
+ }
+
+ fn parse_mysql_select_modifier_keyword(&mut self) -> Option<SelectModifier> {
+ if self.parse_keyword(Keyword::HIGH_PRIORITY) {
+ Some(SelectModifier::HighPriority)
+ } else if self.parse_keyword(Keyword::STRAIGHT_JOIN) {
+ Some(SelectModifier::StraightJoin)
+ } else if self.parse_keyword(Keyword::SQL_SMALL_RESULT) {
+ Some(SelectModifier::SqlSmallResult)
+ } else if self.parse_keyword(Keyword::SQL_BIG_RESULT) {
+ Some(SelectModifier::SqlBigResult)
+ } else if self.parse_keyword(Keyword::SQL_BUFFER_RESULT) {
+ Some(SelectModifier::SqlBufferResult)
+ } else if self.parse_keyword(Keyword::SQL_NO_CACHE) {
+ Some(SelectModifier::SqlNoCache)
+ } else if self.parse_keyword(Keyword::SQL_CALC_FOUND_ROWS) {
+ Some(SelectModifier::SqlCalcFoundRows)
+ } else {
+ None
+ }
+ }
+
/// Parses an optional optimizer hint at the current token position
///
/// [MySQL](https://dev.mysql.com/doc/refman/8.4/en/optimizer-hints.html#optimizer-hints-overview)
diff --git a/tmp/agent-patch-flux-pr-2172.1-of-1.2026-02-21__03-36-16__gpt-5-1-codex-mini/app/tests/sqlparser_bigquery.rs b/app/tests/sqlparser_bigquery.rs
index fb28b4d..50b47af 100644
--- a/tmp/agent-patch-flux-pr-2172.1-of-1.2026-02-21__03-36-16__gpt-5-1-codex-mini/app/tests/sqlparser_bigquery.rs
+++ b/app/tests/sqlparser_bigquery.rs
@@ -2682,7 +2682,9 @@ fn test_export_data() {
Span::empty()
)),
optimizer_hint: None,
- distinct: None,
+ all: false,
+ modifiers: vec![],
+ distinct: None,
top: None,
top_before_distinct: false,
projection: vec![
@@ -2787,7 +2789,9 @@ fn test_export_data() {
Span::empty()
)),
optimizer_hint: None,
- distinct: None,
+ all: false,
+ modifiers: vec![],
+ distinct: None,
top: None,
top_before_distinct: false,
projection: vec![
diff --git a/tmp/agent-patch-flux-pr-2172.1-of-1.2026-02-21__03-36-16__gpt-5-1-codex-mini/app/tests/sqlparser_clickhouse.rs b/app/tests/sqlparser_clickhouse.rs
index ac31a27..3d0d9fe 100644
--- a/tmp/agent-patch-flux-pr-2172.1-of-1.2026-02-21__03-36-16__gpt-5-1-codex-mini/app/tests/sqlparser_clickhouse.rs
+++ b/app/tests/sqlparser_clickhouse.rs
@@ -42,7 +42,9 @@ fn parse_map_access_expr() {
Select {
distinct: None,
optimizer_hint: None,
- select_token: AttachedToken::empty(),
+ all: false,
+ modifiers: vec![],
+select_token: AttachedToken::empty(),
top: None,
top_before_distinct: false,
projection: vec![UnnamedExpr(Expr::CompoundFieldAccess {
diff --git a/tmp/agent-patch-flux-pr-2172.1-of-1.2026-02-21__03-36-16__gpt-5-1-codex-mini/app/tests/sqlparser_common.rs b/app/tests/sqlparser_common.rs
index e6a48c7..3cc37ad 100644
--- a/tmp/agent-patch-flux-pr-2172.1-of-1.2026-02-21__03-36-16__gpt-5-1-codex-mini/app/tests/sqlparser_common.rs
+++ b/app/tests/sqlparser_common.rs
@@ -456,7 +456,9 @@ fn parse_update_set_from() {
Statement::Update(Update {
update_token: AttachedToken::empty(),
optimizer_hint: None,
- table: TableWithJoins {
+ all: false,
+ modifiers: vec![],
+table: TableWithJoins {
relation: table_from_name(ObjectName::from(vec![Ident::new("t1")])),
joins: vec![],
},
@@ -472,7 +474,9 @@ fn parse_update_set_from() {
body: Box::new(SetExpr::Select(Box::new(Select {
select_token: AttachedToken::empty(),
optimizer_hint: None,
- distinct: None,
+ all: false,
+ modifiers: vec![],
+ distinct: None,
top: None,
top_before_distinct: false,
projection: vec![
@@ -551,7 +555,9 @@ fn parse_update_with_table_alias() {
or: None,
limit: None,
optimizer_hint: None,
- update_token: _,
+ all: false,
+ modifiers: vec![],
+update_token: _,
}) => {
assert_eq!(
TableWithJoins {
@@ -1074,7 +1080,10 @@ fn parse_select_distinct_missing_paren() {
#[test]
fn parse_select_all() {
- one_statement_parses_to("SELECT ALL name FROM customer", "SELECT name FROM customer");
+ one_statement_parses_to("SELECT ALL name FROM customer", "SELECT ALL name FROM customer");
+ let select = verified_only_select("SELECT ALL name FROM customer");
+ assert!(select.all);
+ assert!(select.modifiers.is_empty());
}
#[test]
@@ -5808,7 +5817,9 @@ fn test_parse_named_window() {
let expected = Select {
select_token: AttachedToken::empty(),
optimizer_hint: None,
- distinct: None,
+ all: false,
+ modifiers: vec![],
+ distinct: None,
top: None,
top_before_distinct: false,
projection: vec![
@@ -6539,7 +6550,9 @@ fn parse_interval_and_or_xor() {
body: Box::new(SetExpr::Select(Box::new(Select {
select_token: AttachedToken::empty(),
optimizer_hint: None,
- distinct: None,
+ all: false,
+ modifiers: vec![],
+ distinct: None,
top: None,
top_before_distinct: false,
projection: vec![UnnamedExpr(Expr::Identifier(Ident {
@@ -8916,7 +8929,9 @@ fn lateral_function() {
let expected = Select {
select_token: AttachedToken::empty(),
optimizer_hint: None,
- distinct: None,
+ all: false,
+ modifiers: vec![],
+ distinct: None,
top: None,
projection: vec![SelectItem::Wildcard(WildcardAdditionalOptions::default())],
exclude: None,
@@ -9918,7 +9933,9 @@ fn parse_merge() {
body: Box::new(SetExpr::Select(Box::new(Select {
select_token: AttachedToken::empty(),
optimizer_hint: None,
- distinct: None,
+ all: false,
+ modifiers: vec![],
+ distinct: None,
top: None,
top_before_distinct: false,
projection: vec![SelectItem::Wildcard(
@@ -12322,7 +12339,9 @@ fn parse_unload() {
body: Box::new(SetExpr::Select(Box::new(Select {
select_token: AttachedToken::empty(),
optimizer_hint: None,
- distinct: None,
+ all: false,
+ modifiers: vec![],
+ distinct: None,
top: None,
top_before_distinct: false,
projection: vec![UnnamedExpr(Expr::Identifier(Ident::new("cola"))),],
@@ -12631,7 +12650,9 @@ fn parse_connect_by() {
let expect_query = Select {
select_token: AttachedToken::empty(),
optimizer_hint: None,
- distinct: None,
+ all: false,
+ modifiers: vec![],
+ distinct: None,
top: None,
top_before_distinct: false,
projection: vec![
@@ -12714,7 +12735,9 @@ fn parse_connect_by() {
Select {
select_token: AttachedToken::empty(),
optimizer_hint: None,
- distinct: None,
+ all: false,
+ modifiers: vec![],
+ distinct: None,
top: None,
top_before_distinct: false,
projection: vec![
@@ -13648,7 +13671,9 @@ fn test_extract_seconds_ok() {
body: Box::new(SetExpr::Select(Box::new(Select {
select_token: AttachedToken::empty(),
optimizer_hint: None,
- distinct: None,
+ all: false,
+ modifiers: vec![],
+ distinct: None,
top: None,
top_before_distinct: false,
projection: vec![UnnamedExpr(Expr::Extract {
@@ -15788,7 +15813,9 @@ fn test_select_from_first() {
body: Box::new(SetExpr::Select(Box::new(Select {
select_token: AttachedToken::empty(),
optimizer_hint: None,
- distinct: None,
+ all: false,
+ modifiers: vec![],
+ distinct: None,
top: None,
projection,
exclude: None,
diff --git a/tmp/agent-patch-flux-pr-2172.1-of-1.2026-02-21__03-36-16__gpt-5-1-codex-mini/app/tests/sqlparser_duckdb.rs b/app/tests/sqlparser_duckdb.rs
index 7cc710d..9b06183 100644
--- a/tmp/agent-patch-flux-pr-2172.1-of-1.2026-02-21__03-36-16__gpt-5-1-codex-mini/app/tests/sqlparser_duckdb.rs
+++ b/app/tests/sqlparser_duckdb.rs
@@ -267,7 +267,9 @@ fn test_select_union_by_name() {
left: Box::<SetExpr>::new(SetExpr::Select(Box::new(Select {
select_token: AttachedToken::empty(),
optimizer_hint: None,
- distinct: None,
+ all: false,
+ modifiers: vec![],
+ distinct: None,
top: None,
projection: vec![SelectItem::Wildcard(WildcardAdditionalOptions::default())],
exclude: None,
@@ -299,7 +301,9 @@ fn test_select_union_by_name() {
right: Box::<SetExpr>::new(SetExpr::Select(Box::new(Select {
select_token: AttachedToken::empty(),
optimizer_hint: None,
- distinct: None,
+ all: false,
+ modifiers: vec![],
+ distinct: None,
top: None,
projection: vec![SelectItem::Wildcard(WildcardAdditionalOptions::default())],
exclude: None,
diff --git a/tmp/agent-patch-flux-pr-2172.1-of-1.2026-02-21__03-36-16__gpt-5-1-codex-mini/app/tests/sqlparser_mssql.rs b/app/tests/sqlparser_mssql.rs
index d770008..fe6f465 100644
--- a/tmp/agent-patch-flux-pr-2172.1-of-1.2026-02-21__03-36-16__gpt-5-1-codex-mini/app/tests/sqlparser_mssql.rs
+++ b/app/tests/sqlparser_mssql.rs
@@ -142,6 +142,8 @@ fn parse_create_procedure() {
body: Box::new(SetExpr::Select(Box::new(Select {
select_token: AttachedToken::empty(),
optimizer_hint: None,
+ all: false,
+ modifiers: vec![],
distinct: None,
top: None,
top_before_distinct: false,
@@ -1350,6 +1352,8 @@ fn parse_substring_in_select() {
body: Box::new(SetExpr::Select(Box::new(Select {
select_token: AttachedToken::empty(),
optimizer_hint: None,
+ all: false,
+ modifiers: vec![],
distinct: Some(Distinct::Distinct),
top: None,
top_before_distinct: false,
@@ -1508,7 +1512,9 @@ fn parse_mssql_declare() {
body: Box::new(SetExpr::Select(Box::new(Select {
select_token: AttachedToken::empty(),
optimizer_hint: None,
- distinct: None,
+ all: false,
+ modifiers: vec![],
+ distinct: None,
top: None,
top_before_distinct: false,
projection: vec![SelectItem::UnnamedExpr(Expr::BinaryOp {
diff --git a/tmp/agent-patch-flux-pr-2172.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 2c94279..a8d9942 100644
--- a/tmp/agent-patch-flux-pr-2172.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
@@ -61,6 +61,34 @@ fn parse_literal_string() {
);
}
+#[test]
+fn parse_select_mysql_modifiers() {
+ let sql = "SELECT SQL_BUFFER_RESULT HIGH_PRIORITY DISTINCTROW SQL_CALC_FOUND_ROWS name FROM customer";
+ let select = mysql().verified_only_select(sql);
+ assert!(!select.all);
+ assert_eq!(select.distinct, Some(Distinct::Distinct));
+ assert_eq!(
+ select.modifiers,
+ vec![
+ SelectModifier::SqlBufferResult,
+ SelectModifier::HighPriority,
+ SelectModifier::DistinctRow,
+ SelectModifier::SqlCalcFoundRows,
+ ]
+ );
+}
+
+#[test]
+fn parse_select_mysql_all_with_modifier() {
+ let sql = "SELECT SQL_CALC_FOUND_ROWS ALL name FROM customer";
+ let select = mysql().verified_only_select(sql);
+ assert!(select.all);
+ assert_eq!(
+ select.modifiers,
+ vec![SelectModifier::SqlCalcFoundRows]
+ );
+}
+
#[test]
fn parse_flush() {
assert_eq!(
@@ -1436,7 +1464,9 @@ fn parse_escaped_quote_identifiers_with_escape() {
body: Box::new(SetExpr::Select(Box::new(Select {
select_token: AttachedToken::empty(),
optimizer_hint: None,
- distinct: None,
+ all: false,
+ modifiers: vec![],
+ distinct: None,
top: None,
top_before_distinct: false,
projection: vec![SelectItem::UnnamedExpr(Expr::Identifier(Ident {
@@ -1492,7 +1522,9 @@ fn parse_escaped_quote_identifiers_with_no_escape() {
body: Box::new(SetExpr::Select(Box::new(Select {
select_token: AttachedToken::empty(),
optimizer_hint: None,
- distinct: None,
+ all: false,
+ modifiers: vec![],
+ distinct: None,
top: None,
top_before_distinct: false,
projection: vec![SelectItem::UnnamedExpr(Expr::Identifier(Ident {
@@ -1540,7 +1572,9 @@ fn parse_escaped_backticks_with_escape() {
body: Box::new(SetExpr::Select(Box::new(Select {
select_token: AttachedToken::empty(),
optimizer_hint: None,
- distinct: None,
+ all: false,
+ modifiers: vec![],
+ distinct: None,
top: None,
top_before_distinct: false,
projection: vec![SelectItem::UnnamedExpr(Expr::Identifier(Ident {
@@ -1592,7 +1626,9 @@ fn parse_escaped_backticks_with_no_escape() {
body: Box::new(SetExpr::Select(Box::new(Select {
select_token: AttachedToken::empty(),
optimizer_hint: None,
- distinct: None,
+ all: false,
+ modifiers: vec![],
+ distinct: None,
top: None,
top_before_distinct: false,
projection: vec![SelectItem::UnnamedExpr(Expr::Identifier(Ident {
@@ -2412,7 +2448,9 @@ fn parse_select_with_numeric_prefix_column_name() {
Box::new(SetExpr::Select(Box::new(Select {
select_token: AttachedToken::empty(),
optimizer_hint: None,
- distinct: None,
+ all: false,
+ modifiers: vec![],
+ distinct: None,
top: None,
top_before_distinct: false,
projection: vec![SelectItem::UnnamedExpr(Expr::Identifier(Ident::new(
@@ -2587,7 +2625,9 @@ fn parse_select_with_concatenation_of_exp_number_and_numeric_prefix_column() {
Box::new(SetExpr::Select(Box::new(Select {
select_token: AttachedToken::empty(),
optimizer_hint: None,
- distinct: None,
+ all: false,
+ modifiers: vec![],
+ distinct: None,
top: None,
top_before_distinct: false,
projection: vec![
@@ -2655,7 +2695,9 @@ fn parse_update_with_joins() {
or: None,
limit: None,
optimizer_hint: None,
- update_token: _,
+ all: false,
+ modifiers: vec![],
+update_token: _,
}) => {
assert_eq!(
TableWithJoins {
@@ -3221,6 +3263,8 @@ fn parse_substring_in_select() {
body: Box::new(SetExpr::Select(Box::new(Select {
select_token: AttachedToken::empty(),
optimizer_hint: None,
+ all: false,
+ modifiers: vec![],
distinct: Some(Distinct::Distinct),
top: None,
top_before_distinct: false,
@@ -3545,7 +3589,9 @@ fn parse_hex_string_introducer() {
body: Box::new(SetExpr::Select(Box::new(Select {
select_token: AttachedToken::empty(),
optimizer_hint: None,
- distinct: None,
+ all: false,
+ modifiers: vec![],
+ distinct: None,
top: None,
top_before_distinct: false,
projection: vec![SelectItem::UnnamedExpr(Expr::Prefixed {
diff --git a/tmp/agent-patch-flux-pr-2172.1-of-1.2026-02-21__03-36-16__gpt-5-1-codex-mini/app/tests/sqlparser_postgres.rs b/app/tests/sqlparser_postgres.rs
index 1f91bff..7309be7 100644
--- a/tmp/agent-patch-flux-pr-2172.1-of-1.2026-02-21__03-36-16__gpt-5-1-codex-mini/app/tests/sqlparser_postgres.rs
+++ b/app/tests/sqlparser_postgres.rs
@@ -1292,7 +1292,9 @@ fn parse_copy_to() {
body: Box::new(SetExpr::Select(Box::new(Select {
select_token: AttachedToken::empty(),
optimizer_hint: None,
- distinct: None,
+ all: false,
+ modifiers: vec![],
+ distinct: None,
top: None,
top_before_distinct: false,
projection: vec![
@@ -3073,6 +3075,8 @@ fn parse_array_subquery_expr() {
left: Box::new(SetExpr::Select(Box::new(Select {
select_token: AttachedToken::empty(),
optimizer_hint: None,
+ all: false,
+ modifiers: vec![],
distinct: None,
top: None,
top_before_distinct: false,
@@ -3100,6 +3104,8 @@ fn parse_array_subquery_expr() {
right: Box::new(SetExpr::Select(Box::new(Select {
select_token: AttachedToken::empty(),
optimizer_hint: None,
+ all: false,
+ modifiers: vec![],
distinct: None,
top: None,
top_before_distinct: false,
@@ -5395,7 +5401,9 @@ fn test_simple_postgres_insert_with_alias() {
Statement::Insert(Insert {
insert_token: AttachedToken::empty(),
optimizer_hint: None,
- or: None,
+ all: false,
+ modifiers: vec![],
+or: None,
ignore: false,
into: true,
table: TableObject::TableName(ObjectName::from(vec![Ident {
@@ -5467,7 +5475,9 @@ fn test_simple_postgres_insert_with_alias() {
Statement::Insert(Insert {
insert_token: AttachedToken::empty(),
optimizer_hint: None,
- or: None,
+ all: false,
+ modifiers: vec![],
+or: None,
ignore: false,
into: true,
table: TableObject::TableName(ObjectName::from(vec![Ident {
@@ -5541,7 +5551,9 @@ fn test_simple_insert_with_quoted_alias() {
Statement::Insert(Insert {
insert_token: AttachedToken::empty(),
optimizer_hint: None,
- or: None,
+ all: false,
+ modifiers: vec![],
+or: None,
ignore: false,
into: true,
table: TableObject::TableName(ObjectName::from(vec![Ident {
diff --git a/tmp/agent-patch-flux-pr-2172.1-of-1.2026-02-21__03-36-16__gpt-5-1-codex-mini/app/tests/sqlparser_sqlite.rs b/app/tests/sqlparser_sqlite.rs
index da311ac..910445c 100644
--- a/tmp/agent-patch-flux-pr-2172.1-of-1.2026-02-21__03-36-16__gpt-5-1-codex-mini/app/tests/sqlparser_sqlite.rs
+++ b/app/tests/sqlparser_sqlite.rs
@@ -478,7 +478,9 @@ fn parse_update_tuple_row_values() {
sqlite().verified_stmt("UPDATE x SET (a, b) = (1, 2)"),
Statement::Update(Update {
optimizer_hint: None,
- or: None,
+ all: false,
+ modifiers: vec![],
+or: None,
assignments: vec![Assignment {
target: AssignmentTarget::Tuple(vec![
ObjectName::from(vec![Ident::new("a"),]),