Add additional SQL array functions

Closes #1725
Related to #1690

Add `array::append()`, `array::pop()`, `array::prepend()`, `array::push()`, `array::remove()`, and `array::reverse()` SQL functions
This commit is contained in:
Tobie Morgan Hitchcock 2023-03-25 22:35:55 +00:00
parent 2769033451
commit b49d58a362
3 changed files with 104 additions and 18 deletions

View file

@ -23,6 +23,16 @@ pub fn any((arg,): (Value,)) -> Result<Value, Error> {
}
}
pub fn append((array, value): (Value, Value)) -> Result<Value, Error> {
match array {
Value::Array(mut v) => {
v.push(value);
Ok(v.into())
}
_ => Ok(Value::None),
}
}
pub fn combine(arrays: (Value, Value)) -> Result<Value, Error> {
Ok(match arrays {
(Value::Array(v), Value::Array(w)) => v.combine(w).into(),
@ -86,6 +96,7 @@ pub fn insert((array, value, index): (Value, Value, Option<Value>)) -> Result<Va
}
// Insert the value into the array
v.insert(i as usize, value);
// Return the array
Ok(v.into())
}
(Value::Array(mut v), None) => {
@ -124,6 +135,65 @@ pub fn min((arg,): (Value,)) -> Result<Value, Error> {
}
}
pub fn pop((arg,): (Value,)) -> Result<Value, Error> {
match arg {
Value::Array(mut v) => Ok(v.pop().into()),
_ => Ok(Value::None),
}
}
pub fn prepend((array, value): (Value, Value)) -> Result<Value, Error> {
match array {
Value::Array(mut v) => {
v.insert(0, value);
Ok(v.into())
}
_ => Ok(Value::None),
}
}
pub fn push((array, value): (Value, Value)) -> Result<Value, Error> {
match array {
Value::Array(mut v) => {
v.push(value);
Ok(v.into())
}
_ => Ok(Value::None),
}
}
pub fn remove((array, index): (Value, Value)) -> Result<Value, Error> {
match (array, index) {
(Value::Array(mut v), Value::Number(i)) => {
let mut i = i.as_int();
// Negative index means start from the back
if i < 0 {
i += v.len() as i64;
}
// Invalid index so return array unaltered
if i > v.len() as i64 || i < 0 {
return Ok(v.into());
}
// Remove the value from the array
v.remove(i as usize);
// Return the array
Ok(v.into())
}
(Value::Array(v), _) => Ok(v.into()),
(_, _) => Ok(Value::None),
}
}
pub fn reverse((arg,): (Value,)) -> Result<Value, Error> {
match arg {
Value::Array(mut v) => {
v.reverse();
Ok(v.into())
}
_ => Ok(Value::None),
}
}
pub fn sort((array, order): (Value, Option<Value>)) -> Result<Value, Error> {
match array {
Value::Array(mut v) => match order {

View file

@ -68,6 +68,7 @@ pub fn synchronous(ctx: &Context<'_>, name: &str, args: Vec<Value>) -> Result<Va
args,
"array::all" => array::all,
"array::any" => array::any,
"array::append" => array::append,
"array::combine" => array::combine,
"array::complement" => array::complement,
"array::concat" => array::concat,
@ -80,6 +81,11 @@ pub fn synchronous(ctx: &Context<'_>, name: &str, args: Vec<Value>) -> Result<Va
"array::len" => array::len,
"array::max" => array::max,
"array::min" => array::min,
"array::pop" => array::pop,
"array::prepend" => array::prepend,
"array::push" => array::push,
"array::remove" => array::remove,
"array::reverse" => array::reverse,
"array::sort" => array::sort,
"array::union" => array::union,
"array::sort::asc" => array::sort::asc,

View file

@ -302,24 +302,34 @@ fn function_names(i: &str) -> IResult<&str, &str> {
fn function_array(i: &str) -> IResult<&str, &str> {
alt((
tag("array::all"),
tag("array::any"),
tag("array::combine"),
tag("array::complement"),
tag("array::concat"),
tag("array::difference"),
tag("array::distinct"),
tag("array::flatten"),
tag("array::group"),
tag("array::insert"),
tag("array::intersect"),
tag("array::len"),
tag("array::max"),
tag("array::min"),
tag("array::sort::asc"),
tag("array::sort::desc"),
tag("array::sort"),
tag("array::union"),
alt((
tag("array::all"),
tag("array::any"),
tag("array::append"),
tag("array::combine"),
tag("array::complement"),
tag("array::concat"),
tag("array::difference"),
tag("array::distinct"),
tag("array::flatten"),
tag("array::group"),
tag("array::insert"),
)),
alt((
tag("array::intersect"),
tag("array::len"),
tag("array::max"),
tag("array::min"),
tag("array::pop"),
tag("array::prepend"),
tag("array::push"),
tag("array::remove"),
tag("array::reverse"),
tag("array::sort::asc"),
tag("array::sort::desc"),
tag("array::sort"),
tag("array::union"),
)),
))(i)
}