@@ -2461,37 +2461,30 @@ pub enum Statement {
2461
2461
values : Vec < Option < String > > ,
2462
2462
} ,
2463
2463
/// ```sql
2464
- /// COPY INTO <table>
2464
+ /// COPY INTO <table> | <location>
2465
2465
/// ```
2466
- /// See <https://docs.snowflake.com/en/sql-reference/sql/copy-into-table>
2466
+ /// See:
2467
+ /// <https://docs.snowflake.com/en/sql-reference/sql/copy-into-table>
2468
+ /// <https://docs.snowflake.com/en/sql-reference/sql/copy-into-location>
2469
+ ///
2467
2470
/// Copy Into syntax available for Snowflake is different than the one implemented in
2468
2471
/// Postgres. Although they share common prefix, it is reasonable to implement them
2469
2472
/// in different enums. This can be refactored later once custom dialects
2470
2473
/// are allowed to have custom Statements.
2471
- CopyIntoSnowflakeTable {
2474
+ CopyIntoSnowflake {
2475
+ kind : CopyIntoSnowflakeKind ,
2472
2476
into : ObjectName ,
2473
- from_stage : ObjectName ,
2474
- from_stage_alias : Option < Ident > ,
2477
+ from_obj : Option < ObjectName > ,
2478
+ from_obj_alias : Option < Ident > ,
2475
2479
stage_params : StageParamsObject ,
2476
2480
from_transformations : Option < Vec < StageLoadSelectItem > > ,
2481
+ from_query : Option < Box < Query > > ,
2477
2482
files : Option < Vec < String > > ,
2478
2483
pattern : Option < String > ,
2479
2484
file_format : DataLoadingOptions ,
2480
2485
copy_options : DataLoadingOptions ,
2481
2486
validation_mode : Option < String > ,
2482
- } ,
2483
- /// ```sql
2484
- /// COPY INTO <location>
2485
- /// ```
2486
- /// See <https://docs.snowflake.com/en/sql-reference/sql/copy-into-location>
2487
- CopyIntoSnowflakeLocation {
2488
- into : ObjectName ,
2489
- from_table : Option < ObjectName > ,
2490
- from_query : Option < Box < Query > > ,
2491
- stage_params : StageParamsObject ,
2492
- partition : Option < Expr > ,
2493
- file_format : DataLoadingOptions ,
2494
- copy_options : DataLoadingOptions ,
2487
+ partition : Option < Box < Expr > > ,
2495
2488
} ,
2496
2489
/// ```sql
2497
2490
/// CLOSE
@@ -4964,88 +4957,70 @@ impl fmt::Display for Statement {
4964
4957
}
4965
4958
Ok ( ( ) )
4966
4959
}
4967
- Statement :: CopyIntoSnowflakeTable {
4960
+ Statement :: CopyIntoSnowflake {
4961
+ kind,
4968
4962
into,
4969
- from_stage ,
4970
- from_stage_alias ,
4963
+ from_obj ,
4964
+ from_obj_alias ,
4971
4965
stage_params,
4972
4966
from_transformations,
4967
+ from_query,
4973
4968
files,
4974
4969
pattern,
4975
4970
file_format,
4976
4971
copy_options,
4977
4972
validation_mode,
4973
+ partition,
4978
4974
} => {
4979
4975
write ! ( f, "COPY INTO {}" , into) ?;
4980
- if from_transformations. is_none ( ) {
4981
- // Standard data load
4982
- write ! ( f, " FROM {}{}" , from_stage, stage_params) ?;
4983
- if from_stage_alias. as_ref ( ) . is_some ( ) {
4984
- write ! ( f, " AS {}" , from_stage_alias. as_ref( ) . unwrap( ) ) ?;
4985
- }
4986
- } else {
4976
+ if let Some ( from_transformations) = from_transformations {
4987
4977
// Data load with transformation
4988
- write ! (
4989
- f,
4990
- " FROM (SELECT {} FROM {}{}" ,
4991
- display_separated( from_transformations. as_ref( ) . unwrap( ) , ", " ) ,
4992
- from_stage,
4993
- stage_params,
4994
- ) ?;
4995
- if from_stage_alias. as_ref ( ) . is_some ( ) {
4996
- write ! ( f, " AS {}" , from_stage_alias. as_ref( ) . unwrap( ) ) ?;
4978
+ if let Some ( from_stage) = from_obj {
4979
+ write ! (
4980
+ f,
4981
+ " FROM (SELECT {} FROM {}{}" ,
4982
+ display_separated( from_transformations, ", " ) ,
4983
+ from_stage,
4984
+ stage_params
4985
+ ) ?;
4986
+ }
4987
+ if let Some ( from_obj_alias) = from_obj_alias {
4988
+ write ! ( f, " AS {}" , from_obj_alias) ?;
4997
4989
}
4998
4990
write ! ( f, ")" ) ?;
4991
+ } else if let Some ( from_obj) = from_obj {
4992
+ // Standard data load
4993
+ write ! ( f, " FROM {}{}" , from_obj, stage_params) ?;
4994
+ if let Some ( from_obj_alias) = from_obj_alias {
4995
+ write ! ( f, " AS {from_obj_alias}" ) ?;
4996
+ }
4997
+ } else if let Some ( from_query) = from_query {
4998
+ // Data unload from query
4999
+ write ! ( f, " FROM ({from_query})" ) ?;
4999
5000
}
5000
- if files. is_some ( ) {
5001
- write ! (
5002
- f,
5003
- " FILES = ('{}')" ,
5004
- display_separated( files. as_ref( ) . unwrap( ) , "', '" )
5005
- ) ?;
5006
- }
5007
- if pattern. is_some ( ) {
5008
- write ! ( f, " PATTERN = '{}'" , pattern. as_ref( ) . unwrap( ) ) ?;
5009
- }
5010
- if !file_format. options . is_empty ( ) {
5011
- write ! ( f, " FILE_FORMAT=({})" , file_format) ?;
5012
- }
5013
- if !copy_options. options . is_empty ( ) {
5014
- write ! ( f, " COPY_OPTIONS=({})" , copy_options) ?;
5015
- }
5016
- if validation_mode. is_some ( ) {
5017
- write ! (
5018
- f,
5019
- " VALIDATION_MODE = {}" ,
5020
- validation_mode. as_ref( ) . unwrap( )
5021
- ) ?;
5001
+
5002
+ if let Some ( files) = files {
5003
+ write ! ( f, " FILES = ('{}')" , display_separated( files, "', '" ) ) ?;
5022
5004
}
5023
- Ok ( ( ) )
5024
- }
5025
- Statement :: CopyIntoSnowflakeLocation {
5026
- into,
5027
- from_table,
5028
- from_query,
5029
- stage_params,
5030
- partition,
5031
- file_format,
5032
- copy_options,
5033
- } => {
5034
- write ! ( f, "COPY INTO {into} FROM" ) ?;
5035
- if let Some ( from_table) = from_table {
5036
- write ! ( f, " {from_table}" ) ?;
5037
- } else if let Some ( from_query) = from_query {
5038
- write ! ( f, " ({from_query})" ) ?;
5005
+ if let Some ( pattern) = pattern {
5006
+ write ! ( f, " PATTERN = '{}'" , pattern) ?;
5039
5007
}
5040
- write ! ( f, "{stage_params}" ) ?;
5041
5008
if let Some ( partition) = partition {
5042
5009
write ! ( f, " PARTITION BY {partition}" ) ?;
5043
5010
}
5044
5011
if !file_format. options . is_empty ( ) {
5045
5012
write ! ( f, " FILE_FORMAT=({})" , file_format) ?;
5046
5013
}
5047
5014
if !copy_options. options . is_empty ( ) {
5048
- write ! ( f, " {}" , copy_options) ?;
5015
+ match kind {
5016
+ CopyIntoSnowflakeKind :: Table => {
5017
+ write ! ( f, " COPY_OPTIONS=({})" , copy_options) ?
5018
+ }
5019
+ CopyIntoSnowflakeKind :: Location => write ! ( f, " {copy_options}" ) ?,
5020
+ }
5021
+ }
5022
+ if let Some ( validation_mode) = validation_mode {
5023
+ write ! ( f, " VALIDATION_MODE = {}" , validation_mode) ?;
5049
5024
}
5050
5025
Ok ( ( ) )
5051
5026
}
@@ -8459,6 +8434,19 @@ impl Display for StorageSerializationPolicy {
8459
8434
}
8460
8435
}
8461
8436
8437
+ /// Variants of the Snowflake `COPY INTO` statement
8438
+ #[ derive( Debug , Copy , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
8439
+ #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
8440
+ #[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
8441
+ pub enum CopyIntoSnowflakeKind {
8442
+ /// Loads data from files to a table
8443
+ /// See: <https://docs.snowflake.com/en/sql-reference/sql/copy-into-table>
8444
+ Table ,
8445
+ /// Unloads data from a table or query to external files
8446
+ /// See: <https://docs.snowflake.com/en/sql-reference/sql/copy-into-location>
8447
+ Location ,
8448
+ }
8449
+
8462
8450
#[ cfg( test) ]
8463
8451
mod tests {
8464
8452
use super :: * ;
0 commit comments