@@ -371,6 +371,149 @@ mod custom_s3_config {
371371 Ok ( ( ) )
372372 }
373373
374+ #[ tokio:: test]
375+ async fn should_configure_aqe_s3_execute_sql_write_remote ( )
376+ -> datafusion:: error:: Result < ( ) > {
377+ let test_data = examples_test_data ( ) ;
378+
379+ //
380+ // Minio cluster setup
381+ //
382+ let container = crate :: common:: create_minio_container ( ) ;
383+ let node = container. start ( ) . await . unwrap ( ) ;
384+
385+ node. exec ( crate :: common:: create_bucket_command ( ) )
386+ . await
387+ . unwrap ( ) ;
388+
389+ let endpoint_host = node. get_host ( ) . await . unwrap ( ) ;
390+ let endpoint_port = node. get_host_port_ipv4 ( 9000 ) . await . unwrap ( ) ;
391+
392+ log:: info!(
393+ "MINIO testcontainers host: {}, port: {}" ,
394+ endpoint_host,
395+ endpoint_port
396+ ) ;
397+
398+ //
399+ // Session Context and Ballista cluster setup
400+ //
401+
402+ // Setting up configuration producer
403+ //
404+ // configuration producer registers user defined config extension
405+ // S3Option with relevant S3 configuration
406+ let config_producer =
407+ Arc :: new ( ballista_core:: object_store:: session_config_with_s3_support) ;
408+ // Setting up runtime producer
409+ //
410+ // Runtime producer creates object store registry
411+ // which can create object store connecter based on
412+ // S3Option configuration.
413+ let runtime_producer: RuntimeProducer =
414+ Arc :: new ( ballista_core:: object_store:: runtime_env_with_s3_support) ;
415+
416+ // Session builder creates SessionState
417+ //
418+ // which is configured using runtime and configuration producer,
419+ // producing same runtime environment, and providing same
420+ // object store registry.
421+
422+ let session_builder =
423+ Arc :: new ( ballista_core:: object_store:: session_state_with_s3_support) ;
424+
425+ let state = session_builder ( config_producer ( ) ) ?;
426+
427+ // setting up ballista cluster with new runtime, configuration, and session state producers
428+ let ( host, port) = crate :: common:: setup_test_cluster_with_builders (
429+ config_producer,
430+ runtime_producer,
431+ session_builder,
432+ )
433+ . await ;
434+ let url = format ! ( "df://{host}:{port}" ) ;
435+
436+ // establishing cluster connection,
437+ let ctx: SessionContext = SessionContext :: remote_with_state ( & url, state) . await ?;
438+
439+ ctx. sql ( "SET ballista.planner.adaptive.enabled = true" )
440+ . await ?
441+ . show ( )
442+ . await ?;
443+ // setting up relevant S3 options
444+ ctx. sql ( "SET s3.allow_http = true" ) . await ?. show ( ) . await ?;
445+ ctx. sql ( & format ! ( "SET s3.access_key_id = '{}'" , ACCESS_KEY_ID ) )
446+ . await ?
447+ . show ( )
448+ . await ?;
449+ ctx. sql ( & format ! ( "SET s3.secret_access_key = '{}'" , SECRET_KEY ) )
450+ . await ?
451+ . show ( )
452+ . await ?;
453+ ctx. sql ( & format ! (
454+ "SET s3.endpoint = 'http://{}:{}'" ,
455+ endpoint_host, endpoint_port
456+ ) )
457+ . await ?
458+ . show ( )
459+ . await ?;
460+ ctx. sql ( "SET s3.allow_http = true" ) . await ?. show ( ) . await ?;
461+
462+ // verifying that we have set S3Options
463+ ctx. sql ( "select name, value from information_schema.df_settings where name like 's3.%'" ) . await ?. show ( ) . await ?;
464+
465+ ctx. register_parquet (
466+ "test" ,
467+ & format ! ( "{test_data}/alltypes_plain.parquet" ) ,
468+ Default :: default ( ) ,
469+ )
470+ . await ?;
471+
472+ let write_dir_path =
473+ & format ! ( "s3://{}/write_test.parquet" , crate :: common:: BUCKET ) ;
474+
475+ ctx. sql ( "select * from test" )
476+ . await ?
477+ . write_parquet ( write_dir_path, Default :: default ( ) , Default :: default ( ) )
478+ . await ?;
479+
480+ ctx. register_parquet ( "written_table" , write_dir_path, Default :: default ( ) )
481+ . await ?;
482+
483+ let result = ctx
484+ . sql ( "select id, string_col, timestamp_col from written_table where id > 4" )
485+ . await ?
486+ . collect ( )
487+ . await ?;
488+ let expected = [
489+ "+----+------------+---------------------+" ,
490+ "| id | string_col | timestamp_col |" ,
491+ "+----+------------+---------------------+" ,
492+ "| 5 | 31 | 2009-03-01T00:01:00 |" ,
493+ "| 6 | 30 | 2009-04-01T00:00:00 |" ,
494+ "| 7 | 31 | 2009-04-01T00:01:00 |" ,
495+ "+----+------------+---------------------+" ,
496+ ] ;
497+
498+ assert_batches_eq ! ( expected, & result) ;
499+
500+ let result = ctx
501+ . sql ( "select max(id) as max, min(id) as min from written_table" )
502+ . await ?
503+ . collect ( )
504+ . await ?;
505+ let expected = [
506+ "+-----+-----+" ,
507+ "| max | min |" ,
508+ "+-----+-----+" ,
509+ "| 7 | 0 |" ,
510+ "+-----+-----+" ,
511+ ] ;
512+
513+ assert_batches_eq ! ( expected, & result) ;
514+ Ok ( ( ) )
515+ }
516+
374517 // this test shows how to register external ObjectStoreRegistry and configure it
375518 // using infrastructure provided by ballista standalone.
376519 //
0 commit comments