Skip to content
Merged
37 changes: 37 additions & 0 deletions src/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2980,6 +2980,32 @@ pub enum Statement {
show_options: ShowStatementOptions,
},
/// ```sql
/// SHOW [ TERSE ] OBJECTS [ LIKE '<pattern>' ]
/// [ IN
/// {
/// ACCOUNT |
///
/// DATABASE |
/// DATABASE <database_name> |
///
/// SCHEMA |
/// SCHEMA <schema_name> |
/// <schema_name>
///
/// APPLICATION <application_name> |
/// APPLICATION PACKAGE <application_package_name> |
/// }
/// ]
/// [ STARTS WITH '<name_string>' ]
/// [ LIMIT <rows> [ FROM '<name_string>' ] ]
/// ```
Copy link
Contributor

Choose a reason for hiding this comment

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

Thinking since this is quite verbose we can either leave it out, relying on the link to the documentation and a description or we can use a shorter summary of the syntax like an example sql statement?

/// Snowflake-specific statement
/// <https://docs.snowflake.com/en/sql-reference/sql/show-objects>
ShowObjects {
terse: bool,
show_options: ShowStatementOptions,
Copy link
Contributor

Choose a reason for hiding this comment

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

Could we use a struct to wrap the arguments? we're currently trying to move away from the anonymous struct pattern (#1204)
Something like

struct ShowObjects {
         terse: bool,
        show_options: ShowStatementOptions,
}
Statement::ShowObjects(ShowObjects)

},
/// ```sql
/// SHOW TABLES
/// ```
ShowTables {
Expand Down Expand Up @@ -4642,6 +4668,17 @@ impl fmt::Display for Statement {
)?;
Ok(())
}
Statement::ShowObjects {
terse,
show_options,
} => {
write!(
f,
"SHOW {terse}OBJECTS{show_options}",
terse = if *terse { "TERSE " } else { "" },
)?;
Ok(())
}
Statement::ShowTables {
terse,
history,
Expand Down
1 change: 1 addition & 0 deletions src/ast/spans.rs
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,7 @@ impl Spanned for Statement {
Statement::DropPolicy { .. } => 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
26 changes: 23 additions & 3 deletions src/dialect/snowflake.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,10 @@ use crate::ast::helpers::stmt_data_loading::{
StageLoadSelectItem, StageParamsObject,
};
use crate::ast::{
ColumnOption, ColumnPolicy, ColumnPolicyProperty, Ident, IdentityParameters, IdentityProperty,
IdentityPropertyFormatKind, IdentityPropertyKind, IdentityPropertyOrder, ObjectName,
RowAccessPolicy, Statement, TagsColumnOption, WrappedCollection,
ColumnOption, ColumnPolicy, ColumnPolicyProperty, Ident,
IdentityParameters, IdentityProperty, IdentityPropertyFormatKind, IdentityPropertyKind,
IdentityPropertyOrder, ObjectName, RowAccessPolicy, Statement, TagsColumnOption,
WrappedCollection,
};
use crate::dialect::{Dialect, Precedence};
use crate::keywords::Keyword;
Expand Down Expand Up @@ -182,6 +183,15 @@ 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));
} else {
return Some(parser.parse_show());
Copy link
Contributor

Choose a reason for hiding this comment

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

what would be the behavior if terse is true here, can we maybe include a test case demonstrating that scenario?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Originally there was no else branch, but there was a bug in my code, which was fixed like this (maybe this is too hacky?). The bug wasn't found or fixed by me. But for example, before the else branch: when we got DATABASES instead of OBJECTS we got an error in other tests.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think I fixed this the right way, shouldn't need tests now.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added the terse test in other relevant snowflake SHOW statement tests, just in case (checked, they all worked and the ShowObjects also)

}
}

None
}

Expand Down Expand Up @@ -1054,3 +1064,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 {
terse,
show_options,
})
}
1 change: 1 addition & 0 deletions src/keywords.rs
Original file line number Diff line number Diff line change
Expand Up @@ -586,6 +586,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 @@ -14172,7 +14172,7 @@ impl<'a> Parser<'a> {
false
}

fn parse_show_stmt_options(&mut self) -> Result<ShowStatementOptions, ParserError> {
pub 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
19 changes: 19 additions & 0 deletions tests/sqlparser_snowflake.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2975,6 +2975,25 @@ 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'");
}

#[test]
fn test_parse_show_tables() {
snowflake().verified_stmt("SHOW TABLES");
Expand Down