mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-08-31 03:07:20 +00:00
feat: support different USE statement syntaxes (#1387)
This commit is contained in:
parent
19e694aa91
commit
7282ce22f9
11 changed files with 386 additions and 17 deletions
|
@ -193,3 +193,30 @@ impl fmt::Display for AlterRoleOperation {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A `USE` (`Statement::Use`) operation
|
||||||
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
|
||||||
|
pub enum Use {
|
||||||
|
Catalog(ObjectName), // e.g. `USE CATALOG foo.bar`
|
||||||
|
Schema(ObjectName), // e.g. `USE SCHEMA foo.bar`
|
||||||
|
Database(ObjectName), // e.g. `USE DATABASE foo.bar`
|
||||||
|
Warehouse(ObjectName), // e.g. `USE WAREHOUSE foo.bar`
|
||||||
|
Object(ObjectName), // e.g. `USE foo.bar`
|
||||||
|
Default, // e.g. `USE DEFAULT`
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for Use {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
f.write_str("USE ")?;
|
||||||
|
match self {
|
||||||
|
Use::Catalog(name) => write!(f, "CATALOG {}", name),
|
||||||
|
Use::Schema(name) => write!(f, "SCHEMA {}", name),
|
||||||
|
Use::Database(name) => write!(f, "DATABASE {}", name),
|
||||||
|
Use::Warehouse(name) => write!(f, "WAREHOUSE {}", name),
|
||||||
|
Use::Object(name) => write!(f, "{}", name),
|
||||||
|
Use::Default => write!(f, "DEFAULT"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ pub use self::data_type::{
|
||||||
ArrayElemTypeDef, CharLengthUnits, CharacterLength, DataType, ExactNumberInfo,
|
ArrayElemTypeDef, CharLengthUnits, CharacterLength, DataType, ExactNumberInfo,
|
||||||
StructBracketKind, TimezoneInfo,
|
StructBracketKind, TimezoneInfo,
|
||||||
};
|
};
|
||||||
pub use self::dcl::{AlterRoleOperation, ResetConfig, RoleOption, SetConfigValue};
|
pub use self::dcl::{AlterRoleOperation, ResetConfig, RoleOption, SetConfigValue, Use};
|
||||||
pub use self::ddl::{
|
pub use self::ddl::{
|
||||||
AlterColumnOperation, AlterIndexOperation, AlterTableOperation, ColumnDef, ColumnOption,
|
AlterColumnOperation, AlterIndexOperation, AlterTableOperation, ColumnDef, ColumnOption,
|
||||||
ColumnOptionDef, ConstraintCharacteristics, Deduplicate, DeferrableInitial, GeneratedAs,
|
ColumnOptionDef, ConstraintCharacteristics, Deduplicate, DeferrableInitial, GeneratedAs,
|
||||||
|
@ -2515,11 +2515,9 @@ pub enum Statement {
|
||||||
/// Note: this is a MySQL-specific statement.
|
/// Note: this is a MySQL-specific statement.
|
||||||
ShowCollation { filter: Option<ShowStatementFilter> },
|
ShowCollation { filter: Option<ShowStatementFilter> },
|
||||||
/// ```sql
|
/// ```sql
|
||||||
/// USE
|
/// `USE ...`
|
||||||
/// ```
|
/// ```
|
||||||
///
|
Use(Use),
|
||||||
/// Note: This is a MySQL-specific statement.
|
|
||||||
Use { db_name: Ident },
|
|
||||||
/// ```sql
|
/// ```sql
|
||||||
/// START [ TRANSACTION | WORK ] | START TRANSACTION } ...
|
/// START [ TRANSACTION | WORK ] | START TRANSACTION } ...
|
||||||
/// ```
|
/// ```
|
||||||
|
@ -4125,10 +4123,7 @@ impl fmt::Display for Statement {
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
Statement::Use { db_name } => {
|
Statement::Use(use_expr) => use_expr.fmt(f),
|
||||||
write!(f, "USE {db_name}")?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
Statement::ShowCollation { filter } => {
|
Statement::ShowCollation { filter } => {
|
||||||
write!(f, "SHOW COLLATION")?;
|
write!(f, "SHOW COLLATION")?;
|
||||||
if let Some(filter) = filter {
|
if let Some(filter) = filter {
|
||||||
|
|
|
@ -137,6 +137,7 @@ define_keywords!(
|
||||||
CASCADED,
|
CASCADED,
|
||||||
CASE,
|
CASE,
|
||||||
CAST,
|
CAST,
|
||||||
|
CATALOG,
|
||||||
CEIL,
|
CEIL,
|
||||||
CEILING,
|
CEILING,
|
||||||
CENTURY,
|
CENTURY,
|
||||||
|
@ -804,6 +805,7 @@ define_keywords!(
|
||||||
VIEW,
|
VIEW,
|
||||||
VIRTUAL,
|
VIRTUAL,
|
||||||
VOLATILE,
|
VOLATILE,
|
||||||
|
WAREHOUSE,
|
||||||
WEEK,
|
WEEK,
|
||||||
WHEN,
|
WHEN,
|
||||||
WHENEVER,
|
WHENEVER,
|
||||||
|
|
|
@ -9264,8 +9264,31 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_use(&mut self) -> Result<Statement, ParserError> {
|
pub fn parse_use(&mut self) -> Result<Statement, ParserError> {
|
||||||
let db_name = self.parse_identifier(false)?;
|
// Determine which keywords are recognized by the current dialect
|
||||||
Ok(Statement::Use { db_name })
|
let parsed_keyword = if dialect_of!(self is HiveDialect) {
|
||||||
|
// HiveDialect accepts USE DEFAULT; statement without any db specified
|
||||||
|
if self.parse_keyword(Keyword::DEFAULT) {
|
||||||
|
return Ok(Statement::Use(Use::Default));
|
||||||
|
}
|
||||||
|
None // HiveDialect doesn't expect any other specific keyword after `USE`
|
||||||
|
} else if dialect_of!(self is DatabricksDialect) {
|
||||||
|
self.parse_one_of_keywords(&[Keyword::CATALOG, Keyword::DATABASE, Keyword::SCHEMA])
|
||||||
|
} else if dialect_of!(self is SnowflakeDialect) {
|
||||||
|
self.parse_one_of_keywords(&[Keyword::DATABASE, Keyword::SCHEMA, Keyword::WAREHOUSE])
|
||||||
|
} else {
|
||||||
|
None // No specific keywords for other dialects, including GenericDialect
|
||||||
|
};
|
||||||
|
|
||||||
|
let obj_name = self.parse_object_name(false)?;
|
||||||
|
let result = match parsed_keyword {
|
||||||
|
Some(Keyword::CATALOG) => Use::Catalog(obj_name),
|
||||||
|
Some(Keyword::DATABASE) => Use::Database(obj_name),
|
||||||
|
Some(Keyword::SCHEMA) => Use::Schema(obj_name),
|
||||||
|
Some(Keyword::WAREHOUSE) => Use::Warehouse(obj_name),
|
||||||
|
_ => Use::Object(obj_name),
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(Statement::Use(result))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_table_and_joins(&mut self) -> Result<TableWithJoins, ParserError> {
|
pub fn parse_table_and_joins(&mut self) -> Result<TableWithJoins, ParserError> {
|
||||||
|
|
|
@ -1232,6 +1232,39 @@ fn test_prewhere() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parse_use() {
|
||||||
|
let valid_object_names = [
|
||||||
|
"mydb",
|
||||||
|
"SCHEMA",
|
||||||
|
"DATABASE",
|
||||||
|
"CATALOG",
|
||||||
|
"WAREHOUSE",
|
||||||
|
"DEFAULT",
|
||||||
|
];
|
||||||
|
let quote_styles = ['"', '`'];
|
||||||
|
|
||||||
|
for object_name in &valid_object_names {
|
||||||
|
// Test single identifier without quotes
|
||||||
|
assert_eq!(
|
||||||
|
clickhouse().verified_stmt(&format!("USE {}", object_name)),
|
||||||
|
Statement::Use(Use::Object(ObjectName(vec![Ident::new(
|
||||||
|
object_name.to_string()
|
||||||
|
)])))
|
||||||
|
);
|
||||||
|
for "e in "e_styles {
|
||||||
|
// Test single identifier with different type of quotes
|
||||||
|
assert_eq!(
|
||||||
|
clickhouse().verified_stmt(&format!("USE {0}{1}{0}", quote, object_name)),
|
||||||
|
Statement::Use(Use::Object(ObjectName(vec![Ident::with_quote(
|
||||||
|
quote,
|
||||||
|
object_name.to_string(),
|
||||||
|
)])))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_query_with_format_clause() {
|
fn test_query_with_format_clause() {
|
||||||
let format_options = vec!["TabSeparated", "JSONCompact", "NULL"];
|
let format_options = vec!["TabSeparated", "JSONCompact", "NULL"];
|
||||||
|
|
|
@ -189,3 +189,77 @@ fn test_values_clause() {
|
||||||
// TODO: support this example from https://docs.databricks.com/en/sql/language-manual/sql-ref-syntax-qry-select-values.html#examples
|
// TODO: support this example from https://docs.databricks.com/en/sql/language-manual/sql-ref-syntax-qry-select-values.html#examples
|
||||||
// databricks().verified_query("VALUES 1, 2, 3");
|
// databricks().verified_query("VALUES 1, 2, 3");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parse_use() {
|
||||||
|
let valid_object_names = ["mydb", "WAREHOUSE", "DEFAULT"];
|
||||||
|
let quote_styles = ['"', '`'];
|
||||||
|
|
||||||
|
for object_name in &valid_object_names {
|
||||||
|
// Test single identifier without quotes
|
||||||
|
assert_eq!(
|
||||||
|
databricks().verified_stmt(&format!("USE {}", object_name)),
|
||||||
|
Statement::Use(Use::Object(ObjectName(vec![Ident::new(
|
||||||
|
object_name.to_string()
|
||||||
|
)])))
|
||||||
|
);
|
||||||
|
for "e in "e_styles {
|
||||||
|
// Test single identifier with different type of quotes
|
||||||
|
assert_eq!(
|
||||||
|
databricks().verified_stmt(&format!("USE {0}{1}{0}", quote, object_name)),
|
||||||
|
Statement::Use(Use::Object(ObjectName(vec![Ident::with_quote(
|
||||||
|
quote,
|
||||||
|
object_name.to_string(),
|
||||||
|
)])))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for "e in "e_styles {
|
||||||
|
// Test single identifier with keyword and different type of quotes
|
||||||
|
assert_eq!(
|
||||||
|
databricks().verified_stmt(&format!("USE CATALOG {0}my_catalog{0}", quote)),
|
||||||
|
Statement::Use(Use::Catalog(ObjectName(vec![Ident::with_quote(
|
||||||
|
quote,
|
||||||
|
"my_catalog".to_string(),
|
||||||
|
)])))
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
databricks().verified_stmt(&format!("USE DATABASE {0}my_database{0}", quote)),
|
||||||
|
Statement::Use(Use::Database(ObjectName(vec![Ident::with_quote(
|
||||||
|
quote,
|
||||||
|
"my_database".to_string(),
|
||||||
|
)])))
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
databricks().verified_stmt(&format!("USE SCHEMA {0}my_schema{0}", quote)),
|
||||||
|
Statement::Use(Use::Schema(ObjectName(vec![Ident::with_quote(
|
||||||
|
quote,
|
||||||
|
"my_schema".to_string(),
|
||||||
|
)])))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test single identifier with keyword and no quotes
|
||||||
|
assert_eq!(
|
||||||
|
databricks().verified_stmt("USE CATALOG my_catalog"),
|
||||||
|
Statement::Use(Use::Catalog(ObjectName(vec![Ident::new("my_catalog")])))
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
databricks().verified_stmt("USE DATABASE my_schema"),
|
||||||
|
Statement::Use(Use::Database(ObjectName(vec![Ident::new("my_schema")])))
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
databricks().verified_stmt("USE SCHEMA my_schema"),
|
||||||
|
Statement::Use(Use::Schema(ObjectName(vec![Ident::new("my_schema")])))
|
||||||
|
);
|
||||||
|
|
||||||
|
// Test invalid syntax - missing identifier
|
||||||
|
let invalid_cases = ["USE SCHEMA", "USE DATABASE", "USE CATALOG"];
|
||||||
|
for sql in &invalid_cases {
|
||||||
|
assert_eq!(
|
||||||
|
databricks().parse_sql_statements(sql).unwrap_err(),
|
||||||
|
ParserError::ParserError("Expected: identifier, found: EOF".to_string()),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -756,3 +756,55 @@ fn test_duckdb_union_datatype() {
|
||||||
stmt
|
stmt
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parse_use() {
|
||||||
|
let valid_object_names = [
|
||||||
|
"mydb",
|
||||||
|
"SCHEMA",
|
||||||
|
"DATABASE",
|
||||||
|
"CATALOG",
|
||||||
|
"WAREHOUSE",
|
||||||
|
"DEFAULT",
|
||||||
|
];
|
||||||
|
let quote_styles = ['"', '\''];
|
||||||
|
|
||||||
|
for object_name in &valid_object_names {
|
||||||
|
// Test single identifier without quotes
|
||||||
|
assert_eq!(
|
||||||
|
duckdb().verified_stmt(&format!("USE {}", object_name)),
|
||||||
|
Statement::Use(Use::Object(ObjectName(vec![Ident::new(
|
||||||
|
object_name.to_string()
|
||||||
|
)])))
|
||||||
|
);
|
||||||
|
for "e in "e_styles {
|
||||||
|
// Test single identifier with different type of quotes
|
||||||
|
assert_eq!(
|
||||||
|
duckdb().verified_stmt(&format!("USE {0}{1}{0}", quote, object_name)),
|
||||||
|
Statement::Use(Use::Object(ObjectName(vec![Ident::with_quote(
|
||||||
|
quote,
|
||||||
|
object_name.to_string(),
|
||||||
|
)])))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for "e in "e_styles {
|
||||||
|
// Test double identifier with different type of quotes
|
||||||
|
assert_eq!(
|
||||||
|
duckdb().verified_stmt(&format!("USE {0}CATALOG{0}.{0}my_schema{0}", quote)),
|
||||||
|
Statement::Use(Use::Object(ObjectName(vec![
|
||||||
|
Ident::with_quote(quote, "CATALOG"),
|
||||||
|
Ident::with_quote(quote, "my_schema")
|
||||||
|
])))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// Test double identifier without quotes
|
||||||
|
assert_eq!(
|
||||||
|
duckdb().verified_stmt("USE mydb.my_schema"),
|
||||||
|
Statement::Use(Use::Object(ObjectName(vec![
|
||||||
|
Ident::new("mydb"),
|
||||||
|
Ident::new("my_schema")
|
||||||
|
])))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
use sqlparser::ast::{
|
use sqlparser::ast::{
|
||||||
CreateFunctionBody, CreateFunctionUsing, Expr, Function, FunctionArgumentList,
|
CreateFunctionBody, CreateFunctionUsing, Expr, Function, FunctionArgumentList,
|
||||||
FunctionArguments, Ident, ObjectName, OneOrManyWithParens, SelectItem, Statement, TableFactor,
|
FunctionArguments, Ident, ObjectName, OneOrManyWithParens, SelectItem, Statement, TableFactor,
|
||||||
UnaryOperator, Value,
|
UnaryOperator, Use, Value,
|
||||||
};
|
};
|
||||||
use sqlparser::dialect::{GenericDialect, HiveDialect, MsSqlDialect};
|
use sqlparser::dialect::{GenericDialect, HiveDialect, MsSqlDialect};
|
||||||
use sqlparser::parser::ParserError;
|
use sqlparser::parser::ParserError;
|
||||||
|
@ -401,6 +401,36 @@ fn parse_delimited_identifiers() {
|
||||||
//TODO verified_stmt(r#"UPDATE foo SET "bar" = 5"#);
|
//TODO verified_stmt(r#"UPDATE foo SET "bar" = 5"#);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parse_use() {
|
||||||
|
let valid_object_names = ["mydb", "SCHEMA", "DATABASE", "CATALOG", "WAREHOUSE"];
|
||||||
|
let quote_styles = ['\'', '"', '`'];
|
||||||
|
for object_name in &valid_object_names {
|
||||||
|
// Test single identifier without quotes
|
||||||
|
assert_eq!(
|
||||||
|
hive().verified_stmt(&format!("USE {}", object_name)),
|
||||||
|
Statement::Use(Use::Object(ObjectName(vec![Ident::new(
|
||||||
|
object_name.to_string()
|
||||||
|
)])))
|
||||||
|
);
|
||||||
|
for "e in "e_styles {
|
||||||
|
// Test single identifier with different type of quotes
|
||||||
|
assert_eq!(
|
||||||
|
hive().verified_stmt(&format!("USE {}{}{}", quote, object_name, quote)),
|
||||||
|
Statement::Use(Use::Object(ObjectName(vec![Ident::with_quote(
|
||||||
|
quote,
|
||||||
|
object_name.to_string(),
|
||||||
|
)])))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Test DEFAULT keyword that is special case in Hive
|
||||||
|
assert_eq!(
|
||||||
|
hive().verified_stmt("USE DEFAULT"),
|
||||||
|
Statement::Use(Use::Default)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
fn hive() -> TestedDialects {
|
fn hive() -> TestedDialects {
|
||||||
TestedDialects {
|
TestedDialects {
|
||||||
dialects: vec![Box::new(HiveDialect {})],
|
dialects: vec![Box::new(HiveDialect {})],
|
||||||
|
|
|
@ -621,6 +621,38 @@ fn parse_mssql_declare() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parse_use() {
|
||||||
|
let valid_object_names = [
|
||||||
|
"mydb",
|
||||||
|
"SCHEMA",
|
||||||
|
"DATABASE",
|
||||||
|
"CATALOG",
|
||||||
|
"WAREHOUSE",
|
||||||
|
"DEFAULT",
|
||||||
|
];
|
||||||
|
let quote_styles = ['\'', '"'];
|
||||||
|
for object_name in &valid_object_names {
|
||||||
|
// Test single identifier without quotes
|
||||||
|
assert_eq!(
|
||||||
|
ms().verified_stmt(&format!("USE {}", object_name)),
|
||||||
|
Statement::Use(Use::Object(ObjectName(vec![Ident::new(
|
||||||
|
object_name.to_string()
|
||||||
|
)])))
|
||||||
|
);
|
||||||
|
for "e in "e_styles {
|
||||||
|
// Test single identifier with different type of quotes
|
||||||
|
assert_eq!(
|
||||||
|
ms().verified_stmt(&format!("USE {}{}{}", quote, object_name, quote)),
|
||||||
|
Statement::Use(Use::Object(ObjectName(vec![Ident::with_quote(
|
||||||
|
quote,
|
||||||
|
object_name.to_string(),
|
||||||
|
)])))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn ms() -> TestedDialects {
|
fn ms() -> TestedDialects {
|
||||||
TestedDialects {
|
TestedDialects {
|
||||||
dialects: vec![Box::new(MsSqlDialect {})],
|
dialects: vec![Box::new(MsSqlDialect {})],
|
||||||
|
|
|
@ -444,12 +444,35 @@ fn parse_show_collation() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn parse_use() {
|
fn parse_use() {
|
||||||
assert_eq!(
|
let valid_object_names = [
|
||||||
mysql_and_generic().verified_stmt("USE mydb"),
|
"mydb",
|
||||||
Statement::Use {
|
"SCHEMA",
|
||||||
db_name: Ident::new("mydb")
|
"DATABASE",
|
||||||
|
"CATALOG",
|
||||||
|
"WAREHOUSE",
|
||||||
|
"DEFAULT",
|
||||||
|
];
|
||||||
|
let quote_styles = ['\'', '"', '`'];
|
||||||
|
for object_name in &valid_object_names {
|
||||||
|
// Test single identifier without quotes
|
||||||
|
assert_eq!(
|
||||||
|
mysql_and_generic().verified_stmt(&format!("USE {}", object_name)),
|
||||||
|
Statement::Use(Use::Object(ObjectName(vec![Ident::new(
|
||||||
|
object_name.to_string()
|
||||||
|
)])))
|
||||||
|
);
|
||||||
|
for "e in "e_styles {
|
||||||
|
// Test single identifier with different type of quotes
|
||||||
|
assert_eq!(
|
||||||
|
mysql_and_generic()
|
||||||
|
.verified_stmt(&format!("USE {}{}{}", quote, object_name, quote)),
|
||||||
|
Statement::Use(Use::Object(ObjectName(vec![Ident::with_quote(
|
||||||
|
quote,
|
||||||
|
object_name.to_string(),
|
||||||
|
)])))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -2322,3 +2322,81 @@ fn parse_explain_table() {
|
||||||
_ => panic!("Unexpected Statement, must be ExplainTable"),
|
_ => panic!("Unexpected Statement, must be ExplainTable"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parse_use() {
|
||||||
|
let valid_object_names = ["mydb", "CATALOG", "DEFAULT"];
|
||||||
|
let quote_styles = ['\'', '"', '`'];
|
||||||
|
for object_name in &valid_object_names {
|
||||||
|
// Test single identifier without quotes
|
||||||
|
std::assert_eq!(
|
||||||
|
snowflake().verified_stmt(&format!("USE {}", object_name)),
|
||||||
|
Statement::Use(Use::Object(ObjectName(vec![Ident::new(
|
||||||
|
object_name.to_string()
|
||||||
|
)])))
|
||||||
|
);
|
||||||
|
for "e in "e_styles {
|
||||||
|
// Test single identifier with different type of quotes
|
||||||
|
std::assert_eq!(
|
||||||
|
snowflake().verified_stmt(&format!("USE {}{}{}", quote, object_name, quote)),
|
||||||
|
Statement::Use(Use::Object(ObjectName(vec![Ident::with_quote(
|
||||||
|
quote,
|
||||||
|
object_name.to_string(),
|
||||||
|
)])))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for "e in "e_styles {
|
||||||
|
// Test double identifier with different type of quotes
|
||||||
|
std::assert_eq!(
|
||||||
|
snowflake().verified_stmt(&format!("USE {0}CATALOG{0}.{0}my_schema{0}", quote)),
|
||||||
|
Statement::Use(Use::Object(ObjectName(vec![
|
||||||
|
Ident::with_quote(quote, "CATALOG"),
|
||||||
|
Ident::with_quote(quote, "my_schema")
|
||||||
|
])))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// Test double identifier without quotes
|
||||||
|
std::assert_eq!(
|
||||||
|
snowflake().verified_stmt("USE mydb.my_schema"),
|
||||||
|
Statement::Use(Use::Object(ObjectName(vec![
|
||||||
|
Ident::new("mydb"),
|
||||||
|
Ident::new("my_schema")
|
||||||
|
])))
|
||||||
|
);
|
||||||
|
|
||||||
|
for "e in "e_styles {
|
||||||
|
// Test single and double identifier with keyword and different type of quotes
|
||||||
|
std::assert_eq!(
|
||||||
|
snowflake().verified_stmt(&format!("USE DATABASE {0}my_database{0}", quote)),
|
||||||
|
Statement::Use(Use::Database(ObjectName(vec![Ident::with_quote(
|
||||||
|
quote,
|
||||||
|
"my_database".to_string(),
|
||||||
|
)])))
|
||||||
|
);
|
||||||
|
std::assert_eq!(
|
||||||
|
snowflake().verified_stmt(&format!("USE SCHEMA {0}my_schema{0}", quote)),
|
||||||
|
Statement::Use(Use::Schema(ObjectName(vec![Ident::with_quote(
|
||||||
|
quote,
|
||||||
|
"my_schema".to_string(),
|
||||||
|
)])))
|
||||||
|
);
|
||||||
|
std::assert_eq!(
|
||||||
|
snowflake().verified_stmt(&format!("USE SCHEMA {0}CATALOG{0}.{0}my_schema{0}", quote)),
|
||||||
|
Statement::Use(Use::Schema(ObjectName(vec![
|
||||||
|
Ident::with_quote(quote, "CATALOG"),
|
||||||
|
Ident::with_quote(quote, "my_schema")
|
||||||
|
])))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test invalid syntax - missing identifier
|
||||||
|
let invalid_cases = ["USE SCHEMA", "USE DATABASE", "USE WAREHOUSE"];
|
||||||
|
for sql in &invalid_cases {
|
||||||
|
std::assert_eq!(
|
||||||
|
snowflake().parse_sql_statements(sql).unwrap_err(),
|
||||||
|
ParserError::ParserError("Expected: identifier, found: EOF".to_string()),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue