Add SQL array::all()
, array::any()
, array::min()
, and array::max()
functions
Closes #1588
This commit is contained in:
parent
8f89f8729c
commit
3a1294029e
4 changed files with 144 additions and 0 deletions
|
@ -9,6 +9,20 @@ use crate::sql::array::Union;
|
||||||
use crate::sql::array::Uniq;
|
use crate::sql::array::Uniq;
|
||||||
use crate::sql::value::Value;
|
use crate::sql::value::Value;
|
||||||
|
|
||||||
|
pub fn all((arg,): (Value,)) -> Result<Value, Error> {
|
||||||
|
match arg {
|
||||||
|
Value::Array(v) => Ok(v.iter().all(Value::is_truthy).into()),
|
||||||
|
_ => Ok(Value::False),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn any((arg,): (Value,)) -> Result<Value, Error> {
|
||||||
|
match arg {
|
||||||
|
Value::Array(v) => Ok(v.iter().any(Value::is_truthy).into()),
|
||||||
|
_ => Ok(Value::False),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn combine(arrays: (Value, Value)) -> Result<Value, Error> {
|
pub fn combine(arrays: (Value, Value)) -> Result<Value, Error> {
|
||||||
Ok(match arrays {
|
Ok(match arrays {
|
||||||
(Value::Array(v), Value::Array(w)) => v.combine(w).into(),
|
(Value::Array(v), Value::Array(w)) => v.combine(w).into(),
|
||||||
|
@ -96,6 +110,20 @@ pub fn len((arg,): (Value,)) -> Result<Value, Error> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn max((arg,): (Value,)) -> Result<Value, Error> {
|
||||||
|
match arg {
|
||||||
|
Value::Array(v) => Ok(v.into_iter().max().unwrap_or(Value::None)),
|
||||||
|
_ => Ok(Value::None),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn min((arg,): (Value,)) -> Result<Value, Error> {
|
||||||
|
match arg {
|
||||||
|
Value::Array(v) => Ok(v.into_iter().min().unwrap_or(Value::None)),
|
||||||
|
_ => Ok(Value::None),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn sort((array, order): (Value, Option<Value>)) -> Result<Value, Error> {
|
pub fn sort((array, order): (Value, Option<Value>)) -> Result<Value, Error> {
|
||||||
match array {
|
match array {
|
||||||
Value::Array(mut v) => match order {
|
Value::Array(mut v) => match order {
|
||||||
|
|
|
@ -60,6 +60,8 @@ pub fn synchronous(ctx: &Context<'_>, name: &str, args: Vec<Value>) -> Result<Va
|
||||||
dispatch!(
|
dispatch!(
|
||||||
name,
|
name,
|
||||||
args,
|
args,
|
||||||
|
"array::all" => array::all,
|
||||||
|
"array::any" => array::any,
|
||||||
"array::combine" => array::combine,
|
"array::combine" => array::combine,
|
||||||
"array::complement" => array::complement,
|
"array::complement" => array::complement,
|
||||||
"array::concat" => array::concat,
|
"array::concat" => array::concat,
|
||||||
|
@ -70,6 +72,8 @@ pub fn synchronous(ctx: &Context<'_>, name: &str, args: Vec<Value>) -> Result<Va
|
||||||
"array::insert" => array::insert,
|
"array::insert" => array::insert,
|
||||||
"array::intersect" => array::intersect,
|
"array::intersect" => array::intersect,
|
||||||
"array::len" => array::len,
|
"array::len" => array::len,
|
||||||
|
"array::max" => array::max,
|
||||||
|
"array::min" => array::min,
|
||||||
"array::sort" => array::sort,
|
"array::sort" => array::sort,
|
||||||
"array::union" => array::union,
|
"array::union" => array::union,
|
||||||
"array::sort::asc" => array::sort::asc,
|
"array::sort::asc" => array::sort::asc,
|
||||||
|
|
|
@ -234,6 +234,8 @@ fn function_names(i: &str) -> IResult<&str, &str> {
|
||||||
|
|
||||||
fn function_array(i: &str) -> IResult<&str, &str> {
|
fn function_array(i: &str) -> IResult<&str, &str> {
|
||||||
alt((
|
alt((
|
||||||
|
tag("array::all"),
|
||||||
|
tag("array::any"),
|
||||||
tag("array::combine"),
|
tag("array::combine"),
|
||||||
tag("array::complement"),
|
tag("array::complement"),
|
||||||
tag("array::concat"),
|
tag("array::concat"),
|
||||||
|
@ -244,6 +246,8 @@ fn function_array(i: &str) -> IResult<&str, &str> {
|
||||||
tag("array::insert"),
|
tag("array::insert"),
|
||||||
tag("array::intersect"),
|
tag("array::intersect"),
|
||||||
tag("array::len"),
|
tag("array::len"),
|
||||||
|
tag("array::max"),
|
||||||
|
tag("array::min"),
|
||||||
tag("array::sort::asc"),
|
tag("array::sort::asc"),
|
||||||
tag("array::sort::desc"),
|
tag("array::sort::desc"),
|
||||||
tag("array::sort"),
|
tag("array::sort"),
|
||||||
|
|
|
@ -5,6 +5,60 @@ use surrealdb::err::Error;
|
||||||
use surrealdb::kvs::Datastore;
|
use surrealdb::kvs::Datastore;
|
||||||
use surrealdb::sql::Value;
|
use surrealdb::sql::Value;
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn function_array_all() -> Result<(), Error> {
|
||||||
|
let sql = r#"
|
||||||
|
RETURN array::all([]);
|
||||||
|
RETURN array::all("some text");
|
||||||
|
RETURN array::all([1,2,"text",3,NONE,3,4]);
|
||||||
|
"#;
|
||||||
|
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(), 3);
|
||||||
|
//
|
||||||
|
let tmp = res.remove(0).result?;
|
||||||
|
let val = Value::True;
|
||||||
|
assert_eq!(tmp, val);
|
||||||
|
//
|
||||||
|
let tmp = res.remove(0).result?;
|
||||||
|
let val = Value::None;
|
||||||
|
assert_eq!(tmp, val);
|
||||||
|
//
|
||||||
|
let tmp = res.remove(0).result?;
|
||||||
|
let val = Value::False;
|
||||||
|
assert_eq!(tmp, val);
|
||||||
|
//
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn function_array_any() -> Result<(), Error> {
|
||||||
|
let sql = r#"
|
||||||
|
RETURN array::any([]);
|
||||||
|
RETURN array::any("some text");
|
||||||
|
RETURN array::any([1,2,"text",3,NONE,3,4]);
|
||||||
|
"#;
|
||||||
|
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(), 3);
|
||||||
|
//
|
||||||
|
let tmp = res.remove(0).result?;
|
||||||
|
let val = Value::True;
|
||||||
|
assert_eq!(tmp, val);
|
||||||
|
//
|
||||||
|
let tmp = res.remove(0).result?;
|
||||||
|
let val = Value::None;
|
||||||
|
assert_eq!(tmp, val);
|
||||||
|
//
|
||||||
|
let tmp = res.remove(0).result?;
|
||||||
|
let val = Value::True;
|
||||||
|
assert_eq!(tmp, val);
|
||||||
|
//
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn function_array_combine() -> Result<(), Error> {
|
async fn function_array_combine() -> Result<(), Error> {
|
||||||
let sql = r#"
|
let sql = r#"
|
||||||
|
@ -253,6 +307,60 @@ async fn function_array_intersect() -> Result<(), Error> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn function_array_max() -> Result<(), Error> {
|
||||||
|
let sql = r#"
|
||||||
|
RETURN array::max([]);
|
||||||
|
RETURN array::max("some text");
|
||||||
|
RETURN array::max([1,2,"text",3,3,4]);
|
||||||
|
"#;
|
||||||
|
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(), 3);
|
||||||
|
//
|
||||||
|
let tmp = res.remove(0).result?;
|
||||||
|
let val = Value::None;
|
||||||
|
assert_eq!(tmp, val);
|
||||||
|
//
|
||||||
|
let tmp = res.remove(0).result?;
|
||||||
|
let val = Value::None;
|
||||||
|
assert_eq!(tmp, val);
|
||||||
|
//
|
||||||
|
let tmp = res.remove(0).result?;
|
||||||
|
let val = Value::parse("4");
|
||||||
|
assert_eq!(tmp, val);
|
||||||
|
//
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn function_array_min() -> Result<(), Error> {
|
||||||
|
let sql = r#"
|
||||||
|
RETURN array::min([]);
|
||||||
|
RETURN array::min("some text");
|
||||||
|
RETURN array::min([1,2,"text",3,3,4]);
|
||||||
|
"#;
|
||||||
|
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(), 3);
|
||||||
|
//
|
||||||
|
let tmp = res.remove(0).result?;
|
||||||
|
let val = Value::None;
|
||||||
|
assert_eq!(tmp, val);
|
||||||
|
//
|
||||||
|
let tmp = res.remove(0).result?;
|
||||||
|
let val = Value::None;
|
||||||
|
assert_eq!(tmp, val);
|
||||||
|
//
|
||||||
|
let tmp = res.remove(0).result?;
|
||||||
|
let val = Value::parse("1");
|
||||||
|
assert_eq!(tmp, val);
|
||||||
|
//
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn function_array_union() -> Result<(), Error> {
|
async fn function_array_union() -> Result<(), Error> {
|
||||||
let sql = r#"
|
let sql = r#"
|
||||||
|
|
Loading…
Reference in a new issue