Skip to content

Commit d66b2db

Browse files
committed
[MySQL, Oracle] Parse optimizer hints for UPDATEs
1 parent 61727e4 commit d66b2db

7 files changed

Lines changed: 25 additions & 0 deletions

File tree

src/ast/dml.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,11 @@ impl Display for Delete {
265265
pub struct Update {
266266
/// Token for the `UPDATE` keyword
267267
pub update_token: AttachedToken,
268+
/// A query optimizer hint
269+
///
270+
/// [MySQL](https://dev.mysql.com/doc/refman/8.4/en/optimizer-hints.html)
271+
/// [Oracle](https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/Comments.html#GUID-D316D545-89E2-4D54-977F-FC97815CD62E)
272+
pub optimizer_hint: Option<OptimizerHint>,
268273
/// TABLE
269274
pub table: TableWithJoins,
270275
/// Column assignments
@@ -284,6 +289,10 @@ pub struct Update {
284289
impl Display for Update {
285290
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
286291
f.write_str("UPDATE ")?;
292+
if let Some(hint) = self.optimizer_hint.as_ref() {
293+
hint.fmt(f)?;
294+
f.write_str(" ")?;
295+
}
287296
if let Some(or) = &self.or {
288297
or.fmt(f)?;
289298
f.write_str(" ")?;

src/ast/spans.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -927,6 +927,7 @@ impl Spanned for Update {
927927
fn span(&self) -> Span {
928928
let Update {
929929
update_token,
930+
optimizer_hint: _,
930931
table,
931932
assignments,
932933
from,

src/parser/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17011,6 +17011,7 @@ impl<'a> Parser<'a> {
1701117011

1701217012
/// Parse an `UPDATE` statement and return `Statement::Update`.
1701317013
pub fn parse_update(&mut self, update_token: TokenWithSpan) -> Result<Statement, ParserError> {
17014+
let optimizer_hint = self.parse_optional_optimizer_hint()?;
1701417015
let or = self.parse_conflict_clause();
1701517016
let table = self.parse_table_and_joins()?;
1701617017
let from_before_set = if self.parse_keyword(Keyword::FROM) {
@@ -17046,6 +17047,7 @@ impl<'a> Parser<'a> {
1704617047
};
1704717048
Ok(Update {
1704817049
update_token: update_token.into(),
17050+
optimizer_hint,
1704917051
table,
1705017052
assignments,
1705117053
from,

tests/sqlparser_common.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,7 @@ fn parse_update_set_from() {
457457
stmt,
458458
Statement::Update(Update {
459459
update_token: AttachedToken::empty(),
460+
optimizer_hint: None,
460461
table: TableWithJoins {
461462
relation: table_from_name(ObjectName::from(vec![Ident::new("t1")])),
462463
joins: vec![],
@@ -550,6 +551,7 @@ fn parse_update_with_table_alias() {
550551
returning,
551552
or: None,
552553
limit: None,
554+
optimizer_hint: None,
553555
update_token: _,
554556
}) => {
555557
assert_eq!(

tests/sqlparser_mysql.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2635,6 +2635,7 @@ fn parse_update_with_joins() {
26352635
returning,
26362636
or: None,
26372637
limit: None,
2638+
optimizer_hint: None,
26382639
update_token: _,
26392640
}) => {
26402641
assert_eq!(
@@ -4385,4 +4386,10 @@ fn test_optimizer_hints() {
43854386
mysql_dialect.verified_stmt("\
43864387
REPLACE /*+ foobar */ INTO test \
43874388
VALUES (1, 'Old', '2014-08-20 18:47:00')");
4389+
4390+
// ~ updates
4391+
mysql_dialect.verified_stmt("\
4392+
UPDATE /*+ quux */ table_name \
4393+
SET column1 = 1 \
4394+
WHERE 1 = 1");
43884395
}

tests/sqlparser_oracle.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,4 +373,7 @@ fn test_optimizer_hints() {
373373
oracle_dialect.verified_stmt(
374374
"INSERT /*+ append */ INTO t1 SELECT * FROM all_objects");
375375

376+
// ~ updates
377+
oracle_dialect.verified_stmt(
378+
"UPDATE /*+ DISABLE_PARALLEL_DML */ table_name SET column1 = 1");
376379
}

tests/sqlparser_sqlite.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,7 @@ fn parse_update_tuple_row_values() {
477477
assert_eq!(
478478
sqlite().verified_stmt("UPDATE x SET (a, b) = (1, 2)"),
479479
Statement::Update(Update {
480+
optimizer_hint: None,
480481
or: None,
481482
assignments: vec![Assignment {
482483
target: AssignmentTarget::Tuple(vec![

0 commit comments

Comments
 (0)