diff --git a/e2e_test/batch/functions/array_sort.slt.part b/e2e_test/batch/functions/array_sort.slt.part new file mode 100644 index 000000000000..1a9ee1bcc308 --- /dev/null +++ b/e2e_test/batch/functions/array_sort.slt.part @@ -0,0 +1,37 @@ +query I +select array_sort(array[3, 2, 1]); +---- +{1,2,3} + +query I +select array_sort(array[3.14, 2.12, 1.14514]); +---- +{1.14514,2.12,3.14} + +query I +select array_sort(array['b', 'a', 'c']); +---- +{a,b,c} + +query I +select array_sort(array[-1000, 2000, 0]); +---- +{-1000,0,2000} + +query I +select array_sort(array['abcdef', 'aacedf', 'aaadef']); +---- +{aaadef,aacedf,abcdef} + +query I +select array_sort(array['114514🤔️1919810', '113514🥵1919810', '112514😅1919810']); +---- +{112514😅1919810,113514🥵1919810,114514🤔️1919810} + +query I +select array_sort(array[3, 2, NULL, 1, NULL]); +---- +{1,2,3,NULL,NULL} + +query error invalid digit found in string +select array_sort(array[3, 2, 1, 'a']); \ No newline at end of file diff --git a/proto/expr.proto b/proto/expr.proto index 9bd5af893cb8..c4779deafacb 100644 --- a/proto/expr.proto +++ b/proto/expr.proto @@ -199,6 +199,7 @@ message ExprNode { ARRAY_TRANSFORM = 545; ARRAY_MIN = 546; ARRAY_MAX = 547; + ARRAY_SORT = 549; // Int256 functions HEX_TO_INT256 = 560; diff --git a/src/expr/src/vector_op/array_sort.rs b/src/expr/src/vector_op/array_sort.rs new file mode 100644 index 000000000000..7ba455d6bbd6 --- /dev/null +++ b/src/expr/src/vector_op/array_sort.rs @@ -0,0 +1,31 @@ +// Copyright 2023 RisingWave Labs +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use risingwave_common::array::*; +use risingwave_common::types::{Datum, DatumRef, DefaultOrdered, ToOwnedDatum}; +use risingwave_expr_macro::function; + +#[function("array_sort(list) -> list")] +pub fn array_sort(list: ListRef<'_>) -> ListValue { + let mut v = list + .iter() + .map(DefaultOrdered) + .collect::>>>(); + v.sort(); + ListValue::new( + v.into_iter() + .map(|x| x.0.to_owned_datum()) + .collect::>(), + ) +} diff --git a/src/expr/src/vector_op/mod.rs b/src/expr/src/vector_op/mod.rs index f4aaa375f8f7..ae88452b8ea7 100644 --- a/src/expr/src/vector_op/mod.rs +++ b/src/expr/src/vector_op/mod.rs @@ -21,6 +21,7 @@ pub mod array_positions; pub mod array_range_access; pub mod array_remove; pub mod array_replace; +pub mod array_sort; pub mod ascii; pub mod bitwise_op; pub mod cardinality; diff --git a/src/frontend/src/binder/expr/function.rs b/src/frontend/src/binder/expr/function.rs index 51b18b083758..6bfa4883c6a5 100644 --- a/src/frontend/src/binder/expr/function.rs +++ b/src/frontend/src/binder/expr/function.rs @@ -795,6 +795,7 @@ impl Binder { ("array_to_string", raw_call(ExprType::ArrayToString)), ("array_distinct", raw_call(ExprType::ArrayDistinct)), ("array_min", raw_call(ExprType::ArrayMin)), + ("array_sort", raw_call(ExprType::ArraySort)), ("array_length", raw_call(ExprType::ArrayLength)), ("cardinality", raw_call(ExprType::Cardinality)), ("array_remove", raw_call(ExprType::ArrayRemove)), diff --git a/src/frontend/src/expr/pure.rs b/src/frontend/src/expr/pure.rs index bb2e1d12d8f8..a229fed79b4f 100644 --- a/src/frontend/src/expr/pure.rs +++ b/src/frontend/src/expr/pure.rs @@ -154,6 +154,7 @@ impl ExprVisitor for ImpureAnalyzer { | expr_node::Type::ArrayToString | expr_node::Type::ArrayCat | expr_node::Type::ArrayMax + | expr_node::Type::ArraySort | expr_node::Type::ArrayAppend | expr_node::Type::ArrayPrepend | expr_node::Type::FormatType diff --git a/src/frontend/src/expr/type_inference/func.rs b/src/frontend/src/expr/type_inference/func.rs index 1febc46788af..771d7a1c6406 100644 --- a/src/frontend/src/expr/type_inference/func.rs +++ b/src/frontend/src/expr/type_inference/func.rs @@ -601,6 +601,12 @@ fn infer_type_for_special( Ok(Some(inputs[0].return_type().as_list().clone())) } + ExprType::ArraySort => { + ensure_arity!("array_sort", | inputs | == 1); + inputs[0].ensure_array_type()?; + + Ok(Some(inputs[0].return_type())) + } ExprType::ArrayDims => { ensure_arity!("array_dims", | inputs | == 1); inputs[0].ensure_array_type()?;