Implement hashed implementation of Uniq<Array> (#1310)

This commit is contained in:
Allen Lantz 2022-10-27 07:23:24 -05:00 committed by GitHub
parent 12ded8b066
commit d1055e6088
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
68 changed files with 245 additions and 103 deletions

View file

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

View file

@ -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<Value>);
impl From<Value> for Array {
@ -318,13 +319,16 @@ pub trait Uniq<T> {
impl Uniq<Array> 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<usize> = 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);
}
}

View file

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

View file

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

View file

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

View file

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

View file

@ -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<Utc>);
impl Default for Datetime {

View file

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

View file

@ -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<time::Duration> for Duration {

View file

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

View file

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

View file

@ -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<Fetch>);
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 {

View file

@ -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<Field>);
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),

View file

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

View file

@ -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<H: hash::Hasher>(&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)
}

View file

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

View file

@ -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<Group>);
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 {

View file

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

View file

@ -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<String> for Ident {

View file

@ -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<Idiom>);
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<Part>);
impl Deref for Idiom {

View file

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

View file

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

View file

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

View file

@ -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<H: hash::Hasher>(&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) {

View file

@ -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<String, Value>);
impl From<BTreeMap<String, Value>> for Object {

View file

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

View file

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

View file

@ -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<Order>);
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,

View file

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

View file

@ -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<Idiom> for Param {

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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<String> for Script {

View file

@ -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<Split>);
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 {

View file

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

View file

@ -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<Statement>);
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),

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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<String>,
pub db: Option<String>,

View file

@ -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<String> for Strand {

View file

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

View file

@ -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<Table>);
impl From<Table> 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<String> for Table {

View file

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

View file

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

View file

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

View file

@ -55,7 +55,7 @@ use std::str::FromStr;
static MATCHER: Lazy<SkimMatcherV2> = 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<Value>);
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,

View file

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

View file

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

38
lib/tests/function.rs Normal file
View file

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