@@ -11,6 +11,9 @@ use vortex::expr::stats::Precision;
1111mod convert;
1212mod persistent;
1313
14+ #[ cfg( test) ]
15+ mod tests;
16+
1417pub use convert:: exprs:: ExpressionConvertor ;
1518pub use persistent:: * ;
1619
@@ -46,3 +49,101 @@ where
4649 }
4750 }
4851}
52+
53+ #[ cfg( test) ]
54+ mod common_tests {
55+ use std:: sync:: Arc ;
56+ use std:: sync:: LazyLock ;
57+
58+ use datafusion:: arrow:: array:: RecordBatch ;
59+ use datafusion:: datasource:: provider:: DefaultTableFactory ;
60+ use datafusion:: execution:: SessionStateBuilder ;
61+ use datafusion:: prelude:: SessionContext ;
62+ use datafusion_catalog:: TableProvider ;
63+ use datafusion_common:: DFSchema ;
64+ use datafusion_common:: GetExt ;
65+ use datafusion_expr:: CreateExternalTable ;
66+ use object_store:: ObjectStore ;
67+ use object_store:: memory:: InMemory ;
68+ use url:: Url ;
69+ use vortex:: VortexSessionDefault ;
70+ use vortex:: array:: ArrayRef ;
71+ use vortex:: array:: arrow:: FromArrowArray ;
72+ use vortex:: file:: WriteOptionsSessionExt ;
73+ use vortex:: io:: ObjectStoreWriter ;
74+ use vortex:: io:: VortexWrite ;
75+ use vortex:: session:: VortexSession ;
76+
77+ use crate :: VortexFormatFactory ;
78+
79+ static VX_SESSION : LazyLock < VortexSession > = LazyLock :: new ( VortexSession :: default) ;
80+
81+ pub struct TestSessionContext {
82+ pub store : Arc < dyn ObjectStore > ,
83+ pub session : SessionContext ,
84+ }
85+
86+ impl Default for TestSessionContext {
87+ fn default ( ) -> Self {
88+ let store = Arc :: new ( InMemory :: new ( ) ) ;
89+ let factory = Arc :: new ( VortexFormatFactory :: new ( ) ) ;
90+ let session_state_builder = SessionStateBuilder :: new ( )
91+ . with_default_features ( )
92+ . with_table_factory (
93+ factory. get_ext ( ) . to_uppercase ( ) ,
94+ Arc :: new ( DefaultTableFactory :: new ( ) ) ,
95+ )
96+ . with_file_formats ( vec ! [ factory] )
97+ . with_object_store ( & Url :: try_from ( "file://" ) . unwrap ( ) , store. clone ( ) ) ;
98+
99+ let session: SessionContext =
100+ SessionContext :: new_with_state ( session_state_builder. build ( ) ) . enable_url_table ( ) ;
101+
102+ Self { store, session }
103+ }
104+ }
105+
106+ impl TestSessionContext {
107+ // Write arrow data into a vortex file.
108+ pub async fn write_arrow_batch < P > ( & self , path : P , batch : & RecordBatch ) -> anyhow:: Result < ( ) >
109+ where
110+ P : Into < object_store:: path:: Path > ,
111+ {
112+ let array = ArrayRef :: from_arrow ( batch, false ) ?;
113+ let mut write = ObjectStoreWriter :: new ( self . store . clone ( ) , & path. into ( ) ) . await ?;
114+ VX_SESSION
115+ . write_options ( )
116+ . write ( & mut write, array. to_array_stream ( ) )
117+ . await ?;
118+ write. shutdown ( ) . await ?;
119+
120+ Ok ( ( ) )
121+ }
122+
123+ /// Creates a ListingTable provider targeted at the provided path
124+ pub async fn table_provider < S > (
125+ & self ,
126+ name : & str ,
127+ location : impl Into < String > ,
128+ schema : S ,
129+ ) -> anyhow:: Result < Arc < dyn TableProvider > >
130+ where
131+ DFSchema : TryFrom < S > ,
132+ anyhow:: Error : From < <S as TryInto < DFSchema > >:: Error > ,
133+ {
134+ let factory = self . session . table_factory ( "VORTEX" ) . unwrap ( ) ;
135+
136+ let cmd = CreateExternalTable :: builder (
137+ name,
138+ location. into ( ) ,
139+ "vortex" ,
140+ DFSchema :: try_from ( schema) ?. into ( ) ,
141+ )
142+ . build ( ) ;
143+
144+ let table = factory. create ( & self . session . state ( ) , & cmd) . await ?;
145+
146+ Ok ( table)
147+ }
148+ }
149+ }
0 commit comments