Add SQL array::complement function

Closes #1315
This commit is contained in:
Tobie Morgan Hitchcock 2022-11-03 10:59:01 +00:00
parent a4db0d8427
commit 6b20bbd5f7
5 changed files with 43 additions and 16 deletions

View file

@ -1,5 +1,6 @@
use crate::err::Error; use crate::err::Error;
use crate::sql::array::Combine; use crate::sql::array::Combine;
use crate::sql::array::Complement;
use crate::sql::array::Concat; use crate::sql::array::Concat;
use crate::sql::array::Difference; use crate::sql::array::Difference;
use crate::sql::array::Intersect; use crate::sql::array::Intersect;
@ -7,16 +8,23 @@ 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 concat(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.concat(w).into(), (Value::Array(v), Value::Array(w)) => v.combine(w).into(),
_ => Value::None, _ => Value::None,
}) })
} }
pub fn combine(arrays: (Value, Value)) -> Result<Value, Error> { pub fn complement(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.complement(w).into(),
_ => Value::None,
})
}
pub fn concat(arrays: (Value, Value)) -> Result<Value, Error> {
Ok(match arrays {
(Value::Array(v), Value::Array(w)) => v.concat(w).into(),
_ => Value::None, _ => Value::None,
}) })
} }

View file

@ -60,6 +60,7 @@ pub fn synchronous(ctx: &Context<'_>, name: &str, args: Vec<Value>) -> Result<Va
name, name,
args, args,
"array::combine" => array::combine, "array::combine" => array::combine,
"array::complement" => array::complement,
"array::concat" => array::concat, "array::concat" => array::concat,
"array::difference" => array::difference, "array::difference" => array::difference,
"array::distinct" => array::distinct, "array::distinct" => array::distinct,

View file

@ -251,6 +251,24 @@ impl Combine<Array> for Array {
// ------------------------------ // ------------------------------
pub trait Complement<T> {
fn complement(self, other: T) -> T;
}
impl Complement<Array> for Array {
fn complement(self, other: Self) -> Array {
let mut out = Array::new();
for v in self.into_iter() {
if other.contains(&v) {
out.push(v)
}
}
out
}
}
// ------------------------------
pub trait Concat<T> { pub trait Concat<T> {
fn concat(self, other: T) -> T; fn concat(self, other: T) -> T;
} }
@ -269,14 +287,13 @@ pub trait Difference<T> {
} }
impl Difference<Array> for Array { impl Difference<Array> for Array {
fn difference(self, other: Array) -> Array { fn difference(self, mut other: Array) -> Array {
let mut out = Array::new(); let mut out = Array::new();
let mut other: Vec<_> = other.into_iter().collect(); for v in self.into_iter() {
for a in self.into_iter() { if let Some(pos) = other.iter().position(|w| v == *w) {
if let Some(pos) = other.iter().position(|b| a == *b) {
other.remove(pos); other.remove(pos);
} else { } else {
out.push(a); out.push(v);
} }
} }
out.append(&mut other); out.append(&mut other);
@ -291,13 +308,12 @@ pub trait Intersect<T> {
} }
impl Intersect<Self> for Array { impl Intersect<Self> for Array {
fn intersect(self, other: Self) -> Self { fn intersect(self, mut other: Self) -> Self {
let mut out = Self::new(); let mut out = Self::new();
let mut other: Vec<_> = other.into_iter().collect(); for v in self.0.into_iter() {
for a in self.0.into_iter() { if let Some(pos) = other.iter().position(|w| v == *w) {
if let Some(pos) = other.iter().position(|b| a == *b) {
out.push(a);
other.remove(pos); other.remove(pos);
out.push(v);
} }
} }
out out

View file

@ -231,6 +231,7 @@ 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::combine"), tag("array::combine"),
tag("array::complement"),
tag("array::concat"), tag("array::concat"),
tag("array::difference"), tag("array::difference"),
tag("array::distinct"), tag("array::distinct"),

View file

@ -48,8 +48,9 @@ pub enum Operator {
AllInside, // ⊆ AllInside, // ⊆
AnyInside, // ⊂ AnyInside, // ⊂
NoneInside, // ⊄ NoneInside, // ⊄
Outside, // ∈ //
Intersects, // ∩ Outside,
Intersects,
} }
impl Default for Operator { impl Default for Operator {