common_function/scalars/geo/
relation.rs1use common_query::error::Result;
16use common_query::prelude::{Signature, TypeSignature};
17use datafusion::logical_expr::Volatility;
18use datatypes::prelude::ConcreteDataType;
19use datatypes::scalars::ScalarVectorBuilder;
20use datatypes::vectors::{BooleanVectorBuilder, MutableVector, VectorRef};
21use derive_more::Display;
22use geo::algorithm::contains::Contains;
23use geo::algorithm::intersects::Intersects;
24use geo::algorithm::within::Within;
25
26use crate::function::{Function, FunctionContext};
27use crate::scalars::geo::helpers::{ensure_columns_len, ensure_columns_n};
28use crate::scalars::geo::wkt::parse_wkt;
29
30#[derive(Clone, Debug, Default, Display)]
32#[display("{}", self.name())]
33pub struct STContains;
34
35impl Function for STContains {
36 fn name(&self) -> &str {
37 "st_contains"
38 }
39
40 fn return_type(&self, _input_types: &[ConcreteDataType]) -> Result<ConcreteDataType> {
41 Ok(ConcreteDataType::boolean_datatype())
42 }
43
44 fn signature(&self) -> Signature {
45 Signature::new(
46 TypeSignature::Exact(vec![
47 ConcreteDataType::string_datatype(),
48 ConcreteDataType::string_datatype(),
49 ]),
50 Volatility::Stable,
51 )
52 }
53
54 fn eval(&self, _func_ctx: &FunctionContext, columns: &[VectorRef]) -> Result<VectorRef> {
55 ensure_columns_n!(columns, 2);
56
57 let wkt_this_vec = &columns[0];
58 let wkt_that_vec = &columns[1];
59
60 let size = wkt_this_vec.len();
61 let mut results = BooleanVectorBuilder::with_capacity(size);
62
63 for i in 0..size {
64 let wkt_this = wkt_this_vec.get(i).as_string();
65 let wkt_that = wkt_that_vec.get(i).as_string();
66
67 let result = match (wkt_this, wkt_that) {
68 (Some(wkt_this), Some(wkt_that)) => {
69 let geom_this = parse_wkt(&wkt_this)?;
70 let geom_that = parse_wkt(&wkt_that)?;
71
72 Some(geom_this.contains(&geom_that))
73 }
74 _ => None,
75 };
76
77 results.push(result);
78 }
79
80 Ok(results.to_vector())
81 }
82}
83
84#[derive(Clone, Debug, Default, Display)]
86#[display("{}", self.name())]
87pub struct STWithin;
88
89impl Function for STWithin {
90 fn name(&self) -> &str {
91 "st_within"
92 }
93
94 fn return_type(&self, _input_types: &[ConcreteDataType]) -> Result<ConcreteDataType> {
95 Ok(ConcreteDataType::boolean_datatype())
96 }
97
98 fn signature(&self) -> Signature {
99 Signature::new(
100 TypeSignature::Exact(vec![
101 ConcreteDataType::string_datatype(),
102 ConcreteDataType::string_datatype(),
103 ]),
104 Volatility::Stable,
105 )
106 }
107
108 fn eval(&self, _func_ctx: &FunctionContext, columns: &[VectorRef]) -> Result<VectorRef> {
109 ensure_columns_n!(columns, 2);
110
111 let wkt_this_vec = &columns[0];
112 let wkt_that_vec = &columns[1];
113
114 let size = wkt_this_vec.len();
115 let mut results = BooleanVectorBuilder::with_capacity(size);
116
117 for i in 0..size {
118 let wkt_this = wkt_this_vec.get(i).as_string();
119 let wkt_that = wkt_that_vec.get(i).as_string();
120
121 let result = match (wkt_this, wkt_that) {
122 (Some(wkt_this), Some(wkt_that)) => {
123 let geom_this = parse_wkt(&wkt_this)?;
124 let geom_that = parse_wkt(&wkt_that)?;
125
126 Some(geom_this.is_within(&geom_that))
127 }
128 _ => None,
129 };
130
131 results.push(result);
132 }
133
134 Ok(results.to_vector())
135 }
136}
137
138#[derive(Clone, Debug, Default, Display)]
140#[display("{}", self.name())]
141pub struct STIntersects;
142
143impl Function for STIntersects {
144 fn name(&self) -> &str {
145 "st_intersects"
146 }
147
148 fn return_type(&self, _input_types: &[ConcreteDataType]) -> Result<ConcreteDataType> {
149 Ok(ConcreteDataType::boolean_datatype())
150 }
151
152 fn signature(&self) -> Signature {
153 Signature::new(
154 TypeSignature::Exact(vec![
155 ConcreteDataType::string_datatype(),
156 ConcreteDataType::string_datatype(),
157 ]),
158 Volatility::Stable,
159 )
160 }
161
162 fn eval(&self, _func_ctx: &FunctionContext, columns: &[VectorRef]) -> Result<VectorRef> {
163 ensure_columns_n!(columns, 2);
164
165 let wkt_this_vec = &columns[0];
166 let wkt_that_vec = &columns[1];
167
168 let size = wkt_this_vec.len();
169 let mut results = BooleanVectorBuilder::with_capacity(size);
170
171 for i in 0..size {
172 let wkt_this = wkt_this_vec.get(i).as_string();
173 let wkt_that = wkt_that_vec.get(i).as_string();
174
175 let result = match (wkt_this, wkt_that) {
176 (Some(wkt_this), Some(wkt_that)) => {
177 let geom_this = parse_wkt(&wkt_this)?;
178 let geom_that = parse_wkt(&wkt_that)?;
179
180 Some(geom_this.intersects(&geom_that))
181 }
182 _ => None,
183 };
184
185 results.push(result);
186 }
187
188 Ok(results.to_vector())
189 }
190}