@@ -36,6 +36,7 @@ use geo::MultiPoint;
36
36
use geo:: Point ;
37
37
use geo_types:: Polygon ;
38
38
use geohash:: decode_bbox;
39
+ use geohash:: encode;
39
40
use geos:: geo_types;
40
41
use geos:: geo_types:: Coord ;
41
42
use geos:: geo_types:: LineString ;
@@ -48,11 +49,14 @@ use geozero::CoordDimensions;
48
49
use geozero:: ToGeo ;
49
50
use geozero:: ToJson ;
50
51
use geozero:: ToWkb ;
52
+ use geozero:: ToWkt ;
51
53
use jsonb:: parse_value;
52
54
use jsonb:: to_string;
53
55
54
56
pub fn register ( registry : & mut FunctionRegistry ) {
55
57
// aliases
58
+ registry. register_aliases ( "st_aswkb" , & [ "st_asbinary" ] ) ;
59
+ registry. register_aliases ( "st_aswkt" , & [ "st_astext" ] ) ;
56
60
registry. register_aliases ( "st_makegeompoint" , & [ "st_geom_point" ] ) ;
57
61
registry. register_aliases ( "st_makepolygon" , & [ "st_polygon" ] ) ;
58
62
registry. register_aliases ( "st_makeline" , & [ "st_make_line" ] ) ;
@@ -97,6 +101,124 @@ pub fn register(registry: &mut FunctionRegistry) {
97
101
} ) ,
98
102
) ;
99
103
104
+ registry. register_passthrough_nullable_1_arg :: < GeometryType , BinaryType , _ , _ > (
105
+ "st_asewkb" ,
106
+ |_, _| FunctionDomain :: MayThrow ,
107
+ vectorize_with_builder_1_arg :: < GeometryType , BinaryType > ( |geometry, builder, ctx| {
108
+ if let Some ( validity) = & ctx. validity {
109
+ if !validity. get_bit ( builder. len ( ) ) {
110
+ builder. commit_row ( ) ;
111
+ return ;
112
+ }
113
+ }
114
+
115
+ let srid = match read_ewkb_srid ( & mut io:: Cursor :: new ( & geometry) ) {
116
+ Ok ( srid) => srid,
117
+ _ => {
118
+ ctx. set_error (
119
+ builder. len ( ) ,
120
+ ErrorCode :: GeometryError ( "input geometry must has the correct SRID" )
121
+ . to_string ( ) ,
122
+ ) ;
123
+ builder. commit_row ( ) ;
124
+ return ;
125
+ }
126
+ } ;
127
+
128
+ match Ewkb ( geometry) . to_ewkb ( CoordDimensions :: xy ( ) , srid) {
129
+ Ok ( wkb) => builder. put_slice ( wkb. as_slice ( ) ) ,
130
+ Err ( e) => {
131
+ ctx. set_error (
132
+ builder. len ( ) ,
133
+ ErrorCode :: GeometryError ( e. to_string ( ) ) . to_string ( ) ,
134
+ ) ;
135
+ }
136
+ } ;
137
+ builder. commit_row ( ) ;
138
+ } ) ,
139
+ ) ;
140
+
141
+ registry. register_passthrough_nullable_1_arg :: < GeometryType , BinaryType , _ , _ > (
142
+ "st_aswkb" ,
143
+ |_, _| FunctionDomain :: MayThrow ,
144
+ vectorize_with_builder_1_arg :: < GeometryType , BinaryType > ( |geometry, builder, ctx| {
145
+ if let Some ( validity) = & ctx. validity {
146
+ if !validity. get_bit ( builder. len ( ) ) {
147
+ builder. commit_row ( ) ;
148
+ return ;
149
+ }
150
+ }
151
+
152
+ match Ewkb ( geometry) . to_wkb ( CoordDimensions :: xy ( ) ) {
153
+ Ok ( wkb) => builder. put_slice ( wkb. as_slice ( ) ) ,
154
+ Err ( e) => {
155
+ ctx. set_error (
156
+ builder. len ( ) ,
157
+ ErrorCode :: GeometryError ( e. to_string ( ) ) . to_string ( ) ,
158
+ ) ;
159
+ }
160
+ } ;
161
+ builder. commit_row ( ) ;
162
+ } ) ,
163
+ ) ;
164
+
165
+ registry. register_passthrough_nullable_1_arg :: < GeometryType , StringType , _ , _ > (
166
+ "st_asewkt" ,
167
+ |_, _| FunctionDomain :: MayThrow ,
168
+ vectorize_with_builder_1_arg :: < GeometryType , StringType > ( |geometry, builder, ctx| {
169
+ if let Some ( validity) = & ctx. validity {
170
+ if !validity. get_bit ( builder. len ( ) ) {
171
+ builder. commit_row ( ) ;
172
+ return ;
173
+ }
174
+ }
175
+
176
+ let srid = match read_ewkb_srid ( & mut io:: Cursor :: new ( & geometry) ) {
177
+ Ok ( srid) => srid,
178
+ _ => {
179
+ ctx. set_error (
180
+ builder. len ( ) ,
181
+ ErrorCode :: GeometryError ( "input geometry must has the correct SRID" )
182
+ . to_string ( ) ,
183
+ ) ;
184
+ builder. commit_row ( ) ;
185
+ return ;
186
+ }
187
+ } ;
188
+
189
+ match Ewkb ( geometry) . to_ewkt ( srid) {
190
+ Ok ( ewkt) => builder. put_str ( & ewkt) ,
191
+ Err ( e) => ctx. set_error (
192
+ builder. len ( ) ,
193
+ ErrorCode :: GeometryError ( e. to_string ( ) ) . to_string ( ) ,
194
+ ) ,
195
+ } ;
196
+ builder. commit_row ( ) ;
197
+ } ) ,
198
+ ) ;
199
+
200
+ registry. register_passthrough_nullable_1_arg :: < GeometryType , StringType , _ , _ > (
201
+ "st_aswkt" ,
202
+ |_, _| FunctionDomain :: MayThrow ,
203
+ vectorize_with_builder_1_arg :: < GeometryType , StringType > ( |geometry, builder, ctx| {
204
+ if let Some ( validity) = & ctx. validity {
205
+ if !validity. get_bit ( builder. len ( ) ) {
206
+ builder. commit_row ( ) ;
207
+ return ;
208
+ }
209
+ }
210
+
211
+ match Ewkb ( geometry) . to_wkt ( ) {
212
+ Ok ( wkt) => builder. put_str ( & wkt) ,
213
+ Err ( e) => ctx. set_error (
214
+ builder. len ( ) ,
215
+ ErrorCode :: GeometryError ( e. to_string ( ) ) . to_string ( ) ,
216
+ ) ,
217
+ } ;
218
+ builder. commit_row ( ) ;
219
+ } ) ,
220
+ ) ;
221
+
100
222
registry. register_passthrough_nullable_1_arg :: < StringType , GeometryType , _ , _ > (
101
223
"st_geomfromgeohash" ,
102
224
|_, _| FunctionDomain :: MayThrow ,
@@ -109,8 +231,10 @@ pub fn register(registry: &mut FunctionRegistry) {
109
231
}
110
232
111
233
if geohash. len ( ) > 12 {
112
- ctx. set_error ( builder. len ( ) , "" ) ;
113
- builder. put_str ( "Currently the precision only implement within 12 digits!" ) ;
234
+ ctx. set_error (
235
+ builder. len ( ) ,
236
+ "Currently the precision only implement within 12 digits!" ,
237
+ ) ;
114
238
builder. commit_row ( ) ;
115
239
return ;
116
240
}
@@ -354,6 +478,67 @@ pub fn register(registry: &mut FunctionRegistry) {
354
478
) ,
355
479
) ;
356
480
481
+ registry. register_passthrough_nullable_1_arg :: < GeometryType , StringType , _ , _ > (
482
+ "st_geohash" ,
483
+ |_, _| FunctionDomain :: MayThrow ,
484
+ vectorize_with_builder_1_arg :: < GeometryType , StringType > ( |geometry, builder, ctx| {
485
+ if let Some ( validity) = & ctx. validity {
486
+ if !validity. get_bit ( builder. len ( ) ) {
487
+ builder. commit_row ( ) ;
488
+ return ;
489
+ }
490
+ }
491
+
492
+ match point_to_geohash ( geometry, None ) {
493
+ Ok ( hash) => builder. put_str ( & hash) ,
494
+ Err ( e) => {
495
+ ctx. set_error (
496
+ builder. len ( ) ,
497
+ ErrorCode :: GeometryError ( e. to_string ( ) ) . to_string ( ) ,
498
+ ) ;
499
+ return ;
500
+ }
501
+ } ;
502
+ builder. commit_row ( ) ;
503
+ } ) ,
504
+ ) ;
505
+
506
+ registry. register_passthrough_nullable_2_arg :: < GeometryType , Int32Type , StringType , _ , _ > (
507
+ "st_geohash" ,
508
+ |_, _, _| FunctionDomain :: MayThrow ,
509
+ vectorize_with_builder_2_arg :: < GeometryType , Int32Type , StringType > (
510
+ |geometry, precision, builder, ctx| {
511
+ if let Some ( validity) = & ctx. validity {
512
+ if !validity. get_bit ( builder. len ( ) ) {
513
+ builder. commit_row ( ) ;
514
+ return ;
515
+ }
516
+ }
517
+
518
+ if precision > 12 {
519
+ ctx. set_error (
520
+ builder. len ( ) ,
521
+ "Currently the precision only implement within 12 digits!" ,
522
+ ) ;
523
+ builder. commit_row ( ) ;
524
+ return ;
525
+ }
526
+
527
+ match point_to_geohash ( geometry, Some ( precision) ) {
528
+ Ok ( hash) => builder. put_str ( & hash) ,
529
+ Err ( e) => {
530
+ ctx. set_error (
531
+ builder. len ( ) ,
532
+ ErrorCode :: GeometryError ( e. to_string ( ) ) . to_string ( ) ,
533
+ ) ;
534
+ return ;
535
+ }
536
+ } ;
537
+ builder. commit_row ( ) ;
538
+ } ,
539
+ ) ,
540
+ ) ;
541
+
357
542
registry. register_passthrough_nullable_1_arg :: < StringType , GeometryType , _ , _ > (
358
543
"st_geometryfromwkb" ,
359
544
|_, _| FunctionDomain :: MayThrow ,
@@ -1080,3 +1265,22 @@ fn json_to_geometry_impl(
1080
1265
Err ( e) => Err ( ErrorCode :: GeometryError ( e. to_string ( ) ) ) ,
1081
1266
}
1082
1267
}
1268
+
1269
+ fn point_to_geohash (
1270
+ geometry : & [ u8 ] ,
1271
+ precision : Option < i32 > ,
1272
+ ) -> databend_common_exception:: Result < String > {
1273
+ let point = match Ewkb ( geometry) . to_geo ( ) {
1274
+ Ok ( geo) => Point :: try_from ( geo) ,
1275
+ Err ( e) => return Err ( ErrorCode :: GeometryError ( e. to_string ( ) ) ) ,
1276
+ } ;
1277
+
1278
+ let hash = match point {
1279
+ Ok ( point) => encode ( point. 0 , precision. map_or ( 12 , |p| p as usize ) ) ,
1280
+ Err ( e) => return Err ( ErrorCode :: GeometryError ( e. to_string ( ) ) ) ,
1281
+ } ;
1282
+ match hash {
1283
+ Ok ( hash) => Ok ( hash) ,
1284
+ Err ( e) => Err ( ErrorCode :: GeometryError ( e. to_string ( ) ) ) ,
1285
+ }
1286
+ }
0 commit comments