@@ -2040,6 +2040,19 @@ pub enum Statement {
20402040 authorization_owner : Option < ObjectName > ,
20412041 } ,
20422042 /// ```sql
2043+ /// CREATE SECRET
2044+ /// ```
2045+ /// See [duckdb](https://duckdb.org/docs/sql/statements/create_secret.html)
2046+ CreateSecret {
2047+ or_replace : bool ,
2048+ temporary : Option < bool > ,
2049+ if_not_exists : bool ,
2050+ name : Option < Ident > ,
2051+ storage_specifier : Option < Ident > ,
2052+ secret_type : Ident ,
2053+ options : Vec < SecretOption > ,
2054+ } ,
2055+ /// ```sql
20432056 /// ALTER TABLE
20442057 /// ```
20452058 AlterTable {
@@ -2088,6 +2101,31 @@ pub enum Statement {
20882101 /// true if the syntax is 'ATTACH DATABASE', false if it's just 'ATTACH'
20892102 database : bool ,
20902103 } ,
2104+ /// (DuckDB-specific)
2105+ /// ```sql
2106+ /// ATTACH 'sqlite_file.db' AS sqlite_db (READ_ONLY, TYPE SQLITE);
2107+ /// ```
2108+ /// See <https://duckdb.org/docs/sql/statements/attach.html>
2109+ AttachDuckDBDatabase {
2110+ if_not_exists : bool ,
2111+ /// true if the syntax is 'ATTACH DATABASE', false if it's just 'ATTACH'
2112+ database : bool ,
2113+ /// An expression that indicates the path to the database file
2114+ database_path : Ident ,
2115+ database_alias : Option < Ident > ,
2116+ attach_options : Vec < AttachDuckDBDatabaseOption > ,
2117+ } ,
2118+ /// (DuckDB-specific)
2119+ /// ```sql
2120+ /// DETACH db_alias;
2121+ /// ```
2122+ /// See <https://duckdb.org/docs/sql/statements/attach.html>
2123+ DetachDuckDBDatabase {
2124+ if_exists : bool ,
2125+ /// true if the syntax is 'DETACH DATABASE', false if it's just 'DETACH'
2126+ database : bool ,
2127+ database_alias : Ident ,
2128+ } ,
20912129 /// ```sql
20922130 /// DROP [TABLE, VIEW, ...]
20932131 /// ```
@@ -2121,6 +2159,15 @@ pub enum Statement {
21212159 option : Option < ReferentialAction > ,
21222160 } ,
21232161 /// ```sql
2162+ /// DROP SECRET
2163+ /// ```
2164+ DropSecret {
2165+ if_exists : bool ,
2166+ temporary : Option < bool > ,
2167+ name : Ident ,
2168+ storage_specifier : Option < Ident > ,
2169+ } ,
2170+ /// ```sql
21242171 /// DECLARE
21252172 /// ```
21262173 /// Declare Cursor Variables
@@ -2772,6 +2819,40 @@ impl fmt::Display for Statement {
27722819 let keyword = if * database { "DATABASE " } else { "" } ;
27732820 write ! ( f, "ATTACH {keyword}{database_file_name} AS {schema_name}" )
27742821 }
2822+ Statement :: AttachDuckDBDatabase {
2823+ if_not_exists,
2824+ database,
2825+ database_path,
2826+ database_alias,
2827+ attach_options,
2828+ } => {
2829+ write ! (
2830+ f,
2831+ "ATTACH{database}{if_not_exists} {database_path}" ,
2832+ database = if * database { " DATABASE" } else { "" } ,
2833+ if_not_exists = if * if_not_exists { " IF NOT EXISTS" } else { "" } ,
2834+ ) ?;
2835+ if let Some ( alias) = database_alias {
2836+ write ! ( f, " AS {alias}" ) ?;
2837+ }
2838+ if !attach_options. is_empty ( ) {
2839+ write ! ( f, " ({})" , display_comma_separated( attach_options) ) ?;
2840+ }
2841+ Ok ( ( ) )
2842+ }
2843+ Statement :: DetachDuckDBDatabase {
2844+ if_exists,
2845+ database,
2846+ database_alias,
2847+ } => {
2848+ write ! (
2849+ f,
2850+ "DETACH{database}{if_exists} {database_alias}" ,
2851+ database = if * database { " DATABASE" } else { "" } ,
2852+ if_exists = if * if_exists { " IF EXISTS" } else { "" } ,
2853+ ) ?;
2854+ Ok ( ( ) )
2855+ }
27752856 Statement :: Analyze {
27762857 table_name,
27772858 partitions,
@@ -3556,6 +3637,41 @@ impl fmt::Display for Statement {
35563637 }
35573638 Ok ( ( ) )
35583639 }
3640+ Statement :: CreateSecret {
3641+ or_replace,
3642+ temporary,
3643+ if_not_exists,
3644+ name,
3645+ storage_specifier,
3646+ secret_type,
3647+ options,
3648+ } => {
3649+ write ! (
3650+ f,
3651+ "CREATE {or_replace}" ,
3652+ or_replace = if * or_replace { "OR REPLACE " } else { "" } ,
3653+ ) ?;
3654+ if let Some ( t) = temporary {
3655+ write ! ( f, "{}" , if * t { "TEMPORARY " } else { "PERSISTENT " } ) ?;
3656+ }
3657+ write ! (
3658+ f,
3659+ "SECRET {if_not_exists}" ,
3660+ if_not_exists = if * if_not_exists { "IF NOT EXISTS " } else { "" } ,
3661+ ) ?;
3662+ if let Some ( n) = name {
3663+ write ! ( f, "{n} " ) ?;
3664+ } ;
3665+ if let Some ( s) = storage_specifier {
3666+ write ! ( f, "IN {s} " ) ?;
3667+ }
3668+ write ! ( f, "( TYPE {secret_type}" , ) ?;
3669+ if !options. is_empty ( ) {
3670+ write ! ( f, ", {o}" , o = display_comma_separated( options) ) ?;
3671+ }
3672+ write ! ( f, " )" ) ?;
3673+ Ok ( ( ) )
3674+ }
35593675 Statement :: AlterTable {
35603676 name,
35613677 if_exists,
@@ -3636,6 +3752,26 @@ impl fmt::Display for Statement {
36363752 }
36373753 Ok ( ( ) )
36383754 }
3755+ Statement :: DropSecret {
3756+ if_exists,
3757+ temporary,
3758+ name,
3759+ storage_specifier,
3760+ } => {
3761+ write ! ( f, "DROP " ) ?;
3762+ if let Some ( t) = temporary {
3763+ write ! ( f, "{}" , if * t { "TEMPORARY " } else { "PERSISTENT " } ) ?;
3764+ }
3765+ write ! (
3766+ f,
3767+ "SECRET {if_exists}{name}" ,
3768+ if_exists = if * if_exists { "IF EXISTS " } else { "" } ,
3769+ ) ?;
3770+ if let Some ( s) = storage_specifier {
3771+ write ! ( f, " FROM {s}" ) ?;
3772+ }
3773+ Ok ( ( ) )
3774+ }
36393775 Statement :: Discard { object_type } => {
36403776 write ! ( f, "DISCARD {object_type}" ) ?;
36413777 Ok ( ( ) )
@@ -5070,6 +5206,39 @@ impl fmt::Display for SqlOption {
50705206 }
50715207}
50725208
5209+ #[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
5210+ #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
5211+ #[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
5212+ pub struct SecretOption {
5213+ pub key : Ident ,
5214+ pub value : Ident ,
5215+ }
5216+
5217+ impl fmt:: Display for SecretOption {
5218+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
5219+ write ! ( f, "{} {}" , self . key, self . value)
5220+ }
5221+ }
5222+
5223+ #[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
5224+ #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
5225+ #[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
5226+ pub enum AttachDuckDBDatabaseOption {
5227+ ReadOnly ( Option < bool > ) ,
5228+ Type ( Ident ) ,
5229+ }
5230+
5231+ impl fmt:: Display for AttachDuckDBDatabaseOption {
5232+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
5233+ match self {
5234+ AttachDuckDBDatabaseOption :: ReadOnly ( Some ( true ) ) => write ! ( f, "READ_ONLY true" ) ,
5235+ AttachDuckDBDatabaseOption :: ReadOnly ( Some ( false ) ) => write ! ( f, "READ_ONLY false" ) ,
5236+ AttachDuckDBDatabaseOption :: ReadOnly ( None ) => write ! ( f, "READ_ONLY" ) ,
5237+ AttachDuckDBDatabaseOption :: Type ( t) => write ! ( f, "TYPE {}" , t) ,
5238+ }
5239+ }
5240+ }
5241+
50735242#[ derive( Debug , Copy , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
50745243#[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
50755244#[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
0 commit comments