@@ -4878,14 +4878,17 @@ impl<'a> Parser<'a> {
48784878 /// Parse either `ALL`, `DISTINCT` or `DISTINCT ON (...)`. Returns [`None`] if `ALL` is parsed
48794879 /// and results in a [`ParserError`] if both `ALL` and `DISTINCT` are found.
48804880 pub fn parse_all_or_distinct(&mut self) -> Result<Option<Distinct>, ParserError> {
4881- let loc = self.peek_token().span.start;
48824881 let all = self.parse_keyword(Keyword::ALL);
48834882 let distinct = self.parse_keyword(Keyword::DISTINCT);
48844883 if !distinct {
48854884 return Ok(None);
48864885 }
48874886 if all {
4888- return parser_err!("Cannot specify both ALL and DISTINCT".to_string(), loc);
4887+ self.prev_token();
4888+ return self.expected(
4889+ "ALL alone without DISTINCT or DISTINCTROW",
4890+ self.peek_token(),
4891+ );
48894892 }
48904893 let on = self.parse_keyword(Keyword::ON);
48914894 if !on {
@@ -13794,6 +13797,7 @@ impl<'a> Parser<'a> {
1379413797 return Ok(Select {
1379513798 select_token: AttachedToken(from_token),
1379613799 distinct: None,
13800+ select_modifiers: SelectModifiers::default(),
1379713801 top: None,
1379813802 top_before_distinct: false,
1379913803 projection: vec![],
@@ -13822,13 +13826,26 @@ impl<'a> Parser<'a> {
1382213826 let select_token = self.expect_keyword(Keyword::SELECT)?;
1382313827 let value_table_mode = self.parse_value_table_mode()?;
1382413828
13829+ let (select_modifiers, distinct_select_modifier) =
13830+ if self.dialect.supports_select_modifiers() {
13831+ self.parse_select_modifiers()?
13832+ } else {
13833+ (SelectModifiers::default(), None)
13834+ };
13835+
1382513836 let mut top_before_distinct = false;
1382613837 let mut top = None;
1382713838 if self.dialect.supports_top_before_distinct() && self.parse_keyword(Keyword::TOP) {
1382813839 top = Some(self.parse_top()?);
1382913840 top_before_distinct = true;
1383013841 }
13831- let distinct = self.parse_all_or_distinct()?;
13842+
13843+ let distinct = if distinct_select_modifier.is_some() {
13844+ distinct_select_modifier
13845+ } else {
13846+ self.parse_all_or_distinct()?
13847+ };
13848+
1383213849 if !self.dialect.supports_top_before_distinct() && self.parse_keyword(Keyword::TOP) {
1383313850 top = Some(self.parse_top()?);
1383413851 }
@@ -13976,6 +13993,7 @@ impl<'a> Parser<'a> {
1397613993 Ok(Select {
1397713994 select_token: AttachedToken(select_token),
1397813995 distinct,
13996+ select_modifiers,
1397913997 top,
1398013998 top_before_distinct,
1398113999 projection,
@@ -14003,6 +14021,81 @@ impl<'a> Parser<'a> {
1400314021 })
1400414022 }
1400514023
14024+ /// Parses SELECT modifiers and DISTINCT/ALL in any order.
14025+ /// Allows HIGH_PRIORITY, STRAIGHT_JOIN, SQL_SMALL_RESULT, SQL_BIG_RESULT,
14026+ /// SQL_BUFFER_RESULT, SQL_NO_CACHE, SQL_CALC_FOUND_ROWS and DISTINCT/DISTINCTROW/ALL
14027+ /// to appear in any order.
14028+ /// Returns (SelectModifiers, Option<Distinct>).
14029+ fn parse_select_modifiers(
14030+ &mut self,
14031+ ) -> Result<(SelectModifiers, Option<Distinct>), ParserError> {
14032+ let mut modifiers = SelectModifiers::default();
14033+ let mut distinct: Option<Distinct> = None;
14034+ let mut has_all = false;
14035+
14036+ let keywords = &[
14037+ Keyword::ALL,
14038+ Keyword::DISTINCT,
14039+ Keyword::DISTINCTROW,
14040+ Keyword::HIGH_PRIORITY,
14041+ Keyword::STRAIGHT_JOIN,
14042+ Keyword::SQL_SMALL_RESULT,
14043+ Keyword::SQL_BIG_RESULT,
14044+ Keyword::SQL_BUFFER_RESULT,
14045+ Keyword::SQL_NO_CACHE,
14046+ Keyword::SQL_CALC_FOUND_ROWS,
14047+ ];
14048+
14049+ while let Some(keyword) = self.parse_one_of_keywords(keywords) {
14050+ match keyword {
14051+ Keyword::ALL => {
14052+ if has_all {
14053+ self.prev_token();
14054+ return self.expected("SELECT without duplicate ALL", self.peek_token());
14055+ }
14056+ if distinct.is_some() {
14057+ self.prev_token();
14058+ return self.expected("DISTINCT alone without ALL", self.peek_token());
14059+ }
14060+ has_all = true;
14061+ }
14062+ Keyword::DISTINCT | Keyword::DISTINCTROW => {
14063+ if distinct.is_some() {
14064+ self.prev_token();
14065+ return self.expected(
14066+ "SELECT without duplicate DISTINCT or DISTINCTROW",
14067+ self.peek_token(),
14068+ );
14069+ }
14070+ if has_all {
14071+ self.prev_token();
14072+ return self.expected(
14073+ "ALL alone without DISTINCT or DISTINCTROW",
14074+ self.peek_token(),
14075+ );
14076+ }
14077+ distinct = Some(Distinct::Distinct);
14078+ }
14079+ Keyword::HIGH_PRIORITY => modifiers.high_priority = true,
14080+ Keyword::STRAIGHT_JOIN => modifiers.straight_join = true,
14081+ Keyword::SQL_SMALL_RESULT => modifiers.sql_small_result = true,
14082+ Keyword::SQL_BIG_RESULT => modifiers.sql_big_result = true,
14083+ Keyword::SQL_BUFFER_RESULT => modifiers.sql_buffer_result = true,
14084+ Keyword::SQL_NO_CACHE => modifiers.sql_no_cache = true,
14085+ Keyword::SQL_CALC_FOUND_ROWS => modifiers.sql_calc_found_rows = true,
14086+ _ => {
14087+ self.prev_token();
14088+ return self.expected(
14089+ "HIGH_PRIORITY, STRAIGHT_JOIN, or other MySQL select modifier",
14090+ self.peek_token(),
14091+ );
14092+ }
14093+ }
14094+ }
14095+
14096+ Ok((modifiers, distinct))
14097+ }
14098+
1400614099 fn parse_value_table_mode(&mut self) -> Result<Option<ValueTableMode>, ParserError> {
1400714100 if !dialect_of!(self is BigQueryDialect) {
1400814101 return Ok(None);
0 commit comments