Add array::at function (#2294)

This commit is contained in:
hchockarprasad 2023-07-20 13:57:04 +05:30 committed by GitHub
parent 09dde86e73
commit 88bcc87d39
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 65 additions and 1 deletions

View file

@ -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("

View file

@ -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("

View file

@ -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);
}
} }

View file

@ -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,

View file

@ -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,

View file

@ -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"),

View file

@ -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(