@@ -37,6 +37,7 @@ const MAX_ADBC_INGEST_BATCH_BYTES_ENV: &str = "SPICEBENCH_ADBC_MAX_INGEST_BATCH_
3737/// SQL statements derived from key columns in each batch.
3838pub struct AdbcSink {
3939 conn : Mutex < AdbcConnection > ,
40+ target_db_catalog : Option < String > ,
4041 target_db_schema : Option < String > ,
4142}
4243
@@ -53,13 +54,15 @@ impl AdbcSink {
5354 pub fn new (
5455 driver_name : & str ,
5556 db_kwargs : HashMap < String , serde_json:: Value > ,
57+ target_db_catalog : Option < String > ,
5658 target_db_schema : Option < String > ,
5759 ) -> anyhow:: Result < Self > {
5860 let conn = AdbcConnection :: create ( driver_name, db_kwargs)
5961 . map_err ( |e| anyhow:: anyhow!( "Failed to create ADBC connection: {e}" ) ) ?;
6062
6163 Ok ( Self {
6264 conn : Mutex :: new ( conn) ,
65+ target_db_catalog,
6366 target_db_schema,
6467 } )
6568 }
@@ -106,13 +109,45 @@ impl AdbcSink {
106109 }
107110
108111 fn target_table_identifier ( & self , table_name : & str ) -> String {
109- let table_ident = Self :: quote_identifier ( table_name) ;
112+ let mut parts = Vec :: with_capacity ( 3 ) ;
113+
114+ if let Some ( catalog) = self . target_db_catalog . as_deref ( ) {
115+ if !catalog. is_empty ( ) {
116+ parts. push ( Self :: quote_identifier ( catalog) ) ;
117+ }
118+ }
119+
120+ if let Some ( schema) = self . target_db_schema . as_deref ( ) {
121+ if !schema. is_empty ( ) {
122+ parts. push ( Self :: quote_identifier ( schema) ) ;
123+ }
124+ }
125+
126+ parts. push ( Self :: quote_identifier ( table_name) ) ;
127+ parts. join ( "." )
128+ }
129+
130+ fn target_table_ingest_name ( & self , table_name : & str ) -> String {
131+ self . target_table_identifier_unquoted ( table_name)
132+ }
133+
134+ fn target_table_identifier_unquoted ( & self , table_name : & str ) -> String {
135+ let mut parts = Vec :: with_capacity ( 3 ) ;
136+
137+ if let Some ( catalog) = self . target_db_catalog . as_deref ( ) {
138+ if !catalog. is_empty ( ) {
139+ parts. push ( catalog. to_string ( ) ) ;
140+ }
141+ }
142+
110143 if let Some ( schema) = self . target_db_schema . as_deref ( ) {
111144 if !schema. is_empty ( ) {
112- return format ! ( "{}.{}" , Self :: quote_identifier ( schema) , table_ident ) ;
145+ parts . push ( schema. to_string ( ) ) ;
113146 }
114147 }
115- table_ident
148+
149+ parts. push ( table_name. to_string ( ) ) ;
150+ parts. join ( "." )
116151 }
117152
118153 fn create_table_sql ( & self , table_name : & str , schema : & Schema ) -> anyhow:: Result < String > {
@@ -129,7 +164,7 @@ impl AdbcSink {
129164 . join ( ", " ) ;
130165
131166 Ok ( format ! (
132- "CREATE TABLE IF NOT EXISTS spicebench.bench. {} ({columns})" ,
167+ "CREATE TABLE IF NOT EXISTS {} ({columns})" ,
133168 self . target_table_identifier( table_name)
134169 ) )
135170 }
@@ -222,9 +257,20 @@ impl AdbcSink {
222257 table_name : & str ,
223258 batch : RecordBatch ,
224259 ) -> anyhow:: Result < ( ) > {
260+ let ingest_table_name = self . target_table_ingest_name ( table_name) ;
261+ let target_db_catalog = self
262+ . target_db_catalog
263+ . as_deref ( )
264+ . and_then ( |catalog| ( !catalog. is_empty ( ) ) . then_some ( catalog) ) ;
265+ let target_db_schema = self
266+ . target_db_schema
267+ . as_deref ( )
268+ . and_then ( |schema| ( !schema. is_empty ( ) ) . then_some ( schema) ) ;
269+
225270 match conn. bulk_ingest (
226271 table_name,
227- self . target_db_schema . as_deref ( ) ,
272+ target_db_catalog,
273+ target_db_schema,
228274 IngestMode :: CreateAppend ,
229275 batch. clone ( ) ,
230276 ) {
@@ -234,7 +280,7 @@ impl AdbcSink {
234280 if Self :: is_message_too_large_error ( & message) {
235281 if batch. num_rows ( ) <= 1 {
236282 anyhow:: bail!(
237- "ADBC bulk ingest failed for '{table_name}': single-row batch still exceeds FlightSQL message limit: {message}. Configure a larger FlightSQL max message size (e.g. adbc.flight.sql.client_option.with_max_msg_size)."
283+ "ADBC bulk ingest failed for source table '{table_name}' (ingest target '{ingest_table_name}') : single-row batch still exceeds FlightSQL message limit: {message}. Configure a larger FlightSQL max message size (e.g. adbc.flight.sql.client_option.with_max_msg_size)."
238284 ) ;
239285 }
240286
@@ -245,7 +291,9 @@ impl AdbcSink {
245291 self . bulk_ingest_with_retry ( conn, table_name, right) ?;
246292 Ok ( ( ) )
247293 } else {
248- anyhow:: bail!( "ADBC bulk ingest failed for '{table_name}': {message}" )
294+ anyhow:: bail!(
295+ "ADBC bulk ingest failed for source table '{table_name}' (ingest target '{ingest_table_name}'): {message}"
296+ )
249297 }
250298 }
251299 }
0 commit comments