1use std::collections::{BTreeSet, HashSet};
33
34use std;
35use std::fmt;
36use std::rc::Rc;
37use std::sync::Arc;
38
39use crate::{BigInt, DateTime, OrderedFloat, Utc, Uuid};
40
41use crate::value_rc::{FromRc, ValueRc};
42
43pub use crate::{Keyword, PlainSymbol};
44
45pub type SrcVarName = String; #[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
48pub struct Variable(pub Arc<PlainSymbol>);
49
50impl Variable {
51 pub fn as_str(&self) -> &str {
52 self.0.as_ref().0.as_str()
53 }
54
55 pub fn name(&self) -> PlainSymbol {
56 self.0.as_ref().clone()
57 }
58
59 pub fn from_valid_name(name: &str) -> Variable {
61 let s = PlainSymbol::plain(name);
62 assert!(s.is_var_symbol());
63 Variable(Arc::new(s))
64 }
65}
66
67pub trait ToVariable {
68 fn to_var(&self) -> Variable;
69}
70
71impl ToVariable for str {
72 fn to_var(&self) -> Variable {
73 Variable::from_valid_name(self)
74 }
75}
76
77pub trait FromValue<T> {
78 fn from_value(v: &crate::ValueAndSpan) -> Option<T>;
79}
80
81impl FromValue<Variable> for Variable {
85 fn from_value(v: &crate::ValueAndSpan) -> Option<Variable> {
86 if let crate::SpannedValue::PlainSymbol(ref s) = v.inner {
87 Variable::from_symbol(s)
88 } else {
89 None
90 }
91 }
92}
93
94impl Variable {
95 pub fn from_arc(sym: Arc<PlainSymbol>) -> Option<Variable> {
96 if sym.is_var_symbol() {
97 Some(Variable(sym.clone()))
98 } else {
99 None
100 }
101 }
102
103 pub fn from_symbol(sym: &PlainSymbol) -> Option<Variable> {
105 if sym.is_var_symbol() {
106 Some(Variable(Arc::new(sym.clone())))
107 } else {
108 None
109 }
110 }
111}
112
113impl fmt::Debug for Variable {
114 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
115 write!(f, "var({})", self.0)
116 }
117}
118
119impl std::fmt::Display for Variable {
120 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
121 write!(f, "{}", self.0)
122 }
123}
124
125#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
126pub struct QueryFunction(pub PlainSymbol);
127
128impl FromValue<QueryFunction> for QueryFunction {
129 fn from_value(v: &crate::ValueAndSpan) -> Option<QueryFunction> {
130 if let crate::SpannedValue::PlainSymbol(ref s) = v.inner {
131 QueryFunction::from_symbol(s)
132 } else {
133 None
134 }
135 }
136}
137
138impl QueryFunction {
139 pub fn from_symbol(sym: &PlainSymbol) -> Option<QueryFunction> {
140 Some(QueryFunction(sym.clone()))
142 }
143}
144
145impl std::fmt::Display for QueryFunction {
146 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
147 write!(f, "{}", self.0)
148 }
149}
150
151#[derive(Clone, Debug, Eq, PartialEq)]
152pub enum Direction {
153 Ascending,
154 Descending,
155}
156
157#[derive(Clone, Debug, Eq, PartialEq)]
159pub struct Order(pub Direction, pub Variable); #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
162pub enum SrcVar {
163 DefaultSrc,
164 NamedSrc(SrcVarName),
165}
166
167impl FromValue<SrcVar> for SrcVar {
168 fn from_value(v: &crate::ValueAndSpan) -> Option<SrcVar> {
169 if let crate::SpannedValue::PlainSymbol(ref s) = v.inner {
170 SrcVar::from_symbol(s)
171 } else {
172 None
173 }
174 }
175}
176
177impl SrcVar {
178 pub fn from_symbol(sym: &PlainSymbol) -> Option<SrcVar> {
179 if sym.is_src_symbol() {
180 if sym.0 == "$" {
181 Some(SrcVar::DefaultSrc)
182 } else {
183 Some(SrcVar::NamedSrc(sym.name().to_string()))
184 }
185 } else {
186 None
187 }
188 }
189}
190
191#[derive(Clone, Debug, Eq, PartialEq)]
193pub enum NonIntegerConstant {
194 Boolean(bool),
195 BigInteger(BigInt),
196 Float(OrderedFloat<f64>),
197 Text(ValueRc<String>),
198 Instant(DateTime<Utc>),
199 Uuid(Uuid),
200}
201
202impl<'a> From<&'a str> for NonIntegerConstant {
203 fn from(val: &'a str) -> NonIntegerConstant {
204 NonIntegerConstant::Text(ValueRc::new(val.to_string()))
205 }
206}
207
208impl From<String> for NonIntegerConstant {
209 fn from(val: String) -> NonIntegerConstant {
210 NonIntegerConstant::Text(ValueRc::new(val))
211 }
212}
213
214#[derive(Clone, Debug, Eq, PartialEq)]
215pub enum FnArg {
216 Variable(Variable),
217 SrcVar(SrcVar),
218 EntidOrInteger(i64),
219 IdentOrKeyword(Keyword),
220 Constant(NonIntegerConstant),
221 SExpr(PlainSymbol, Vec<FnArg>),
223}
224
225impl FromValue<FnArg> for FnArg {
226 fn from_value(v: &crate::ValueAndSpan) -> Option<FnArg> {
227 use crate::SpannedValue::*;
228 match v.inner {
229 Integer(x) => Some(FnArg::EntidOrInteger(x)),
230 PlainSymbol(ref x) if x.is_src_symbol() => SrcVar::from_symbol(x).map(FnArg::SrcVar),
231 PlainSymbol(ref x) if x.is_var_symbol() => {
232 Variable::from_symbol(x).map(FnArg::Variable)
233 }
234 PlainSymbol(_) => None,
235 Keyword(ref x) => Some(FnArg::IdentOrKeyword(x.clone())),
236 Instant(x) => Some(FnArg::Constant(NonIntegerConstant::Instant(x))),
237 Uuid(x) => Some(FnArg::Constant(NonIntegerConstant::Uuid(x))),
238 Boolean(x) => Some(FnArg::Constant(NonIntegerConstant::Boolean(x))),
239 Float(x) => Some(FnArg::Constant(NonIntegerConstant::Float(x))),
240 BigInteger(ref x) => Some(FnArg::Constant(NonIntegerConstant::BigInteger(x.clone()))),
241 Text(ref x) =>
242 {
244 Some(FnArg::Constant(x.clone().into()))
245 }
246 Nil | NamespacedSymbol(_) | Vector(_) | List(_) | Set(_) | Map(_) => None,
247 }
248 }
249}
250
251impl std::fmt::Display for FnArg {
253 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
254 match self {
255 FnArg::Variable(var) => write!(f, "{}", var),
256 FnArg::SrcVar(var) => {
257 if var == &SrcVar::DefaultSrc {
258 write!(f, "$")
259 } else {
260 write!(
261 f,
262 "${}",
263 match var {
264 SrcVar::NamedSrc(ref n) => n,
265 _ => "",
266 }
267 )
268 }
269 }
270 &FnArg::EntidOrInteger(entid) => write!(f, "{}", entid),
271 FnArg::IdentOrKeyword(kw) => write!(f, "{}", kw),
272 FnArg::Constant(constant) => write!(f, "{}", constant),
273 FnArg::SExpr(ref func, ref args) => {
274 write!(f, "({}", func)?;
275 for arg in args {
276 write!(f, " {}", arg)?;
277 }
278 write!(f, ")")
279 }
280 }
281 }
282}
283
284impl FnArg {
285 pub fn as_variable(&self) -> Option<&Variable> {
286 match self {
287 FnArg::Variable(v) => Some(v),
288 _ => None,
289 }
290 }
291}
292
293#[derive(Clone, Debug, Eq, PartialEq)]
300pub enum PatternNonValuePlace {
301 Placeholder,
302 Variable(Variable),
303 Entid(i64), Ident(ValueRc<Keyword>),
305}
306
307impl From<Rc<Keyword>> for PatternNonValuePlace {
308 fn from(value: Rc<Keyword>) -> Self {
309 PatternNonValuePlace::Ident(ValueRc::from_rc(value))
310 }
311}
312
313impl From<Keyword> for PatternNonValuePlace {
314 fn from(value: Keyword) -> Self {
315 PatternNonValuePlace::Ident(ValueRc::new(value))
316 }
317}
318
319impl PatternNonValuePlace {
320 #[allow(dead_code)]
322 fn into_pattern_value_place(self) -> PatternValuePlace {
323 match self {
324 PatternNonValuePlace::Placeholder => PatternValuePlace::Placeholder,
325 PatternNonValuePlace::Variable(x) => PatternValuePlace::Variable(x),
326 PatternNonValuePlace::Entid(x) => PatternValuePlace::EntidOrInteger(x),
327 PatternNonValuePlace::Ident(x) => PatternValuePlace::IdentOrKeyword(x),
328 }
329 }
330
331 fn to_pattern_value_place(&self) -> PatternValuePlace {
332 match *self {
333 PatternNonValuePlace::Placeholder => PatternValuePlace::Placeholder,
334 PatternNonValuePlace::Variable(ref x) => PatternValuePlace::Variable(x.clone()),
335 PatternNonValuePlace::Entid(x) => PatternValuePlace::EntidOrInteger(x),
336 PatternNonValuePlace::Ident(ref x) => PatternValuePlace::IdentOrKeyword(x.clone()),
337 }
338 }
339}
340
341impl FromValue<PatternNonValuePlace> for PatternNonValuePlace {
342 fn from_value(v: &crate::ValueAndSpan) -> Option<PatternNonValuePlace> {
343 match v.inner {
344 crate::SpannedValue::Integer(x) => {
345 if x >= 0 {
346 Some(PatternNonValuePlace::Entid(x))
347 } else {
348 None
349 }
350 }
351 crate::SpannedValue::PlainSymbol(ref x) => {
352 if x.0.as_str() == "_" {
353 Some(PatternNonValuePlace::Placeholder)
354 } else {
355 Variable::from_symbol(x).map(PatternNonValuePlace::Variable)
356 }
357 }
358 crate::SpannedValue::Keyword(ref x) => Some(x.clone().into()),
359 _ => None,
360 }
361 }
362}
363
364#[derive(Clone, Debug, Eq, PartialEq)]
365pub enum IdentOrEntid {
366 Ident(Keyword),
367 Entid(i64),
368}
369
370#[derive(Clone, Debug, Eq, PartialEq)]
374pub enum PatternValuePlace {
375 Placeholder,
376 Variable(Variable),
377 EntidOrInteger(i64),
378 IdentOrKeyword(ValueRc<Keyword>),
379 Constant(NonIntegerConstant),
380}
381
382impl From<Rc<Keyword>> for PatternValuePlace {
383 fn from(value: Rc<Keyword>) -> Self {
384 PatternValuePlace::IdentOrKeyword(ValueRc::from_rc(value))
385 }
386}
387
388impl From<Keyword> for PatternValuePlace {
389 fn from(value: Keyword) -> Self {
390 PatternValuePlace::IdentOrKeyword(ValueRc::new(value))
391 }
392}
393
394impl FromValue<PatternValuePlace> for PatternValuePlace {
395 fn from_value(v: &crate::ValueAndSpan) -> Option<PatternValuePlace> {
396 match v.inner {
397 crate::SpannedValue::Integer(x) => Some(PatternValuePlace::EntidOrInteger(x)),
398 crate::SpannedValue::PlainSymbol(ref x) if x.0.as_str() == "_" => {
399 Some(PatternValuePlace::Placeholder)
400 }
401 crate::SpannedValue::PlainSymbol(ref x) => {
402 Variable::from_symbol(x).map(PatternValuePlace::Variable)
403 }
404 crate::SpannedValue::Keyword(ref x) if x.is_namespaced() => Some(x.clone().into()),
405 crate::SpannedValue::Boolean(x) => {
406 Some(PatternValuePlace::Constant(NonIntegerConstant::Boolean(x)))
407 }
408 crate::SpannedValue::Float(x) => {
409 Some(PatternValuePlace::Constant(NonIntegerConstant::Float(x)))
410 }
411 crate::SpannedValue::BigInteger(ref x) => Some(PatternValuePlace::Constant(
412 NonIntegerConstant::BigInteger(x.clone()),
413 )),
414 crate::SpannedValue::Instant(x) => {
415 Some(PatternValuePlace::Constant(NonIntegerConstant::Instant(x)))
416 }
417 crate::SpannedValue::Text(ref x) =>
418 {
420 Some(PatternValuePlace::Constant(x.clone().into()))
421 }
422 crate::SpannedValue::Uuid(ref u) => {
423 Some(PatternValuePlace::Constant(NonIntegerConstant::Uuid(*u)))
424 }
425
426 crate::SpannedValue::Nil => None,
429 crate::SpannedValue::NamespacedSymbol(_) => None,
430 crate::SpannedValue::Keyword(ref x) => Some(x.clone().into()),
431 crate::SpannedValue::Map(_) => None,
432 crate::SpannedValue::List(_) => None,
433 crate::SpannedValue::Set(_) => None,
434 crate::SpannedValue::Vector(_) => None,
435 }
436 }
437}
438
439impl PatternValuePlace {
440 #[allow(dead_code)]
442 fn into_pattern_non_value_place(self) -> Option<PatternNonValuePlace> {
443 match self {
444 PatternValuePlace::Placeholder => Some(PatternNonValuePlace::Placeholder),
445 PatternValuePlace::Variable(x) => Some(PatternNonValuePlace::Variable(x)),
446 PatternValuePlace::EntidOrInteger(x) => {
447 if x >= 0 {
448 Some(PatternNonValuePlace::Entid(x))
449 } else {
450 None
451 }
452 }
453 PatternValuePlace::IdentOrKeyword(x) => Some(PatternNonValuePlace::Ident(x)),
454 PatternValuePlace::Constant(_) => None,
455 }
456 }
457
458 fn to_pattern_non_value_place(&self) -> Option<PatternNonValuePlace> {
459 match *self {
460 PatternValuePlace::Placeholder => Some(PatternNonValuePlace::Placeholder),
461 PatternValuePlace::Variable(ref x) => Some(PatternNonValuePlace::Variable(x.clone())),
462 PatternValuePlace::EntidOrInteger(x) => {
463 if x >= 0 {
464 Some(PatternNonValuePlace::Entid(x))
465 } else {
466 None
467 }
468 }
469 PatternValuePlace::IdentOrKeyword(ref x) => {
470 Some(PatternNonValuePlace::Ident(x.clone()))
471 }
472 PatternValuePlace::Constant(_) => None,
473 }
474 }
475}
476
477#[derive(Clone, Debug, Eq, PartialEq)]
485pub enum PullConcreteAttribute {
486 Ident(Arc<Keyword>),
487 Entid(i64),
488}
489
490#[derive(Clone, Debug, Eq, PartialEq)]
491pub struct NamedPullAttribute {
492 pub attribute: PullConcreteAttribute,
493 pub alias: Option<Arc<Keyword>>,
494}
495
496impl From<PullConcreteAttribute> for NamedPullAttribute {
497 fn from(a: PullConcreteAttribute) -> Self {
498 NamedPullAttribute {
499 attribute: a,
500 alias: None,
501 }
502 }
503}
504
505#[derive(Clone, Debug, Eq, PartialEq)]
506pub enum PullAttributeSpec {
507 Wildcard,
508 Attribute(NamedPullAttribute),
509 }
513
514impl std::fmt::Display for PullConcreteAttribute {
515 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
516 match self {
517 PullConcreteAttribute::Ident(k) => {
518 write!(f, "{}", k)
519 }
520 &PullConcreteAttribute::Entid(i) => {
521 write!(f, "{}", i)
522 }
523 }
524 }
525}
526
527impl std::fmt::Display for NamedPullAttribute {
528 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
529 if let Some(alias) = &self.alias {
530 write!(f, "{} :as {}", self.attribute, alias)
531 } else {
532 write!(f, "{}", self.attribute)
533 }
534 }
535}
536
537impl std::fmt::Display for PullAttributeSpec {
538 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
539 match self {
540 &PullAttributeSpec::Wildcard => {
541 write!(f, "*")
542 }
543 PullAttributeSpec::Attribute(attr) => {
544 write!(f, "{}", attr)
545 }
546 }
547 }
548}
549
550#[derive(Clone, Debug, Eq, PartialEq)]
551pub struct Pull {
552 pub var: Variable,
553 pub patterns: Vec<PullAttributeSpec>,
554}
555
556#[derive(Clone, Debug, Eq, PartialEq)]
557pub struct Aggregate {
558 pub func: QueryFunction,
559 pub args: Vec<FnArg>,
560}
561
562#[derive(Clone, Debug, Eq, PartialEq)]
563pub enum Element {
564 Variable(Variable),
565 Aggregate(Aggregate),
566
567 Corresponding(Variable),
573 Pull(Pull),
574}
575
576impl Element {
577 pub fn is_unit(&self) -> bool {
579 match *self {
580 Element::Variable(_) => false,
581 Element::Pull(_) => false,
582 Element::Aggregate(_) => true,
583 Element::Corresponding(_) => true,
584 }
585 }
586}
587
588impl From<Variable> for Element {
589 fn from(x: Variable) -> Element {
590 Element::Variable(x)
591 }
592}
593
594impl std::fmt::Display for Element {
595 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
596 match self {
597 Element::Variable(var) => {
598 write!(f, "{}", var)
599 }
600 &Element::Pull(Pull {
601 ref var,
602 ref patterns,
603 }) => {
604 write!(f, "(pull {} [ ", var)?;
605 for p in patterns.iter() {
606 write!(f, "{} ", p)?;
607 }
608 write!(f, "])")
609 }
610 Element::Aggregate(agg) => match agg.args.len() {
611 0 => write!(f, "({})", agg.func),
612 1 => write!(f, "({} {})", agg.func, agg.args[0]),
613 _ => write!(f, "({} {:?})", agg.func, agg.args),
614 },
615 Element::Corresponding(var) => {
616 write!(f, "(the {})", var)
617 }
618 }
619 }
620}
621
622#[derive(Clone, Debug, Eq, PartialEq)]
623pub enum Limit {
624 None,
625 Fixed(u64),
626 Variable(Variable),
627}
628
629#[derive(Clone, Debug, Eq, PartialEq)]
657pub enum FindSpec {
658 FindRel(Vec<Element>),
660
661 FindColl(Element),
665
666 FindTuple(Vec<Element>),
669
670 FindScalar(Element),
673}
674
675impl FindSpec {
677 pub fn is_unit_limited(&self) -> bool {
678 use self::FindSpec::*;
679 match *self {
680 FindScalar(..) => true,
681 FindTuple(..) => true,
682 FindRel(..) => false,
683 FindColl(..) => false,
684 }
685 }
686
687 pub fn expected_column_count(&self) -> usize {
688 use self::FindSpec::*;
689 match self {
690 &FindScalar(..) => 1,
691 &FindColl(..) => 1,
692 &FindTuple(ref elems) | &FindRel(ref elems) => elems.len(),
693 }
694 }
695
696 pub fn requires_distinct(&self) -> bool {
715 !self.is_unit_limited()
716 }
717
718 pub fn columns<'s>(&'s self) -> Box<dyn Iterator<Item = &'s Element> + 's> {
719 use self::FindSpec::*;
720 match self {
721 FindScalar(e) => Box::new(std::iter::once(e)),
722 FindColl(e) => Box::new(std::iter::once(e)),
723 FindTuple(v) => Box::new(v.iter()),
724 FindRel(v) => Box::new(v.iter()),
725 }
726 }
727}
728
729#[derive(Clone, Debug, Eq, Hash, PartialEq)]
732pub enum VariableOrPlaceholder {
733 Placeholder,
734 Variable(Variable),
735}
736
737impl VariableOrPlaceholder {
738 pub fn into_var(self) -> Option<Variable> {
739 match self {
740 VariableOrPlaceholder::Placeholder => None,
741 VariableOrPlaceholder::Variable(var) => Some(var),
742 }
743 }
744
745 pub fn var(&self) -> Option<&Variable> {
746 match self {
747 &VariableOrPlaceholder::Placeholder => None,
748 VariableOrPlaceholder::Variable(var) => Some(var),
749 }
750 }
751}
752
753#[derive(Clone, Debug, Eq, PartialEq)]
754pub enum Binding {
755 BindScalar(Variable),
756 BindColl(Variable),
757 BindRel(Vec<VariableOrPlaceholder>),
758 BindTuple(Vec<VariableOrPlaceholder>),
759}
760
761impl Binding {
762 pub fn variables(&self) -> Vec<Option<Variable>> {
764 match self {
765 &Binding::BindScalar(ref var) | &Binding::BindColl(ref var) => vec![Some(var.clone())],
766 &Binding::BindRel(ref vars) | &Binding::BindTuple(ref vars) => {
767 vars.iter().map(|x| x.var().cloned()).collect()
768 }
769 }
770 }
771
772 pub fn is_empty(&self) -> bool {
774 match self {
775 &Binding::BindScalar(_) | &Binding::BindColl(_) => false,
776 &Binding::BindRel(ref vars) | &Binding::BindTuple(ref vars) => {
777 vars.iter().all(|x| x.var().is_none())
778 }
779 }
780 }
781
782 pub fn is_valid(&self) -> bool {
801 match self {
802 &Binding::BindScalar(_) | &Binding::BindColl(_) => true,
803 &Binding::BindRel(ref vars) | &Binding::BindTuple(ref vars) => {
804 let mut acc = HashSet::<Variable>::new();
805 for var in vars {
806 if let VariableOrPlaceholder::Variable(var) = var {
807 if !acc.insert(var.clone()) {
808 return false;
811 }
812 }
813 }
814 !acc.is_empty()
816 }
817 }
818 }
819}
820
821#[derive(Clone, Debug, Eq, PartialEq)]
826pub struct Pattern {
827 pub source: Option<SrcVar>,
828 pub entity: PatternNonValuePlace,
829 pub attribute: PatternNonValuePlace,
830 pub value: PatternValuePlace,
831 pub tx: PatternNonValuePlace,
832}
833
834impl Pattern {
835 pub fn simple(
836 e: PatternNonValuePlace,
837 a: PatternNonValuePlace,
838 v: PatternValuePlace,
839 ) -> Option<Pattern> {
840 Pattern::new(None, e, a, v, PatternNonValuePlace::Placeholder)
841 }
842
843 pub fn new(
844 src: Option<SrcVar>,
845 e: PatternNonValuePlace,
846 a: PatternNonValuePlace,
847 v: PatternValuePlace,
848 tx: PatternNonValuePlace,
849 ) -> Option<Pattern> {
850 let aa = a.clone(); if let PatternNonValuePlace::Ident(ref k) = aa {
852 if k.is_backward() {
853 let e_v = e.to_pattern_value_place();
857 if let Some(v_e) = v.to_pattern_non_value_place() {
858 return Some(Pattern {
859 source: src,
860 entity: v_e,
861 attribute: k.to_reversed().into(),
862 value: e_v,
863 tx,
864 });
865 } else {
866 return None;
867 }
868 }
869 }
870 Some(Pattern {
871 source: src,
872 entity: e,
873 attribute: a,
874 value: v,
875 tx,
876 })
877 }
878}
879
880#[derive(Clone, Debug, Eq, PartialEq)]
881pub struct Predicate {
882 pub expr: FnArg, }
884
885#[derive(Clone, Debug, Eq, PartialEq)]
886pub struct WhereFn {
887 pub expr: FnArg, pub binding: Binding,
889}
890
891#[derive(Clone, Debug, Eq, PartialEq)]
892pub enum UnifyVars {
893 Implicit,
907
908 Explicit(BTreeSet<Variable>),
918}
919
920impl WhereClause {
921 pub fn is_pattern(&self) -> bool {
922 matches!(self, WhereClause::Pattern(_))
923 }
924}
925
926#[derive(Clone, Debug, Eq, PartialEq)]
927pub enum OrWhereClause {
928 Clause(WhereClause),
929 And(Vec<WhereClause>),
930}
931
932impl OrWhereClause {
933 pub fn is_pattern_or_patterns(&self) -> bool {
934 match self {
935 &OrWhereClause::Clause(WhereClause::Pattern(_)) => true,
936 OrWhereClause::And(clauses) => clauses.iter().all(|clause| clause.is_pattern()),
937 _ => false,
938 }
939 }
940}
941
942#[derive(Clone, Debug, Eq, PartialEq)]
943pub struct OrJoin {
944 pub unify_vars: UnifyVars,
945 pub clauses: Vec<OrWhereClause>,
946
947 mentioned_vars: Option<BTreeSet<Variable>>,
949}
950
951#[derive(Clone, Debug, Eq, PartialEq)]
952pub struct NotJoin {
953 pub unify_vars: UnifyVars,
954 pub clauses: Vec<WhereClause>,
955}
956
957impl NotJoin {
958 pub fn new(unify_vars: UnifyVars, clauses: Vec<WhereClause>) -> NotJoin {
959 NotJoin {
960 unify_vars,
961 clauses,
962 }
963 }
964}
965
966#[derive(Clone, Debug, Eq, PartialEq)]
967pub struct TypeAnnotation {
968 pub value_type: Keyword,
969 pub variable: Variable,
970}
971
972#[allow(dead_code)]
973#[derive(Clone, Debug, Eq, PartialEq)]
974pub enum WhereClause {
975 NotJoin(NotJoin),
976 OrJoin(OrJoin),
977 Pred(Predicate),
978 WhereFn(WhereFn),
979 RuleExpr,
980 Pattern(Pattern),
981 TypeAnnotation(TypeAnnotation),
982}
983
984#[allow(dead_code)]
985#[derive(Clone, Debug, Eq, PartialEq)]
986pub struct ParsedQuery {
987 pub find_spec: FindSpec,
988 pub default_source: SrcVar,
989 pub with: Vec<Variable>,
990 pub in_bindings: Vec<Binding>,
991 pub in_sources: BTreeSet<SrcVar>,
992 pub limit: Limit,
993 pub where_clauses: Vec<WhereClause>,
994 pub order: Option<Vec<Order>>,
995}
996
997pub(crate) enum QueryPart {
998 FindSpec(FindSpec),
999 WithVars(Vec<Variable>),
1000 InBindings(Vec<Binding>),
1001 Limit(Limit),
1002 WhereClauses(Vec<WhereClause>),
1003 Order(Vec<Order>),
1004}
1005
1006impl ParsedQuery {
1013 pub fn in_vars(&self) -> Vec<Variable> {
1015 self.in_bindings
1016 .iter()
1017 .flat_map(|b| b.variables().into_iter().flatten())
1018 .collect()
1019 }
1020
1021 pub(crate) fn from_parts(
1022 parts: Vec<QueryPart>,
1023 ) -> std::result::Result<ParsedQuery, &'static str> {
1024 let mut find_spec: Option<FindSpec> = None;
1025 let mut with: Option<Vec<Variable>> = None;
1026 let mut in_bindings: Option<Vec<Binding>> = None;
1027 let mut limit: Option<Limit> = None;
1028 let mut where_clauses: Option<Vec<WhereClause>> = None;
1029 let mut order: Option<Vec<Order>> = None;
1030
1031 for part in parts.into_iter() {
1032 match part {
1033 QueryPart::FindSpec(x) => {
1034 if find_spec.is_some() {
1035 return Err("find query has repeated :find");
1036 }
1037 find_spec = Some(x)
1038 }
1039 QueryPart::WithVars(x) => {
1040 if with.is_some() {
1041 return Err("find query has repeated :with");
1042 }
1043 with = Some(x)
1044 }
1045 QueryPart::InBindings(x) => {
1046 if in_bindings.is_some() {
1047 return Err("find query has repeated :in");
1048 }
1049 in_bindings = Some(x)
1050 }
1051 QueryPart::Limit(x) => {
1052 if limit.is_some() {
1053 return Err("find query has repeated :limit");
1054 }
1055 limit = Some(x)
1056 }
1057 QueryPart::WhereClauses(x) => {
1058 if where_clauses.is_some() {
1059 return Err("find query has repeated :where");
1060 }
1061 where_clauses = Some(x)
1062 }
1063 QueryPart::Order(x) => {
1064 if order.is_some() {
1065 return Err("find query has repeated :order");
1066 }
1067 order = Some(x)
1068 }
1069 }
1070 }
1071
1072 Ok(ParsedQuery {
1073 find_spec: find_spec.ok_or("expected :find")?,
1074 default_source: SrcVar::DefaultSrc,
1075 with: with.unwrap_or(vec![]),
1076 in_bindings: in_bindings.unwrap_or(vec![]),
1077 in_sources: BTreeSet::default(),
1078 limit: limit.unwrap_or(Limit::None),
1079 where_clauses: where_clauses.ok_or("expected :where")?,
1080 order,
1081 })
1082 }
1083}
1084
1085impl OrJoin {
1086 pub fn new(unify_vars: UnifyVars, clauses: Vec<OrWhereClause>) -> OrJoin {
1087 OrJoin {
1088 unify_vars,
1089 clauses,
1090 mentioned_vars: None,
1091 }
1092 }
1093
1094 pub fn is_fully_unified(&self) -> bool {
1097 match &self.unify_vars {
1098 &UnifyVars::Implicit => true,
1099 UnifyVars::Explicit(vars) => {
1100 if let Some(ref mentioned) = self.mentioned_vars {
1106 vars.len() == mentioned.len()
1107 } else {
1108 vars.len() == self.collect_mentioned_variables().len()
1109 }
1110 }
1111 }
1112 }
1113}
1114
1115pub trait ContainsVariables {
1116 fn accumulate_mentioned_variables(&self, acc: &mut BTreeSet<Variable>);
1117 fn collect_mentioned_variables(&self) -> BTreeSet<Variable> {
1118 let mut out = BTreeSet::new();
1119 self.accumulate_mentioned_variables(&mut out);
1120 out
1121 }
1122}
1123
1124impl ContainsVariables for WhereClause {
1125 fn accumulate_mentioned_variables(&self, acc: &mut BTreeSet<Variable>) {
1126 use self::WhereClause::*;
1127 match self {
1128 OrJoin(o) => o.accumulate_mentioned_variables(acc),
1129 Pred(p) => p.accumulate_mentioned_variables(acc),
1130 Pattern(p) => p.accumulate_mentioned_variables(acc),
1131 NotJoin(n) => n.accumulate_mentioned_variables(acc),
1132 WhereFn(f) => f.accumulate_mentioned_variables(acc),
1133 TypeAnnotation(a) => a.accumulate_mentioned_variables(acc),
1134 &RuleExpr => (),
1135 }
1136 }
1137}
1138
1139impl ContainsVariables for OrWhereClause {
1140 fn accumulate_mentioned_variables(&self, acc: &mut BTreeSet<Variable>) {
1141 use self::OrWhereClause::*;
1142 match self {
1143 And(clauses) => {
1144 for clause in clauses {
1145 clause.accumulate_mentioned_variables(acc)
1146 }
1147 }
1148 Clause(clause) => clause.accumulate_mentioned_variables(acc),
1149 }
1150 }
1151}
1152
1153impl ContainsVariables for OrJoin {
1154 fn accumulate_mentioned_variables(&self, acc: &mut BTreeSet<Variable>) {
1155 for clause in &self.clauses {
1156 clause.accumulate_mentioned_variables(acc);
1157 }
1158 }
1159}
1160
1161impl OrJoin {
1162 pub fn dismember(self) -> (Vec<OrWhereClause>, UnifyVars, BTreeSet<Variable>) {
1163 let vars = match self.mentioned_vars {
1164 Some(m) => m,
1165 None => self.collect_mentioned_variables(),
1166 };
1167 (self.clauses, self.unify_vars, vars)
1168 }
1169
1170 pub fn mentioned_variables(&mut self) -> &BTreeSet<Variable> {
1171 if self.mentioned_vars.is_none() {
1172 let m = self.collect_mentioned_variables();
1173 self.mentioned_vars = Some(m);
1174 }
1175
1176 if let Some(ref mentioned) = self.mentioned_vars {
1177 mentioned
1178 } else {
1179 unreachable!()
1180 }
1181 }
1182}
1183
1184impl ContainsVariables for NotJoin {
1185 fn accumulate_mentioned_variables(&self, acc: &mut BTreeSet<Variable>) {
1186 for clause in &self.clauses {
1187 clause.accumulate_mentioned_variables(acc);
1188 }
1189 }
1190}
1191
1192fn accumulate_fn_arg_variables(arg: &FnArg, acc: &mut BTreeSet<Variable>) {
1193 match arg {
1194 FnArg::Variable(v) => acc_ref(acc, v),
1195 FnArg::SExpr(_, args) => {
1196 for a in args {
1197 accumulate_fn_arg_variables(a, acc);
1198 }
1199 }
1200 _ => {}
1201 }
1202}
1203
1204impl ContainsVariables for Predicate {
1205 fn accumulate_mentioned_variables(&self, acc: &mut BTreeSet<Variable>) {
1206 accumulate_fn_arg_variables(&self.expr, acc);
1207 }
1208}
1209
1210impl ContainsVariables for TypeAnnotation {
1211 fn accumulate_mentioned_variables(&self, acc: &mut BTreeSet<Variable>) {
1212 acc_ref(acc, &self.variable);
1213 }
1214}
1215
1216impl ContainsVariables for Binding {
1217 fn accumulate_mentioned_variables(&self, acc: &mut BTreeSet<Variable>) {
1218 match self {
1219 &Binding::BindScalar(ref v) | &Binding::BindColl(ref v) => acc_ref(acc, v),
1220 &Binding::BindRel(ref vs) | &Binding::BindTuple(ref vs) => {
1221 for v in vs {
1222 if let VariableOrPlaceholder::Variable(v) = v {
1223 acc_ref(acc, v);
1224 }
1225 }
1226 }
1227 }
1228 }
1229}
1230
1231impl ContainsVariables for WhereFn {
1232 fn accumulate_mentioned_variables(&self, acc: &mut BTreeSet<Variable>) {
1233 accumulate_fn_arg_variables(&self.expr, acc);
1234 self.binding.accumulate_mentioned_variables(acc);
1235 }
1236}
1237
1238fn acc_ref<T: Clone + Ord>(acc: &mut BTreeSet<T>, v: &T) {
1239 if !acc.contains(v) {
1241 acc.insert(v.clone());
1242 }
1243}
1244
1245impl ContainsVariables for Pattern {
1246 fn accumulate_mentioned_variables(&self, acc: &mut BTreeSet<Variable>) {
1247 if let PatternNonValuePlace::Variable(ref v) = self.entity {
1248 acc_ref(acc, v)
1249 }
1250 if let PatternNonValuePlace::Variable(ref v) = self.attribute {
1251 acc_ref(acc, v)
1252 }
1253 if let PatternValuePlace::Variable(ref v) = self.value {
1254 acc_ref(acc, v)
1255 }
1256 if let PatternNonValuePlace::Variable(ref v) = self.tx {
1257 acc_ref(acc, v)
1258 }
1259 }
1260}
1261
1262impl std::fmt::Display for NonIntegerConstant {
1267 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
1268 use chrono::SecondsFormat;
1269 match self {
1270 NonIntegerConstant::Boolean(v) => write!(f, "{}", v),
1271 NonIntegerConstant::BigInteger(ref v) => write!(f, "{}N", v),
1272 NonIntegerConstant::Float(ref v) => {
1273 if *v == OrderedFloat(f64::INFINITY) {
1274 write!(f, "#f +Infinity")
1275 } else if *v == OrderedFloat(f64::NEG_INFINITY) {
1276 write!(f, "#f -Infinity")
1277 } else if v.is_nan() {
1278 write!(f, "#f NaN")
1279 } else if v.fract() == 0.0 {
1280 write!(f, "{:.1}", v)
1281 } else {
1282 write!(f, "{}", v)
1283 }
1284 }
1285 NonIntegerConstant::Text(ref v) => {
1286 write!(f, "\"")?;
1287 for c in v.chars() {
1288 match c {
1289 '"' => write!(f, "\\\"")?,
1290 '\\' => write!(f, "\\\\")?,
1291 '\n' => write!(f, "\\n")?,
1292 '\r' => write!(f, "\\r")?,
1293 '\t' => write!(f, "\\t")?,
1294 c => write!(f, "{}", c)?,
1295 }
1296 }
1297 write!(f, "\"")
1298 }
1299 NonIntegerConstant::Instant(v) => write!(
1300 f,
1301 "#inst \"{}\"",
1302 v.to_rfc3339_opts(SecondsFormat::AutoSi, true)
1303 ),
1304 NonIntegerConstant::Uuid(ref u) => write!(f, "#uuid \"{}\"", u.hyphenated()),
1305 }
1306 }
1307}
1308
1309impl std::fmt::Display for PatternNonValuePlace {
1310 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
1311 match self {
1312 PatternNonValuePlace::Placeholder => write!(f, "_"),
1313 PatternNonValuePlace::Variable(ref v) => write!(f, "{}", v),
1314 PatternNonValuePlace::Entid(e) => write!(f, "{}", e),
1315 PatternNonValuePlace::Ident(ref k) => write!(f, "{}", k),
1316 }
1317 }
1318}
1319
1320impl std::fmt::Display for PatternValuePlace {
1321 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
1322 match self {
1323 PatternValuePlace::Placeholder => write!(f, "_"),
1324 PatternValuePlace::Variable(ref v) => write!(f, "{}", v),
1325 PatternValuePlace::EntidOrInteger(i) => write!(f, "{}", i),
1326 PatternValuePlace::IdentOrKeyword(ref k) => write!(f, "{}", k),
1327 PatternValuePlace::Constant(ref c) => write!(f, "{}", c),
1328 }
1329 }
1330}
1331
1332impl std::fmt::Display for Pattern {
1333 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
1334 write!(f, "[{} {} {}", self.entity, self.attribute, self.value)?;
1335 if !matches!(self.tx, PatternNonValuePlace::Placeholder) {
1336 write!(f, " {}", self.tx)?;
1337 }
1338 write!(f, "]")
1339 }
1340}
1341
1342impl std::fmt::Display for Predicate {
1343 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
1344 write!(f, "{}", self.expr)
1345 }
1346}
1347
1348impl std::fmt::Display for Binding {
1349 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
1350 match self {
1351 Binding::BindScalar(ref v) => write!(f, "{}", v),
1352 Binding::BindColl(ref v) => write!(f, "[{} ...]", v),
1353 Binding::BindTuple(ref vs) => {
1354 write!(f, "[")?;
1355 for (i, v) in vs.iter().enumerate() {
1356 if i > 0 {
1357 write!(f, " ")?;
1358 }
1359 match v {
1360 VariableOrPlaceholder::Variable(ref var) => write!(f, "{}", var)?,
1361 VariableOrPlaceholder::Placeholder => write!(f, "_")?,
1362 }
1363 }
1364 write!(f, "]")
1365 }
1366 Binding::BindRel(ref vs) => {
1367 write!(f, "[[")?;
1368 for (i, v) in vs.iter().enumerate() {
1369 if i > 0 {
1370 write!(f, " ")?;
1371 }
1372 match v {
1373 VariableOrPlaceholder::Variable(ref var) => write!(f, "{}", var)?,
1374 VariableOrPlaceholder::Placeholder => write!(f, "_")?,
1375 }
1376 }
1377 write!(f, "]]")
1378 }
1379 }
1380 }
1381}
1382
1383impl std::fmt::Display for WhereFn {
1384 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
1385 write!(f, "[{} {}]", self.expr, self.binding)
1386 }
1387}
1388
1389impl std::fmt::Display for WhereClause {
1390 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
1391 match self {
1392 WhereClause::Pattern(ref p) => write!(f, "{}", p),
1393 WhereClause::Pred(ref p) => write!(f, "[{}]", p),
1394 WhereClause::WhereFn(ref wf) => write!(f, "{}", wf),
1395 WhereClause::NotJoin(ref nj) => write!(f, "{}", nj),
1396 WhereClause::OrJoin(ref oj) => write!(f, "{}", oj),
1397 WhereClause::TypeAnnotation(ref ta) => {
1398 write!(f, "[(type {} {})]", ta.variable, ta.value_type)
1399 }
1400 WhereClause::RuleExpr => write!(f, "(rule-expr)"),
1401 }
1402 }
1403}
1404
1405impl std::fmt::Display for NotJoin {
1406 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
1407 match self.unify_vars {
1408 UnifyVars::Implicit => write!(f, "(not")?,
1409 UnifyVars::Explicit(ref vars) => {
1410 write!(f, "(not-join [")?;
1411 for (i, v) in vars.iter().enumerate() {
1412 if i > 0 {
1413 write!(f, " ")?;
1414 }
1415 write!(f, "{}", v)?;
1416 }
1417 write!(f, "]")?;
1418 }
1419 }
1420 for clause in &self.clauses {
1421 write!(f, " {}", clause)?;
1422 }
1423 write!(f, ")")
1424 }
1425}
1426
1427impl std::fmt::Display for OrWhereClause {
1428 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
1429 match self {
1430 OrWhereClause::Clause(ref c) => write!(f, "{}", c),
1431 OrWhereClause::And(ref clauses) => {
1432 write!(f, "(and")?;
1433 for c in clauses {
1434 write!(f, " {}", c)?;
1435 }
1436 write!(f, ")")
1437 }
1438 }
1439 }
1440}
1441
1442impl std::fmt::Display for OrJoin {
1443 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
1444 match self.unify_vars {
1445 UnifyVars::Implicit => write!(f, "(or")?,
1446 UnifyVars::Explicit(ref vars) => {
1447 write!(f, "(or-join [")?;
1448 for (i, v) in vars.iter().enumerate() {
1449 if i > 0 {
1450 write!(f, " ")?;
1451 }
1452 write!(f, "{}", v)?;
1453 }
1454 write!(f, "]")?;
1455 }
1456 }
1457 for clause in &self.clauses {
1458 write!(f, " {}", clause)?;
1459 }
1460 write!(f, ")")
1461 }
1462}
1463
1464impl std::fmt::Display for FindSpec {
1465 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
1466 match self {
1467 FindSpec::FindRel(ref elems) => {
1468 for (i, e) in elems.iter().enumerate() {
1469 if i > 0 {
1470 write!(f, " ")?;
1471 }
1472 write!(f, "{}", e)?;
1473 }
1474 Ok(())
1475 }
1476 FindSpec::FindColl(ref e) => write!(f, "[{} ...]", e),
1477 FindSpec::FindTuple(ref elems) => {
1478 write!(f, "[")?;
1479 for (i, e) in elems.iter().enumerate() {
1480 if i > 0 {
1481 write!(f, " ")?;
1482 }
1483 write!(f, "{}", e)?;
1484 }
1485 write!(f, "]")
1486 }
1487 FindSpec::FindScalar(ref e) => write!(f, "{} .", e),
1488 }
1489 }
1490}
1491
1492impl std::fmt::Display for Order {
1493 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
1494 match self.0 {
1495 Direction::Ascending => write!(f, "[{} :asc]", self.1),
1496 Direction::Descending => write!(f, "[{} :desc]", self.1),
1497 }
1498 }
1499}
1500
1501impl std::fmt::Display for Limit {
1502 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
1503 match self {
1504 Limit::None => Ok(()),
1505 Limit::Fixed(n) => write!(f, "{}", n),
1506 Limit::Variable(ref v) => write!(f, "{}", v),
1507 }
1508 }
1509}
1510
1511impl std::str::FromStr for ParsedQuery {
1512 type Err = peg::error::ParseError<peg::str::LineCol>;
1513
1514 fn from_str(s: &str) -> Result<Self, Self::Err> {
1515 crate::parse::parse_query(s)
1516 }
1517}
1518
1519impl std::fmt::Display for ParsedQuery {
1520 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
1521 write!(f, "{{:find [{}]", self.find_spec)?;
1522 if !self.with.is_empty() {
1523 write!(f, " :with [")?;
1524 for (i, v) in self.with.iter().enumerate() {
1525 if i > 0 {
1526 write!(f, " ")?;
1527 }
1528 write!(f, "{}", v)?;
1529 }
1530 write!(f, "]")?;
1531 }
1532 if !self.in_bindings.is_empty() {
1533 write!(f, " :in [")?;
1534 for (i, b) in self.in_bindings.iter().enumerate() {
1535 if i > 0 {
1536 write!(f, " ")?;
1537 }
1538 write!(f, "{}", b)?;
1539 }
1540 write!(f, "]")?;
1541 }
1542 write!(f, " :where [")?;
1543 for (i, c) in self.where_clauses.iter().enumerate() {
1544 if i > 0 {
1545 write!(f, " ")?;
1546 }
1547 write!(f, "{}", c)?;
1548 }
1549 write!(f, "]")?;
1550 if let Some(ref orders) = self.order {
1551 write!(f, " :order [")?;
1552 for (i, o) in orders.iter().enumerate() {
1553 if i > 0 {
1554 write!(f, " ")?;
1555 }
1556 write!(f, "{}", o)?;
1557 }
1558 write!(f, "]")?;
1559 }
1560 if let Limit::Fixed(_) | Limit::Variable(_) = self.limit {
1561 write!(f, " :limit {}", self.limit)?;
1562 }
1563 write!(f, "}}")
1564 }
1565}