snowflake: fix rendering of SELECT TOP (#1070)

This commit is contained in:
Joey Hain 2023-12-22 10:43:31 -08:00 committed by GitHub
parent 1baec96685
commit 2950a843c3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 53 additions and 11 deletions

View file

@ -42,8 +42,8 @@ pub use self::query::{
JsonTableColumnErrorHandling, LateralView, LockClause, LockType, NamedWindowDefinition,
NonBlock, Offset, OffsetRows, OrderByExpr, Query, RenameSelectItem, ReplaceSelectElement,
ReplaceSelectItem, Select, SelectInto, SelectItem, SetExpr, SetOperator, SetQuantifier, Table,
TableAlias, TableFactor, TableVersion, TableWithJoins, Top, Values, WildcardAdditionalOptions,
With,
TableAlias, TableFactor, TableVersion, TableWithJoins, Top, TopQuantity, Values,
WildcardAdditionalOptions, With,
};
pub use self::value::{
escape_quoted_string, DateTimeField, DollarQuotedString, TrimWhereField, Value,

View file

@ -1278,9 +1278,21 @@ impl fmt::Display for Distinct {
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct Top {
/// SQL semantic equivalent of LIMIT but with same structure as FETCH.
/// MSSQL only.
pub with_ties: bool,
/// MSSQL only.
pub percent: bool,
pub quantity: Option<Expr>,
pub quantity: Option<TopQuantity>,
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum TopQuantity {
// A parenthesized expression. MSSQL only.
Expr(Expr),
// An unparenthesized integer constant.
Constant(u64),
}
impl fmt::Display for Top {
@ -1288,7 +1300,12 @@ impl fmt::Display for Top {
let extension = if self.with_ties { " WITH TIES" } else { "" };
if let Some(ref quantity) = self.quantity {
let percent = if self.percent { " PERCENT" } else { "" };
write!(f, "TOP ({quantity}){percent}{extension}")
match quantity {
TopQuantity::Expr(quantity) => write!(f, "TOP ({quantity}){percent}{extension}"),
TopQuantity::Constant(quantity) => {
write!(f, "TOP {quantity}{percent}{extension}")
}
}
} else {
write!(f, "TOP{extension}")
}

View file

@ -7843,9 +7843,14 @@ impl<'a> Parser<'a> {
let quantity = if self.consume_token(&Token::LParen) {
let quantity = self.parse_expr()?;
self.expect_token(&Token::RParen)?;
Some(quantity)
Some(TopQuantity::Expr(quantity))
} else {
Some(Expr::Value(self.parse_number_value()?))
let next_token = self.next_token();
let quantity = match next_token.token {
Token::Number(s, _) => s.parse::<u64>().expect("literal int"),
_ => self.expected("literal int", next_token)?,
};
Some(TopQuantity::Constant(quantity))
};
let percent = self.parse_keyword(Keyword::PERCENT);