Skip to content

Commit

Permalink
Support CREATE/DROP SECRET for duckdb dialect (sqlparser-rs#1208)
Browse files Browse the repository at this point in the history
Co-authored-by: Jichao Sun <4977515+JichaoS@users.noreply.github.com>
  • Loading branch information
alamb and JichaoS committed May 7, 2024
1 parent d870cb8 commit d13a5eb
Show file tree
Hide file tree
Showing 2 changed files with 166 additions and 0 deletions.
25 changes: 25 additions & 0 deletions src/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2101,6 +2101,31 @@ pub enum Statement {
/// true if the syntax is 'ATTACH DATABASE', false if it's just 'ATTACH'
database: bool,
},
/// (DuckDB-specific)
/// ```sql
/// ATTACH 'sqlite_file.db' AS sqlite_db (READ_ONLY, TYPE SQLITE);
/// ```
/// See <https://duckdb.org/docs/sql/statements/attach.html>
AttachDuckDBDatabase {
if_not_exists: bool,
/// true if the syntax is 'ATTACH DATABASE', false if it's just 'ATTACH'
database: bool,
/// An expression that indicates the path to the database file
database_path: Ident,
database_alias: Option<Ident>,
attach_options: Vec<AttachDuckDBDatabaseOption>,
},
/// (DuckDB-specific)
/// ```sql
/// DETACH db_alias;
/// ```
/// See <https://duckdb.org/docs/sql/statements/attach.html>
DetachDuckDBDatabase {
if_exists: bool,
/// true if the syntax is 'DETACH DATABASE', false if it's just 'DETACH'
database: bool,
database_alias: Ident,
},
/// ```sql
/// ATTACH 'sqlite_file.db' AS sqlite_db (READ_ONLY, TYPE SQLITE);
/// ```
Expand Down
141 changes: 141 additions & 0 deletions tests/sqlparser_duckdb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,147 @@ fn test_duckdb_struct_literal() {
);
}

#[test]
fn test_create_secret() {
let sql = r#"CREATE OR REPLACE PERSISTENT SECRET IF NOT EXISTS name IN storage ( TYPE type, key1 value1, key2 value2 )"#;
let stmt = duckdb().verified_stmt(sql);
assert_eq!(
Statement::CreateSecret {
or_replace: true,
temporary: Some(false),
if_not_exists: true,
name: Some(Ident::new("name")),
storage_specifier: Some(Ident::new("storage")),
secret_type: Ident::new("type"),
options: vec![
SecretOption {
key: Ident::new("key1"),
value: Ident::new("value1"),
},
SecretOption {
key: Ident::new("key2"),
value: Ident::new("value2"),
}
]
},
stmt
);
}

#[test]
fn test_create_secret_simple() {
let sql = r#"CREATE SECRET ( TYPE type )"#;
let stmt = duckdb().verified_stmt(sql);
assert_eq!(
Statement::CreateSecret {
or_replace: false,
temporary: None,
if_not_exists: false,
name: None,
storage_specifier: None,
secret_type: Ident::new("type"),
options: vec![]
},
stmt
);
}

#[test]
fn test_drop_secret() {
let sql = r#"DROP PERSISTENT SECRET IF EXISTS secret FROM storage"#;
let stmt = duckdb().verified_stmt(sql);
assert_eq!(
Statement::DropSecret {
if_exists: true,
temporary: Some(false),
name: Ident::new("secret"),
storage_specifier: Some(Ident::new("storage"))
},
stmt
);
}

#[test]
fn test_drop_secret_simple() {
let sql = r#"DROP SECRET secret"#;
let stmt = duckdb().verified_stmt(sql);
assert_eq!(
Statement::DropSecret {
if_exists: false,
temporary: None,
name: Ident::new("secret"),
storage_specifier: None
},
stmt
);
}

#[test]
fn test_attach_database() {
let sql = r#"ATTACH DATABASE IF NOT EXISTS 'sqlite_file.db' AS sqlite_db (READ_ONLY false, TYPE SQLITE)"#;
let stmt = duckdb().verified_stmt(sql);
assert_eq!(
Statement::AttachDuckDBDatabase {
if_not_exists: true,
database: true,
database_path: Ident::with_quote('\'', "sqlite_file.db"),
database_alias: Some(Ident::new("sqlite_db")),
attach_options: vec![
AttachDuckDBDatabaseOption::ReadOnly(Some(false)),
AttachDuckDBDatabaseOption::Type(Ident::new("SQLITE")),
]
},
stmt
);
}

#[test]
fn test_attach_database_simple() {
let sql = r#"ATTACH 'postgres://user.name:pass-word@some.url.com:5432/postgres'"#;
let stmt = duckdb().verified_stmt(sql);
assert_eq!(
Statement::AttachDuckDBDatabase {
if_not_exists: false,
database: false,
database_path: Ident::with_quote(
'\'',
"postgres://user.name:pass-word@some.url.com:5432/postgres"
),
database_alias: None,
attach_options: vec![]
},
stmt
);
}

#[test]
fn test_detach_database() {
let sql = r#"DETACH DATABASE IF EXISTS db_name"#;
let stmt = duckdb().verified_stmt(sql);
assert_eq!(
Statement::DetachDuckDBDatabase {
if_exists: true,
database: true,
database_alias: Ident::new("db_name"),
},
stmt
);
}

#[test]
fn test_detach_database_simple() {
let sql = r#"DETACH db_name"#;
let stmt = duckdb().verified_stmt(sql);
assert_eq!(
Statement::DetachDuckDBDatabase {
if_exists: false,
database: false,
database_alias: Ident::new("db_name"),
},
stmt
);
}

#[test]
fn test_duckdb_named_argument_function_with_assignment_operator() {
let sql = "SELECT FUN(a := '1', b := '2') FROM foo";
Expand Down

0 comments on commit d13a5eb

Please sign in to comment.