Add array::at function (#2294)
This commit is contained in:
parent
09dde86e73
commit
88bcc87d39
7 changed files with 65 additions and 1 deletions
|
@ -151,6 +151,7 @@
|
||||||
"array::all("
|
"array::all("
|
||||||
"array::any("
|
"array::any("
|
||||||
"array::append("
|
"array::append("
|
||||||
|
"array::at("
|
||||||
"array::boolean_and("
|
"array::boolean_and("
|
||||||
"array::boolean_not("
|
"array::boolean_not("
|
||||||
"array::boolean_or("
|
"array::boolean_or("
|
||||||
|
|
|
@ -150,6 +150,7 @@
|
||||||
"array::add("
|
"array::add("
|
||||||
"array::all("
|
"array::all("
|
||||||
"array::any("
|
"array::any("
|
||||||
|
"array::at("
|
||||||
"array::append("
|
"array::append("
|
||||||
"array::boolean_and("
|
"array::boolean_and("
|
||||||
"array::boolean_not("
|
"array::boolean_not("
|
||||||
|
|
|
@ -45,6 +45,14 @@ pub fn append((mut array, value): (Array, Value)) -> Result<Value, Error> {
|
||||||
Ok(array.into())
|
Ok(array.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn at((array, i): (Array, i64)) -> Result<Value, Error> {
|
||||||
|
let mut idx = i as usize;
|
||||||
|
if i < 0 {
|
||||||
|
idx = (array.len() as i64 + i) as usize;
|
||||||
|
}
|
||||||
|
Ok(array.get(idx).cloned().unwrap_or_default())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn boolean_and((lh, rh): (Array, Array)) -> Result<Value, Error> {
|
pub fn boolean_and((lh, rh): (Array, Array)) -> Result<Value, Error> {
|
||||||
let longest_length = lh.len().max(rh.len());
|
let longest_length = lh.len().max(rh.len());
|
||||||
let mut results = Array::with_capacity(longest_length);
|
let mut results = Array::with_capacity(longest_length);
|
||||||
|
@ -391,7 +399,7 @@ pub mod sort {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::{first, join, last, slice};
|
use super::{at, first, join, last, slice};
|
||||||
use crate::sql::{Array, Value};
|
use crate::sql::{Array, Value};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -455,4 +463,13 @@ mod tests {
|
||||||
test(vec!["hello", "world"].into(), "world".into());
|
test(vec!["hello", "world"].into(), "world".into());
|
||||||
test(Array::new(), Value::None);
|
test(Array::new(), Value::None);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn array_at() {
|
||||||
|
fn test(arr: Array, i: i64, expected: Value) {
|
||||||
|
assert_eq!(at((arr, i)).unwrap(), expected);
|
||||||
|
}
|
||||||
|
test(vec!["hello", "world"].into(), -2, "hello".into());
|
||||||
|
test(vec!["hello", "world"].into(), -3, Value::None);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,6 +82,7 @@ pub fn synchronous(ctx: &Context<'_>, name: &str, args: Vec<Value>) -> Result<Va
|
||||||
"array::all" => array::all,
|
"array::all" => array::all,
|
||||||
"array::any" => array::any,
|
"array::any" => array::any,
|
||||||
"array::append" => array::append,
|
"array::append" => array::append,
|
||||||
|
"array::at" => array::at,
|
||||||
"array::boolean_and" => array::boolean_and,
|
"array::boolean_and" => array::boolean_and,
|
||||||
"array::boolean_not" => array::boolean_not,
|
"array::boolean_not" => array::boolean_not,
|
||||||
"array::boolean_or" => array::boolean_or,
|
"array::boolean_or" => array::boolean_or,
|
||||||
|
|
|
@ -10,6 +10,7 @@ impl_module_def!(
|
||||||
"add" => run,
|
"add" => run,
|
||||||
"all" => run,
|
"all" => run,
|
||||||
"any" => run,
|
"any" => run,
|
||||||
|
"at" => run,
|
||||||
"append" => run,
|
"append" => run,
|
||||||
"boolean_and" => run,
|
"boolean_and" => run,
|
||||||
"boolean_not" => run,
|
"boolean_not" => run,
|
||||||
|
|
|
@ -281,6 +281,7 @@ fn function_array(i: &str) -> IResult<&str, &str> {
|
||||||
tag("all"),
|
tag("all"),
|
||||||
tag("any"),
|
tag("any"),
|
||||||
tag("append"),
|
tag("append"),
|
||||||
|
tag("at"),
|
||||||
tag("boolean_and"),
|
tag("boolean_and"),
|
||||||
tag("boolean_not"),
|
tag("boolean_not"),
|
||||||
tag("boolean_or"),
|
tag("boolean_or"),
|
||||||
|
|
|
@ -200,6 +200,48 @@ async fn function_array_append() -> Result<(), Error> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn function_array_at() -> Result<(), Error> {
|
||||||
|
let sql = r#"
|
||||||
|
RETURN array::at(["hello", "world"], 0);
|
||||||
|
RETURN array::at(["hello", "world"], -1);
|
||||||
|
RETURN array::at(["hello", "world"], 3);
|
||||||
|
RETURN array::at(["hello", "world"], -3);
|
||||||
|
RETURN array::at([], 0);
|
||||||
|
RETURN array::at([], 3);
|
||||||
|
RETURN array::at([], -3);
|
||||||
|
"#;
|
||||||
|
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).await?;
|
||||||
|
assert_eq!(res.len(), 7);
|
||||||
|
//
|
||||||
|
let tmp = res.remove(0).result?;
|
||||||
|
let val = Value::Strand("hello".into());
|
||||||
|
assert_eq!(tmp, val);
|
||||||
|
//
|
||||||
|
let tmp = res.remove(0).result?;
|
||||||
|
let val = Value::Strand("world".into());
|
||||||
|
assert_eq!(tmp, val);
|
||||||
|
//
|
||||||
|
let tmp = res.remove(0).result?;
|
||||||
|
assert_eq!(tmp, Value::None);
|
||||||
|
//
|
||||||
|
let tmp = res.remove(0).result?;
|
||||||
|
assert_eq!(tmp, Value::None);
|
||||||
|
//
|
||||||
|
let tmp = res.remove(0).result?;
|
||||||
|
assert_eq!(tmp, Value::None);
|
||||||
|
//
|
||||||
|
let tmp = res.remove(0).result?;
|
||||||
|
assert_eq!(tmp, Value::None);
|
||||||
|
//
|
||||||
|
let tmp = res.remove(0).result?;
|
||||||
|
assert_eq!(tmp, Value::None);
|
||||||
|
//
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn function_array_boolean_and() -> Result<(), Error> {
|
async fn function_array_boolean_and() -> Result<(), Error> {
|
||||||
test_queries(
|
test_queries(
|
||||||
|
|
Loading…
Reference in a new issue