@@ -26,13 +26,15 @@ use common_planners::SelectPlan;
26
26
use common_streams:: DataBlockStream ;
27
27
use common_streams:: SendableDataBlockStream ;
28
28
use parking_lot:: Mutex ;
29
+ use common_base:: base:: { GlobalIORuntime , TrySpawn } ;
29
30
30
31
use super :: commit2table;
31
32
use super :: interpreter_common:: append2table;
32
33
use crate :: interpreters:: Interpreter ;
34
+ use crate :: interpreters:: interpreter_common:: execute_pipeline;
33
35
use crate :: interpreters:: SelectInterpreter ;
34
36
use crate :: pipelines:: processors:: port:: OutputPort ;
35
- use crate :: pipelines:: processors:: BlocksSource ;
37
+ use crate :: pipelines:: processors:: { BlocksSource , TransformAddOn } ;
36
38
use crate :: pipelines:: processors:: TransformCastSchema ;
37
39
use crate :: pipelines:: Pipeline ;
38
40
use crate :: pipelines:: PipelineBuildResult ;
@@ -85,13 +87,21 @@ impl Interpreter for InsertInterpreter {
85
87
}
86
88
87
89
async fn execute ( & self ) -> Result < SendableDataBlockStream > {
90
+ let build_res = self . create_new_pipeline ( ) . await ?;
91
+
92
+ execute_pipeline ( self . ctx . clone ( ) , build_res) ?;
93
+ Ok ( Box :: pin ( DataBlockStream :: create ( self . plan . schema ( ) , None , vec ! [ ] ) ) )
94
+ }
95
+
96
+ async fn create_new_pipeline ( & self ) -> Result < PipelineBuildResult > {
88
97
let plan = & self . plan ;
89
98
let settings = self . ctx . get_settings ( ) ;
90
99
let table = self
91
100
. ctx
92
101
. get_table ( & plan. catalog , & plan. database , & plan. table )
93
102
. await ?;
94
- let mut build_res = self . create_new_pipeline ( ) . await ?;
103
+
104
+ let mut build_res = PipelineBuildResult :: create ( ) ;
95
105
let mut builder = SourcePipeBuilder :: create ( ) ;
96
106
if self . async_insert {
97
107
build_res. main_pipeline . add_pipe (
@@ -160,21 +170,54 @@ impl Interpreter for InsertInterpreter {
160
170
} ;
161
171
}
162
172
163
- append2table ( self . ctx . clone ( ) , table. clone ( ) , plan. schema ( ) , build_res) ?;
164
- commit2table ( self . ctx . clone ( ) , table. clone ( ) , plan. overwrite ) . await ?;
165
- Ok ( Box :: pin ( DataBlockStream :: create (
166
- self . plan . schema ( ) ,
167
- None ,
168
- vec ! [ ] ,
169
- ) ) )
170
- }
173
+ if table. schema ( ) != plan. schema ( ) {
174
+ build_res. main_pipeline
175
+ . add_transform ( |transform_input_port, transform_output_port| {
176
+ TransformAddOn :: try_create (
177
+ transform_input_port,
178
+ transform_output_port,
179
+ plan. schema ( ) . clone ( ) ,
180
+ table. schema ( ) ,
181
+ self . ctx . clone ( ) ,
182
+ )
183
+ } ) ?;
184
+ }
171
185
172
- async fn create_new_pipeline ( & self ) -> Result < PipelineBuildResult > {
173
- let insert_pipeline = Pipeline :: create ( ) ;
174
- Ok ( PipelineBuildResult {
175
- main_pipeline : insert_pipeline,
176
- sources_pipelines : vec ! [ ] ,
177
- } )
186
+ table. append2 ( self . ctx . clone ( ) , & mut build_res. main_pipeline ) ?;
187
+
188
+ let ctx = self . ctx . clone ( ) ;
189
+ let overwrite = self . plan . overwrite ;
190
+
191
+ build_res. main_pipeline . set_on_finished ( move |may_error| {
192
+ // capture out variable
193
+ let overwrite = overwrite;
194
+ let ctx = ctx. clone ( ) ;
195
+ let table = table. clone ( ) ;
196
+
197
+ if may_error. is_none ( ) {
198
+ let append_entries = ctx. consume_precommit_blocks ( ) ;
199
+ // We must put the commit operation to global runtime, which will avoid the "dispatch dropped without returning error" in tower
200
+ let catalog_name = ctx. get_current_catalog ( ) ;
201
+ let commit_handle = GlobalIORuntime :: instance ( ) . spawn ( async move {
202
+ table
203
+ . commit_insertion ( ctx, & catalog_name, append_entries, overwrite)
204
+ . await
205
+ } ) ;
206
+
207
+ return match futures:: executor:: block_on ( commit_handle) {
208
+ Ok ( Ok ( _) ) => Ok ( ( ) ) ,
209
+ Ok ( Err ( error) ) => Err ( error) ,
210
+ Err ( cause) => Err ( ErrorCode :: PanicError ( format ! (
211
+ "Maybe panic while in commit insert. {}" ,
212
+ cause
213
+ ) ) )
214
+ } ;
215
+ }
216
+
217
+ Err ( may_error. as_ref ( ) . unwrap ( ) . clone ( ) )
218
+ } ) ;
219
+
220
+ Ok ( build_res)
178
221
}
179
222
180
223
fn set_source_pipe_builder ( & self , builder : Option < SourcePipeBuilder > ) -> Result < ( ) > {
0 commit comments