From d1055e608807b80b2401c470e70040fc776db8f8 Mon Sep 17 00:00:00 2001 From: Allen Lantz Date: Thu, 27 Oct 2022 07:23:24 -0500 Subject: [PATCH] Implement hashed implementation of `Uniq` (#1310) --- lib/src/sql/algorithm.rs | 2 +- lib/src/sql/array.rs | 36 +++++++++++++--- lib/src/sql/base.rs | 2 +- lib/src/sql/cond.rs | 2 +- lib/src/sql/constant.rs | 2 +- lib/src/sql/data.rs | 2 +- lib/src/sql/datetime.rs | 2 +- lib/src/sql/dir.rs | 2 +- lib/src/sql/duration.rs | 2 +- lib/src/sql/edges.rs | 2 +- lib/src/sql/expression.rs | 2 +- lib/src/sql/fetch.rs | 4 +- lib/src/sql/field.rs | 4 +- lib/src/sql/function.rs | 2 +- lib/src/sql/geometry.rs | 71 +++++++++++++++++++++++++++++++- lib/src/sql/graph.rs | 2 +- lib/src/sql/group.rs | 4 +- lib/src/sql/id.rs | 2 +- lib/src/sql/ident.rs | 2 +- lib/src/sql/idiom.rs | 4 +- lib/src/sql/kind.rs | 2 +- lib/src/sql/limit.rs | 2 +- lib/src/sql/model.rs | 2 +- lib/src/sql/number.rs | 11 +++++ lib/src/sql/object.rs | 2 +- lib/src/sql/operation.rs | 4 +- lib/src/sql/operator.rs | 2 +- lib/src/sql/order.rs | 4 +- lib/src/sql/output.rs | 2 +- lib/src/sql/param.rs | 2 +- lib/src/sql/part.rs | 2 +- lib/src/sql/permission.rs | 4 +- lib/src/sql/query.rs | 2 +- lib/src/sql/range.rs | 2 +- lib/src/sql/regex.rs | 2 +- lib/src/sql/script.rs | 2 +- lib/src/sql/split.rs | 4 +- lib/src/sql/start.rs | 2 +- lib/src/sql/statement.rs | 4 +- lib/src/sql/statements/begin.rs | 2 +- lib/src/sql/statements/cancel.rs | 2 +- lib/src/sql/statements/commit.rs | 2 +- lib/src/sql/statements/create.rs | 2 +- lib/src/sql/statements/define.rs | 26 ++++++------ lib/src/sql/statements/delete.rs | 2 +- lib/src/sql/statements/ifelse.rs | 2 +- lib/src/sql/statements/info.rs | 2 +- lib/src/sql/statements/insert.rs | 2 +- lib/src/sql/statements/kill.rs | 2 +- lib/src/sql/statements/live.rs | 2 +- lib/src/sql/statements/option.rs | 2 +- lib/src/sql/statements/output.rs | 2 +- lib/src/sql/statements/relate.rs | 2 +- lib/src/sql/statements/remove.rs | 20 ++++----- lib/src/sql/statements/select.rs | 2 +- lib/src/sql/statements/set.rs | 2 +- lib/src/sql/statements/update.rs | 2 +- lib/src/sql/statements/yuse.rs | 2 +- lib/src/sql/strand.rs | 2 +- lib/src/sql/subquery.rs | 2 +- lib/src/sql/table.rs | 4 +- lib/src/sql/thing.rs | 2 +- lib/src/sql/timeout.rs | 2 +- lib/src/sql/uuid.rs | 2 +- lib/src/sql/value/value.rs | 4 +- lib/src/sql/version.rs | 2 +- lib/src/sql/view.rs | 2 +- lib/tests/function.rs | 38 +++++++++++++++++ 68 files changed, 245 insertions(+), 103 deletions(-) create mode 100644 lib/tests/function.rs diff --git a/lib/src/sql/algorithm.rs b/lib/src/sql/algorithm.rs index ba07df84..651f80a9 100644 --- a/lib/src/sql/algorithm.rs +++ b/lib/src/sql/algorithm.rs @@ -5,7 +5,7 @@ use nom::combinator::map; use serde::{Deserialize, Serialize}; use std::fmt; -#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Hash)] pub enum Algorithm { EdDSA, Es256, diff --git a/lib/src/sql/array.rs b/lib/src/sql/array.rs index 03e22d52..d848f2b8 100644 --- a/lib/src/sql/array.rs +++ b/lib/src/sql/array.rs @@ -15,12 +15,13 @@ use nom::character::complete::char; use nom::combinator::opt; use nom::multi::separated_list0; use serde::{Deserialize, Serialize}; +use std::collections::HashSet; use std::fmt::{self, Display, Formatter}; use std::ops; use std::ops::Deref; use std::ops::DerefMut; -#[derive(Clone, Debug, Default, Eq, Ord, PartialEq, PartialOrd, Deserialize)] +#[derive(Clone, Debug, Default, Eq, Ord, PartialEq, PartialOrd, Deserialize, Hash)] pub struct Array(pub Vec); impl From for Array { @@ -318,13 +319,16 @@ pub trait Uniq { impl Uniq for Array { fn uniq(mut self) -> Array { - for x in (0..self.len()).rev() { - for y in (x + 1..self.len()).rev() { - if self[x] == self[y] { - self.remove(y); - } + let mut set: HashSet<&Value> = HashSet::new(); + let mut to_remove: Vec = Vec::new(); + for (i, item) in self.iter().enumerate() { + if !set.insert(item) { + to_remove.push(i); } } + for i in to_remove.iter().rev() { + self.remove(*i); + } self } } @@ -352,6 +356,16 @@ mod tests { use super::*; + #[test] + fn array_empty() { + let sql = "[]"; + let res = array(sql); + assert!(res.is_ok()); + let out = res.unwrap().1; + assert_eq!("[]", format!("{}", out)); + assert_eq!(out.0.len(), 0); + } + #[test] fn array_normal() { let sql = "[1,2,3]"; @@ -381,4 +395,14 @@ mod tests { assert_eq!("[1, 2, 3 + 1]", format!("{}", out)); assert_eq!(out.0.len(), 3); } + + #[test] + fn array_fnc_uniq_normal() { + let sql = "[1,2,1,3,3,4]"; + let res = array(sql); + assert!(res.is_ok()); + let out = res.unwrap().1.uniq(); + assert_eq!("[1, 2, 3, 4]", format!("{}", out)); + assert_eq!(out.0.len(), 4); + } } diff --git a/lib/src/sql/base.rs b/lib/src/sql/base.rs index d56081cf..d16fad0c 100644 --- a/lib/src/sql/base.rs +++ b/lib/src/sql/base.rs @@ -7,7 +7,7 @@ use nom::combinator::map; use serde::{Deserialize, Serialize}; use std::fmt; -#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Hash)] pub enum Base { Kv, Ns, diff --git a/lib/src/sql/cond.rs b/lib/src/sql/cond.rs index f1565a11..13d2263e 100644 --- a/lib/src/sql/cond.rs +++ b/lib/src/sql/cond.rs @@ -6,7 +6,7 @@ use serde::{Deserialize, Serialize}; use std::fmt; use std::ops::Deref; -#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize)] +#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)] pub struct Cond(pub Value); impl Deref for Cond { diff --git a/lib/src/sql/constant.rs b/lib/src/sql/constant.rs index b6ef0b9a..18ee8e8b 100644 --- a/lib/src/sql/constant.rs +++ b/lib/src/sql/constant.rs @@ -12,7 +12,7 @@ use nom::combinator::map; use serde::{Deserialize, Serialize}; use std::fmt; -#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Deserialize, Store)] +#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Deserialize, Store, Hash)] pub enum Constant { MathE, MathFrac1Pi, diff --git a/lib/src/sql/data.rs b/lib/src/sql/data.rs index b1e8d75b..51853100 100644 --- a/lib/src/sql/data.rs +++ b/lib/src/sql/data.rs @@ -18,7 +18,7 @@ use nom::multi::separated_list1; use serde::{Deserialize, Serialize}; use std::fmt::{self, Display, Formatter}; -#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Hash)] pub enum Data { EmptyExpression, SetExpression(Vec<(Idiom, Operator, Value)>), diff --git a/lib/src/sql/datetime.rs b/lib/src/sql/datetime.rs index 21d73622..7e48a38a 100644 --- a/lib/src/sql/datetime.rs +++ b/lib/src/sql/datetime.rs @@ -14,7 +14,7 @@ use std::ops; use std::ops::Deref; use std::str; -#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Deserialize)] +#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Deserialize, Hash)] pub struct Datetime(pub DateTime); impl Default for Datetime { diff --git a/lib/src/sql/dir.rs b/lib/src/sql/dir.rs index a15e9fe6..9199e837 100644 --- a/lib/src/sql/dir.rs +++ b/lib/src/sql/dir.rs @@ -4,7 +4,7 @@ use nom::character::complete::char; use serde::{Deserialize, Serialize}; use std::fmt; -#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize)] +#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)] pub enum Dir { In, Out, diff --git a/lib/src/sql/duration.rs b/lib/src/sql/duration.rs index 640ba7ac..c9076b2c 100644 --- a/lib/src/sql/duration.rs +++ b/lib/src/sql/duration.rs @@ -20,7 +20,7 @@ static SECONDS_PER_DAY: u64 = 24 * SECONDS_PER_HOUR; static SECONDS_PER_HOUR: u64 = 60 * SECONDS_PER_MINUTE; static SECONDS_PER_MINUTE: u64 = 60; -#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Deserialize)] +#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Deserialize, Hash)] pub struct Duration(pub time::Duration); impl From for Duration { diff --git a/lib/src/sql/edges.rs b/lib/src/sql/edges.rs index a096489f..84d192c5 100644 --- a/lib/src/sql/edges.rs +++ b/lib/src/sql/edges.rs @@ -9,7 +9,7 @@ use nom::combinator::map; use serde::{Deserialize, Serialize}; use std::fmt; -#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize)] +#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)] pub struct Edges { pub dir: Dir, pub from: Thing, diff --git a/lib/src/sql/expression.rs b/lib/src/sql/expression.rs index cfde7744..243df76d 100644 --- a/lib/src/sql/expression.rs +++ b/lib/src/sql/expression.rs @@ -10,7 +10,7 @@ use serde::{Deserialize, Serialize}; use std::fmt; use std::str; -#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize)] +#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)] pub struct Expression { pub l: Value, pub o: Operator, diff --git a/lib/src/sql/fetch.rs b/lib/src/sql/fetch.rs index 1ac70a7d..da88ca0a 100644 --- a/lib/src/sql/fetch.rs +++ b/lib/src/sql/fetch.rs @@ -9,7 +9,7 @@ use serde::{Deserialize, Serialize}; use std::fmt::{self, Display, Formatter}; use std::ops::Deref; -#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Hash)] pub struct Fetchs(pub Vec); impl Deref for Fetchs { @@ -33,7 +33,7 @@ impl fmt::Display for Fetchs { } } -#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Hash)] pub struct Fetch(pub Idiom); impl Deref for Fetch { diff --git a/lib/src/sql/field.rs b/lib/src/sql/field.rs index 7520afc5..837a24c1 100644 --- a/lib/src/sql/field.rs +++ b/lib/src/sql/field.rs @@ -16,7 +16,7 @@ use serde::{Deserialize, Serialize}; use std::fmt::{self, Display, Formatter, Write}; use std::ops::Deref; -#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize)] +#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)] pub struct Fields(pub Vec); impl Fields { @@ -191,7 +191,7 @@ pub fn fields(i: &str) -> IResult<&str, Fields> { Ok((i, Fields(v))) } -#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize)] +#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)] pub enum Field { All, Alone(Value), diff --git a/lib/src/sql/function.rs b/lib/src/sql/function.rs index 33ee0ef9..6d41955a 100644 --- a/lib/src/sql/function.rs +++ b/lib/src/sql/function.rs @@ -17,7 +17,7 @@ use serde::{Deserialize, Serialize}; use std::cmp::Ordering; use std::fmt; -#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Hash)] pub enum Function { Future(Value), Cast(String, Value), diff --git a/lib/src/sql/geometry.rs b/lib/src/sql/geometry.rs index 78111bf1..f3ebf0a3 100644 --- a/lib/src/sql/geometry.rs +++ b/lib/src/sql/geometry.rs @@ -1,3 +1,5 @@ +#![allow(clippy::derive_hash_xor_eq)] + use crate::sql::comment::mightbespace; use crate::sql::common::commas; use crate::sql::error::IResult; @@ -18,8 +20,8 @@ use nom::sequence::preceded; use serde::ser::SerializeMap; use serde::{Deserialize, Serialize}; use std::cmp::Ordering; -use std::fmt; use std::iter::FromIterator; +use std::{fmt, hash}; const SINGLE: char = '\''; const DOUBLE: char = '\"'; @@ -514,6 +516,73 @@ impl Serialize for Geometry { } } +impl hash::Hash for Geometry { + fn hash(&self, state: &mut H) { + match self { + Geometry::Point(p) => { + "Point".hash(state); + p.x().to_bits().hash(state); + p.y().to_bits().hash(state); + } + Geometry::Line(l) => { + "Line".hash(state); + l.points().for_each(|v| { + v.x().to_bits().hash(state); + v.y().to_bits().hash(state); + }); + } + Geometry::Polygon(p) => { + "Polygon".hash(state); + p.exterior().points().for_each(|ext| { + ext.x().to_bits().hash(state); + ext.y().to_bits().hash(state); + }); + p.interiors().iter().for_each(|int| { + int.points().for_each(|v| { + v.x().to_bits().hash(state); + v.y().to_bits().hash(state); + }); + }); + } + Geometry::MultiPoint(v) => { + "MultiPoint".hash(state); + v.0.iter().for_each(|v| { + v.x().to_bits().hash(state); + v.y().to_bits().hash(state); + }); + } + Geometry::MultiLine(ml) => { + "MultiLine".hash(state); + ml.0.iter().for_each(|ls| { + ls.points().for_each(|p| { + p.x().to_bits().hash(state); + p.y().to_bits().hash(state); + }); + }); + } + Geometry::MultiPolygon(mp) => { + "MultiPolygon".hash(state); + mp.0.iter().for_each(|p| { + p.exterior().points().for_each(|ext| { + ext.x().to_bits().hash(state); + ext.y().to_bits().hash(state); + }); + p.interiors().iter().for_each(|int| { + int.points().for_each(|v| { + v.x().to_bits().hash(state); + v.y().to_bits().hash(state); + }); + }); + }); + } + Geometry::Collection(v) => { + "GeometryCollection".hash(state); + v.iter().for_each(|v| v.hash(state)); + } + } + } +} + pub fn geometry(i: &str) -> IResult<&str, Geometry> { alt((simple, point, line, polygon, multipoint, multiline, multipolygon, collection))(i) } diff --git a/lib/src/sql/graph.rs b/lib/src/sql/graph.rs index ce4eef4f..9ed02221 100644 --- a/lib/src/sql/graph.rs +++ b/lib/src/sql/graph.rs @@ -13,7 +13,7 @@ use nom::combinator::opt; use serde::{Deserialize, Serialize}; use std::fmt::{self, Display, Formatter, Write}; -#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize)] +#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)] pub struct Graph { pub dir: Dir, pub what: Tables, diff --git a/lib/src/sql/group.rs b/lib/src/sql/group.rs index f9390beb..2c596b3b 100644 --- a/lib/src/sql/group.rs +++ b/lib/src/sql/group.rs @@ -11,7 +11,7 @@ use serde::{Deserialize, Serialize}; use std::fmt::{self, Display, Formatter}; use std::ops::Deref; -#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize)] +#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)] pub struct Groups(pub Vec); impl Deref for Groups { @@ -35,7 +35,7 @@ impl Display for Groups { } } -#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize)] +#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)] pub struct Group(pub Idiom); impl Deref for Group { diff --git a/lib/src/sql/id.rs b/lib/src/sql/id.rs index 64f54cfe..eff71caf 100644 --- a/lib/src/sql/id.rs +++ b/lib/src/sql/id.rs @@ -14,7 +14,7 @@ use nom::combinator::map; use serde::{Deserialize, Serialize}; use std::fmt::{self, Display, Formatter}; -#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize)] +#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)] pub enum Id { Number(i64), String(String), diff --git a/lib/src/sql/ident.rs b/lib/src/sql/ident.rs index 3100cdd3..ab21d7b7 100644 --- a/lib/src/sql/ident.rs +++ b/lib/src/sql/ident.rs @@ -21,7 +21,7 @@ const BRACKET_END: &str = r#"⟩"#; const BACKTICK: &str = r#"`"#; const BACKTICK_ESC: &str = r#"\`"#; -#[derive(Clone, Debug, Default, Eq, Ord, PartialEq, PartialOrd, Serialize, Deserialize)] +#[derive(Clone, Debug, Default, Eq, Ord, PartialEq, PartialOrd, Serialize, Deserialize, Hash)] pub struct Ident(pub String); impl From for Ident { diff --git a/lib/src/sql/idiom.rs b/lib/src/sql/idiom.rs index 3f8604f7..a3341421 100644 --- a/lib/src/sql/idiom.rs +++ b/lib/src/sql/idiom.rs @@ -19,7 +19,7 @@ use std::fmt::{self, Display, Formatter}; use std::ops::Deref; use std::str; -#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize)] +#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)] pub struct Idioms(pub Vec); impl Deref for Idioms { @@ -40,7 +40,7 @@ pub fn locals(i: &str) -> IResult<&str, Idioms> { Ok((i, Idioms(v))) } -#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize)] +#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)] pub struct Idiom(pub Vec); impl Deref for Idiom { diff --git a/lib/src/sql/kind.rs b/lib/src/sql/kind.rs index 361d1f8c..0131e459 100644 --- a/lib/src/sql/kind.rs +++ b/lib/src/sql/kind.rs @@ -11,7 +11,7 @@ use nom::multi::separated_list1; use serde::{Deserialize, Serialize}; use std::fmt::{self, Display, Formatter}; -#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Hash)] pub enum Kind { Any, Array, diff --git a/lib/src/sql/limit.rs b/lib/src/sql/limit.rs index 50d3e52c..5585d644 100644 --- a/lib/src/sql/limit.rs +++ b/lib/src/sql/limit.rs @@ -11,7 +11,7 @@ use nom::sequence::tuple; use serde::{Deserialize, Serialize}; use std::fmt; -#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize)] +#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)] pub struct Limit(pub Value); impl Limit { diff --git a/lib/src/sql/model.rs b/lib/src/sql/model.rs index b648b0bc..8e5cf4c2 100644 --- a/lib/src/sql/model.rs +++ b/lib/src/sql/model.rs @@ -44,7 +44,7 @@ impl Iterator for IntoIter { } } -#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize)] +#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)] pub enum Model { Count(String, u64), Range(String, u64, u64), diff --git a/lib/src/sql/number.rs b/lib/src/sql/number.rs index 1929495a..fe8d7481 100644 --- a/lib/src/sql/number.rs +++ b/lib/src/sql/number.rs @@ -12,6 +12,7 @@ use nom::number::complete::recognize_float; use serde::{Deserialize, Serialize}; use std::cmp::Ordering; use std::fmt::{self, Display, Formatter}; +use std::hash; use std::iter::Product; use std::iter::Sum; use std::ops; @@ -386,6 +387,16 @@ impl Ord for Number { } } +impl hash::Hash for Number { + fn hash(&self, state: &mut H) { + match self { + Number::Int(v) => v.hash(state), + Number::Float(v) => v.to_bits().hash(state), + Number::Decimal(v) => v.hash(state), + } + } +} + impl PartialEq for Number { fn eq(&self, other: &Self) -> bool { match (self, other) { diff --git a/lib/src/sql/object.rs b/lib/src/sql/object.rs index ba6ecc74..cc8d0fe2 100644 --- a/lib/src/sql/object.rs +++ b/lib/src/sql/object.rs @@ -26,7 +26,7 @@ use std::fmt; use std::ops::Deref; use std::ops::DerefMut; -#[derive(Clone, Debug, Default, Eq, Ord, PartialEq, PartialOrd, Deserialize)] +#[derive(Clone, Debug, Default, Eq, Ord, PartialEq, PartialOrd, Deserialize, Hash)] pub struct Object(pub BTreeMap); impl From> for Object { diff --git a/lib/src/sql/operation.rs b/lib/src/sql/operation.rs index 3f307f6f..54455997 100644 --- a/lib/src/sql/operation.rs +++ b/lib/src/sql/operation.rs @@ -2,14 +2,14 @@ use crate::sql::idiom::Idiom; use crate::sql::value::Value; use serde::{Deserialize, Serialize}; -#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize)] +#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)] pub struct Operation { pub op: Op, pub path: Idiom, pub value: Value, } -#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize)] +#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)] pub enum Op { None, Add, diff --git a/lib/src/sql/operator.rs b/lib/src/sql/operator.rs index abe151b8..b3a2fbb5 100644 --- a/lib/src/sql/operator.rs +++ b/lib/src/sql/operator.rs @@ -9,7 +9,7 @@ use nom::combinator::map; use serde::{Deserialize, Serialize}; use std::fmt; -#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize)] +#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)] pub enum Operator { Or, // || And, // && diff --git a/lib/src/sql/order.rs b/lib/src/sql/order.rs index 38f92a06..dd215dc2 100644 --- a/lib/src/sql/order.rs +++ b/lib/src/sql/order.rs @@ -12,7 +12,7 @@ use serde::{Deserialize, Serialize}; use std::fmt; use std::ops::Deref; -#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize)] +#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)] pub struct Orders(pub Vec); impl Deref for Orders { @@ -36,7 +36,7 @@ impl fmt::Display for Orders { } } -#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize)] +#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)] pub struct Order { pub order: Idiom, pub random: bool, diff --git a/lib/src/sql/output.rs b/lib/src/sql/output.rs index 5dbe8d2a..288c00b5 100644 --- a/lib/src/sql/output.rs +++ b/lib/src/sql/output.rs @@ -7,7 +7,7 @@ use nom::combinator::map; use serde::{Deserialize, Serialize}; use std::fmt::{self, Display}; -#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Hash)] pub enum Output { None, Null, diff --git a/lib/src/sql/param.rs b/lib/src/sql/param.rs index cc90e62e..14a8c189 100644 --- a/lib/src/sql/param.rs +++ b/lib/src/sql/param.rs @@ -14,7 +14,7 @@ use std::fmt; use std::ops::Deref; use std::str; -#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize)] +#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)] pub struct Param(pub Idiom); impl From for Param { diff --git a/lib/src/sql/part.rs b/lib/src/sql/part.rs index 55d82afd..6850785e 100644 --- a/lib/src/sql/part.rs +++ b/lib/src/sql/part.rs @@ -15,7 +15,7 @@ use serde::{Deserialize, Serialize}; use std::fmt; use std::str; -#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize)] +#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)] pub enum Part { All, Last, diff --git a/lib/src/sql/permission.rs b/lib/src/sql/permission.rs index eda82969..708fa89a 100644 --- a/lib/src/sql/permission.rs +++ b/lib/src/sql/permission.rs @@ -11,7 +11,7 @@ use serde::{Deserialize, Serialize}; use std::fmt; use std::str; -#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Hash)] pub struct Permissions { pub select: Permission, pub create: Permission, @@ -131,7 +131,7 @@ fn specific(i: &str) -> IResult<&str, Permissions> { )) } -#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Hash)] pub enum Permission { None, Full, diff --git a/lib/src/sql/query.rs b/lib/src/sql/query.rs index 7bb680be..84c0e1e9 100644 --- a/lib/src/sql/query.rs +++ b/lib/src/sql/query.rs @@ -7,7 +7,7 @@ use std::fmt::{self, Display, Formatter}; use std::ops::Deref; use std::str; -#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store)] +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)] pub struct Query(pub Statements); impl Deref for Query { diff --git a/lib/src/sql/range.rs b/lib/src/sql/range.rs index 13eec1fe..b72f1ebf 100644 --- a/lib/src/sql/range.rs +++ b/lib/src/sql/range.rs @@ -5,7 +5,7 @@ use nom::character::complete::char; use serde::{Deserialize, Serialize}; use std::fmt; -#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize)] +#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)] pub struct Range { pub tb: String, pub beg: Id, diff --git a/lib/src/sql/regex.rs b/lib/src/sql/regex.rs index 4ea9347d..6d31e7b6 100644 --- a/lib/src/sql/regex.rs +++ b/lib/src/sql/regex.rs @@ -8,7 +8,7 @@ use std::fmt; use std::ops::Deref; use std::str; -#[derive(Clone, Debug, Default, Eq, Ord, PartialEq, PartialOrd, Serialize, Deserialize)] +#[derive(Clone, Debug, Default, Eq, Ord, PartialEq, PartialOrd, Serialize, Deserialize, Hash)] pub struct Regex(String); impl From<&str> for Regex { diff --git a/lib/src/sql/script.rs b/lib/src/sql/script.rs index e929e723..437d76e5 100644 --- a/lib/src/sql/script.rs +++ b/lib/src/sql/script.rs @@ -23,7 +23,7 @@ const BACKTICK_ESC: &str = r#"\`"#; const OBJECT_BEG: &str = "{"; const OBJECT_END: &str = "}"; -#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize)] +#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)] pub struct Script(pub String); impl From for Script { diff --git a/lib/src/sql/split.rs b/lib/src/sql/split.rs index d91d9f39..3e72e5aa 100644 --- a/lib/src/sql/split.rs +++ b/lib/src/sql/split.rs @@ -11,7 +11,7 @@ use serde::{Deserialize, Serialize}; use std::fmt::{self, Display, Formatter}; use std::ops::Deref; -#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize)] +#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)] pub struct Splits(pub Vec); impl Deref for Splits { @@ -35,7 +35,7 @@ impl fmt::Display for Splits { } } -#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize)] +#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)] pub struct Split(pub Idiom); impl Deref for Split { diff --git a/lib/src/sql/start.rs b/lib/src/sql/start.rs index 7735f202..8c4157c6 100644 --- a/lib/src/sql/start.rs +++ b/lib/src/sql/start.rs @@ -11,7 +11,7 @@ use nom::sequence::tuple; use serde::{Deserialize, Serialize}; use std::fmt; -#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize)] +#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)] pub struct Start(pub Value); impl Start { diff --git a/lib/src/sql/statement.rs b/lib/src/sql/statement.rs index 635ca2b3..9ece2092 100644 --- a/lib/src/sql/statement.rs +++ b/lib/src/sql/statement.rs @@ -35,7 +35,7 @@ use std::fmt::{self, Display, Formatter}; use std::ops::Deref; use std::time::Duration; -#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Hash)] pub struct Statements(pub Vec); impl Deref for Statements { @@ -60,7 +60,7 @@ pub fn statements(i: &str) -> IResult<&str, Statements> { Ok((i, Statements(v))) } -#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Hash)] pub enum Statement { Use(UseStatement), Set(SetStatement), diff --git a/lib/src/sql/statements/begin.rs b/lib/src/sql/statements/begin.rs index 7521a175..54a6cac5 100644 --- a/lib/src/sql/statements/begin.rs +++ b/lib/src/sql/statements/begin.rs @@ -8,7 +8,7 @@ use nom::sequence::tuple; use serde::{Deserialize, Serialize}; use std::fmt; -#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store)] +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)] pub struct BeginStatement; impl fmt::Display for BeginStatement { diff --git a/lib/src/sql/statements/cancel.rs b/lib/src/sql/statements/cancel.rs index bd284902..b2747da5 100644 --- a/lib/src/sql/statements/cancel.rs +++ b/lib/src/sql/statements/cancel.rs @@ -8,7 +8,7 @@ use nom::sequence::tuple; use serde::{Deserialize, Serialize}; use std::fmt; -#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store)] +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)] pub struct CancelStatement; impl fmt::Display for CancelStatement { diff --git a/lib/src/sql/statements/commit.rs b/lib/src/sql/statements/commit.rs index 5bf15b69..3efcc059 100644 --- a/lib/src/sql/statements/commit.rs +++ b/lib/src/sql/statements/commit.rs @@ -8,7 +8,7 @@ use nom::sequence::tuple; use serde::{Deserialize, Serialize}; use std::fmt; -#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store)] +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)] pub struct CommitStatement; impl fmt::Display for CommitStatement { diff --git a/lib/src/sql/statements/create.rs b/lib/src/sql/statements/create.rs index 844f23c8..e14cbdf1 100644 --- a/lib/src/sql/statements/create.rs +++ b/lib/src/sql/statements/create.rs @@ -19,7 +19,7 @@ use nom::sequence::preceded; use serde::{Deserialize, Serialize}; use std::fmt; -#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store)] +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)] pub struct CreateStatement { pub what: Values, pub data: Option, diff --git a/lib/src/sql/statements/define.rs b/lib/src/sql/statements/define.rs index 59695696..4b0fcfdc 100644 --- a/lib/src/sql/statements/define.rs +++ b/lib/src/sql/statements/define.rs @@ -33,7 +33,7 @@ use serde::{Deserialize, Serialize}; use std::fmt; use std::fmt::Display; -#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Store)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Store, Hash)] pub enum DefineStatement { Namespace(DefineNamespaceStatement), Database(DefineDatabaseStatement), @@ -102,7 +102,7 @@ pub fn define(i: &str) -> IResult<&str, DefineStatement> { // -------------------------------------------------- // -------------------------------------------------- -#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store)] +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)] pub struct DefineNamespaceStatement { pub name: Ident, } @@ -151,7 +151,7 @@ fn namespace(i: &str) -> IResult<&str, DefineNamespaceStatement> { // -------------------------------------------------- // -------------------------------------------------- -#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store)] +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)] pub struct DefineDatabaseStatement { pub name: Ident, } @@ -205,7 +205,7 @@ fn database(i: &str) -> IResult<&str, DefineDatabaseStatement> { // -------------------------------------------------- // -------------------------------------------------- -#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store)] +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)] pub struct DefineLoginStatement { pub name: Ident, pub base: Base, @@ -328,7 +328,7 @@ fn login_hash(i: &str) -> IResult<&str, DefineLoginOption> { // -------------------------------------------------- // -------------------------------------------------- -#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store)] +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)] pub struct DefineTokenStatement { pub name: Ident, pub base: Base, @@ -447,7 +447,7 @@ fn token(i: &str) -> IResult<&str, DefineTokenStatement> { // -------------------------------------------------- // -------------------------------------------------- -#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store)] +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)] pub struct DefineScopeStatement { pub name: Ident, pub code: String, @@ -530,7 +530,7 @@ fn scope(i: &str) -> IResult<&str, DefineScopeStatement> { )) } -#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Hash)] pub enum DefineScopeOption { Session(Duration), Signup(Value), @@ -569,7 +569,7 @@ fn scope_signin(i: &str) -> IResult<&str, DefineScopeOption> { // -------------------------------------------------- // -------------------------------------------------- -#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store)] +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)] pub struct DefineTableStatement { pub name: Ident, pub drop: bool, @@ -698,7 +698,7 @@ fn table(i: &str) -> IResult<&str, DefineTableStatement> { )) } -#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Hash)] pub enum DefineTableOption { Drop, View(View), @@ -745,7 +745,7 @@ fn table_permissions(i: &str) -> IResult<&str, DefineTableOption> { // -------------------------------------------------- // -------------------------------------------------- -#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store)] +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)] pub struct DefineEventStatement { pub name: Ident, pub what: Ident, @@ -824,7 +824,7 @@ fn event(i: &str) -> IResult<&str, DefineEventStatement> { // -------------------------------------------------- // -------------------------------------------------- -#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store)] +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)] pub struct DefineFieldStatement { pub name: Idiom, pub what: Ident, @@ -920,7 +920,7 @@ fn field(i: &str) -> IResult<&str, DefineFieldStatement> { )) } -#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Hash)] pub enum DefineFieldOption { Kind(Kind), Value(Value), @@ -966,7 +966,7 @@ fn field_permissions(i: &str) -> IResult<&str, DefineFieldOption> { // -------------------------------------------------- // -------------------------------------------------- -#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store)] +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)] pub struct DefineIndexStatement { pub name: Ident, pub what: Ident, diff --git a/lib/src/sql/statements/delete.rs b/lib/src/sql/statements/delete.rs index f9e483a5..e4f692a4 100644 --- a/lib/src/sql/statements/delete.rs +++ b/lib/src/sql/statements/delete.rs @@ -20,7 +20,7 @@ use nom::sequence::tuple; use serde::{Deserialize, Serialize}; use std::fmt; -#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store)] +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)] pub struct DeleteStatement { pub what: Values, pub cond: Option, diff --git a/lib/src/sql/statements/ifelse.rs b/lib/src/sql/statements/ifelse.rs index 8b966b25..19e2f066 100644 --- a/lib/src/sql/statements/ifelse.rs +++ b/lib/src/sql/statements/ifelse.rs @@ -12,7 +12,7 @@ use nom::multi::separated_list0; use serde::{Deserialize, Serialize}; use std::fmt; -#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store)] +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)] pub struct IfelseStatement { pub exprs: Vec<(Value, Value)>, pub close: Option, diff --git a/lib/src/sql/statements/info.rs b/lib/src/sql/statements/info.rs index 1284657d..e66ed97e 100644 --- a/lib/src/sql/statements/info.rs +++ b/lib/src/sql/statements/info.rs @@ -14,7 +14,7 @@ use nom::bytes::complete::tag_no_case; use serde::{Deserialize, Serialize}; use std::fmt; -#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Store)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Store, Hash)] pub enum InfoStatement { Kv, Ns, diff --git a/lib/src/sql/statements/insert.rs b/lib/src/sql/statements/insert.rs index 3760c5d7..aa85e2e2 100644 --- a/lib/src/sql/statements/insert.rs +++ b/lib/src/sql/statements/insert.rs @@ -21,7 +21,7 @@ use nom::sequence::preceded; use serde::{Deserialize, Serialize}; use std::fmt; -#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store)] +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)] pub struct InsertStatement { pub into: Table, pub data: Data, diff --git a/lib/src/sql/statements/kill.rs b/lib/src/sql/statements/kill.rs index 99bcdfad..d47b2f57 100644 --- a/lib/src/sql/statements/kill.rs +++ b/lib/src/sql/statements/kill.rs @@ -12,7 +12,7 @@ use nom::bytes::complete::tag_no_case; use serde::{Deserialize, Serialize}; use std::fmt; -#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store)] +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)] pub struct KillStatement { pub id: Uuid, } diff --git a/lib/src/sql/statements/live.rs b/lib/src/sql/statements/live.rs index 5f2798a2..02ab0e6f 100644 --- a/lib/src/sql/statements/live.rs +++ b/lib/src/sql/statements/live.rs @@ -21,7 +21,7 @@ use nom::sequence::preceded; use serde::{Deserialize, Serialize}; use std::fmt; -#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store)] +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)] pub struct LiveStatement { pub id: Uuid, pub expr: Fields, diff --git a/lib/src/sql/statements/option.rs b/lib/src/sql/statements/option.rs index 562a9934..8573ff74 100644 --- a/lib/src/sql/statements/option.rs +++ b/lib/src/sql/statements/option.rs @@ -11,7 +11,7 @@ use nom::sequence::tuple; use serde::{Deserialize, Serialize}; use std::fmt; -#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store)] +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)] pub struct OptionStatement { pub name: Ident, pub what: bool, diff --git a/lib/src/sql/statements/output.rs b/lib/src/sql/statements/output.rs index eb8d9872..28c7679e 100644 --- a/lib/src/sql/statements/output.rs +++ b/lib/src/sql/statements/output.rs @@ -13,7 +13,7 @@ use nom::sequence::preceded; use serde::{Deserialize, Serialize}; use std::fmt; -#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store)] +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)] pub struct OutputStatement { pub what: Value, pub fetch: Option, diff --git a/lib/src/sql/statements/relate.rs b/lib/src/sql/statements/relate.rs index 65146e11..67a6d304 100644 --- a/lib/src/sql/statements/relate.rs +++ b/lib/src/sql/statements/relate.rs @@ -28,7 +28,7 @@ use nom::sequence::preceded; use serde::{Deserialize, Serialize}; use std::fmt; -#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store)] +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)] pub struct RelateStatement { pub kind: Table, pub from: Value, diff --git a/lib/src/sql/statements/remove.rs b/lib/src/sql/statements/remove.rs index 93f26469..f1be1879 100644 --- a/lib/src/sql/statements/remove.rs +++ b/lib/src/sql/statements/remove.rs @@ -18,7 +18,7 @@ use nom::sequence::tuple; use serde::{Deserialize, Serialize}; use std::fmt::{self, Display, Formatter}; -#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Store)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Store, Hash)] pub enum RemoveStatement { Namespace(RemoveNamespaceStatement), Database(RemoveDatabaseStatement), @@ -87,7 +87,7 @@ pub fn remove(i: &str) -> IResult<&str, RemoveStatement> { // -------------------------------------------------- // -------------------------------------------------- -#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store)] +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)] pub struct RemoveNamespaceStatement { pub name: Ident, } @@ -143,7 +143,7 @@ fn namespace(i: &str) -> IResult<&str, RemoveNamespaceStatement> { // -------------------------------------------------- // -------------------------------------------------- -#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store)] +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)] pub struct RemoveDatabaseStatement { pub name: Ident, } @@ -199,7 +199,7 @@ fn database(i: &str) -> IResult<&str, RemoveDatabaseStatement> { // -------------------------------------------------- // -------------------------------------------------- -#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store)] +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)] pub struct RemoveLoginStatement { pub name: Ident, pub base: Base, @@ -278,7 +278,7 @@ fn login(i: &str) -> IResult<&str, RemoveLoginStatement> { // -------------------------------------------------- // -------------------------------------------------- -#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store)] +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)] pub struct RemoveTokenStatement { pub name: Ident, pub base: Base, @@ -372,7 +372,7 @@ fn token(i: &str) -> IResult<&str, RemoveTokenStatement> { // -------------------------------------------------- // -------------------------------------------------- -#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store)] +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)] pub struct RemoveScopeStatement { pub name: Ident, } @@ -428,7 +428,7 @@ fn scope(i: &str) -> IResult<&str, RemoveScopeStatement> { // -------------------------------------------------- // -------------------------------------------------- -#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store)] +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)] pub struct RemoveTableStatement { pub name: Ident, } @@ -484,7 +484,7 @@ fn table(i: &str) -> IResult<&str, RemoveTableStatement> { // -------------------------------------------------- // -------------------------------------------------- -#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store)] +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)] pub struct RemoveEventStatement { pub name: Ident, pub what: Ident, @@ -544,7 +544,7 @@ fn event(i: &str) -> IResult<&str, RemoveEventStatement> { // -------------------------------------------------- // -------------------------------------------------- -#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store)] +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)] pub struct RemoveFieldStatement { pub name: Idiom, pub what: Ident, @@ -604,7 +604,7 @@ fn field(i: &str) -> IResult<&str, RemoveFieldStatement> { // -------------------------------------------------- // -------------------------------------------------- -#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store)] +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)] pub struct RemoveIndexStatement { pub name: Ident, pub what: Ident, diff --git a/lib/src/sql/statements/select.rs b/lib/src/sql/statements/select.rs index 1ae713d3..67fba065 100644 --- a/lib/src/sql/statements/select.rs +++ b/lib/src/sql/statements/select.rs @@ -26,7 +26,7 @@ use nom::sequence::preceded; use serde::{Deserialize, Serialize}; use std::fmt; -#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store)] +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)] pub struct SelectStatement { pub expr: Fields, pub what: Values, diff --git a/lib/src/sql/statements/set.rs b/lib/src/sql/statements/set.rs index c96e49b1..92cc2812 100644 --- a/lib/src/sql/statements/set.rs +++ b/lib/src/sql/statements/set.rs @@ -14,7 +14,7 @@ use nom::sequence::preceded; use serde::{Deserialize, Serialize}; use std::fmt; -#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store)] +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)] pub struct SetStatement { pub name: String, pub what: Value, diff --git a/lib/src/sql/statements/update.rs b/lib/src/sql/statements/update.rs index 8430eb9a..e5efab96 100644 --- a/lib/src/sql/statements/update.rs +++ b/lib/src/sql/statements/update.rs @@ -20,7 +20,7 @@ use nom::sequence::preceded; use serde::{Deserialize, Serialize}; use std::fmt; -#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store)] +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)] pub struct UpdateStatement { pub what: Values, pub data: Option, diff --git a/lib/src/sql/statements/yuse.rs b/lib/src/sql/statements/yuse.rs index 8b9b6ad6..99a7c3d8 100644 --- a/lib/src/sql/statements/yuse.rs +++ b/lib/src/sql/statements/yuse.rs @@ -7,7 +7,7 @@ use nom::bytes::complete::tag_no_case; use serde::{Deserialize, Serialize}; use std::fmt; -#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store)] +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)] pub struct UseStatement { pub ns: Option, pub db: Option, diff --git a/lib/src/sql/strand.rs b/lib/src/sql/strand.rs index e0683bb1..7a905987 100644 --- a/lib/src/sql/strand.rs +++ b/lib/src/sql/strand.rs @@ -21,7 +21,7 @@ const SINGLE_ESC: &str = r#"\'"#; const DOUBLE: char = '"'; const DOUBLE_ESC: &str = r#"\""#; -#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Deserialize)] +#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Deserialize, Hash)] pub struct Strand(pub String); impl From for Strand { diff --git a/lib/src/sql/subquery.rs b/lib/src/sql/subquery.rs index 3572c867..cb50b42d 100644 --- a/lib/src/sql/subquery.rs +++ b/lib/src/sql/subquery.rs @@ -20,7 +20,7 @@ use serde::{Deserialize, Serialize}; use std::cmp::Ordering; use std::fmt::{self, Display, Formatter}; -#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Hash)] pub enum Subquery { Value(Value), Ifelse(IfelseStatement), diff --git a/lib/src/sql/table.rs b/lib/src/sql/table.rs index f95bf7b1..bc58a7fd 100644 --- a/lib/src/sql/table.rs +++ b/lib/src/sql/table.rs @@ -11,7 +11,7 @@ use std::fmt::{self, Display, Formatter}; use std::ops::Deref; use std::str; -#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize)] +#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)] pub struct Tables(pub Vec); impl From
for Tables { @@ -38,7 +38,7 @@ pub fn tables(i: &str) -> IResult<&str, Tables> { Ok((i, Tables(v))) } -#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize)] +#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)] pub struct Table(pub String); impl From for Table { diff --git a/lib/src/sql/thing.rs b/lib/src/sql/thing.rs index 295f9f24..76766e5c 100644 --- a/lib/src/sql/thing.rs +++ b/lib/src/sql/thing.rs @@ -16,7 +16,7 @@ use serde::ser::SerializeStruct; use serde::{Deserialize, Serialize}; use std::fmt; -#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Deserialize, Store)] +#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Deserialize, Store, Hash)] pub struct Thing { pub tb: String, pub id: Id, diff --git a/lib/src/sql/timeout.rs b/lib/src/sql/timeout.rs index 81b2cdca..67a32626 100644 --- a/lib/src/sql/timeout.rs +++ b/lib/src/sql/timeout.rs @@ -6,7 +6,7 @@ use serde::{Deserialize, Serialize}; use std::fmt; use std::ops::Deref; -#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize)] +#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)] pub struct Timeout(pub Duration); impl Deref for Timeout { diff --git a/lib/src/sql/uuid.rs b/lib/src/sql/uuid.rs index 7c777e47..0c8cb694 100644 --- a/lib/src/sql/uuid.rs +++ b/lib/src/sql/uuid.rs @@ -13,7 +13,7 @@ use std::fmt::{self, Display, Formatter}; use std::ops::Deref; use std::str; -#[derive(Clone, Debug, Default, Eq, Ord, PartialEq, PartialOrd, Deserialize)] +#[derive(Clone, Debug, Default, Eq, Ord, PartialEq, PartialOrd, Deserialize, Hash)] pub struct Uuid(pub uuid::Uuid); impl From<&str> for Uuid { diff --git a/lib/src/sql/value/value.rs b/lib/src/sql/value/value.rs index 88d3805b..d0f2681e 100644 --- a/lib/src/sql/value/value.rs +++ b/lib/src/sql/value/value.rs @@ -55,7 +55,7 @@ use std::str::FromStr; static MATCHER: Lazy = Lazy::new(|| SkimMatcherV2::default().ignore_case()); -#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Hash)] pub struct Values(pub Vec); impl Deref for Values { @@ -94,7 +94,7 @@ pub fn whats(i: &str) -> IResult<&str, Values> { Ok((i, Values(v))) } -#[derive(Clone, Debug, PartialEq, PartialOrd, Deserialize, Store)] +#[derive(Clone, Debug, PartialEq, PartialOrd, Deserialize, Store, Hash)] pub enum Value { None, Null, diff --git a/lib/src/sql/version.rs b/lib/src/sql/version.rs index d823f191..3cc9af78 100644 --- a/lib/src/sql/version.rs +++ b/lib/src/sql/version.rs @@ -5,7 +5,7 @@ use nom::bytes::complete::tag_no_case; use serde::{Deserialize, Serialize}; use std::fmt; -#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize)] +#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)] pub struct Version(pub Datetime); impl fmt::Display for Version { diff --git a/lib/src/sql/view.rs b/lib/src/sql/view.rs index 3c615e32..3590fdce 100644 --- a/lib/src/sql/view.rs +++ b/lib/src/sql/view.rs @@ -10,7 +10,7 @@ use nom::sequence::preceded; use serde::{Deserialize, Serialize}; use std::fmt; -#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize)] +#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)] pub struct View { pub expr: Fields, pub what: Tables, diff --git a/lib/tests/function.rs b/lib/tests/function.rs new file mode 100644 index 00000000..98c64bcb --- /dev/null +++ b/lib/tests/function.rs @@ -0,0 +1,38 @@ +mod parse; +use parse::Parse; +use surrealdb::sql::Value; +use surrealdb::Datastore; +use surrealdb::Error; +use surrealdb::Session; + +#[tokio::test] +async fn array_distinct() -> Result<(), Error> { + let sql = r#" + SELECT * FROM array::distinct([1, 3, 2, 1, 3, 3, 4]); + SELECT * FROM array::distinct([]); + SELECT * FROM array::distinct("something"); + SELECT * FROM array::distinct(["something"]); + "#; + 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, false).await?; + assert_eq!(res.len(), 4); + // + let tmp = res.remove(0).result?; + let val = Value::parse("[1, 3, 2, 4]"); + assert_eq!(tmp, val); + // + let tmp = res.remove(0).result?; + let val = Value::parse("[]"); + assert_eq!(tmp, val); + // + let tmp = res.remove(0).result?; + let val = Value::parse("[NONE]"); + assert_eq!(tmp, val); + // + let tmp = res.remove(0).result?; + let val = Value::parse("['something']"); + assert_eq!(tmp, val); + // + Ok(()) +}