Skip to content

Commit b72f3e1

Browse files
authored
feat(query): support interval function (#17093)
* feat(query): support interval function * use register_simple_domain_type_cmp & MonthDayNano -> MonthDayMicros
1 parent ff6cb3e commit b72f3e1

File tree

12 files changed

+751
-12
lines changed

12 files changed

+751
-12
lines changed

src/common/column/src/types/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,8 @@ pub enum PrimitiveType {
8585
Float64,
8686
/// Two i32 representing days and ms
8787
DaysMs,
88-
/// months_days_ns(i32, i32, i64)
89-
MonthDayNano,
88+
/// months_days_micros(i32, i32, i64)
89+
MonthDayMicros,
9090
}
9191

9292
mod private {

src/common/column/src/types/native.rs

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@
1313
// See the License for the specific language governing permissions and
1414
// limitations under the License.
1515

16+
use std::cmp::Ordering;
1617
use std::convert::TryFrom;
18+
use std::hash::Hash;
19+
use std::hash::Hasher;
1720
use std::ops::Neg;
1821
use std::panic::RefUnwindSafe;
1922

@@ -252,11 +255,7 @@ impl NativeType for days_ms {
252255
Copy,
253256
Clone,
254257
Default,
255-
PartialEq,
256-
PartialOrd,
257-
Ord,
258258
Eq,
259-
Hash,
260259
Zeroable,
261260
Pod,
262261
Serialize,
@@ -268,6 +267,33 @@ impl NativeType for days_ms {
268267
#[repr(C)]
269268
pub struct months_days_micros(pub i128);
270269

270+
const MICROS_PER_DAY: i64 = 24 * 3600 * 1_000_000;
271+
const MICROS_PER_MONTH: i64 = 30 * MICROS_PER_DAY;
272+
273+
impl Hash for months_days_micros {
274+
fn hash<H: Hasher>(&self, state: &mut H) {
275+
self.total_micros().hash(state)
276+
}
277+
}
278+
impl PartialEq for months_days_micros {
279+
fn eq(&self, other: &Self) -> bool {
280+
self.total_micros() == other.total_micros()
281+
}
282+
}
283+
impl PartialOrd for months_days_micros {
284+
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
285+
Some(self.cmp(other))
286+
}
287+
}
288+
289+
impl Ord for months_days_micros {
290+
fn cmp(&self, other: &Self) -> Ordering {
291+
let total_micros = self.total_micros();
292+
let other_micros = other.total_micros();
293+
total_micros.cmp(&other_micros)
294+
}
295+
}
296+
271297
impl months_days_micros {
272298
pub fn new(months: i32, days: i32, microseconds: i64) -> Self {
273299
let months_bits = (months as i128) << 96;
@@ -291,10 +317,16 @@ impl months_days_micros {
291317
pub fn microseconds(&self) -> i64 {
292318
(self.0 & 0xFFFFFFFFFFFFFFFF) as i64
293319
}
320+
321+
pub fn total_micros(&self) -> i64 {
322+
(self.months() as i64 * MICROS_PER_MONTH)
323+
+ (self.days() as i64 * MICROS_PER_DAY)
324+
+ self.microseconds()
325+
}
294326
}
295327

296328
impl NativeType for months_days_micros {
297-
const PRIMITIVE: PrimitiveType = PrimitiveType::MonthDayNano;
329+
const PRIMITIVE: PrimitiveType = PrimitiveType::MonthDayMicros;
298330
type Bytes = [u8; 16];
299331
#[inline]
300332
fn to_le_bytes(&self) -> Self::Bytes {

src/common/io/tests/it/interval.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ fn test_interval_from_string() {
7676
}
7777

7878
#[test]
79-
fn test_string_to_interval() {
79+
fn test_interval_to_string() {
8080
let tests = vec![
8181
(
8282
Interval {
@@ -142,6 +142,14 @@ fn test_string_to_interval() {
142142
},
143143
"-1 day 1:23:45",
144144
),
145+
(
146+
Interval {
147+
months: 0,
148+
days: -225,
149+
micros: -52550000000,
150+
},
151+
"-225 days -14:35:50",
152+
),
145153
(
146154
Interval {
147155
months: 0,

src/common/native/src/write/primitive.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ pub(crate) fn write_primitive<T: NativeType, W: Write>(
8787

8888
PrimitiveType::Float16 => unimplemented!(),
8989
PrimitiveType::DaysMs => unimplemented!(),
90-
PrimitiveType::MonthDayNano => unimplemented!(),
90+
PrimitiveType::MonthDayMicros => unimplemented!(),
9191
PrimitiveType::UInt128 => unimplemented!(),
9292
}
9393
w.write_all(scratch.as_slice())?;

src/query/functions/src/scalars/comparison.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ use databend_common_expression::types::DataType;
2828
use databend_common_expression::types::DateType;
2929
use databend_common_expression::types::EmptyArrayType;
3030
use databend_common_expression::types::GenericType;
31+
use databend_common_expression::types::IntervalType;
3132
use databend_common_expression::types::MutableBitmap;
3233
use databend_common_expression::types::NumberClass;
3334
use databend_common_expression::types::NumberType;
@@ -65,6 +66,7 @@ pub fn register(registry: &mut FunctionRegistry) {
6566
register_array_cmp(registry);
6667
register_tuple_cmp(registry);
6768
register_like(registry);
69+
register_interval_cmp(registry);
6870
}
6971

7072
pub const ALL_COMP_FUNC_NAMES: &[&str] = &["eq", "noteq", "lt", "lte", "gt", "gte", "contains"];
@@ -226,6 +228,10 @@ fn register_timestamp_cmp(registry: &mut FunctionRegistry) {
226228
register_simple_domain_type_cmp!(registry, TimestampType);
227229
}
228230

231+
fn register_interval_cmp(registry: &mut FunctionRegistry) {
232+
register_simple_domain_type_cmp!(registry, IntervalType);
233+
}
234+
229235
fn register_boolean_cmp(registry: &mut FunctionRegistry) {
230236
registry.register_comparison_2_arg::<BooleanType, BooleanType, _, _>(
231237
"eq",

0 commit comments

Comments
 (0)