Skip to content

Commit b2ceea9

Browse files
committed
Code review comments
1 parent 5a3af57 commit b2ceea9

File tree

4 files changed

+43
-20
lines changed

4 files changed

+43
-20
lines changed

src/ast/mod.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7354,6 +7354,9 @@ impl Display for UtilityOption {
73547354
}
73557355
}
73567356

7357+
/// Represents the different options available for a SHOW <OBJECT>
7358+
/// statement to filter the results. Example from Snowflake:
7359+
/// https://docs.snowflake.com/en/sql-reference/sql/show-tables
73577360
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
73587361
pub struct ShowStatementOptions {
73597362
pub show_in: Option<ShowStatementIn>,
@@ -7365,7 +7368,7 @@ pub struct ShowStatementOptions {
73657368

73667369
impl Display for ShowStatementOptions {
73677370
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7368-
let (life_in_infix, like_in_suffix) = match &self.filter_position {
7371+
let (like_in_infix, like_in_suffix) = match &self.filter_position {
73697372
Some(ShowStatementFilterPosition::Infix(filter)) => {
73707373
(format!(" {filter}"), "".to_string())
73717374
}
@@ -7376,7 +7379,7 @@ impl Display for ShowStatementOptions {
73767379
};
73777380
write!(
73787381
f,
7379-
"{life_in_infix}{show_in}{starts_with}{limit}{from}{like_in_suffix}",
7382+
"{like_in_infix}{show_in}{starts_with}{limit}{from}{like_in_suffix}",
73807383
show_in = match &self.show_in {
73817384
Some(i) => format!(" {i}"),
73827385
None => String::new(),

src/keywords.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ define_keywords!(
9292
AND,
9393
ANTI,
9494
ANY,
95+
APPLICATION,
9596
APPLY,
9697
ARCHIVE,
9798
ARE,

src/parser/mod.rs

Lines changed: 36 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3205,6 +3205,22 @@ impl<'a> Parser<'a> {
32053205
})
32063206
}
32073207

3208+
/// Look for all of the expected keywords in sequence, without consuming them
3209+
fn peek_keyword(&mut self, expected: Keyword) -> bool {
3210+
let index = self.index;
3211+
let matched = self.parse_keyword(expected);
3212+
self.index = index;
3213+
matched
3214+
}
3215+
3216+
/// Look for all of the expected keywords in sequence, without consuming them
3217+
fn peek_keywords(&mut self, expected: &[Keyword]) -> bool {
3218+
let index = self.index;
3219+
let matched = self.parse_keywords(expected);
3220+
self.index = index;
3221+
matched
3222+
}
3223+
32083224
/// Return the first non-whitespace token that has not yet been processed
32093225
/// (or None if reached end-of-file) and mark it as processed. OK to call
32103226
/// repeatedly after reaching EOF.
@@ -12385,19 +12401,6 @@ impl<'a> Parser<'a> {
1238512401
false
1238612402
}
1238712403

12388-
/// Look for all of the expected keywords in sequence, without consuming them
12389-
fn peek_keywords(&mut self, expected: &[Keyword]) -> bool {
12390-
let index = self.index;
12391-
for kw in expected {
12392-
if !self.parse_keyword(*kw) {
12393-
self.index = index;
12394-
return false;
12395-
}
12396-
}
12397-
self.index = index;
12398-
true
12399-
}
12400-
1240112404
fn parse_show_stmt_options(&mut self) -> Result<ShowStatementOptions, ParserError> {
1240212405
let show_in;
1240312406
let mut filter_position = None;
@@ -12428,7 +12431,8 @@ impl<'a> Parser<'a> {
1242812431
let clause = match self.parse_one_of_keywords(&[Keyword::FROM, Keyword::IN]) {
1242912432
Some(Keyword::FROM) => ShowStatementInClause::FROM,
1243012433
Some(Keyword::IN) => ShowStatementInClause::IN,
12431-
_ => return Ok(None),
12434+
None => return Ok(None),
12435+
_ => return self.expected("FROM or IN", self.peek_token()),
1243212436
};
1243312437

1243412438
let (parent_type, parent_name) = match self.parse_one_of_keywords(&[
@@ -12438,13 +12442,23 @@ impl<'a> Parser<'a> {
1243812442
Keyword::TABLE,
1243912443
Keyword::VIEW,
1244012444
]) {
12441-
Some(Keyword::DATABASE) if self.peek_keywords(&[Keyword::STARTS, Keyword::WITH]) => {
12445+
// If we see these next keywords it means we don't have a parent name
12446+
Some(Keyword::DATABASE)
12447+
if self.peek_keywords(&[Keyword::STARTS, Keyword::WITH])
12448+
| self.peek_keyword(Keyword::LIMIT) =>
12449+
{
1244212450
(Some(ShowStatementInParentType::Database), None)
1244312451
}
12444-
Some(Keyword::SCHEMA) if self.peek_keywords(&[Keyword::STARTS, Keyword::WITH]) => {
12452+
Some(Keyword::SCHEMA)
12453+
if self.peek_keywords(&[Keyword::STARTS, Keyword::WITH])
12454+
| self.peek_keyword(Keyword::LIMIT) =>
12455+
{
1244512456
(Some(ShowStatementInParentType::Schema), None)
1244612457
}
1244712458
Some(parent_kw) => {
12459+
// The parent name here is still optional, for example:
12460+
// SHOW TABLES IN ACCOUNT, so parsing the object name
12461+
// may fail because the statement ends.
1244812462
let parent_name = match self.parse_object_name(false) {
1244912463
Ok(n) => Some(n),
1245012464
_ => None,
@@ -12455,7 +12469,12 @@ impl<'a> Parser<'a> {
1245512469
Keyword::SCHEMA => (Some(ShowStatementInParentType::Schema), parent_name),
1245612470
Keyword::TABLE => (Some(ShowStatementInParentType::Table), parent_name),
1245712471
Keyword::VIEW => (Some(ShowStatementInParentType::View), parent_name),
12458-
_ => unreachable!(),
12472+
_ => {
12473+
return self.expected(
12474+
"one of ACCOUNT, DATABASE, SCHEMA, TABLE or VIEW",
12475+
self.peek_token(),
12476+
)
12477+
}
1245912478
}
1246012479
}
1246112480
None => {

tests/sqlparser_snowflake.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2842,7 +2842,7 @@ fn test_show_views() {
28422842

28432843
#[test]
28442844
fn test_parse_show_columns_sql() {
2845+
snowflake().verified_stmt("SHOW COLUMNS IN TABLE");
28452846
snowflake().verified_stmt("SHOW COLUMNS IN TABLE abc");
28462847
snowflake().verified_stmt("SHOW COLUMNS LIKE '%xyz%' IN TABLE abc");
2847-
snowflake().verified_stmt("SHOW COLUMNS IN TABLE");
28482848
}

0 commit comments

Comments
 (0)