@@ -86,30 +86,34 @@ impl<T: Transaction, A: AsRef<[(&'static str, DataValue)]>> Binder<'_, '_, T, A>
8686 target : CopyTarget ,
8787 options : & [ CopyOption ] ,
8888 ) -> Result < LogicalPlan , DatabaseError > {
89+ let ext_source = copy_ext_source ( target, options) ?;
90+
8991 let ( table_name, ..) = match source {
9092 CopySource :: Table {
9193 table_name,
9294 columns,
9395 } => ( table_name, columns) ,
94- CopySource :: Query ( _) => {
95- return Err ( DatabaseError :: UnsupportedStmt ( "'COPY SOURCE'" . to_string ( ) ) ) ;
96+ CopySource :: Query ( query) => {
97+ if !to {
98+ return Err ( DatabaseError :: UnsupportedStmt (
99+ "'COPY FROM query'" . to_string ( ) ,
100+ ) ) ;
101+ }
102+ let mut input_plan = self . bind_query ( & query) ?;
103+ let schema_ref = input_plan. output_schema ( ) . clone ( ) ;
104+ return Ok ( LogicalPlan :: new (
105+ Operator :: CopyToFile ( CopyToFileOperator {
106+ target : ext_source,
107+ schema_ref,
108+ } ) ,
109+ Childrens :: Only ( Box :: new ( input_plan) ) ,
110+ ) ) ;
96111 }
97112 } ;
98113 let table_name: Arc < str > = lower_case_name ( & table_name) ?. into ( ) ;
99114
100115 if let Some ( table) = self . context . table ( table_name. clone ( ) ) ? {
101116 let schema_ref = table. schema_ref ( ) . clone ( ) ;
102- let ext_source = ExtSource {
103- path : match target {
104- CopyTarget :: File { filename } => filename. into ( ) ,
105- t => {
106- return Err ( DatabaseError :: UnsupportedStmt ( format ! (
107- "copy target: {t:?}"
108- ) ) )
109- }
110- } ,
111- format : FileFormat :: from_options ( options) ,
112- } ;
113117
114118 if to {
115119 // COPY <source_table> TO <dest_file>
@@ -139,6 +143,20 @@ impl<T: Transaction, A: AsRef<[(&'static str, DataValue)]>> Binder<'_, '_, T, A>
139143 }
140144}
141145
146+ fn copy_ext_source ( target : CopyTarget , options : & [ CopyOption ] ) -> Result < ExtSource , DatabaseError > {
147+ Ok ( ExtSource {
148+ path : match target {
149+ CopyTarget :: File { filename } => filename. into ( ) ,
150+ t => {
151+ return Err ( DatabaseError :: UnsupportedStmt ( format ! (
152+ "copy target: {t:?}"
153+ ) ) )
154+ }
155+ } ,
156+ format : FileFormat :: from_options ( options) ,
157+ } )
158+ }
159+
142160impl FileFormat {
143161 /// Create from copy options.
144162 pub fn from_options ( options : & [ CopyOption ] ) -> Self {
0 commit comments