@@ -44,18 +44,17 @@ impl PyAccumulator {
4444
4545impl Accumulator for PyAccumulator {
4646 fn state ( & self ) -> Result < Vec < datafusion:: scalar:: ScalarValue > > {
47- let gil = pyo3:: Python :: acquire_gil ( ) ;
48- let py = gil. python ( ) ;
49-
50- let state = self
51- . accum
52- . as_ref ( py)
53- . call_method0 ( "to_scalars" )
54- . map_err ( |e| InnerDataFusionError :: Execution ( format ! ( "{}" , e) ) ) ?
55- . extract :: < Vec < Scalar > > ( )
56- . map_err ( |e| InnerDataFusionError :: Execution ( format ! ( "{}" , e) ) ) ?;
57-
58- Ok ( state. into_iter ( ) . map ( |v| v. scalar ) . collect :: < Vec < _ > > ( ) )
47+ Python :: with_gil ( |py| {
48+ let state = self
49+ . accum
50+ . as_ref ( py)
51+ . call_method0 ( "to_scalars" )
52+ . map_err ( |e| InnerDataFusionError :: Execution ( format ! ( "{}" , e) ) ) ?
53+ . extract :: < Vec < Scalar > > ( )
54+ . map_err ( |e| InnerDataFusionError :: Execution ( format ! ( "{}" , e) ) ) ?;
55+
56+ Ok ( state. into_iter ( ) . map ( |v| v. scalar ) . collect :: < Vec < _ > > ( ) )
57+ } )
5958 }
6059
6160 fn update ( & mut self , _values : & [ ScalarValue ] ) -> Result < ( ) > {
@@ -69,79 +68,72 @@ impl Accumulator for PyAccumulator {
6968 }
7069
7170 fn evaluate ( & self ) -> Result < datafusion:: scalar:: ScalarValue > {
72- // get GIL
73- let gil = pyo3:: Python :: acquire_gil ( ) ;
74- let py = gil. python ( ) ;
75-
76- let value = self
77- . accum
78- . as_ref ( py)
79- . call_method0 ( "evaluate" )
80- . map_err ( |e| InnerDataFusionError :: Execution ( format ! ( "{}" , e) ) ) ?;
81-
82- to_rust_scalar ( value)
83- . map_err ( |e| InnerDataFusionError :: Execution ( format ! ( "{}" , e) ) )
71+ Python :: with_gil ( |py| {
72+ let value = self
73+ . accum
74+ . as_ref ( py)
75+ . call_method0 ( "evaluate" )
76+ . map_err ( |e| InnerDataFusionError :: Execution ( format ! ( "{}" , e) ) ) ?;
77+
78+ to_rust_scalar ( value)
79+ . map_err ( |e| InnerDataFusionError :: Execution ( format ! ( "{}" , e) ) )
80+ } )
8481 }
8582
8683 fn update_batch ( & mut self , values : & [ ArrayRef ] ) -> Result < ( ) > {
87- // get GIL
88- let gil = pyo3:: Python :: acquire_gil ( ) ;
89- let py = gil. python ( ) ;
90-
91- // 1. cast args to Pyarrow array
92- // 2. call function
93-
94- // 1.
95- let py_args = values
96- . iter ( )
97- . map ( |arg| {
98- // remove unwrap
99- to_py_array ( arg, py) . unwrap ( )
100- } )
101- . collect :: < Vec < _ > > ( ) ;
102- let py_args = PyTuple :: new ( py, py_args) ;
103-
104- // update accumulator
105- self . accum
106- . as_ref ( py)
107- . call_method1 ( "update" , py_args)
108- . map_err ( |e| InnerDataFusionError :: Execution ( format ! ( "{}" , e) ) ) ?;
109-
110- Ok ( ( ) )
84+ Python :: with_gil ( |py| {
85+ // 1. cast args to Pyarrow array
86+ // 2. call function
87+
88+ // 1.
89+ let py_args = values
90+ . iter ( )
91+ . map ( |arg| {
92+ // remove unwrap
93+ to_py_array ( arg, py) . unwrap ( )
94+ } )
95+ . collect :: < Vec < _ > > ( ) ;
96+ let py_args = PyTuple :: new ( py, py_args) ;
97+
98+ // update accumulator
99+ self . accum
100+ . as_ref ( py)
101+ . call_method1 ( "update" , py_args)
102+ . map_err ( |e| InnerDataFusionError :: Execution ( format ! ( "{}" , e) ) ) ?;
103+
104+ Ok ( ( ) )
105+ } )
111106 }
112107
113108 fn merge_batch ( & mut self , states : & [ ArrayRef ] ) -> Result < ( ) > {
114- // get GIL
115- let gil = pyo3:: Python :: acquire_gil ( ) ;
116- let py = gil. python ( ) ;
117-
118- // 1. cast states to Pyarrow array
119- // 2. merge
120- let state = & states[ 0 ] ;
121-
122- let state = to_py_array ( state, py)
123- . map_err ( |e| InnerDataFusionError :: Execution ( format ! ( "{}" , e) ) ) ?;
124-
125- // 2.
126- self . accum
127- . as_ref ( py)
128- . call_method1 ( "merge" , ( state, ) )
129- . map_err ( |e| InnerDataFusionError :: Execution ( format ! ( "{}" , e) ) ) ?;
130-
131- Ok ( ( ) )
109+ Python :: with_gil ( |py| {
110+ // 1. cast states to Pyarrow array
111+ // 2. merge
112+ let state = & states[ 0 ] ;
113+
114+ let state = to_py_array ( state, py)
115+ . map_err ( |e| InnerDataFusionError :: Execution ( format ! ( "{}" , e) ) ) ?;
116+
117+ // 2.
118+ self . accum
119+ . as_ref ( py)
120+ . call_method1 ( "merge" , ( state, ) )
121+ . map_err ( |e| InnerDataFusionError :: Execution ( format ! ( "{}" , e) ) ) ?;
122+
123+ Ok ( ( ) )
124+ } )
132125 }
133126}
134127
135128pub fn array_udaf (
136129 accumulator : PyObject ,
137130) -> Arc < dyn Fn ( ) -> Result < Box < dyn Accumulator > > + Send + Sync > {
138131 Arc :: new ( move || -> Result < Box < dyn Accumulator > > {
139- let gil = pyo3:: Python :: acquire_gil ( ) ;
140- let py = gil. python ( ) ;
141-
142- let accumulator = accumulator
143- . call0 ( py)
144- . map_err ( |e| InnerDataFusionError :: Execution ( format ! ( "{}" , e) ) ) ?;
132+ let accumulator = Python :: with_gil ( |py| {
133+ accumulator
134+ . call0 ( py)
135+ . map_err ( |e| InnerDataFusionError :: Execution ( format ! ( "{}" , e) ) )
136+ } ) ?;
145137 Ok ( Box :: new ( PyAccumulator :: new ( accumulator) ) )
146138 } )
147139}
0 commit comments