Feature: Implementation of array::join (#1920)

This commit is contained in:
Jan Tebernum 2023-05-04 22:38:02 +02:00 committed by GitHub
parent 975ea616dd
commit e9ebecfdd6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 63 additions and 1 deletions

View file

@ -160,6 +160,7 @@
"array::group(" "array::group("
"array::insert(" "array::insert("
"array::intersect(" "array::intersect("
"array::join("
"array::len(" "array::len("
"array::max(" "array::max("
"array::min(" "array::min("

View file

@ -160,6 +160,7 @@
"array::group(" "array::group("
"array::insert(" "array::insert("
"array::intersect(" "array::intersect("
"array::join("
"array::len(" "array::len("
"array::max(" "array::max("
"array::min(" "array::min("

View file

@ -97,6 +97,10 @@ pub fn intersect((array, other): (Array, Array)) -> Result<Value, Error> {
Ok(array.intersect(other).into()) Ok(array.intersect(other).into())
} }
pub fn join((arr, sep): (Array, String)) -> Result<Value, Error> {
Ok(arr.into_iter().map(|s| s.to_raw_string()).collect::<Vec<_>>().join(&sep).into())
}
pub fn len((array,): (Array,)) -> Result<Value, Error> { pub fn len((array,): (Array,)) -> Result<Value, Error> {
Ok(array.len().into()) Ok(array.len().into())
} }
@ -217,7 +221,7 @@ pub mod sort {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::slice; use super::{join, slice};
use crate::sql::{Array, Value}; use crate::sql::{Array, Value};
#[test] #[test]
@ -239,4 +243,26 @@ mod tests {
test(array, Some(-4), Some(2), &[b'd', b'e']); test(array, Some(-4), Some(2), &[b'd', b'e']);
test(array, Some(-4), Some(-1), &[b'd', b'e', b'f']); test(array, Some(-4), Some(-1), &[b'd', b'e', b'f']);
} }
#[test]
fn array_join() {
fn test(arr: Array, sep: &str, expected: &str) {
assert_eq!(join((arr, sep.to_string())).unwrap(), expected.into());
}
test(Vec::<Value>::new().into(), ",", "");
test(vec!["hello"].into(), ",", "hello");
test(vec!["hello", "world"].into(), ",", "hello,world");
test(vec!["again"; 512].into(), " and ", &vec!["again"; 512].join(" and "));
test(
vec![Value::from(true), Value::from(false), Value::from(true)].into(),
" is ",
"true is false is true",
);
test(
vec![Value::from(3.14), Value::from(2.72), Value::from(1.61)].into(),
" is not ",
"3.14 is not 2.72 is not 1.61",
);
}
} }

View file

@ -77,6 +77,7 @@ pub fn synchronous(ctx: &Context<'_>, name: &str, args: Vec<Value>) -> Result<Va
"array::group" => array::group, "array::group" => array::group,
"array::insert" => array::insert, "array::insert" => array::insert,
"array::intersect" => array::intersect, "array::intersect" => array::intersect,
"array::join" => array::join,
"array::len" => array::len, "array::len" => array::len,
"array::max" => array::max, "array::max" => array::max,
"array::min" => array::min, "array::min" => array::min,

View file

@ -309,6 +309,7 @@ fn function_array(i: &str) -> IResult<&str, &str> {
)), )),
alt(( alt((
tag("intersect"), tag("intersect"),
tag("join"),
tag("len"), tag("len"),
tag("max"), tag("max"),
tag("min"), tag("min"),

View file

@ -403,6 +403,38 @@ async fn function_array_intersect() -> Result<(), Error> {
Ok(()) Ok(())
} }
#[tokio::test]
async fn function_string_join_arr() -> Result<(), Error> {
let sql = r#"
RETURN array::join([], "");
RETURN array::join(["hello", "world"], ", ");
RETURN array::join(["again", "again", "again"], " and ");
RETURN array::join([42, 3.14, 2.72, 1.61], " and ");
"#;
let dbs = Datastore::new("memory").await?;
let ses = Session::for_kv().with_ns("test").with_db("test");
let res = &mut dbs.execute(&sql, &ses, None, false).await?;
assert_eq!(res.len(), 4);
//
let tmp = res.remove(0).result?;
let val = Value::from("");
assert_eq!(tmp, val);
//
let tmp = res.remove(0).result?;
let val = Value::from("hello, world");
assert_eq!(tmp, val);
//
let tmp = res.remove(0).result?;
let val = Value::from("again and again and again");
assert_eq!(tmp, val);
//
let tmp = res.remove(0).result?;
let val = Value::from("42 and 3.14 and 2.72 and 1.61");
assert_eq!(tmp, val);
//
Ok(())
}
#[tokio::test] #[tokio::test]
async fn function_array_len() -> Result<(), Error> { async fn function_array_len() -> Result<(), Error> {
let sql = r#" let sql = r#"