1212// See the License for the specific language governing permissions and
1313// limitations under the License.
1414
15+ use std:: sync:: Arc ;
16+
1517use common_error:: ext:: { BoxedError , PlainError } ;
1618use common_error:: status_code:: StatusCode ;
1719use common_query:: error:: { self , Result } ;
18- use datafusion:: arrow:: datatypes:: DataType ;
19- use datafusion_expr:: { Signature , Volatility } ;
20- use datatypes:: scalars:: ScalarVectorBuilder ;
21- use datatypes:: vectors:: { Float64VectorBuilder , MutableVector , VectorRef } ;
20+ use datafusion_common:: arrow:: array:: { Array , AsArray , Float64Builder } ;
21+ use datafusion_common:: arrow:: compute;
22+ use datafusion_common:: arrow:: datatypes:: DataType ;
23+ use datafusion_common:: utils;
24+ use datafusion_expr:: { ColumnarValue , ScalarFunctionArgs , Signature , Volatility } ;
2225use derive_more:: Display ;
2326use geo:: algorithm:: line_measures:: metric_spaces:: Euclidean ;
2427use geo:: { Area , Distance , Haversine } ;
2528use geo_types:: Geometry ;
2629use snafu:: ResultExt ;
2730
28- use crate :: function:: { Function , FunctionContext } ;
29- use crate :: scalars:: geo:: helpers:: { ensure_columns_len, ensure_columns_n} ;
31+ use crate :: function:: Function ;
3032use crate :: scalars:: geo:: wkt:: parse_wkt;
3133
3234/// Return WGS84(SRID: 4326) euclidean distance between two geometry object, in degree
@@ -47,33 +49,39 @@ impl Function for STDistance {
4749 Signature :: string ( 2 , Volatility :: Stable )
4850 }
4951
50- fn eval ( & self , _func_ctx : & FunctionContext , columns : & [ VectorRef ] ) -> Result < VectorRef > {
51- ensure_columns_n ! ( columns, 2 ) ;
52+ fn invoke_with_args (
53+ & self ,
54+ args : ScalarFunctionArgs ,
55+ ) -> datafusion_common:: Result < ColumnarValue > {
56+ let args = ColumnarValue :: values_to_arrays ( & args. args ) ?;
57+ let [ arg0, arg1] = utils:: take_function_args ( self . name ( ) , args) ?;
5258
53- let wkt_this_vec = & columns[ 0 ] ;
54- let wkt_that_vec = & columns[ 1 ] ;
59+ let arg0 = compute:: cast ( & arg0, & DataType :: Utf8View ) ?;
60+ let wkt_this_vec = arg0. as_string_view ( ) ;
61+ let arg1 = compute:: cast ( & arg1, & DataType :: Utf8View ) ?;
62+ let wkt_that_vec = arg1. as_string_view ( ) ;
5563
5664 let size = wkt_this_vec. len ( ) ;
57- let mut results = Float64VectorBuilder :: with_capacity ( size) ;
65+ let mut builder = Float64Builder :: with_capacity ( size) ;
5866
5967 for i in 0 ..size {
60- let wkt_this = wkt_this_vec. get ( i) . as_string ( ) ;
61- let wkt_that = wkt_that_vec. get ( i) . as_string ( ) ;
68+ let wkt_this = wkt_this_vec. is_valid ( i) . then ( || wkt_this_vec . value ( i ) ) ;
69+ let wkt_that = wkt_that_vec. is_valid ( i) . then ( || wkt_that_vec . value ( i ) ) ;
6270
6371 let result = match ( wkt_this, wkt_that) {
6472 ( Some ( wkt_this) , Some ( wkt_that) ) => {
65- let geom_this = parse_wkt ( & wkt_this) ?;
66- let geom_that = parse_wkt ( & wkt_that) ?;
73+ let geom_this = parse_wkt ( wkt_this) ?;
74+ let geom_that = parse_wkt ( wkt_that) ?;
6775
6876 Some ( Euclidean :: distance ( & geom_this, & geom_that) )
6977 }
7078 _ => None ,
7179 } ;
7280
73- results . push ( result) ;
81+ builder . append_option ( result) ;
7482 }
7583
76- Ok ( results . to_vector ( ) )
84+ Ok ( ColumnarValue :: Array ( Arc :: new ( builder . finish ( ) ) ) )
7785 }
7886}
7987
@@ -95,23 +103,29 @@ impl Function for STDistanceSphere {
95103 Signature :: string ( 2 , Volatility :: Stable )
96104 }
97105
98- fn eval ( & self , _func_ctx : & FunctionContext , columns : & [ VectorRef ] ) -> Result < VectorRef > {
99- ensure_columns_n ! ( columns, 2 ) ;
106+ fn invoke_with_args (
107+ & self ,
108+ args : ScalarFunctionArgs ,
109+ ) -> datafusion_common:: Result < ColumnarValue > {
110+ let args = ColumnarValue :: values_to_arrays ( & args. args ) ?;
111+ let [ arg0, arg1] = utils:: take_function_args ( self . name ( ) , args) ?;
100112
101- let wkt_this_vec = & columns[ 0 ] ;
102- let wkt_that_vec = & columns[ 1 ] ;
113+ let arg0 = compute:: cast ( & arg0, & DataType :: Utf8View ) ?;
114+ let wkt_this_vec = arg0. as_string_view ( ) ;
115+ let arg1 = compute:: cast ( & arg1, & DataType :: Utf8View ) ?;
116+ let wkt_that_vec = arg1. as_string_view ( ) ;
103117
104118 let size = wkt_this_vec. len ( ) ;
105- let mut results = Float64VectorBuilder :: with_capacity ( size) ;
119+ let mut builder = Float64Builder :: with_capacity ( size) ;
106120
107121 for i in 0 ..size {
108- let wkt_this = wkt_this_vec. get ( i) . as_string ( ) ;
109- let wkt_that = wkt_that_vec. get ( i) . as_string ( ) ;
122+ let wkt_this = wkt_this_vec. is_valid ( i) . then ( || wkt_this_vec . value ( i ) ) ;
123+ let wkt_that = wkt_that_vec. is_valid ( i) . then ( || wkt_that_vec . value ( i ) ) ;
110124
111125 let result = match ( wkt_this, wkt_that) {
112126 ( Some ( wkt_this) , Some ( wkt_that) ) => {
113- let geom_this = parse_wkt ( & wkt_this) ?;
114- let geom_that = parse_wkt ( & wkt_that) ?;
127+ let geom_this = parse_wkt ( wkt_this) ?;
128+ let geom_that = parse_wkt ( wkt_that) ?;
115129
116130 match ( geom_this, geom_that) {
117131 ( Geometry :: Point ( this) , Geometry :: Point ( that) ) => {
@@ -128,10 +142,10 @@ impl Function for STDistanceSphere {
128142 _ => None ,
129143 } ;
130144
131- results . push ( result) ;
145+ builder . append_option ( result) ;
132146 }
133147
134- Ok ( results . to_vector ( ) )
148+ Ok ( ColumnarValue :: Array ( Arc :: new ( builder . finish ( ) ) ) )
135149 }
136150}
137151
@@ -153,27 +167,32 @@ impl Function for STArea {
153167 Signature :: string ( 1 , Volatility :: Stable )
154168 }
155169
156- fn eval ( & self , _func_ctx : & FunctionContext , columns : & [ VectorRef ] ) -> Result < VectorRef > {
157- ensure_columns_n ! ( columns, 1 ) ;
170+ fn invoke_with_args (
171+ & self ,
172+ args : ScalarFunctionArgs ,
173+ ) -> datafusion_common:: Result < ColumnarValue > {
174+ let args = ColumnarValue :: values_to_arrays ( & args. args ) ?;
175+ let [ arg0] = utils:: take_function_args ( self . name ( ) , args) ?;
158176
159- let wkt_vec = & columns[ 0 ] ;
177+ let arg0 = compute:: cast ( & arg0, & DataType :: Utf8View ) ?;
178+ let wkt_vec = arg0. as_string_view ( ) ;
160179
161180 let size = wkt_vec. len ( ) ;
162- let mut results = Float64VectorBuilder :: with_capacity ( size) ;
181+ let mut builder = Float64Builder :: with_capacity ( size) ;
163182
164183 for i in 0 ..size {
165- let wkt = wkt_vec. get ( i) . as_string ( ) ;
184+ let wkt = wkt_vec. is_valid ( i) . then ( || wkt_vec . value ( i ) ) ;
166185
167186 let result = if let Some ( wkt) = wkt {
168- let geom = parse_wkt ( & wkt) ?;
187+ let geom = parse_wkt ( wkt) ?;
169188 Some ( geom. unsigned_area ( ) )
170189 } else {
171190 None
172191 } ;
173192
174- results . push ( result) ;
193+ builder . append_option ( result) ;
175194 }
176195
177- Ok ( results . to_vector ( ) )
196+ Ok ( ColumnarValue :: Array ( Arc :: new ( builder . finish ( ) ) ) )
178197 }
179198}
0 commit comments