From 03f107c425f24a256cfbd303d2adba8b73d4442d Mon Sep 17 00:00:00 2001 From: Richard Newman Date: Thu, 27 Apr 2017 09:49:25 -0700 Subject: [PATCH] Part 7: parse and algebrize UUIDs in queries. --- query-algebrizer/src/clauses/resolve.rs | 2 ++ query-parser/Cargo.toml | 3 +++ query-parser/tests/find_tests.rs | 18 ++++++++++++++++ query/src/lib.rs | 28 +++++++++++++++++++++---- 4 files changed, 47 insertions(+), 4 deletions(-) diff --git a/query-algebrizer/src/clauses/resolve.rs b/query-algebrizer/src/clauses/resolve.rs index aba0ba35..6231bd23 100644 --- a/query-algebrizer/src/clauses/resolve.rs +++ b/query-algebrizer/src/clauses/resolve.rs @@ -54,6 +54,7 @@ impl ConjoiningClauses { SrcVar(_) | Constant(NonIntegerConstant::Boolean(_)) | Constant(NonIntegerConstant::Text(_)) | + Constant(NonIntegerConstant::Uuid(_)) | Constant(NonIntegerConstant::BigInteger(_)) => { self.mark_known_empty(EmptyBecause::NonNumericArgument); bail!(ErrorKind::NonNumericArgument(function.clone(), position)); @@ -80,6 +81,7 @@ impl ConjoiningClauses { Constant(NonIntegerConstant::Boolean(val)) => Ok(QueryValue::TypedValue(TypedValue::Boolean(val))), Constant(NonIntegerConstant::Float(f)) => Ok(QueryValue::TypedValue(TypedValue::Double(f))), Constant(NonIntegerConstant::Text(s)) => Ok(QueryValue::TypedValue(TypedValue::typed_string(s.as_str()))), + Constant(NonIntegerConstant::Uuid(u)) => Ok(QueryValue::TypedValue(TypedValue::Uuid(u))), Constant(NonIntegerConstant::BigInteger(_)) => unimplemented!(), SrcVar(_) => unimplemented!(), } diff --git a/query-parser/Cargo.toml b/query-parser/Cargo.toml index 7dde1314..69488bbd 100644 --- a/query-parser/Cargo.toml +++ b/query-parser/Cargo.toml @@ -11,6 +11,9 @@ matches = "0.1" [dependencies.edn] path = "../edn" +[dependencies.mentat_core] + path = "../core" + [dependencies.mentat_parser_utils] path = "../parser-utils" diff --git a/query-parser/tests/find_tests.rs b/query-parser/tests/find_tests.rs index 7e577fdd..be8ddd6c 100644 --- a/query-parser/tests/find_tests.rs +++ b/query-parser/tests/find_tests.rs @@ -9,9 +9,12 @@ // specific language governing permissions and limitations under the License. extern crate edn; +extern crate mentat_core; extern crate mentat_query; extern crate mentat_query_parser; +use std::rc::Rc; + use edn::{ NamespacedKeyword, PlainSymbol, @@ -23,6 +26,7 @@ use mentat_query::{ FindSpec, FnArg, Limit, + NonIntegerConstant, Order, OrJoin, OrWhereClause, @@ -267,3 +271,17 @@ fn can_parse_limit() { let variable_without_in = "[:find ?x :where [?x :foo/baz ?y] :limit ?limit]"; assert!(parse_find_string(variable_without_in).is_err()); } + +#[test] +fn can_parse_uuid() { + let expected = edn::Uuid::parse_str("4cb3f828-752d-497a-90c9-b1fd516d5644").expect("valid uuid"); + let s = "[:find ?x :where [?x :foo/baz #uuid \"4cb3f828-752d-497a-90c9-b1fd516d5644\"]]"; + assert_eq!(parse_find_string(s).expect("parsed").where_clauses.pop().expect("a where clause"), + WhereClause::Pattern( + Pattern::new(None, + PatternNonValuePlace::Variable(Variable::from_valid_name("?x")), + PatternNonValuePlace::Ident(Rc::new(NamespacedKeyword::new("foo", "baz"))), + PatternValuePlace::Constant(NonIntegerConstant::Uuid(expected)), + PatternNonValuePlace::Placeholder) + .expect("valid pattern"))); +} diff --git a/query/src/lib.rs b/query/src/lib.rs index cf102545..d5d2bdbe 100644 --- a/query/src/lib.rs +++ b/query/src/lib.rs @@ -40,8 +40,16 @@ use std::collections::{ use std::fmt; use std::rc::Rc; -use edn::{BigInt, OrderedFloat}; -pub use edn::{NamespacedKeyword, PlainSymbol}; +use edn::{ + BigInt, + OrderedFloat, + Uuid, +}; + +pub use edn::{ + NamespacedKeyword, + PlainSymbol, +}; use mentat_core::{ TypedValue, @@ -178,6 +186,7 @@ pub enum NonIntegerConstant { BigInteger(BigInt), Float(OrderedFloat), Text(Rc), + Uuid(Uuid), } impl NonIntegerConstant { @@ -187,6 +196,7 @@ impl NonIntegerConstant { NonIntegerConstant::Boolean(v) => TypedValue::Boolean(v), NonIntegerConstant::Float(v) => TypedValue::Double(v), NonIntegerConstant::Text(v) => TypedValue::String(v), + NonIntegerConstant::Uuid(v) => TypedValue::Uuid(v), } } } @@ -313,7 +323,17 @@ impl FromValue for PatternValuePlace { edn::SpannedValue::Text(ref x) => // TODO: intern strings. #398. Some(PatternValuePlace::Constant(NonIntegerConstant::Text(Rc::new(x.clone())))), - _ => None, + edn::SpannedValue::Uuid(ref u) => + Some(PatternValuePlace::Constant(NonIntegerConstant::Uuid(u.clone()))), + + // These don't appear in queries. + edn::SpannedValue::Nil => None, + edn::SpannedValue::NamespacedSymbol(_) => None, + edn::SpannedValue::Keyword(_) => None, + edn::SpannedValue::Map(_) => None, + edn::SpannedValue::List(_) => None, + edn::SpannedValue::Set(_) => None, + edn::SpannedValue::Vector(_) => None, } } } @@ -761,4 +781,4 @@ impl ContainsVariables for Pattern { acc_ref(acc, v) } } -} \ No newline at end of file +}