diff --git a/src/parser/mod.rs b/src/parser/mod.rs index dc0258418..4c689c48a 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -20,6 +20,8 @@ use alloc::{ vec, vec::Vec, }; +#[cfg(feature = "bigdecimal-sql")] +use bigdecimal::BigDecimal; use core::fmt; use std::collections::BTreeSet; @@ -5769,9 +5771,25 @@ impl<'a> Parser<'a> { value.verify_duration()?; let by = if self.parse_keyword(Keyword::BY) { self.expect_token(&Token::LParen)?; - let by = self.parse_comma_separated(Parser::parse_expr)?; - self.expect_token(&Token::RParen)?; - by + if self.consume_token(&Token::RParen) { + // for case like `by ()` + // The user explicitly specifies that the aggregation key is empty. In this case, there is no aggregation key. + // All data will be aggregated into a group, which is equivalent to using a random constant as the aggregation key. + // Therefore, in this case, the constant 1 is used directly as the aggregation key. + // `()` == `(1)` + #[cfg(not(feature = "bigdecimal-sql"))] + { + vec![Expr::Value(Value::Number("1".into(), false))] + } + #[cfg(feature = "bigdecimal-sql")] + { + vec![Expr::Value(Value::Number(BigDecimal::from(1), false))] + } + } else { + let by = self.parse_comma_separated(Parser::parse_expr)?; + self.expect_token(&Token::RParen)?; + by + } } else { vec![] }; diff --git a/tests/sqlparser_common.rs b/tests/sqlparser_common.rs index da5283121..8970b8f53 100644 --- a/tests/sqlparser_common.rs +++ b/tests/sqlparser_common.rs @@ -7415,6 +7415,10 @@ fn parse_range_select() { assert_sql("SELECT rate(metrics) RANGE '5m', sum(metrics) RANGE '10m' FILL MAX, sum(metrics) RANGE '10m' FROM t ALIGN '1h' by ((a+1)/2, b) FILL NULL;", "SELECT range_fn(rate(metrics), '5m', 'NULL', '2', (a + 1) / 2, b, '1h'), range_fn(sum(metrics), '10m', 'MAX', '2', (a + 1) / 2, b, '1h'), range_fn(sum(metrics), '10m', 'NULL', '2', (a + 1) / 2, b, '1h') FROM t GROUP BY a, b"); + // explicit empty by + assert_sql("SELECT rate(metrics) RANGE '5m', sum(metrics) RANGE '10m' FILL MAX, sum(metrics) RANGE '10m' FROM t ALIGN '1h' by () FILL NULL;", + "SELECT range_fn(rate(metrics), '5m', 'NULL', '1', 1, '1h'), range_fn(sum(metrics), '10m', 'MAX', '1', 1, '1h'), range_fn(sum(metrics), '10m', 'NULL', '1', 1, '1h') FROM t"); + // expression1 assert_sql( "SELECT avg(a/2 + 1) RANGE '5m' FILL NULL FROM t ALIGN '1h' FILL NULL;",