Coverage Report

Created: 2026-03-16 21:05

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
be/src/exprs/function/geo/functions_geo.cpp
Line
Count
Source
1
// Licensed to the Apache Software Foundation (ASF) under one
2
// or more contributor license agreements.  See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership.  The ASF licenses this file
5
// to you under the Apache License, Version 2.0 (the
6
// "License"); you may not use this file except in compliance
7
// with the License.  You may obtain a copy of the License at
8
//
9
//   http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing,
12
// software distributed under the License is distributed on an
13
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
// KIND, either express or implied.  See the License for the
15
// specific language governing permissions and limitations
16
// under the License.
17
18
#include "exprs/function/geo/functions_geo.h"
19
20
#include <glog/logging.h>
21
22
#include <algorithm>
23
#include <boost/iterator/iterator_facade.hpp>
24
#include <utility>
25
26
#include "common/compiler_util.h"
27
#include "core/assert_cast.h"
28
#include "core/block/block.h"
29
#include "core/block/column_with_type_and_name.h"
30
#include "core/column/column.h"
31
#include "core/column/column_execute_util.h"
32
#include "core/column/column_nullable.h"
33
#include "core/data_type/data_type_nullable.h"
34
#include "core/data_type/data_type_number.h"
35
#include "core/data_type/data_type_string.h"
36
#include "core/data_type/define_primitive_type.h"
37
#include "core/string_ref.h"
38
#include "exprs/function/geo/geo_common.h"
39
#include "exprs/function/geo/geo_types.h"
40
#include "exprs/function/simple_function_factory.h"
41
42
namespace doris {
43
44
struct StPoint {
45
    static constexpr auto NAME = "st_point";
46
    static const size_t NUM_ARGS = 2;
47
    using Type = DataTypeString;
48
3
    static Status execute(Block& block, const ColumnNumbers& arguments, size_t result) {
49
3
        DCHECK_EQ(arguments.size(), 2);
50
3
        auto return_type = block.get_data_type(result);
51
52
3
        auto x_col = ColumnView<TYPE_DOUBLE>::create(block.get_by_position(arguments[0]).column);
53
3
        auto y_col = ColumnView<TYPE_DOUBLE>::create(block.get_by_position(arguments[1]).column);
54
55
3
        const auto size = x_col.size();
56
57
3
        auto res = ColumnString::create();
58
3
        auto null_map = ColumnUInt8::create(size, 0);
59
3
        auto& null_map_data = null_map->get_data();
60
3
        GeoPoint point;
61
3
        std::string buf;
62
8
        for (int row = 0; row < size; ++row) {
63
5
            auto cur_res = point.from_coord(x_col.value_at(row), y_col.value_at(row));
64
5
            if (cur_res != GEO_PARSE_OK) {
65
0
                null_map_data[row] = 1;
66
0
                res->insert_default();
67
0
                continue;
68
0
            }
69
5
            buf.clear();
70
5
            point.encode_to(&buf);
71
5
            res->insert_data(buf.data(), buf.size());
72
5
        }
73
74
3
        block.replace_by_position(result,
75
3
                                  ColumnNullable::create(std::move(res), std::move(null_map)));
76
3
        return Status::OK();
77
3
    }
78
};
79
80
struct StAsTextName {
81
    static constexpr auto NAME = "st_astext";
82
};
83
struct StAsWktName {
84
    static constexpr auto NAME = "st_aswkt";
85
};
86
87
template <typename FunctionName>
88
struct StAsText {
89
    static constexpr auto NAME = FunctionName::NAME;
90
    static const size_t NUM_ARGS = 1;
91
    using Type = DataTypeString;
92
2
    static Status execute(Block& block, const ColumnNumbers& arguments, size_t result) {
93
2
        DCHECK_EQ(arguments.size(), 1);
94
2
        auto return_type = block.get_data_type(result);
95
96
2
        auto& input = block.get_by_position(arguments[0]).column;
97
98
2
        auto size = input->size();
99
100
2
        auto res = ColumnString::create();
101
2
        auto null_map = ColumnUInt8::create(size, 0);
102
2
        auto& null_map_data = null_map->get_data();
103
104
2
        std::unique_ptr<GeoShape> shape;
105
6
        for (int row = 0; row < size; ++row) {
106
4
            auto shape_value = input->get_data_at(row);
107
4
            shape = GeoShape::from_encoded(shape_value.data, shape_value.size);
108
4
            if (shape == nullptr) {
109
2
                null_map_data[row] = 1;
110
2
                res->insert_default();
111
2
                continue;
112
2
            }
113
2
            auto wkt = shape->as_wkt();
114
2
            res->insert_data(wkt.data(), wkt.size());
115
2
        }
116
2
        block.replace_by_position(result,
117
2
                                  ColumnNullable::create(std::move(res), std::move(null_map)));
118
119
2
        return Status::OK();
120
2
    }
_ZN5doris8StAsTextINS_11StAsWktNameEE7executeERNS_5BlockERKSt6vectorIjSaIjEEm
Line
Count
Source
92
1
    static Status execute(Block& block, const ColumnNumbers& arguments, size_t result) {
93
1
        DCHECK_EQ(arguments.size(), 1);
94
1
        auto return_type = block.get_data_type(result);
95
96
1
        auto& input = block.get_by_position(arguments[0]).column;
97
98
1
        auto size = input->size();
99
100
1
        auto res = ColumnString::create();
101
1
        auto null_map = ColumnUInt8::create(size, 0);
102
1
        auto& null_map_data = null_map->get_data();
103
104
1
        std::unique_ptr<GeoShape> shape;
105
3
        for (int row = 0; row < size; ++row) {
106
2
            auto shape_value = input->get_data_at(row);
107
2
            shape = GeoShape::from_encoded(shape_value.data, shape_value.size);
108
2
            if (shape == nullptr) {
109
1
                null_map_data[row] = 1;
110
1
                res->insert_default();
111
1
                continue;
112
1
            }
113
1
            auto wkt = shape->as_wkt();
114
1
            res->insert_data(wkt.data(), wkt.size());
115
1
        }
116
1
        block.replace_by_position(result,
117
1
                                  ColumnNullable::create(std::move(res), std::move(null_map)));
118
119
1
        return Status::OK();
120
1
    }
_ZN5doris8StAsTextINS_12StAsTextNameEE7executeERNS_5BlockERKSt6vectorIjSaIjEEm
Line
Count
Source
92
1
    static Status execute(Block& block, const ColumnNumbers& arguments, size_t result) {
93
1
        DCHECK_EQ(arguments.size(), 1);
94
1
        auto return_type = block.get_data_type(result);
95
96
1
        auto& input = block.get_by_position(arguments[0]).column;
97
98
1
        auto size = input->size();
99
100
1
        auto res = ColumnString::create();
101
1
        auto null_map = ColumnUInt8::create(size, 0);
102
1
        auto& null_map_data = null_map->get_data();
103
104
1
        std::unique_ptr<GeoShape> shape;
105
3
        for (int row = 0; row < size; ++row) {
106
2
            auto shape_value = input->get_data_at(row);
107
2
            shape = GeoShape::from_encoded(shape_value.data, shape_value.size);
108
2
            if (shape == nullptr) {
109
1
                null_map_data[row] = 1;
110
1
                res->insert_default();
111
1
                continue;
112
1
            }
113
1
            auto wkt = shape->as_wkt();
114
1
            res->insert_data(wkt.data(), wkt.size());
115
1
        }
116
1
        block.replace_by_position(result,
117
1
                                  ColumnNullable::create(std::move(res), std::move(null_map)));
118
119
1
        return Status::OK();
120
1
    }
121
};
122
123
struct StX {
124
    static constexpr auto NAME = "st_x";
125
    static const size_t NUM_ARGS = 1;
126
    using Type = DataTypeFloat64;
127
1
    static Status execute(Block& block, const ColumnNumbers& arguments, size_t result) {
128
1
        DCHECK_EQ(arguments.size(), 1);
129
1
        auto return_type = block.get_data_type(result);
130
131
1
        auto& input = block.get_by_position(arguments[0]).column;
132
133
1
        auto size = input->size();
134
135
1
        auto res = ColumnFloat64::create();
136
1
        auto null_map = ColumnUInt8::create(size, 0);
137
1
        auto& null_map_data = null_map->get_data();
138
1
        res->reserve(size);
139
140
1
        GeoPoint point;
141
3
        for (int row = 0; row < size; ++row) {
142
2
            auto point_value = input->get_data_at(row);
143
2
            auto pt = point.decode_from(point_value.data, point_value.size);
144
145
2
            if (!pt) {
146
1
                null_map_data[row] = 1;
147
1
                res->insert_default();
148
1
                continue;
149
1
            }
150
1
            auto x_value = point.x();
151
1
            res->insert_value(x_value);
152
1
        }
153
1
        block.replace_by_position(result,
154
1
                                  ColumnNullable::create(std::move(res), std::move(null_map)));
155
156
1
        return Status::OK();
157
1
    }
158
};
159
160
struct StY {
161
    static constexpr auto NAME = "st_y";
162
    static const size_t NUM_ARGS = 1;
163
    using Type = DataTypeFloat64;
164
1
    static Status execute(Block& block, const ColumnNumbers& arguments, size_t result) {
165
1
        DCHECK_EQ(arguments.size(), 1);
166
1
        auto return_type = block.get_data_type(result);
167
168
1
        auto& input = block.get_by_position(arguments[0]).column;
169
170
1
        auto size = input->size();
171
172
1
        auto res = ColumnFloat64::create();
173
1
        res->reserve(size);
174
1
        auto null_map = ColumnUInt8::create(size, 0);
175
1
        auto& null_map_data = null_map->get_data();
176
177
1
        GeoPoint point;
178
3
        for (int row = 0; row < size; ++row) {
179
2
            auto point_value = input->get_data_at(row);
180
2
            auto pt = point.decode_from(point_value.data, point_value.size);
181
182
2
            if (!pt) {
183
1
                null_map_data[row] = 1;
184
1
                res->insert_default();
185
1
                continue;
186
1
            }
187
1
            auto y_value = point.y();
188
1
            res->insert_value(y_value);
189
1
        }
190
1
        block.replace_by_position(result,
191
1
                                  ColumnNullable::create(std::move(res), std::move(null_map)));
192
193
1
        return Status::OK();
194
1
    }
195
};
196
197
struct StDistanceSphere {
198
    static constexpr auto NAME = "st_distance_sphere";
199
    static const size_t NUM_ARGS = 4;
200
    using Type = DataTypeFloat64;
201
1
    static Status execute(Block& block, const ColumnNumbers& arguments, size_t result) {
202
1
        DCHECK_EQ(arguments.size(), 4);
203
1
        auto return_type = block.get_data_type(result);
204
205
1
        auto x_lng = ColumnView<TYPE_DOUBLE>::create(block.get_by_position(arguments[0]).column);
206
1
        auto x_lat = ColumnView<TYPE_DOUBLE>::create(block.get_by_position(arguments[1]).column);
207
1
        auto y_lng = ColumnView<TYPE_DOUBLE>::create(block.get_by_position(arguments[2]).column);
208
1
        auto y_lat = ColumnView<TYPE_DOUBLE>::create(block.get_by_position(arguments[3]).column);
209
210
1
        const auto size = x_lng.size();
211
1
        auto res = ColumnFloat64::create();
212
1
        res->reserve(size);
213
1
        auto null_map = ColumnUInt8::create(size, 0);
214
1
        auto& null_map_data = null_map->get_data();
215
6
        for (int row = 0; row < size; ++row) {
216
5
            double distance = 0;
217
5
            if (!GeoPoint::ComputeDistance(x_lng.value_at(row), x_lat.value_at(row),
218
5
                                           y_lng.value_at(row), y_lat.value_at(row), &distance)) {
219
0
                null_map_data[row] = 1;
220
0
                res->insert_default();
221
0
                continue;
222
0
            }
223
5
            res->insert_value(distance);
224
5
        }
225
226
1
        block.replace_by_position(result,
227
1
                                  ColumnNullable::create(std::move(res), std::move(null_map)));
228
1
        return Status::OK();
229
1
    }
230
};
231
232
struct StAngleSphere {
233
    static constexpr auto NAME = "st_angle_sphere";
234
    static const size_t NUM_ARGS = 4;
235
    using Type = DataTypeFloat64;
236
1
    static Status execute(Block& block, const ColumnNumbers& arguments, size_t result) {
237
1
        DCHECK_EQ(arguments.size(), 4);
238
1
        auto return_type = block.get_data_type(result);
239
240
1
        auto x_lng = ColumnView<TYPE_DOUBLE>::create(block.get_by_position(arguments[0]).column);
241
1
        auto x_lat = ColumnView<TYPE_DOUBLE>::create(block.get_by_position(arguments[1]).column);
242
1
        auto y_lng = ColumnView<TYPE_DOUBLE>::create(block.get_by_position(arguments[2]).column);
243
1
        auto y_lat = ColumnView<TYPE_DOUBLE>::create(block.get_by_position(arguments[3]).column);
244
245
1
        const auto size = x_lng.size();
246
247
1
        auto res = ColumnFloat64::create();
248
1
        res->reserve(size);
249
1
        auto null_map = ColumnUInt8::create(size, 0);
250
1
        auto& null_map_data = null_map->get_data();
251
252
6
        for (int row = 0; row < size; ++row) {
253
5
            double angle = 0;
254
5
            if (!GeoPoint::ComputeAngleSphere(x_lng.value_at(row), x_lat.value_at(row),
255
5
                                              y_lng.value_at(row), y_lat.value_at(row), &angle)) {
256
0
                null_map_data[row] = 1;
257
0
                res->insert_default();
258
0
                continue;
259
0
            }
260
5
            res->insert_value(angle);
261
5
        }
262
263
1
        block.replace_by_position(result,
264
1
                                  ColumnNullable::create(std::move(res), std::move(null_map)));
265
1
        return Status::OK();
266
1
    }
267
};
268
269
struct StAngle {
270
    static constexpr auto NAME = "st_angle";
271
    static const size_t NUM_ARGS = 3;
272
    using Type = DataTypeFloat64;
273
1
    static Status execute(Block& block, const ColumnNumbers& arguments, size_t result) {
274
1
        DCHECK_EQ(arguments.size(), 3);
275
1
        auto return_type = block.get_data_type(result);
276
277
1
        auto p1 = ColumnView<TYPE_STRING>::create(block.get_by_position(arguments[0]).column);
278
1
        auto p2 = ColumnView<TYPE_STRING>::create(block.get_by_position(arguments[1]).column);
279
1
        auto p3 = ColumnView<TYPE_STRING>::create(block.get_by_position(arguments[2]).column);
280
1
        const auto size = p1.size();
281
1
        auto res = ColumnFloat64::create();
282
1
        res->reserve(size);
283
1
        auto null_map = ColumnUInt8::create(size, 0);
284
1
        auto& null_map_data = null_map->get_data();
285
286
1
        GeoPoint point1;
287
1
        GeoPoint point2;
288
1
        GeoPoint point3;
289
290
5
        for (int row = 0; row < size; ++row) {
291
4
            auto shape_value1 = p1.value_at(row);
292
4
            auto pt1 = point1.decode_from(shape_value1.data, shape_value1.size);
293
4
            if (!pt1) {
294
1
                null_map_data[row] = 1;
295
1
                res->insert_default();
296
1
                continue;
297
1
            }
298
299
3
            auto shape_value2 = p2.value_at(row);
300
3
            auto pt2 = point2.decode_from(shape_value2.data, shape_value2.size);
301
3
            if (!pt2) {
302
1
                null_map_data[row] = 1;
303
1
                res->insert_default();
304
1
                continue;
305
1
            }
306
2
            auto shape_value3 = p3.value_at(row);
307
2
            auto pt3 = point3.decode_from(shape_value3.data, shape_value3.size);
308
2
            if (!pt3) {
309
1
                null_map_data[row] = 1;
310
1
                res->insert_default();
311
1
                continue;
312
1
            }
313
314
1
            double angle = 0;
315
1
            if (!GeoPoint::ComputeAngle(&point1, &point2, &point3, &angle)) {
316
0
                null_map_data[row] = 1;
317
0
                res->insert_default();
318
0
                continue;
319
0
            }
320
1
            res->insert_value(angle);
321
1
        }
322
1
        block.replace_by_position(result,
323
1
                                  ColumnNullable::create(std::move(res), std::move(null_map)));
324
1
        return Status::OK();
325
1
    }
326
};
327
328
struct StAzimuth {
329
    static constexpr auto NAME = "st_azimuth";
330
    static const size_t NUM_ARGS = 2;
331
    using Type = DataTypeFloat64;
332
3
    static Status execute(Block& block, const ColumnNumbers& arguments, size_t result) {
333
3
        DCHECK_EQ(arguments.size(), 2);
334
3
        auto return_type = block.get_data_type(result);
335
336
3
        auto left_col = ColumnView<TYPE_STRING>::create(block.get_by_position(arguments[0]).column);
337
3
        auto right_col =
338
3
                ColumnView<TYPE_STRING>::create(block.get_by_position(arguments[1]).column);
339
340
3
        const auto size = left_col.size();
341
3
        auto res = ColumnFloat64::create();
342
3
        res->reserve(size);
343
3
        auto null_map = ColumnUInt8::create(size, 0);
344
3
        auto& null_map_data = null_map->get_data();
345
3
        GeoPoint point1;
346
3
        GeoPoint point2;
347
8
        for (int row = 0; row < size; ++row) {
348
5
            auto shape_value1 = left_col.value_at(row);
349
5
            auto pt1 = point1.decode_from(shape_value1.data, shape_value1.size);
350
5
            auto shape_value2 = right_col.value_at(row);
351
5
            auto pt2 = point2.decode_from(shape_value2.data, shape_value2.size);
352
353
5
            if (!(pt1 && pt2)) {
354
2
                null_map_data[row] = 1;
355
2
                res->insert_default();
356
2
                continue;
357
2
            }
358
359
3
            double angle = 0;
360
3
            if (!GeoPoint::ComputeAzimuth(&point1, &point2, &angle)) {
361
0
                null_map_data[row] = 1;
362
0
                res->insert_default();
363
0
                continue;
364
0
            }
365
3
            res->insert_value(angle);
366
3
        }
367
3
        block.replace_by_position(result,
368
3
                                  ColumnNullable::create(std::move(res), std::move(null_map)));
369
3
        return Status::OK();
370
3
    }
371
};
372
373
struct StAreaSquareMeters {
374
    static constexpr auto NAME = "st_area_square_meters";
375
    static const size_t NUM_ARGS = 1;
376
    using Type = DataTypeFloat64;
377
1
    static Status execute(Block& block, const ColumnNumbers& arguments, size_t result) {
378
1
        DCHECK_EQ(arguments.size(), 1);
379
1
        auto return_type = block.get_data_type(result);
380
381
1
        auto col = block.get_by_position(arguments[0]).column->convert_to_full_column_if_const();
382
1
        const auto size = col->size();
383
1
        auto res = ColumnFloat64::create();
384
1
        res->reserve(size);
385
1
        auto null_map = ColumnUInt8::create(size, 0);
386
1
        auto& null_map_data = null_map->get_data();
387
1
        std::unique_ptr<GeoShape> shape;
388
389
3
        for (int row = 0; row < size; ++row) {
390
2
            auto shape_value = col->get_data_at(row);
391
2
            shape = GeoShape::from_encoded(shape_value.data, shape_value.size);
392
2
            if (!shape) {
393
1
                null_map_data[row] = 1;
394
1
                res->insert_default();
395
1
                continue;
396
1
            }
397
398
1
            double area = 0;
399
1
            if (!GeoShape::ComputeArea(shape.get(), &area, "square_meters")) {
400
0
                null_map_data[row] = 1;
401
0
                res->insert_default();
402
0
                continue;
403
0
            }
404
1
            res->insert_value(area);
405
1
        }
406
407
1
        block.replace_by_position(result,
408
1
                                  ColumnNullable::create(std::move(res), std::move(null_map)));
409
1
        return Status::OK();
410
1
    }
411
};
412
413
struct StAreaSquareKm {
414
    static constexpr auto NAME = "st_area_square_km";
415
    static const size_t NUM_ARGS = 1;
416
    using Type = DataTypeFloat64;
417
1
    static Status execute(Block& block, const ColumnNumbers& arguments, size_t result) {
418
1
        DCHECK_EQ(arguments.size(), 1);
419
1
        auto return_type = block.get_data_type(result);
420
421
1
        auto col = block.get_by_position(arguments[0]).column->convert_to_full_column_if_const();
422
1
        const auto size = col->size();
423
1
        auto res = ColumnFloat64::create();
424
1
        res->reserve(size);
425
1
        auto null_map = ColumnUInt8::create(size, 0);
426
1
        auto& null_map_data = null_map->get_data();
427
428
1
        std::unique_ptr<GeoShape> shape;
429
430
3
        for (int row = 0; row < size; ++row) {
431
2
            auto shape_value = col->get_data_at(row);
432
2
            shape = GeoShape::from_encoded(shape_value.data, shape_value.size);
433
2
            if (!shape) {
434
1
                null_map_data[row] = 1;
435
1
                res->insert_default();
436
1
                continue;
437
1
            }
438
439
1
            double area = 0;
440
1
            if (!GeoShape::ComputeArea(shape.get(), &area, "square_km")) {
441
0
                null_map_data[row] = 1;
442
0
                res->insert_default();
443
0
                ;
444
0
                continue;
445
0
            }
446
1
            res->insert_value(area);
447
1
        }
448
449
1
        block.replace_by_position(result,
450
1
                                  ColumnNullable::create(std::move(res), std::move(null_map)));
451
1
        return Status::OK();
452
1
    }
453
};
454
455
struct StCircle {
456
    static constexpr auto NAME = "st_circle";
457
    static const size_t NUM_ARGS = 3;
458
    using Type = DataTypeString;
459
1
    static Status execute(Block& block, const ColumnNumbers& arguments, size_t result) {
460
1
        DCHECK_EQ(arguments.size(), 3);
461
1
        auto return_type = block.get_data_type(result);
462
1
        auto center_lng =
463
1
                ColumnView<TYPE_DOUBLE>::create(block.get_by_position(arguments[0]).column);
464
1
        auto center_lat =
465
1
                ColumnView<TYPE_DOUBLE>::create(block.get_by_position(arguments[1]).column);
466
1
        auto radius = ColumnView<TYPE_DOUBLE>::create(block.get_by_position(arguments[2]).column);
467
468
1
        const auto size = center_lng.size();
469
470
1
        auto res = ColumnString::create();
471
472
1
        auto null_map = ColumnUInt8::create(size, 0);
473
1
        auto& null_map_data = null_map->get_data();
474
475
1
        GeoCircle circle;
476
1
        std::string buf;
477
5
        for (int row = 0; row < size; ++row) {
478
4
            auto lng_value = center_lng.value_at(row);
479
4
            auto lat_value = center_lat.value_at(row);
480
4
            auto radius_value = radius.value_at(row);
481
482
4
            auto value = circle.init(lng_value, lat_value, radius_value);
483
4
            if (value != GEO_PARSE_OK) {
484
0
                null_map_data[row] = 1;
485
0
                res->insert_default();
486
0
                continue;
487
0
            }
488
4
            buf.clear();
489
4
            circle.encode_to(&buf);
490
4
            res->insert_data(buf.data(), buf.size());
491
4
        }
492
1
        block.replace_by_position(result,
493
1
                                  ColumnNullable::create(std::move(res), std::move(null_map)));
494
1
        return Status::OK();
495
1
    }
496
};
497
498
template <typename Func>
499
struct StRelationFunction {
500
    static constexpr auto NAME = Func::NAME;
501
    static const size_t NUM_ARGS = 2;
502
    using Type = DataTypeUInt8;
503
504
5
    static Status execute(Block& block, const ColumnNumbers& arguments, size_t result) {
505
5
        DCHECK_EQ(arguments.size(), 2);
506
5
        auto return_type = block.get_data_type(result);
507
5
        auto left_col = ColumnView<TYPE_STRING>::create(block.get_by_position(arguments[0]).column);
508
5
        auto right_col =
509
5
                ColumnView<TYPE_STRING>::create(block.get_by_position(arguments[1]).column);
510
511
5
        const auto size = left_col.size();
512
513
5
        auto res = ColumnUInt8::create(size, 0);
514
5
        auto null_map = ColumnUInt8::create(size, 0);
515
5
        auto& null_map_data = null_map->get_data();
516
517
13
        for (int row = 0; row < size; ++row) {
518
8
            auto lhs_value = left_col.value_at(row);
519
8
            auto rhs_value = right_col.value_at(row);
520
521
8
            std::unique_ptr<GeoShape> shape1(
522
8
                    GeoShape::from_encoded(lhs_value.data, lhs_value.size));
523
8
            std::unique_ptr<GeoShape> shape2(
524
8
                    GeoShape::from_encoded(rhs_value.data, rhs_value.size));
525
526
8
            if (!shape1 || !shape2) {
527
2
                null_map_data[row] = 1;
528
2
                continue;
529
2
            }
530
6
            auto relation_value = Func::evaluate(shape1.get(), shape2.get());
531
6
            res->get_data()[row] = relation_value;
532
6
        }
533
5
        block.replace_by_position(result,
534
5
                                  ColumnNullable::create(std::move(res), std::move(null_map)));
535
5
        return Status::OK();
536
5
    }
_ZN5doris18StRelationFunctionINS_14StContainsFuncEE7executeERNS_5BlockERKSt6vectorIjSaIjEEm
Line
Count
Source
504
5
    static Status execute(Block& block, const ColumnNumbers& arguments, size_t result) {
505
5
        DCHECK_EQ(arguments.size(), 2);
506
5
        auto return_type = block.get_data_type(result);
507
5
        auto left_col = ColumnView<TYPE_STRING>::create(block.get_by_position(arguments[0]).column);
508
5
        auto right_col =
509
5
                ColumnView<TYPE_STRING>::create(block.get_by_position(arguments[1]).column);
510
511
5
        const auto size = left_col.size();
512
513
5
        auto res = ColumnUInt8::create(size, 0);
514
5
        auto null_map = ColumnUInt8::create(size, 0);
515
5
        auto& null_map_data = null_map->get_data();
516
517
13
        for (int row = 0; row < size; ++row) {
518
8
            auto lhs_value = left_col.value_at(row);
519
8
            auto rhs_value = right_col.value_at(row);
520
521
8
            std::unique_ptr<GeoShape> shape1(
522
8
                    GeoShape::from_encoded(lhs_value.data, lhs_value.size));
523
8
            std::unique_ptr<GeoShape> shape2(
524
8
                    GeoShape::from_encoded(rhs_value.data, rhs_value.size));
525
526
8
            if (!shape1 || !shape2) {
527
2
                null_map_data[row] = 1;
528
2
                continue;
529
2
            }
530
6
            auto relation_value = Func::evaluate(shape1.get(), shape2.get());
531
6
            res->get_data()[row] = relation_value;
532
6
        }
533
5
        block.replace_by_position(result,
534
5
                                  ColumnNullable::create(std::move(res), std::move(null_map)));
535
5
        return Status::OK();
536
5
    }
Unexecuted instantiation: _ZN5doris18StRelationFunctionINS_16StIntersectsFuncEE7executeERNS_5BlockERKSt6vectorIjSaIjEEm
Unexecuted instantiation: _ZN5doris18StRelationFunctionINS_14StDisjointFuncEE7executeERNS_5BlockERKSt6vectorIjSaIjEEm
Unexecuted instantiation: _ZN5doris18StRelationFunctionINS_13StTouchesFuncEE7executeERNS_5BlockERKSt6vectorIjSaIjEEm
537
};
538
539
struct StContainsFunc {
540
    static constexpr auto NAME = "st_contains";
541
6
    static bool evaluate(GeoShape* shape1, GeoShape* shape2) { return shape1->contains(shape2); }
542
};
543
544
struct StIntersectsFunc {
545
    static constexpr auto NAME = "st_intersects";
546
0
    static bool evaluate(GeoShape* shape1, GeoShape* shape2) { return shape1->intersects(shape2); }
547
};
548
549
struct StDisjointFunc {
550
    static constexpr auto NAME = "st_disjoint";
551
0
    static bool evaluate(GeoShape* shape1, GeoShape* shape2) { return shape1->disjoint(shape2); }
552
};
553
554
struct StTouchesFunc {
555
    static constexpr auto NAME = "st_touches";
556
0
    static bool evaluate(GeoShape* shape1, GeoShape* shape2) { return shape1->touches(shape2); }
557
};
558
559
struct StGeometryFromText {
560
    static constexpr auto NAME = "st_geometryfromtext";
561
    static constexpr GeoShapeType shape_type = GEO_SHAPE_ANY;
562
};
563
564
struct StGeomFromText {
565
    static constexpr auto NAME = "st_geomfromtext";
566
    static constexpr GeoShapeType shape_type = GEO_SHAPE_ANY;
567
};
568
569
struct StLineFromText {
570
    static constexpr auto NAME = "st_linefromtext";
571
    static constexpr GeoShapeType shape_type = GEO_SHAPE_LINE_STRING;
572
};
573
574
struct StLineStringFromText {
575
    static constexpr auto NAME = "st_linestringfromtext";
576
    static constexpr GeoShapeType shape_type = GEO_SHAPE_LINE_STRING;
577
};
578
579
struct StPolygon {
580
    static constexpr auto NAME = "st_polygon";
581
    static constexpr GeoShapeType shape_type = GEO_SHAPE_POLYGON;
582
};
583
584
struct StPolyFromText {
585
    static constexpr auto NAME = "st_polyfromtext";
586
    static constexpr GeoShapeType shape_type = GEO_SHAPE_POLYGON;
587
};
588
589
struct StPolygonFromText {
590
    static constexpr auto NAME = "st_polygonfromtext";
591
    static constexpr GeoShapeType shape_type = GEO_SHAPE_POLYGON;
592
};
593
594
template <typename Impl>
595
struct StGeoFromText {
596
    static constexpr auto NAME = Impl::NAME;
597
    static const size_t NUM_ARGS = 1;
598
    using Type = DataTypeString;
599
5
    static Status execute(Block& block, const ColumnNumbers& arguments, size_t result) {
600
5
        DCHECK_EQ(arguments.size(), 1);
601
5
        auto return_type = block.get_data_type(result);
602
5
        auto& geo = block.get_by_position(arguments[0]).column;
603
604
5
        const auto size = geo->size();
605
5
        auto res = ColumnString::create();
606
5
        auto null_map = ColumnUInt8::create(size, 0);
607
5
        auto& null_map_data = null_map->get_data();
608
5
        GeoParseStatus status;
609
5
        std::string buf;
610
15
        for (int row = 0; row < size; ++row) {
611
10
            auto value = geo->get_data_at(row);
612
10
            auto shape = GeoShape::from_wkt(value.data, value.size, status);
613
10
            if (shape == nullptr || status != GEO_PARSE_OK ||
614
10
                (Impl::shape_type != GEO_SHAPE_ANY && shape->type() != Impl::shape_type)) {
615
5
                null_map_data[row] = 1;
616
5
                res->insert_default();
617
5
                continue;
618
5
            }
619
5
            buf.clear();
620
5
            shape->encode_to(&buf);
621
5
            res->insert_data(buf.data(), buf.size());
622
5
        }
623
5
        block.replace_by_position(result,
624
5
                                  ColumnNullable::create(std::move(res), std::move(null_map)));
625
5
        return Status::OK();
626
5
    }
_ZN5doris13StGeoFromTextINS_18StGeometryFromTextEE7executeERNS_5BlockERKSt6vectorIjSaIjEEm
Line
Count
Source
599
1
    static Status execute(Block& block, const ColumnNumbers& arguments, size_t result) {
600
1
        DCHECK_EQ(arguments.size(), 1);
601
1
        auto return_type = block.get_data_type(result);
602
1
        auto& geo = block.get_by_position(arguments[0]).column;
603
604
1
        const auto size = geo->size();
605
1
        auto res = ColumnString::create();
606
1
        auto null_map = ColumnUInt8::create(size, 0);
607
1
        auto& null_map_data = null_map->get_data();
608
1
        GeoParseStatus status;
609
1
        std::string buf;
610
3
        for (int row = 0; row < size; ++row) {
611
2
            auto value = geo->get_data_at(row);
612
2
            auto shape = GeoShape::from_wkt(value.data, value.size, status);
613
2
            if (shape == nullptr || status != GEO_PARSE_OK ||
614
2
                (Impl::shape_type != GEO_SHAPE_ANY && shape->type() != Impl::shape_type)) {
615
1
                null_map_data[row] = 1;
616
1
                res->insert_default();
617
1
                continue;
618
1
            }
619
1
            buf.clear();
620
1
            shape->encode_to(&buf);
621
1
            res->insert_data(buf.data(), buf.size());
622
1
        }
623
1
        block.replace_by_position(result,
624
1
                                  ColumnNullable::create(std::move(res), std::move(null_map)));
625
1
        return Status::OK();
626
1
    }
_ZN5doris13StGeoFromTextINS_14StGeomFromTextEE7executeERNS_5BlockERKSt6vectorIjSaIjEEm
Line
Count
Source
599
1
    static Status execute(Block& block, const ColumnNumbers& arguments, size_t result) {
600
1
        DCHECK_EQ(arguments.size(), 1);
601
1
        auto return_type = block.get_data_type(result);
602
1
        auto& geo = block.get_by_position(arguments[0]).column;
603
604
1
        const auto size = geo->size();
605
1
        auto res = ColumnString::create();
606
1
        auto null_map = ColumnUInt8::create(size, 0);
607
1
        auto& null_map_data = null_map->get_data();
608
1
        GeoParseStatus status;
609
1
        std::string buf;
610
3
        for (int row = 0; row < size; ++row) {
611
2
            auto value = geo->get_data_at(row);
612
2
            auto shape = GeoShape::from_wkt(value.data, value.size, status);
613
2
            if (shape == nullptr || status != GEO_PARSE_OK ||
614
2
                (Impl::shape_type != GEO_SHAPE_ANY && shape->type() != Impl::shape_type)) {
615
1
                null_map_data[row] = 1;
616
1
                res->insert_default();
617
1
                continue;
618
1
            }
619
1
            buf.clear();
620
1
            shape->encode_to(&buf);
621
1
            res->insert_data(buf.data(), buf.size());
622
1
        }
623
1
        block.replace_by_position(result,
624
1
                                  ColumnNullable::create(std::move(res), std::move(null_map)));
625
1
        return Status::OK();
626
1
    }
_ZN5doris13StGeoFromTextINS_14StLineFromTextEE7executeERNS_5BlockERKSt6vectorIjSaIjEEm
Line
Count
Source
599
1
    static Status execute(Block& block, const ColumnNumbers& arguments, size_t result) {
600
1
        DCHECK_EQ(arguments.size(), 1);
601
1
        auto return_type = block.get_data_type(result);
602
1
        auto& geo = block.get_by_position(arguments[0]).column;
603
604
1
        const auto size = geo->size();
605
1
        auto res = ColumnString::create();
606
1
        auto null_map = ColumnUInt8::create(size, 0);
607
1
        auto& null_map_data = null_map->get_data();
608
1
        GeoParseStatus status;
609
1
        std::string buf;
610
3
        for (int row = 0; row < size; ++row) {
611
2
            auto value = geo->get_data_at(row);
612
2
            auto shape = GeoShape::from_wkt(value.data, value.size, status);
613
2
            if (shape == nullptr || status != GEO_PARSE_OK ||
614
2
                (Impl::shape_type != GEO_SHAPE_ANY && shape->type() != Impl::shape_type)) {
615
1
                null_map_data[row] = 1;
616
1
                res->insert_default();
617
1
                continue;
618
1
            }
619
1
            buf.clear();
620
1
            shape->encode_to(&buf);
621
1
            res->insert_data(buf.data(), buf.size());
622
1
        }
623
1
        block.replace_by_position(result,
624
1
                                  ColumnNullable::create(std::move(res), std::move(null_map)));
625
1
        return Status::OK();
626
1
    }
Unexecuted instantiation: _ZN5doris13StGeoFromTextINS_20StLineStringFromTextEE7executeERNS_5BlockERKSt6vectorIjSaIjEEm
_ZN5doris13StGeoFromTextINS_9StPolygonEE7executeERNS_5BlockERKSt6vectorIjSaIjEEm
Line
Count
Source
599
1
    static Status execute(Block& block, const ColumnNumbers& arguments, size_t result) {
600
1
        DCHECK_EQ(arguments.size(), 1);
601
1
        auto return_type = block.get_data_type(result);
602
1
        auto& geo = block.get_by_position(arguments[0]).column;
603
604
1
        const auto size = geo->size();
605
1
        auto res = ColumnString::create();
606
1
        auto null_map = ColumnUInt8::create(size, 0);
607
1
        auto& null_map_data = null_map->get_data();
608
1
        GeoParseStatus status;
609
1
        std::string buf;
610
3
        for (int row = 0; row < size; ++row) {
611
2
            auto value = geo->get_data_at(row);
612
2
            auto shape = GeoShape::from_wkt(value.data, value.size, status);
613
2
            if (shape == nullptr || status != GEO_PARSE_OK ||
614
2
                (Impl::shape_type != GEO_SHAPE_ANY && shape->type() != Impl::shape_type)) {
615
1
                null_map_data[row] = 1;
616
1
                res->insert_default();
617
1
                continue;
618
1
            }
619
1
            buf.clear();
620
1
            shape->encode_to(&buf);
621
1
            res->insert_data(buf.data(), buf.size());
622
1
        }
623
1
        block.replace_by_position(result,
624
1
                                  ColumnNullable::create(std::move(res), std::move(null_map)));
625
1
        return Status::OK();
626
1
    }
_ZN5doris13StGeoFromTextINS_17StPolygonFromTextEE7executeERNS_5BlockERKSt6vectorIjSaIjEEm
Line
Count
Source
599
1
    static Status execute(Block& block, const ColumnNumbers& arguments, size_t result) {
600
1
        DCHECK_EQ(arguments.size(), 1);
601
1
        auto return_type = block.get_data_type(result);
602
1
        auto& geo = block.get_by_position(arguments[0]).column;
603
604
1
        const auto size = geo->size();
605
1
        auto res = ColumnString::create();
606
1
        auto null_map = ColumnUInt8::create(size, 0);
607
1
        auto& null_map_data = null_map->get_data();
608
1
        GeoParseStatus status;
609
1
        std::string buf;
610
3
        for (int row = 0; row < size; ++row) {
611
2
            auto value = geo->get_data_at(row);
612
2
            auto shape = GeoShape::from_wkt(value.data, value.size, status);
613
2
            if (shape == nullptr || status != GEO_PARSE_OK ||
614
2
                (Impl::shape_type != GEO_SHAPE_ANY && shape->type() != Impl::shape_type)) {
615
1
                null_map_data[row] = 1;
616
1
                res->insert_default();
617
1
                continue;
618
1
            }
619
1
            buf.clear();
620
1
            shape->encode_to(&buf);
621
1
            res->insert_data(buf.data(), buf.size());
622
1
        }
623
1
        block.replace_by_position(result,
624
1
                                  ColumnNullable::create(std::move(res), std::move(null_map)));
625
1
        return Status::OK();
626
1
    }
Unexecuted instantiation: _ZN5doris13StGeoFromTextINS_14StPolyFromTextEE7executeERNS_5BlockERKSt6vectorIjSaIjEEm
627
};
628
629
struct StGeometryFromWKB {
630
    static constexpr auto NAME = "st_geometryfromwkb";
631
    static constexpr GeoShapeType shape_type = GEO_SHAPE_ANY;
632
};
633
634
struct StGeomFromWKB {
635
    static constexpr auto NAME = "st_geomfromwkb";
636
    static constexpr GeoShapeType shape_type = GEO_SHAPE_ANY;
637
};
638
639
template <typename Impl>
640
struct StGeoFromWkb {
641
    static constexpr auto NAME = Impl::NAME;
642
    static const size_t NUM_ARGS = 1;
643
    using Type = DataTypeString;
644
0
    static Status execute(Block& block, const ColumnNumbers& arguments, size_t result) {
645
0
        DCHECK_EQ(arguments.size(), 1);
646
0
        auto return_type = block.get_data_type(result);
647
0
        auto& geo = block.get_by_position(arguments[0]).column;
648
649
0
        const auto size = geo->size();
650
0
        auto res = ColumnString::create();
651
0
        auto null_map = ColumnUInt8::create(size, 0);
652
0
        auto& null_map_data = null_map->get_data();
653
0
        GeoParseStatus status;
654
0
        std::string buf;
655
0
        for (int row = 0; row < size; ++row) {
656
0
            auto value = geo->get_data_at(row);
657
0
            std::unique_ptr<GeoShape> shape = GeoShape::from_wkb(value.data, value.size, status);
658
0
            if (shape == nullptr || status != GEO_PARSE_OK) {
659
0
                null_map_data[row] = 1;
660
0
                res->insert_default();
661
0
                continue;
662
0
            }
663
0
            buf.clear();
664
0
            shape->encode_to(&buf);
665
0
            res->insert_data(buf.data(), buf.size());
666
0
        }
667
0
        block.replace_by_position(result,
668
0
                                  ColumnNullable::create(std::move(res), std::move(null_map)));
669
0
        return Status::OK();
670
0
    }
Unexecuted instantiation: _ZN5doris12StGeoFromWkbINS_17StGeometryFromWKBEE7executeERNS_5BlockERKSt6vectorIjSaIjEEm
Unexecuted instantiation: _ZN5doris12StGeoFromWkbINS_13StGeomFromWKBEE7executeERNS_5BlockERKSt6vectorIjSaIjEEm
671
};
672
673
struct StAsBinary {
674
    static constexpr auto NAME = "st_asbinary";
675
    static const size_t NUM_ARGS = 1;
676
    using Type = DataTypeString;
677
0
    static Status execute(Block& block, const ColumnNumbers& arguments, size_t result) {
678
0
        DCHECK_EQ(arguments.size(), 1);
679
0
        auto return_type = block.get_data_type(result);
680
0
        auto res = ColumnString::create();
681
682
0
        auto col = block.get_by_position(arguments[0]).column;
683
0
        const auto size = col->size();
684
0
        auto null_map = ColumnUInt8::create(size, 0);
685
0
        auto& null_map_data = null_map->get_data();
686
0
        std::unique_ptr<GeoShape> shape;
687
688
0
        for (int row = 0; row < size; ++row) {
689
0
            auto shape_value = col->get_data_at(row);
690
0
            shape = GeoShape::from_encoded(shape_value.data, shape_value.size);
691
0
            if (!shape) {
692
0
                null_map_data[row] = 1;
693
0
                res->insert_default();
694
0
                continue;
695
0
            }
696
697
0
            std::string binary = GeoShape::as_binary(shape.get());
698
0
            if (binary.empty()) {
699
0
                null_map_data[row] = 1;
700
0
                res->insert_default();
701
0
                continue;
702
0
            }
703
0
            res->insert_data(binary.data(), binary.size());
704
0
        }
705
706
0
        block.replace_by_position(result,
707
0
                                  ColumnNullable::create(std::move(res), std::move(null_map)));
708
0
        return Status::OK();
709
0
    }
710
};
711
712
struct StLength {
713
    static constexpr auto NAME = "st_length";
714
    static const size_t NUM_ARGS = 1;
715
    using Type = DataTypeFloat64;
716
0
    static Status execute(Block& block, const ColumnNumbers& arguments, size_t result) {
717
0
        DCHECK_EQ(arguments.size(), 1);
718
0
        auto return_type = block.get_data_type(result);
719
720
0
        auto col = block.get_by_position(arguments[0]).column->convert_to_full_column_if_const();
721
0
        const auto size = col->size();
722
0
        auto res = ColumnFloat64::create();
723
0
        res->reserve(size);
724
0
        auto null_map = ColumnUInt8::create(size, 0);
725
0
        auto& null_map_data = null_map->get_data();
726
727
0
        std::unique_ptr<GeoShape> shape;
728
0
        for (int row = 0; row < size; ++row) {
729
0
            auto shape_value = col->get_data_at(row);
730
0
            shape = GeoShape::from_encoded(shape_value.data, shape_value.size);
731
0
            if (!shape) {
732
0
                null_map_data[row] = 1;
733
0
                res->insert_default();
734
0
                continue;
735
0
            }
736
737
0
            double length = shape->Length();
738
0
            res->insert_value(length);
739
0
        }
740
741
0
        block.replace_by_position(result,
742
0
                                  ColumnNullable::create(std::move(res), std::move(null_map)));
743
0
        return Status::OK();
744
0
    }
745
};
746
747
struct StGeometryType {
748
    static constexpr auto NAME = "st_geometrytype";
749
    static const size_t NUM_ARGS = 1;
750
    using Type = DataTypeString;
751
0
    static Status execute(Block& block, const ColumnNumbers& arguments, size_t result) {
752
0
        DCHECK_EQ(arguments.size(), 1);
753
0
        auto return_type = block.get_data_type(result);
754
755
0
        auto col = block.get_by_position(arguments[0]).column->convert_to_full_column_if_const();
756
0
        const auto size = col->size();
757
0
        auto res = ColumnString::create();
758
0
        auto null_map = ColumnUInt8::create(size, 0);
759
0
        auto& null_map_data = null_map->get_data();
760
761
0
        std::unique_ptr<GeoShape> shape;
762
0
        for (int row = 0; row < size; ++row) {
763
0
            auto shape_value = col->get_data_at(row);
764
0
            shape = GeoShape::from_encoded(shape_value.data, shape_value.size);
765
0
            if (!shape) {
766
0
                null_map_data[row] = 1;
767
0
                res->insert_default();
768
0
                continue;
769
0
            }
770
771
0
            auto geo_type = shape->GeometryType();
772
0
            res->insert_data(geo_type.data(), geo_type.size());
773
0
        }
774
775
0
        block.replace_by_position(result,
776
0
                                  ColumnNullable::create(std::move(res), std::move(null_map)));
777
0
        return Status::OK();
778
0
    }
779
};
780
781
struct StDistance {
782
    static constexpr auto NAME = "st_distance";
783
    static const size_t NUM_ARGS = 2;
784
    using Type = DataTypeFloat64;
785
786
0
    static Status execute(Block& block, const ColumnNumbers& arguments, size_t result) {
787
0
        DCHECK_EQ(arguments.size(), 2);
788
0
        auto return_type = block.get_data_type(result);
789
0
        const auto& [left_column, left_const] =
790
0
                unpack_if_const(block.get_by_position(arguments[0]).column);
791
0
        const auto& [right_column, right_const] =
792
0
                unpack_if_const(block.get_by_position(arguments[1]).column);
793
794
0
        const auto size = std::max(left_column->size(), right_column->size());
795
796
0
        auto res = ColumnFloat64::create();
797
0
        res->reserve(size);
798
0
        auto null_map = ColumnUInt8::create(size, 0);
799
0
        auto& null_map_data = null_map->get_data();
800
801
0
        if (left_const) {
802
0
            const_vector(left_column, right_column, res, null_map_data, size);
803
0
        } else if (right_const) {
804
0
            vector_const(left_column, right_column, res, null_map_data, size);
805
0
        } else {
806
0
            vector_vector(left_column, right_column, res, null_map_data, size);
807
0
        }
808
0
        block.replace_by_position(result,
809
0
                                  ColumnNullable::create(std::move(res), std::move(null_map)));
810
0
        return Status::OK();
811
0
    }
812
813
private:
814
0
    static bool decode_shape(const StringRef& value, std::unique_ptr<GeoShape>& shape) {
815
0
        shape = GeoShape::from_encoded(value.data, value.size);
816
0
        return static_cast<bool>(shape);
817
0
    }
818
819
    static void loop_do(StringRef& lhs_value, StringRef& rhs_value,
820
                        std::vector<std::unique_ptr<GeoShape>>& shapes,
821
0
                        ColumnFloat64::MutablePtr& res, NullMap& null_map, int row) {
822
0
        StringRef* strs[2] = {&lhs_value, &rhs_value};
823
0
        for (int i = 0; i < 2; ++i) {
824
0
            if (!decode_shape(*strs[i], shapes[i])) {
825
0
                null_map[row] = 1;
826
0
                res->insert_default();
827
0
                return;
828
0
            }
829
0
        }
830
0
        double distance = shapes[0]->Distance(shapes[1].get());
831
0
        if (UNLIKELY(distance < 0)) {
832
0
            null_map[row] = 1;
833
0
            res->insert_default();
834
0
            return;
835
0
        }
836
0
        res->insert_value(distance);
837
0
    }
838
839
    static void const_vector(const ColumnPtr& left_column, const ColumnPtr& right_column,
840
0
                             ColumnFloat64::MutablePtr& res, NullMap& null_map, const size_t size) {
841
0
        const auto* left_string = assert_cast<const ColumnString*>(left_column.get());
842
0
        const auto* right_string = assert_cast<const ColumnString*>(right_column.get());
843
844
0
        auto lhs_value = left_string->get_data_at(0);
845
0
        std::unique_ptr<GeoShape> lhs_shape;
846
0
        if (!decode_shape(lhs_value, lhs_shape)) {
847
0
            for (int row = 0; row < size; ++row) {
848
0
                null_map[row] = 1;
849
0
                res->insert_default();
850
0
            }
851
0
            return;
852
0
        }
853
854
0
        std::unique_ptr<GeoShape> rhs_shape;
855
0
        for (int row = 0; row < size; ++row) {
856
0
            auto rhs_value = right_string->get_data_at(row);
857
0
            if (!decode_shape(rhs_value, rhs_shape)) {
858
0
                null_map[row] = 1;
859
0
                res->insert_default();
860
0
                continue;
861
0
            }
862
0
            double distance = lhs_shape->Distance(rhs_shape.get());
863
0
            if (UNLIKELY(distance < 0)) {
864
0
                null_map[row] = 1;
865
0
                res->insert_default();
866
0
                continue;
867
0
            }
868
0
            res->insert_value(distance);
869
0
        }
870
0
    }
871
872
    static void vector_const(const ColumnPtr& left_column, const ColumnPtr& right_column,
873
0
                             ColumnFloat64::MutablePtr& res, NullMap& null_map, const size_t size) {
874
0
        const auto* left_string = assert_cast<const ColumnString*>(left_column.get());
875
0
        const auto* right_string = assert_cast<const ColumnString*>(right_column.get());
876
877
0
        auto rhs_value = right_string->get_data_at(0);
878
0
        std::unique_ptr<GeoShape> rhs_shape;
879
0
        if (!decode_shape(rhs_value, rhs_shape)) {
880
0
            for (int row = 0; row < size; ++row) {
881
0
                null_map[row] = 1;
882
0
                res->insert_default();
883
0
            }
884
0
            return;
885
0
        }
886
887
0
        std::unique_ptr<GeoShape> lhs_shape;
888
0
        for (int row = 0; row < size; ++row) {
889
0
            auto lhs_value = left_string->get_data_at(row);
890
0
            if (!decode_shape(lhs_value, lhs_shape)) {
891
0
                null_map[row] = 1;
892
0
                res->insert_default();
893
0
                continue;
894
0
            }
895
0
            double distance = lhs_shape->Distance(rhs_shape.get());
896
0
            if (UNLIKELY(distance < 0)) {
897
0
                null_map[row] = 1;
898
0
                res->insert_default();
899
0
                continue;
900
0
            }
901
0
            res->insert_value(distance);
902
0
        }
903
0
    }
904
905
    static void vector_vector(const ColumnPtr& left_column, const ColumnPtr& right_column,
906
                              ColumnFloat64::MutablePtr& res, NullMap& null_map,
907
0
                              const size_t size) {
908
0
        const auto* left_string = assert_cast<const ColumnString*>(left_column.get());
909
0
        const auto* right_string = assert_cast<const ColumnString*>(right_column.get());
910
911
0
        std::vector<std::unique_ptr<GeoShape>> shapes(2);
912
0
        for (int row = 0; row < size; ++row) {
913
0
            auto lhs_value = left_string->get_data_at(row);
914
0
            auto rhs_value = right_string->get_data_at(row);
915
0
            loop_do(lhs_value, rhs_value, shapes, res, null_map, row);
916
0
        }
917
0
    }
918
};
919
920
1
void register_function_geo(SimpleFunctionFactory& factory) {
921
1
    factory.register_function<GeoFunction<StPoint>>();
922
1
    factory.register_function<GeoFunction<StAsText<StAsWktName>>>();
923
1
    factory.register_function<GeoFunction<StAsText<StAsTextName>>>();
924
1
    factory.register_function<GeoFunction<StX>>();
925
1
    factory.register_function<GeoFunction<StY>>();
926
1
    factory.register_function<GeoFunction<StDistanceSphere>>();
927
1
    factory.register_function<GeoFunction<StAngleSphere>>();
928
1
    factory.register_function<GeoFunction<StAngle>>();
929
1
    factory.register_function<GeoFunction<StAzimuth>>();
930
1
    factory.register_function<GeoFunction<StRelationFunction<StContainsFunc>>>();
931
1
    factory.register_function<GeoFunction<StRelationFunction<StIntersectsFunc>>>();
932
1
    factory.register_function<GeoFunction<StRelationFunction<StDisjointFunc>>>();
933
1
    factory.register_function<GeoFunction<StRelationFunction<StTouchesFunc>>>();
934
1
    factory.register_function<GeoFunction<StCircle>>();
935
1
    factory.register_function<GeoFunction<StGeoFromText<StGeometryFromText>>>();
936
1
    factory.register_function<GeoFunction<StGeoFromText<StGeomFromText>>>();
937
1
    factory.register_function<GeoFunction<StGeoFromText<StLineFromText>>>();
938
1
    factory.register_function<GeoFunction<StGeoFromText<StLineStringFromText>>>();
939
1
    factory.register_function<GeoFunction<StGeoFromText<StPolygon>>>();
940
1
    factory.register_function<GeoFunction<StGeoFromText<StPolygonFromText>>>();
941
1
    factory.register_function<GeoFunction<StGeoFromText<StPolyFromText>>>();
942
1
    factory.register_function<GeoFunction<StAreaSquareMeters>>();
943
1
    factory.register_function<GeoFunction<StAreaSquareKm>>();
944
1
    factory.register_function<GeoFunction<StGeoFromWkb<StGeometryFromWKB>>>();
945
1
    factory.register_function<GeoFunction<StGeoFromWkb<StGeomFromWKB>>>();
946
1
    factory.register_function<GeoFunction<StAsBinary>>();
947
1
    factory.register_function<GeoFunction<StLength>>();
948
1
    factory.register_function<GeoFunction<StGeometryType>>();
949
1
    factory.register_function<GeoFunction<StDistance>>();
950
1
}
951
952
} // namespace doris