Skip to content

Commit

Permalink
feat(expr): add array_max (#12100)
Browse files Browse the repository at this point in the history
Co-authored-by: Runji Wang <[email protected]>
  • Loading branch information
xzhseh and wangrunji0408 authored Sep 7, 2023
1 parent 893f636 commit 183a98b
Show file tree
Hide file tree
Showing 8 changed files with 106 additions and 1 deletion.
72 changes: 72 additions & 0 deletions e2e_test/batch/functions/array_max.slt.part
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
query I
select array_max(array[1, 2, 3]);
----
3

query I
select array_max(array[2, 3, 5, 2, 4]);
----
5

query I
select array_max(array[114514, 114513]);
----
114514

query I
select array_max(array['a', 'b', 'c', 'a']);
----
c

query I
select array_max(array['e💩a', 'f🤔️b', 'c🥵c', 'd🥳d', 'e💩e']);
----
f🤔️b

query I
select array_max(array['2c😅🤔😅️c2', '114🥵514', '30🤣🥳03', '5🥵💩💩🥵5']);
----
5🥵💩💩🥵5

query error invalid digit found in string
select array_max(array['a', 'b', 'c', 114514]);

query error invalid digit found in string
select array_max(array[114514, 'a', 'b', 'c']);

# i32::MIN & i32::MIN - 1 & i32::MAX
query I
select array_max(array[-2147483648, 2147483647, -2147483649]);
----
2147483647

# i64::MIN & i64::MIN - 1 & i64::MAX
query I
select array_max(array[-9223372036854775808, 9223372036854775807, -9223372036854775809]);
----
9223372036854775807

query I
select array_max(array['a', '', 'c']);
----
c

query I
select array_max(array[3.14, 1.14, 1.14514]);
----
3.14

query I
select array_max(array[3.1415926, 191.14, 114514, 1313.1414]);
----
114514

query I
select array_max(array[1e-4, 1.14514e5, 1.14514e-5]);
----
114514

query I
select array_max(array[date'2002-10-30', date'2023-09-06', date'2017-06-18']);
----
2023-09-06
1 change: 1 addition & 0 deletions proto/expr.proto
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ message ExprNode {
ARRAY_DIMS = 544;
ARRAY_TRANSFORM = 545;
ARRAY_MIN = 546;
ARRAY_MAX = 547;

// Int256 functions
HEX_TO_INT256 = 560;
Expand Down
3 changes: 3 additions & 0 deletions src/expr/src/sig/func.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,9 @@ mod tests {
ArrayMin: [
"array_min(list) -> bytea/varchar/timestamptz/timestamp/time/date/int256/serial/decimal/float32/float64/int16/int32/int64",
],
ArrayMax: [
"array_max(list) -> bytea/varchar/timestamptz/timestamp/time/date/int256/serial/decimal/float32/float64/int16/int32/int64",
],
}
"#]];
expected.assert_debug_eq(&duplicated);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ use risingwave_expr_macro::function;

use crate::Result;

/// FIXME: #[`function("array_min(list`) -> any")] supports
/// In this way we could avoid manual macro expansion
#[function("array_min(list) -> *int")]
#[function("array_min(list) -> *float")]
#[function("array_min(list) -> decimal")]
Expand All @@ -36,3 +38,22 @@ pub fn array_min<T: Scalar>(list: ListRef<'_>) -> Result<Option<T>> {
None => Ok(None),
}
}

#[function("array_max(list) -> *int")]
#[function("array_max(list) -> *float")]
#[function("array_max(list) -> decimal")]
#[function("array_max(list) -> serial")]
#[function("array_max(list) -> int256")]
#[function("array_max(list) -> date")]
#[function("array_max(list) -> time")]
#[function("array_max(list) -> timestamp")]
#[function("array_max(list) -> timestamptz")]
#[function("array_max(list) -> varchar")]
#[function("array_max(list) -> bytea")]
pub fn array_max<T: Scalar>(list: ListRef<'_>) -> Result<Option<T>> {
let max_value = list.iter().flatten().map(DefaultOrdered).max();
match max_value.map(|v| v.0).to_owned_datum() {
Some(s) => Ok(Some(s.try_into()?)),
None => Ok(None),
}
}
2 changes: 1 addition & 1 deletion src/expr/src/vector_op/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ pub mod arithmetic_op;
pub mod array_access;
pub mod array_distinct;
pub mod array_length;
pub mod array_min;
pub mod array_min_max;
pub mod array_positions;
pub mod array_range_access;
pub mod array_remove;
Expand Down
1 change: 1 addition & 0 deletions src/frontend/src/binder/expr/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -793,6 +793,7 @@ impl Binder {
("cardinality", raw_call(ExprType::Cardinality)),
("array_remove", raw_call(ExprType::ArrayRemove)),
("array_replace", raw_call(ExprType::ArrayReplace)),
("array_max", raw_call(ExprType::ArrayMax)),
("array_position", raw_call(ExprType::ArrayPosition)),
("array_positions", raw_call(ExprType::ArrayPositions)),
("trim_array", raw_call(ExprType::TrimArray)),
Expand Down
1 change: 1 addition & 0 deletions src/frontend/src/expr/pure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ impl ExprVisitor<bool> for ImpureAnalyzer {
| expr_node::Type::Row
| expr_node::Type::ArrayToString
| expr_node::Type::ArrayCat
| expr_node::Type::ArrayMax
| expr_node::Type::ArrayAppend
| expr_node::Type::ArrayPrepend
| expr_node::Type::FormatType
Expand Down
6 changes: 6 additions & 0 deletions src/frontend/src/expr/type_inference/func.rs
Original file line number Diff line number Diff line change
Expand Up @@ -613,6 +613,12 @@ fn infer_type_for_special(
}
Ok(Some(DataType::Varchar))
}
ExprType::ArrayMax => {
ensure_arity!("array_max", | inputs | == 1);
inputs[0].ensure_array_type()?;

Ok(Some(inputs[0].return_type().as_list().clone()))
}
ExprType::StringToArray => {
ensure_arity!("string_to_array", 2 <= | inputs | <= 3);

Expand Down

0 comments on commit 183a98b

Please sign in to comment.