@@ -4906,14 +4906,17 @@ impl<'a> Parser<'a> {
49064906 /// Parse either `ALL`, `DISTINCT` or `DISTINCT ON (...)`. Returns [`None`] if `ALL` is parsed
49074907 /// and results in a [`ParserError`] if both `ALL` and `DISTINCT` are found.
49084908 pub fn parse_all_or_distinct(&mut self) -> Result<Option<Distinct>, ParserError> {
4909- let loc = self.peek_token().span.start;
49104909 let all = self.parse_keyword(Keyword::ALL);
49114910 let distinct = self.parse_keyword(Keyword::DISTINCT);
49124911 if !distinct {
49134912 return Ok(None);
49144913 }
49154914 if all {
4916- return parser_err!("Cannot specify both ALL and DISTINCT".to_string(), loc);
4915+ self.prev_token();
4916+ return self.expected(
4917+ "ALL alone without DISTINCT or DISTINCTROW",
4918+ self.peek_token(),
4919+ );
49174920 }
49184921 let on = self.parse_keyword(Keyword::ON);
49194922 if !on {
@@ -13823,6 +13826,7 @@ impl<'a> Parser<'a> {
1382313826 return Ok(Select {
1382413827 select_token: AttachedToken(from_token),
1382513828 distinct: None,
13829+ select_modifiers: SelectModifiers::default(),
1382613830 top: None,
1382713831 top_before_distinct: false,
1382813832 projection: vec![],
@@ -13851,13 +13855,26 @@ impl<'a> Parser<'a> {
1385113855 let select_token = self.expect_keyword(Keyword::SELECT)?;
1385213856 let value_table_mode = self.parse_value_table_mode()?;
1385313857
13858+ let (select_modifiers, distinct_select_modifier) =
13859+ if self.dialect.supports_select_modifiers() {
13860+ self.parse_select_modifiers()?
13861+ } else {
13862+ (SelectModifiers::default(), None)
13863+ };
13864+
1385413865 let mut top_before_distinct = false;
1385513866 let mut top = None;
1385613867 if self.dialect.supports_top_before_distinct() && self.parse_keyword(Keyword::TOP) {
1385713868 top = Some(self.parse_top()?);
1385813869 top_before_distinct = true;
1385913870 }
13860- let distinct = self.parse_all_or_distinct()?;
13871+
13872+ let distinct = if distinct_select_modifier.is_some() {
13873+ distinct_select_modifier
13874+ } else {
13875+ self.parse_all_or_distinct()?
13876+ };
13877+
1386113878 if !self.dialect.supports_top_before_distinct() && self.parse_keyword(Keyword::TOP) {
1386213879 top = Some(self.parse_top()?);
1386313880 }
@@ -14005,6 +14022,7 @@ impl<'a> Parser<'a> {
1400514022 Ok(Select {
1400614023 select_token: AttachedToken(select_token),
1400714024 distinct,
14025+ select_modifiers,
1400814026 top,
1400914027 top_before_distinct,
1401014028 projection,
@@ -14032,6 +14050,79 @@ impl<'a> Parser<'a> {
1403214050 })
1403314051 }
1403414052
14053+ /// Parses SELECT modifiers and DISTINCT/ALL in any order. Allows HIGH_PRIORITY, STRAIGHT_JOIN,
14054+ /// SQL_SMALL_RESULT, SQL_BIG_RESULT, SQL_BUFFER_RESULT, SQL_NO_CACHE, SQL_CALC_FOUND_ROWS and
14055+ /// DISTINCT/DISTINCTROW/ALL to appear in any order.
14056+ fn parse_select_modifiers(
14057+ &mut self,
14058+ ) -> Result<(SelectModifiers, Option<Distinct>), ParserError> {
14059+ let mut modifiers = SelectModifiers::default();
14060+ let mut distinct: Option<Distinct> = None;
14061+ let mut has_all = false;
14062+
14063+ let keywords = &[
14064+ Keyword::ALL,
14065+ Keyword::DISTINCT,
14066+ Keyword::DISTINCTROW,
14067+ Keyword::HIGH_PRIORITY,
14068+ Keyword::STRAIGHT_JOIN,
14069+ Keyword::SQL_SMALL_RESULT,
14070+ Keyword::SQL_BIG_RESULT,
14071+ Keyword::SQL_BUFFER_RESULT,
14072+ Keyword::SQL_NO_CACHE,
14073+ Keyword::SQL_CALC_FOUND_ROWS,
14074+ ];
14075+
14076+ while let Some(keyword) = self.parse_one_of_keywords(keywords) {
14077+ match keyword {
14078+ Keyword::ALL => {
14079+ if has_all {
14080+ self.prev_token();
14081+ return self.expected("SELECT without duplicate ALL", self.peek_token());
14082+ }
14083+ if distinct.is_some() {
14084+ self.prev_token();
14085+ return self.expected("DISTINCT alone without ALL", self.peek_token());
14086+ }
14087+ has_all = true;
14088+ }
14089+ Keyword::DISTINCT | Keyword::DISTINCTROW => {
14090+ if distinct.is_some() {
14091+ self.prev_token();
14092+ return self.expected(
14093+ "SELECT without duplicate DISTINCT or DISTINCTROW",
14094+ self.peek_token(),
14095+ );
14096+ }
14097+ if has_all {
14098+ self.prev_token();
14099+ return self.expected(
14100+ "ALL alone without DISTINCT or DISTINCTROW",
14101+ self.peek_token(),
14102+ );
14103+ }
14104+ distinct = Some(Distinct::Distinct);
14105+ }
14106+ Keyword::HIGH_PRIORITY => modifiers.high_priority = true,
14107+ Keyword::STRAIGHT_JOIN => modifiers.straight_join = true,
14108+ Keyword::SQL_SMALL_RESULT => modifiers.sql_small_result = true,
14109+ Keyword::SQL_BIG_RESULT => modifiers.sql_big_result = true,
14110+ Keyword::SQL_BUFFER_RESULT => modifiers.sql_buffer_result = true,
14111+ Keyword::SQL_NO_CACHE => modifiers.sql_no_cache = true,
14112+ Keyword::SQL_CALC_FOUND_ROWS => modifiers.sql_calc_found_rows = true,
14113+ _ => {
14114+ self.prev_token();
14115+ return self.expected(
14116+ "HIGH_PRIORITY, STRAIGHT_JOIN, or other MySQL select modifier",
14117+ self.peek_token(),
14118+ );
14119+ }
14120+ }
14121+ }
14122+
14123+ Ok((modifiers, distinct))
14124+ }
14125+
1403514126 fn parse_value_table_mode(&mut self) -> Result<Option<ValueTableMode>, ParserError> {
1403614127 if !dialect_of!(self is BigQueryDialect) {
1403714128 return Ok(None);
0 commit comments