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

View file

@ -60,6 +60,7 @@ pub fn synchronous(ctx: &Context<'_>, name: &str, args: Vec<Value>) -> Result<Va
name,
args,
"array::combine" => array::combine,
"array::complement" => array::complement,
"array::concat" => array::concat,
"array::difference" => array::difference,
"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> {
fn concat(self, other: T) -> T;
}
@ -269,14 +287,13 @@ pub trait Difference<T> {
}
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 other: Vec<_> = other.into_iter().collect();
for a in self.into_iter() {
if let Some(pos) = other.iter().position(|b| a == *b) {
for v in self.into_iter() {
if let Some(pos) = other.iter().position(|w| v == *w) {
other.remove(pos);
} else {
out.push(a);
out.push(v);
}
}
out.append(&mut other);
@ -291,13 +308,12 @@ pub trait Intersect<T> {
}
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 other: Vec<_> = other.into_iter().collect();
for a in self.0.into_iter() {
if let Some(pos) = other.iter().position(|b| a == *b) {
out.push(a);
for v in self.0.into_iter() {
if let Some(pos) = other.iter().position(|w| v == *w) {
other.remove(pos);
out.push(v);
}
}
out

View file

@ -231,6 +231,7 @@ fn function_names(i: &str) -> IResult<&str, &str> {
fn function_array(i: &str) -> IResult<&str, &str> {
alt((
tag("array::combine"),
tag("array::complement"),
tag("array::concat"),
tag("array::difference"),
tag("array::distinct"),

View file

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