Skip to content

Add suppport for Show Objects statement for the Snowflake parser #1702

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 14 commits into from
Feb 6, 2025
25 changes: 25 additions & 0 deletions src/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3010,6 +3010,12 @@ pub enum Statement {
show_options: ShowStatementOptions,
},
/// ```sql
/// SHOW OBJECTS LIKE 'line%' IN mydb.public
/// ```
/// Snowflake-specific statement
/// <https://docs.snowflake.com/en/sql-reference/sql/show-objects>
ShowObjects(ShowObjects),
/// ```sql
/// SHOW TABLES
/// ```
ShowTables {
Expand Down Expand Up @@ -4703,6 +4709,17 @@ impl fmt::Display for Statement {
)?;
Ok(())
}
Statement::ShowObjects(ShowObjects {
terse,
show_options,
}) => {
write!(
f,
"SHOW {terse}OBJECTS{show_options}",
terse = if *terse { "TERSE " } else { "" },
)?;
Ok(())
}
Statement::ShowTables {
terse,
history,
Expand Down Expand Up @@ -8343,6 +8360,14 @@ impl fmt::Display for ShowStatementIn {
}
}

#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct ShowObjects {
pub terse: bool,
pub show_options: ShowStatementOptions,
}

/// MSSQL's json null clause
///
/// ```plaintext
Expand Down
1 change: 1 addition & 0 deletions src/ast/spans.rs
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,7 @@ impl Spanned for Statement {
Statement::DropConnector { .. } => Span::empty(),
Statement::ShowDatabases { .. } => Span::empty(),
Statement::ShowSchemas { .. } => Span::empty(),
Statement::ShowObjects { .. } => Span::empty(),
Statement::ShowViews { .. } => Span::empty(),
Statement::LISTEN { .. } => Span::empty(),
Statement::NOTIFY { .. } => Span::empty(),
Expand Down
25 changes: 24 additions & 1 deletion src/dialect/snowflake.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use crate::ast::helpers::stmt_data_loading::{
use crate::ast::{
ColumnOption, ColumnPolicy, ColumnPolicyProperty, CopyIntoSnowflakeKind, Ident,
IdentityParameters, IdentityProperty, IdentityPropertyFormatKind, IdentityPropertyKind,
IdentityPropertyOrder, ObjectName, RowAccessPolicy, Statement, TagsColumnOption,
IdentityPropertyOrder, ObjectName, RowAccessPolicy, ShowObjects, Statement, TagsColumnOption,
WrappedCollection,
};
use crate::dialect::{Dialect, Precedence};
Expand Down Expand Up @@ -185,6 +185,19 @@ impl Dialect for SnowflakeDialect {
return Some(parse_file_staging_command(kw, parser));
}

if parser.parse_keyword(Keyword::SHOW) {
let terse = parser.parse_keyword(Keyword::TERSE);
if parser.parse_keyword(Keyword::OBJECTS) {
return Some(parse_show_objects(terse, parser));
}
//Give back Keyword::TERSE
if terse {
parser.prev_token();
}
//Give back Keyword::SHOW
parser.prev_token();
}

None
}

Expand Down Expand Up @@ -1092,3 +1105,13 @@ fn parse_column_tags(parser: &mut Parser, with: bool) -> Result<TagsColumnOption

Ok(TagsColumnOption { with, tags })
}

/// Parse snowflake show objects.
/// <https://docs.snowflake.com/en/sql-reference/sql/show-objects>
fn parse_show_objects(terse: bool, parser: &mut Parser) -> Result<Statement, ParserError> {
let show_options = parser.parse_show_stmt_options()?;
Ok(Statement::ShowObjects(ShowObjects {
terse,
show_options,
}))
}
1 change: 1 addition & 0 deletions src/keywords.rs
Original file line number Diff line number Diff line change
Expand Up @@ -588,6 +588,7 @@ define_keywords!(
NUMERIC,
NVARCHAR,
OBJECT,
OBJECTS,
OCCURRENCES_REGEX,
OCTETS,
OCTET_LENGTH,
Expand Down
2 changes: 1 addition & 1 deletion src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14231,7 +14231,7 @@ impl<'a> Parser<'a> {
false
}

fn parse_show_stmt_options(&mut self) -> Result<ShowStatementOptions, ParserError> {
pub(crate) fn parse_show_stmt_options(&mut self) -> Result<ShowStatementOptions, ParserError> {
let show_in;
let mut filter_position = None;
if self.dialect.supports_show_like_before_in() {
Expand Down
45 changes: 45 additions & 0 deletions tests/sqlparser_snowflake.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3083,6 +3083,7 @@ fn test_parentheses_overflow() {
#[test]
fn test_show_databases() {
snowflake().verified_stmt("SHOW DATABASES");
snowflake().verified_stmt("SHOW TERSE DATABASES");
snowflake().verified_stmt("SHOW DATABASES HISTORY");
snowflake().verified_stmt("SHOW DATABASES LIKE '%abc%'");
snowflake().verified_stmt("SHOW DATABASES STARTS WITH 'demo_db'");
Expand All @@ -3095,6 +3096,7 @@ fn test_show_databases() {
#[test]
fn test_parse_show_schemas() {
snowflake().verified_stmt("SHOW SCHEMAS");
snowflake().verified_stmt("SHOW TERSE SCHEMAS");
snowflake().verified_stmt("SHOW SCHEMAS IN ACCOUNT");
snowflake().verified_stmt("SHOW SCHEMAS IN ACCOUNT abc");
snowflake().verified_stmt("SHOW SCHEMAS IN DATABASE");
Expand All @@ -3104,9 +3106,51 @@ fn test_parse_show_schemas() {
snowflake().verified_stmt("SHOW SCHEMAS IN DATABASE STARTS WITH 'abc' LIMIT 20 FROM 'xyz'");
}

#[test]
fn test_parse_show_objects() {
snowflake().verified_stmt("SHOW OBJECTS");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this introduces a new node in the AST, can we add an assertion for one of these test cases covering that the AST looks like what is expected? i.e a test in this syle

snowflake().verified_stmt("SHOW OBJECTS IN abc");
snowflake().verified_stmt("SHOW OBJECTS LIKE '%test%' IN abc");
snowflake().verified_stmt("SHOW OBJECTS IN ACCOUNT");
snowflake().verified_stmt("SHOW OBJECTS IN DATABASE");
snowflake().verified_stmt("SHOW OBJECTS IN DATABASE abc");
snowflake().verified_stmt("SHOW OBJECTS IN SCHEMA");
snowflake().verified_stmt("SHOW OBJECTS IN SCHEMA abc");
snowflake().verified_stmt("SHOW TERSE OBJECTS");
snowflake().verified_stmt("SHOW TERSE OBJECTS IN abc");
snowflake().verified_stmt("SHOW TERSE OBJECTS LIKE '%test%' IN abc");
snowflake().verified_stmt("SHOW TERSE OBJECTS LIKE '%test%' IN abc STARTS WITH 'b'");
snowflake().verified_stmt("SHOW TERSE OBJECTS LIKE '%test%' IN abc STARTS WITH 'b' LIMIT 10");
snowflake()
.verified_stmt("SHOW TERSE OBJECTS LIKE '%test%' IN abc STARTS WITH 'b' LIMIT 10 FROM 'x'");
match snowflake().verified_stmt("SHOW TERSE OBJECTS LIKE '%test%' IN abc") {
Statement::ShowObjects(ShowObjects {
terse,
show_options,
}) => {
assert!(terse);
let name = match show_options.show_in {
Some(ShowStatementIn {
parent_name: Some(val),
..
}) => val.to_string(),
_ => unreachable!(),
};
assert_eq!("abc", name);
let like = match show_options.filter_position {
Some(ShowStatementFilterPosition::Infix(ShowStatementFilter::Like(val))) => val,
_ => unreachable!(),
};
assert_eq!("%test%", like);
}
_ => unreachable!(),
}
}

#[test]
fn test_parse_show_tables() {
snowflake().verified_stmt("SHOW TABLES");
snowflake().verified_stmt("SHOW TERSE TABLES");
snowflake().verified_stmt("SHOW TABLES IN ACCOUNT");
snowflake().verified_stmt("SHOW TABLES IN DATABASE");
snowflake().verified_stmt("SHOW TABLES IN DATABASE xyz");
Expand All @@ -3129,6 +3173,7 @@ fn test_parse_show_tables() {
#[test]
fn test_show_views() {
snowflake().verified_stmt("SHOW VIEWS");
snowflake().verified_stmt("SHOW TERSE VIEWS");
snowflake().verified_stmt("SHOW VIEWS IN ACCOUNT");
snowflake().verified_stmt("SHOW VIEWS IN DATABASE");
snowflake().verified_stmt("SHOW VIEWS IN DATABASE xyz");
Expand Down