1use std::collections::{BTreeSet, HashSet};
33
34use std;
35use std::fmt;
36use std::rc::Rc;
37
38use crate::{BigInt, DateTime, OrderedFloat, Utc, Uuid};
39
40use crate::value_rc::{FromRc, ValueRc};
41
42pub use crate::{Keyword, PlainSymbol};
43
44pub type SrcVarName = String; #[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
47pub struct Variable(pub Rc<PlainSymbol>);
48
49impl Variable {
50 pub fn as_str(&self) -> &str {
51 self.0.as_ref().0.as_str()
52 }
53
54 pub fn name(&self) -> PlainSymbol {
55 self.0.as_ref().clone()
56 }
57
58 pub fn from_valid_name(name: &str) -> Variable {
60 let s = PlainSymbol::plain(name);
61 assert!(s.is_var_symbol());
62 Variable(Rc::new(s))
63 }
64}
65
66pub trait FromValue<T> {
67 fn from_value(v: &crate::ValueAndSpan) -> Option<T>;
68}
69
70impl FromValue<Variable> for Variable {
74 fn from_value(v: &crate::ValueAndSpan) -> Option<Variable> {
75 if let crate::SpannedValue::PlainSymbol(ref s) = v.inner {
76 Variable::from_symbol(s)
77 } else {
78 None
79 }
80 }
81}
82
83impl Variable {
84 pub fn from_rc(sym: Rc<PlainSymbol>) -> Option<Variable> {
85 if sym.is_var_symbol() {
86 Some(Variable(sym))
87 } else {
88 None
89 }
90 }
91
92 pub fn from_symbol(sym: &PlainSymbol) -> Option<Variable> {
94 if sym.is_var_symbol() {
95 Some(Variable(Rc::new(sym.clone())))
96 } else {
97 None
98 }
99 }
100}
101
102impl fmt::Debug for Variable {
103 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
104 write!(f, "var({})", self.0)
105 }
106}
107
108impl std::fmt::Display for Variable {
109 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
110 write!(f, "{}", self.0)
111 }
112}
113
114#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
115pub struct QueryFunction(pub PlainSymbol);
116
117impl FromValue<QueryFunction> for QueryFunction {
118 fn from_value(v: &crate::ValueAndSpan) -> Option<QueryFunction> {
119 if let crate::SpannedValue::PlainSymbol(ref s) = v.inner {
120 QueryFunction::from_symbol(s)
121 } else {
122 None
123 }
124 }
125}
126
127impl QueryFunction {
128 pub fn from_symbol(sym: &PlainSymbol) -> Option<QueryFunction> {
129 Some(QueryFunction(sym.clone()))
131 }
132}
133
134impl std::fmt::Display for QueryFunction {
135 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
136 write!(f, "{}", self.0)
137 }
138}
139
140#[derive(Clone, Debug, Eq, PartialEq)]
141pub enum Direction {
142 Ascending,
143 Descending,
144}
145
146#[derive(Clone, Debug, Eq, PartialEq)]
148pub struct Order(pub Direction, pub Variable); #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
151pub enum SrcVar {
152 DefaultSrc,
153 NamedSrc(SrcVarName),
154}
155
156impl FromValue<SrcVar> for SrcVar {
157 fn from_value(v: &crate::ValueAndSpan) -> Option<SrcVar> {
158 if let crate::SpannedValue::PlainSymbol(ref s) = v.inner {
159 SrcVar::from_symbol(s)
160 } else {
161 None
162 }
163 }
164}
165
166impl SrcVar {
167 pub fn from_symbol(sym: &PlainSymbol) -> Option<SrcVar> {
168 if sym.is_src_symbol() {
169 if sym.0 == "$" {
170 Some(SrcVar::DefaultSrc)
171 } else {
172 Some(SrcVar::NamedSrc(sym.name().to_string()))
173 }
174 } else {
175 None
176 }
177 }
178}
179
180#[derive(Clone, Debug, Eq, PartialEq)]
182pub enum NonIntegerConstant {
183 Boolean(bool),
184 BigInteger(BigInt),
185 Float(OrderedFloat<f64>),
186 Text(ValueRc<String>),
187 Instant(DateTime<Utc>),
188 Uuid(Uuid),
189}
190
191impl<'a> From<&'a str> for NonIntegerConstant {
192 fn from(val: &'a str) -> NonIntegerConstant {
193 NonIntegerConstant::Text(ValueRc::new(val.to_string()))
194 }
195}
196
197impl From<String> for NonIntegerConstant {
198 fn from(val: String) -> NonIntegerConstant {
199 NonIntegerConstant::Text(ValueRc::new(val))
200 }
201}
202
203#[derive(Clone, Debug, Eq, PartialEq)]
204pub enum FnArg {
205 Variable(Variable),
206 SrcVar(SrcVar),
207 EntidOrInteger(i64),
208 IdentOrKeyword(Keyword),
209 Constant(NonIntegerConstant),
210 Vector(Vec<FnArg>),
213}
214
215impl FromValue<FnArg> for FnArg {
216 fn from_value(v: &crate::ValueAndSpan) -> Option<FnArg> {
217 use crate::SpannedValue::*;
218 match v.inner {
219 Integer(x) => Some(FnArg::EntidOrInteger(x)),
220 PlainSymbol(ref x) if x.is_src_symbol() => SrcVar::from_symbol(x).map(FnArg::SrcVar),
221 PlainSymbol(ref x) if x.is_var_symbol() => {
222 Variable::from_symbol(x).map(FnArg::Variable)
223 }
224 PlainSymbol(_) => None,
225 Keyword(ref x) => Some(FnArg::IdentOrKeyword(x.clone())),
226 Instant(x) => Some(FnArg::Constant(NonIntegerConstant::Instant(x))),
227 Uuid(x) => Some(FnArg::Constant(NonIntegerConstant::Uuid(x))),
228 Boolean(x) => Some(FnArg::Constant(NonIntegerConstant::Boolean(x))),
229 Float(x) => Some(FnArg::Constant(NonIntegerConstant::Float(x))),
230 BigInteger(ref x) => Some(FnArg::Constant(NonIntegerConstant::BigInteger(x.clone()))),
231 Text(ref x) =>
232 {
234 Some(FnArg::Constant(x.clone().into()))
235 }
236 Nil | NamespacedSymbol(_) | Vector(_) | List(_) | Set(_) | Map(_) | Bytes(_) => None,
237 }
238 }
239}
240
241impl std::fmt::Display for FnArg {
243 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
244 match self {
245 FnArg::Variable(ref var) => write!(f, "{}", var),
246 FnArg::SrcVar(ref var) => {
247 if var == &SrcVar::DefaultSrc {
248 write!(f, "$")
249 } else {
250 write!(f, "{:?}", var)
251 }
252 }
253 FnArg::EntidOrInteger(entid) => write!(f, "{}", entid),
254 FnArg::IdentOrKeyword(ref kw) => write!(f, "{}", kw),
255 FnArg::Constant(ref constant) => write!(f, "{:?}", constant),
256 FnArg::Vector(ref vec) => write!(f, "{:?}", vec),
257 }
258 }
259}
260
261impl FnArg {
262 pub fn as_variable(&self) -> Option<&Variable> {
263 match self {
264 FnArg::Variable(ref v) => Some(v),
265 _ => None,
266 }
267 }
268}
269
270#[derive(Clone, Debug, Eq, PartialEq)]
277pub enum PatternNonValuePlace {
278 Placeholder,
279 Variable(Variable),
280 Entid(i64), Ident(ValueRc<Keyword>),
282}
283
284impl From<Rc<Keyword>> for PatternNonValuePlace {
285 fn from(value: Rc<Keyword>) -> Self {
286 PatternNonValuePlace::Ident(ValueRc::from_rc(value))
287 }
288}
289
290impl From<Keyword> for PatternNonValuePlace {
291 fn from(value: Keyword) -> Self {
292 PatternNonValuePlace::Ident(ValueRc::new(value))
293 }
294}
295
296impl PatternNonValuePlace {
297 #[allow(dead_code)]
299 fn into_pattern_value_place(self) -> PatternValuePlace {
300 match self {
301 PatternNonValuePlace::Placeholder => PatternValuePlace::Placeholder,
302 PatternNonValuePlace::Variable(x) => PatternValuePlace::Variable(x),
303 PatternNonValuePlace::Entid(x) => PatternValuePlace::EntidOrInteger(x),
304 PatternNonValuePlace::Ident(x) => PatternValuePlace::IdentOrKeyword(x),
305 }
306 }
307
308 fn to_pattern_value_place(&self) -> PatternValuePlace {
309 match *self {
310 PatternNonValuePlace::Placeholder => PatternValuePlace::Placeholder,
311 PatternNonValuePlace::Variable(ref x) => PatternValuePlace::Variable(x.clone()),
312 PatternNonValuePlace::Entid(x) => PatternValuePlace::EntidOrInteger(x),
313 PatternNonValuePlace::Ident(ref x) => PatternValuePlace::IdentOrKeyword(x.clone()),
314 }
315 }
316}
317
318impl FromValue<PatternNonValuePlace> for PatternNonValuePlace {
319 fn from_value(v: &crate::ValueAndSpan) -> Option<PatternNonValuePlace> {
320 match v.inner {
321 crate::SpannedValue::Integer(x) => {
322 if x >= 0 {
323 Some(PatternNonValuePlace::Entid(x))
324 } else {
325 None
326 }
327 }
328 crate::SpannedValue::PlainSymbol(ref x) => {
329 if x.0.as_str() == "_" {
330 Some(PatternNonValuePlace::Placeholder)
331 } else {
332 Variable::from_symbol(x).map(PatternNonValuePlace::Variable)
333 }
334 }
335 crate::SpannedValue::Keyword(ref x) => Some(x.clone().into()),
336 _ => None,
337 }
338 }
339}
340
341#[derive(Clone, Debug, Eq, PartialEq)]
342pub enum IdentOrEntid {
343 Ident(Keyword),
344 Entid(i64),
345}
346
347#[derive(Clone, Debug, Eq, PartialEq)]
351pub enum PatternValuePlace {
352 Placeholder,
353 Variable(Variable),
354 EntidOrInteger(i64),
355 IdentOrKeyword(ValueRc<Keyword>),
356 Constant(NonIntegerConstant),
357}
358
359impl From<Rc<Keyword>> for PatternValuePlace {
360 fn from(value: Rc<Keyword>) -> Self {
361 PatternValuePlace::IdentOrKeyword(ValueRc::from_rc(value))
362 }
363}
364
365impl From<Keyword> for PatternValuePlace {
366 fn from(value: Keyword) -> Self {
367 PatternValuePlace::IdentOrKeyword(ValueRc::new(value))
368 }
369}
370
371impl FromValue<PatternValuePlace> for PatternValuePlace {
372 fn from_value(v: &crate::ValueAndSpan) -> Option<PatternValuePlace> {
373 match v.inner {
374 crate::SpannedValue::Integer(x) => Some(PatternValuePlace::EntidOrInteger(x)),
375 crate::SpannedValue::PlainSymbol(ref x) if x.0.as_str() == "_" => {
376 Some(PatternValuePlace::Placeholder)
377 }
378 crate::SpannedValue::PlainSymbol(ref x) => {
379 Variable::from_symbol(x).map(PatternValuePlace::Variable)
380 }
381 crate::SpannedValue::Keyword(ref x) => Some(x.clone().into()),
382 crate::SpannedValue::Boolean(x) => {
383 Some(PatternValuePlace::Constant(NonIntegerConstant::Boolean(x)))
384 }
385 crate::SpannedValue::Float(x) => {
386 Some(PatternValuePlace::Constant(NonIntegerConstant::Float(x)))
387 }
388 crate::SpannedValue::BigInteger(ref x) => Some(PatternValuePlace::Constant(
389 NonIntegerConstant::BigInteger(x.clone()),
390 )),
391 crate::SpannedValue::Instant(x) => {
392 Some(PatternValuePlace::Constant(NonIntegerConstant::Instant(x)))
393 }
394 crate::SpannedValue::Text(ref x) =>
395 {
397 Some(PatternValuePlace::Constant(x.clone().into()))
398 }
399 crate::SpannedValue::Uuid(ref u) => {
400 Some(PatternValuePlace::Constant(NonIntegerConstant::Uuid(*u)))
401 }
402
403 crate::SpannedValue::Nil => None,
405 crate::SpannedValue::NamespacedSymbol(_) => None,
406 crate::SpannedValue::Map(_) => None,
407 crate::SpannedValue::List(_) => None,
408 crate::SpannedValue::Set(_) => None,
409 crate::SpannedValue::Vector(_) => None,
410 crate::SpannedValue::Bytes(_) => None,
411 }
412 }
413}
414
415impl PatternValuePlace {
416 #[allow(dead_code)]
418 fn into_pattern_non_value_place(self) -> Option<PatternNonValuePlace> {
419 match self {
420 PatternValuePlace::Placeholder => Some(PatternNonValuePlace::Placeholder),
421 PatternValuePlace::Variable(x) => Some(PatternNonValuePlace::Variable(x)),
422 PatternValuePlace::EntidOrInteger(x) => {
423 if x >= 0 {
424 Some(PatternNonValuePlace::Entid(x))
425 } else {
426 None
427 }
428 }
429 PatternValuePlace::IdentOrKeyword(x) => Some(PatternNonValuePlace::Ident(x)),
430 PatternValuePlace::Constant(_) => None,
431 }
432 }
433
434 fn to_pattern_non_value_place(&self) -> Option<PatternNonValuePlace> {
435 match *self {
436 PatternValuePlace::Placeholder => Some(PatternNonValuePlace::Placeholder),
437 PatternValuePlace::Variable(ref x) => Some(PatternNonValuePlace::Variable(x.clone())),
438 PatternValuePlace::EntidOrInteger(x) => {
439 if x >= 0 {
440 Some(PatternNonValuePlace::Entid(x))
441 } else {
442 None
443 }
444 }
445 PatternValuePlace::IdentOrKeyword(ref x) => {
446 Some(PatternNonValuePlace::Ident(x.clone()))
447 }
448 PatternValuePlace::Constant(_) => None,
449 }
450 }
451}
452
453#[derive(Clone, Debug, Eq, PartialEq)]
461pub enum PullConcreteAttribute {
462 Ident(Rc<Keyword>),
463 Entid(i64),
464}
465
466#[derive(Clone, Debug, Eq, PartialEq)]
467pub struct NamedPullAttribute {
468 pub attribute: PullConcreteAttribute,
469 pub alias: Option<Rc<Keyword>>,
470 pub reverse: bool,
475}
476
477impl From<PullConcreteAttribute> for NamedPullAttribute {
478 fn from(a: PullConcreteAttribute) -> Self {
479 NamedPullAttribute {
480 attribute: a,
481 alias: None,
482 reverse: false,
483 }
484 }
485}
486
487#[derive(Clone, Debug, Eq, PartialEq)]
488pub enum PullAttributeSpec {
489 Wildcard,
490 Attribute(NamedPullAttribute),
491 Nested(NamedPullAttribute, Vec<PullAttributeSpec>),
495 }
498
499impl std::fmt::Display for PullConcreteAttribute {
500 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
501 match self {
502 PullConcreteAttribute::Ident(ref k) => write!(f, "{}", k),
503 PullConcreteAttribute::Entid(i) => write!(f, "{}", i),
504 }
505 }
506}
507
508impl std::fmt::Display for NamedPullAttribute {
509 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
510 match (&self.attribute, self.reverse) {
513 (PullConcreteAttribute::Ident(k), true) => write!(f, "{}", k.to_reversed())?,
514 (attr, true) => write!(f, "_{}", attr)?,
515 (attr, false) => write!(f, "{}", attr)?,
516 }
517 if let Some(ref alias) = self.alias {
518 write!(f, " :as {}", alias)?;
519 }
520 Ok(())
521 }
522}
523
524impl std::fmt::Display for PullAttributeSpec {
525 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
526 match self {
527 PullAttributeSpec::Wildcard => write!(f, "*"),
528 PullAttributeSpec::Attribute(ref attr) => write!(f, "{}", attr),
529 PullAttributeSpec::Nested(ref attr, ref patterns) => {
530 write!(f, "{{{} [", attr)?;
531 for (i, p) in patterns.iter().enumerate() {
532 if i > 0 {
533 write!(f, " ")?;
534 }
535 write!(f, "{}", p)?;
536 }
537 write!(f, "]}}")
538 }
539 }
540 }
541}
542
543#[derive(Clone, Debug, Eq, PartialEq)]
544pub struct Pull {
545 pub var: Variable,
546 pub patterns: Vec<PullAttributeSpec>,
547}
548
549#[derive(Clone, Debug, Eq, PartialEq)]
550pub struct Aggregate {
551 pub func: QueryFunction,
552 pub args: Vec<FnArg>,
553}
554
555#[derive(Clone, Debug, Eq, PartialEq)]
556pub enum Element {
557 Variable(Variable),
558 Aggregate(Aggregate),
559
560 Corresponding(Variable),
566 Pull(Pull),
567}
568
569impl Element {
570 pub fn is_unit(&self) -> bool {
572 match self {
573 Element::Variable(_) => false,
574 Element::Pull(_) => false,
575 Element::Aggregate(_) => true,
576 Element::Corresponding(_) => true,
577 }
578 }
579}
580
581impl From<Variable> for Element {
582 fn from(x: Variable) -> Element {
583 Element::Variable(x)
584 }
585}
586
587impl std::fmt::Display for Element {
588 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
589 match self {
590 Element::Variable(ref var) => write!(f, "{}", var),
591 Element::Pull(Pull {
592 ref var,
593 ref patterns,
594 }) => {
595 write!(f, "(pull {} [ ", var)?;
596 for p in patterns.iter() {
597 write!(f, "{} ", p)?;
598 }
599 write!(f, "])")
600 }
601 Element::Aggregate(ref agg) => match agg.args.len() {
602 0 => write!(f, "({})", agg.func),
603 1 => write!(f, "({} {})", agg.func, agg.args[0]),
604 _ => write!(f, "({} {:?})", agg.func, agg.args),
605 },
606 Element::Corresponding(ref var) => write!(f, "(the {})", var),
607 }
608 }
609}
610
611#[derive(Clone, Debug, Eq, PartialEq)]
612pub enum Limit {
613 Unlimited,
614 Fixed(u64),
615 Variable(Variable),
616}
617
618#[derive(Clone, Debug, Eq, PartialEq)]
621pub enum Offset {
622 Unlimited,
624 Fixed(u64),
625 Variable(Variable),
626}
627
628#[derive(Clone, Debug, Eq, PartialEq)]
651pub enum FindSpec {
652 FindRel(Vec<Element>),
654
655 FindColl(Element),
659
660 FindTuple(Vec<Element>),
663
664 FindScalar(Element),
667}
668
669impl FindSpec {
671 pub fn is_unit_limited(&self) -> bool {
672 use self::FindSpec::*;
673 match self {
674 FindScalar(..) => true,
675 FindTuple(..) => true,
676 FindRel(..) => false,
677 FindColl(..) => false,
678 }
679 }
680
681 pub fn expected_column_count(&self) -> usize {
682 use self::FindSpec::*;
683 match self {
684 FindScalar(..) => 1,
685 FindColl(..) => 1,
686 FindTuple(ref elems) | &FindRel(ref elems) => elems.len(),
687 }
688 }
689
690 pub fn requires_distinct(&self) -> bool {
709 !self.is_unit_limited()
710 }
711
712 pub fn columns<'s>(&'s self) -> Box<dyn Iterator<Item = &'s Element> + 's> {
713 use self::FindSpec::*;
714 match self {
715 FindScalar(ref e) => Box::new(std::iter::once(e)),
716 FindColl(ref e) => Box::new(std::iter::once(e)),
717 FindTuple(ref v) => Box::new(v.iter()),
718 FindRel(ref v) => Box::new(v.iter()),
719 }
720 }
721}
722
723#[derive(Clone, Debug, Eq, Hash, PartialEq)]
726pub enum VariableOrPlaceholder {
727 Placeholder,
728 Variable(Variable),
729}
730
731impl VariableOrPlaceholder {
732 pub fn into_var(self) -> Option<Variable> {
733 match self {
734 VariableOrPlaceholder::Placeholder => None,
735 VariableOrPlaceholder::Variable(var) => Some(var),
736 }
737 }
738
739 pub fn var(&self) -> Option<&Variable> {
740 match self {
741 VariableOrPlaceholder::Placeholder => None,
742 VariableOrPlaceholder::Variable(ref var) => Some(var),
743 }
744 }
745}
746
747#[derive(Clone, Debug, Eq, PartialEq)]
748pub enum Binding {
749 BindScalar(Variable),
750 BindColl(Variable),
751 BindRel(Vec<VariableOrPlaceholder>),
752 BindTuple(Vec<VariableOrPlaceholder>),
753}
754
755impl Binding {
756 pub fn variables(&self) -> Vec<Option<Variable>> {
758 match self {
759 &Binding::BindScalar(ref var) | &Binding::BindColl(ref var) => vec![Some(var.clone())],
760 &Binding::BindRel(ref vars) | &Binding::BindTuple(ref vars) => {
761 vars.iter().map(|x| x.var().cloned()).collect()
762 }
763 }
764 }
765
766 pub fn is_empty(&self) -> bool {
768 match self {
769 &Binding::BindScalar(_) | &Binding::BindColl(_) => false,
770 &Binding::BindRel(ref vars) | &Binding::BindTuple(ref vars) => {
771 vars.iter().all(|x| x.var().is_none())
772 }
773 }
774 }
775
776 pub fn is_valid(&self) -> bool {
795 match self {
796 Binding::BindScalar(_) | &Binding::BindColl(_) => true,
797 Binding::BindRel(ref vars) | &Binding::BindTuple(ref vars) => {
798 let mut acc = HashSet::<Variable>::new();
799 for var in vars {
800 if let VariableOrPlaceholder::Variable(ref var) = *var {
801 if !acc.insert(var.clone()) {
802 return false;
805 }
806 }
807 }
808 !acc.is_empty()
810 }
811 }
812 }
813}
814
815#[derive(Clone, Debug, Eq, PartialEq)]
820pub struct Pattern {
821 pub source: Option<SrcVar>,
822 pub entity: PatternNonValuePlace,
823 pub attribute: PatternNonValuePlace,
824 pub value: PatternValuePlace,
825 pub tx: PatternNonValuePlace,
826 pub added: PatternNonValuePlace,
829}
830
831impl Pattern {
832 pub fn simple(
833 e: PatternNonValuePlace,
834 a: PatternNonValuePlace,
835 v: PatternValuePlace,
836 ) -> Option<Pattern> {
837 Pattern::new(
838 None,
839 e,
840 a,
841 v,
842 PatternNonValuePlace::Placeholder,
843 PatternNonValuePlace::Placeholder,
844 )
845 }
846
847 pub fn new(
848 src: Option<SrcVar>,
849 e: PatternNonValuePlace,
850 a: PatternNonValuePlace,
851 v: PatternValuePlace,
852 tx: PatternNonValuePlace,
853 added: PatternNonValuePlace,
854 ) -> Option<Pattern> {
855 let aa = a.clone(); if let PatternNonValuePlace::Ident(ref k) = aa {
857 if k.is_backward() {
858 let e_v = e.to_pattern_value_place();
862 if let Some(v_e) = v.to_pattern_non_value_place() {
863 return Some(Pattern {
864 source: src,
865 entity: v_e,
866 attribute: k.to_reversed().into(),
867 value: e_v,
868 tx,
869 added,
870 });
871 } else {
872 return None;
873 }
874 }
875 }
876 Some(Pattern {
877 source: src,
878 entity: e,
879 attribute: a,
880 value: v,
881 tx,
882 added,
883 })
884 }
885}
886
887#[derive(Clone, Debug, Eq, PartialEq)]
888pub struct Predicate {
889 pub operator: PlainSymbol,
890 pub args: Vec<FnArg>,
891}
892
893#[derive(Clone, Debug, Eq, PartialEq)]
894pub struct WhereFn {
895 pub operator: PlainSymbol,
896 pub args: Vec<FnArg>,
897 pub binding: Binding,
898}
899
900#[derive(Clone, Debug, Eq, PartialEq)]
901pub enum UnifyVars {
902 Implicit,
916
917 Explicit(BTreeSet<Variable>),
927}
928
929impl WhereClause {
930 pub fn is_pattern(&self) -> bool {
931 matches!(self, WhereClause::Pattern(_))
932 }
933}
934
935#[derive(Clone, Debug, Eq, PartialEq)]
936pub enum OrWhereClause {
937 Clause(WhereClause),
938 And(Vec<WhereClause>),
939}
940
941impl OrWhereClause {
942 pub fn is_pattern_or_patterns(&self) -> bool {
943 match self {
944 OrWhereClause::Clause(WhereClause::Pattern(_)) => true,
945 OrWhereClause::And(ref clauses) => clauses.iter().all(|clause| clause.is_pattern()),
946 _ => false,
947 }
948 }
949}
950
951#[derive(Clone, Debug, Eq, PartialEq)]
952pub struct OrJoin {
953 pub unify_vars: UnifyVars,
954 pub clauses: Vec<OrWhereClause>,
955
956 mentioned_vars: Option<BTreeSet<Variable>>,
958}
959
960#[derive(Clone, Debug, Eq, PartialEq)]
961pub struct NotJoin {
962 pub unify_vars: UnifyVars,
963 pub clauses: Vec<WhereClause>,
964}
965
966impl NotJoin {
967 pub fn new(unify_vars: UnifyVars, clauses: Vec<WhereClause>) -> NotJoin {
968 NotJoin {
969 unify_vars,
970 clauses,
971 }
972 }
973}
974
975#[derive(Clone, Debug, Eq, PartialEq)]
976pub struct TypeAnnotation {
977 pub value_type: Keyword,
978 pub variable: Variable,
979}
980
981#[allow(dead_code)]
982#[derive(Clone, Debug, Eq, PartialEq)]
985pub struct RuleInvocation {
986 pub name: PlainSymbol,
987 pub args: Vec<FnArg>,
988}
989
990#[derive(Clone, Debug, Eq, PartialEq)]
994pub struct RuleClause {
995 pub head: RuleInvocation,
996 pub body: Vec<WhereClause>,
997}
998
999#[derive(Clone, Debug, Eq, PartialEq)]
1002pub struct Rule {
1003 pub name: PlainSymbol,
1004 pub clauses: Vec<RuleClause>,
1005}
1006
1007#[derive(Clone, Debug, Eq, PartialEq)]
1008pub enum WhereClause {
1009 NotJoin(NotJoin),
1010 OrJoin(OrJoin),
1011 Pred(Predicate),
1012 WhereFn(WhereFn),
1013 RuleExpr(RuleInvocation),
1014 Pattern(Pattern),
1015 TypeAnnotation(TypeAnnotation),
1016}
1017
1018#[allow(dead_code)]
1019#[derive(Debug, Eq, PartialEq)]
1020pub struct ParsedQuery {
1021 pub find_spec: FindSpec,
1022 pub default_source: SrcVar,
1023 pub with: Vec<Variable>,
1024 pub in_vars: Vec<Variable>,
1025 pub in_bindings: Vec<Binding>,
1026 pub in_sources: BTreeSet<SrcVar>,
1027 pub limit: Limit,
1028 pub offset: Offset,
1029 pub where_clauses: Vec<WhereClause>,
1030 pub order: Option<Vec<Order>>,
1031 pub distinct: bool,
1032 pub rules: Vec<Rule>,
1033}
1034
1035pub(crate) enum QueryPart {
1036 FindSpec(FindSpec),
1037 WithVars(Vec<Variable>),
1038 #[allow(dead_code)]
1039 InVars(Vec<Variable>),
1040 InBindings(Vec<Binding>),
1041 InSources(Vec<SrcVar>),
1046 Limit(Limit),
1047 Offset(Offset),
1048 WhereClauses(Vec<WhereClause>),
1049 Order(Vec<Order>),
1050 Distinct,
1051 Rules(Vec<Rule>),
1052}
1053impl ParsedQuery {
1060 pub(crate) fn from_parts(
1061 parts: Vec<QueryPart>,
1062 ) -> std::result::Result<ParsedQuery, &'static str> {
1063 let mut find_spec: Option<FindSpec> = None;
1064 let mut with: Option<Vec<Variable>> = None;
1065 let mut in_vars: Option<Vec<Variable>> = None;
1066 let mut in_bindings: Option<Vec<Binding>> = None;
1067 let mut in_sources: Option<Vec<SrcVar>> = None;
1068 let mut limit: Option<Limit> = None;
1069 let mut offset: Option<Offset> = None;
1070 let mut where_clauses: Option<Vec<WhereClause>> = None;
1071 let mut order: Option<Vec<Order>> = None;
1072 let mut distinct = false;
1073 let mut rules: Option<Vec<Rule>> = None;
1074
1075 for part in parts.into_iter() {
1076 match part {
1077 QueryPart::FindSpec(x) => {
1078 if find_spec.is_some() {
1079 return Err("find query has repeated :find");
1080 }
1081 find_spec = Some(x)
1082 }
1083 QueryPart::WithVars(x) => {
1084 if with.is_some() {
1085 return Err("find query has repeated :with");
1086 }
1087 with = Some(x)
1088 }
1089 QueryPart::InVars(x) => {
1090 if in_vars.is_some() {
1091 return Err("find query has repeated :in");
1092 }
1093 in_vars = Some(x)
1094 }
1095 QueryPart::InBindings(x) => {
1096 if in_bindings.is_some() {
1097 return Err("find query has repeated :in");
1098 }
1099 in_bindings = Some(x)
1100 }
1101 QueryPart::InSources(x) => {
1102 if in_sources.is_some() {
1103 return Err("find query has repeated :in");
1104 }
1105 in_sources = Some(x)
1106 }
1107 QueryPart::Limit(x) => {
1108 if limit.is_some() {
1109 return Err("find query has repeated :limit");
1110 }
1111 limit = Some(x)
1112 }
1113 QueryPart::Offset(x) => {
1114 if offset.is_some() {
1115 return Err("find query has repeated :offset");
1116 }
1117 offset = Some(x)
1118 }
1119 QueryPart::WhereClauses(x) => {
1120 if where_clauses.is_some() {
1121 return Err("find query has repeated :where");
1122 }
1123 where_clauses = Some(x)
1124 }
1125 QueryPart::Order(x) => {
1126 if order.is_some() {
1127 return Err("find query has repeated :order");
1128 }
1129 order = Some(x)
1130 }
1131 QueryPart::Distinct => {
1132 distinct = true;
1133 }
1134 QueryPart::Rules(x) => {
1135 if rules.is_some() {
1136 return Err("find query has repeated :rules");
1137 }
1138 rules = Some(x)
1139 }
1140 }
1141 }
1142
1143 let final_in_bindings = in_bindings.unwrap_or_default();
1146 let final_in_vars = if let Some(v) = in_vars {
1147 v
1148 } else {
1149 final_in_bindings
1150 .iter()
1151 .filter_map(|b| match b {
1152 Binding::BindScalar(v) => Some(v.clone()),
1153 _ => None,
1154 })
1155 .collect()
1156 };
1157
1158 Ok(ParsedQuery {
1159 find_spec: find_spec.ok_or("expected :find")?,
1160 default_source: SrcVar::DefaultSrc,
1161 with: with.unwrap_or_default(),
1162 in_vars: final_in_vars,
1163 in_bindings: final_in_bindings,
1164 in_sources: in_sources.unwrap_or_default().into_iter().collect(),
1165 limit: limit.unwrap_or(Limit::Unlimited),
1166 offset: offset.unwrap_or(Offset::Unlimited),
1167 where_clauses: where_clauses.ok_or("expected :where")?,
1168 order,
1169 distinct,
1170 rules: rules.unwrap_or_default(),
1171 })
1172 }
1173}
1174
1175impl OrJoin {
1176 pub fn new(unify_vars: UnifyVars, clauses: Vec<OrWhereClause>) -> OrJoin {
1177 OrJoin {
1178 unify_vars,
1179 clauses,
1180 mentioned_vars: None,
1181 }
1182 }
1183
1184 pub fn is_fully_unified(&self) -> bool {
1187 match &self.unify_vars {
1188 UnifyVars::Implicit => true,
1189 UnifyVars::Explicit(ref vars) => {
1190 if let Some(ref mentioned) = self.mentioned_vars {
1196 vars.len() == mentioned.len()
1197 } else {
1198 vars.len() == self.collect_mentioned_variables().len()
1199 }
1200 }
1201 }
1202 }
1203}
1204
1205pub trait ContainsVariables {
1206 fn accumulate_mentioned_variables(&self, acc: &mut BTreeSet<Variable>);
1207 fn collect_mentioned_variables(&self) -> BTreeSet<Variable> {
1208 let mut out = BTreeSet::new();
1209 self.accumulate_mentioned_variables(&mut out);
1210 out
1211 }
1212}
1213
1214impl ContainsVariables for WhereClause {
1215 fn accumulate_mentioned_variables(&self, acc: &mut BTreeSet<Variable>) {
1216 use self::WhereClause::*;
1217 match self {
1218 OrJoin(ref o) => o.accumulate_mentioned_variables(acc),
1219 Pred(ref p) => p.accumulate_mentioned_variables(acc),
1220 Pattern(ref p) => p.accumulate_mentioned_variables(acc),
1221 NotJoin(ref n) => n.accumulate_mentioned_variables(acc),
1222 WhereFn(ref f) => f.accumulate_mentioned_variables(acc),
1223 TypeAnnotation(ref a) => a.accumulate_mentioned_variables(acc),
1224 RuleExpr(ref invocation) => {
1225 for arg in &invocation.args {
1226 if let FnArg::Variable(ref var) = arg {
1227 acc.insert(var.clone());
1228 }
1229 }
1230 }
1231 }
1232 }
1233}
1234
1235impl ContainsVariables for OrWhereClause {
1236 fn accumulate_mentioned_variables(&self, acc: &mut BTreeSet<Variable>) {
1237 use self::OrWhereClause::*;
1238 match self {
1239 And(ref clauses) => {
1240 for clause in clauses {
1241 clause.accumulate_mentioned_variables(acc)
1242 }
1243 }
1244 Clause(ref clause) => clause.accumulate_mentioned_variables(acc),
1245 }
1246 }
1247}
1248
1249impl ContainsVariables for OrJoin {
1250 fn accumulate_mentioned_variables(&self, acc: &mut BTreeSet<Variable>) {
1251 for clause in &self.clauses {
1252 clause.accumulate_mentioned_variables(acc);
1253 }
1254 }
1255}
1256
1257impl OrJoin {
1258 pub fn dismember(self) -> (Vec<OrWhereClause>, UnifyVars, BTreeSet<Variable>) {
1259 let vars = match self.mentioned_vars {
1260 Some(m) => m,
1261 None => self.collect_mentioned_variables(),
1262 };
1263 (self.clauses, self.unify_vars, vars)
1264 }
1265
1266 pub fn mentioned_variables(&mut self) -> &BTreeSet<Variable> {
1267 if self.mentioned_vars.is_none() {
1268 let m = self.collect_mentioned_variables();
1269 self.mentioned_vars = Some(m);
1270 }
1271
1272 if let Some(ref mentioned) = self.mentioned_vars {
1273 mentioned
1274 } else {
1275 unreachable!()
1276 }
1277 }
1278}
1279
1280impl ContainsVariables for NotJoin {
1281 fn accumulate_mentioned_variables(&self, acc: &mut BTreeSet<Variable>) {
1282 for clause in &self.clauses {
1283 clause.accumulate_mentioned_variables(acc);
1284 }
1285 }
1286}
1287
1288impl ContainsVariables for Predicate {
1289 fn accumulate_mentioned_variables(&self, acc: &mut BTreeSet<Variable>) {
1290 for arg in &self.args {
1291 if let FnArg::Variable(ref v) = *arg {
1292 acc_ref(acc, v)
1293 }
1294 }
1295 }
1296}
1297
1298impl ContainsVariables for TypeAnnotation {
1299 fn accumulate_mentioned_variables(&self, acc: &mut BTreeSet<Variable>) {
1300 acc_ref(acc, &self.variable);
1301 }
1302}
1303
1304impl ContainsVariables for Binding {
1305 fn accumulate_mentioned_variables(&self, acc: &mut BTreeSet<Variable>) {
1306 match self {
1307 Binding::BindScalar(ref v) | &Binding::BindColl(ref v) => acc_ref(acc, v),
1308 Binding::BindRel(ref vs) | &Binding::BindTuple(ref vs) => {
1309 for v in vs {
1310 if let VariableOrPlaceholder::Variable(ref v) = *v {
1311 acc_ref(acc, v);
1312 }
1313 }
1314 }
1315 }
1316 }
1317}
1318
1319impl ContainsVariables for WhereFn {
1320 fn accumulate_mentioned_variables(&self, acc: &mut BTreeSet<Variable>) {
1321 for arg in &self.args {
1322 if let FnArg::Variable(ref v) = *arg {
1323 acc_ref(acc, v)
1324 }
1325 }
1326 self.binding.accumulate_mentioned_variables(acc);
1327 }
1328}
1329
1330fn acc_ref<T: Clone + Ord>(acc: &mut BTreeSet<T>, v: &T) {
1331 if !acc.contains(v) {
1333 acc.insert(v.clone());
1334 }
1335}
1336
1337impl ContainsVariables for Pattern {
1338 fn accumulate_mentioned_variables(&self, acc: &mut BTreeSet<Variable>) {
1339 if let PatternNonValuePlace::Variable(ref v) = self.entity {
1340 acc_ref(acc, v)
1341 }
1342 if let PatternNonValuePlace::Variable(ref v) = self.attribute {
1343 acc_ref(acc, v)
1344 }
1345 if let PatternValuePlace::Variable(ref v) = self.value {
1346 acc_ref(acc, v)
1347 }
1348 if let PatternNonValuePlace::Variable(ref v) = self.tx {
1349 acc_ref(acc, v)
1350 }
1351 if let PatternNonValuePlace::Variable(ref v) = self.added {
1352 acc_ref(acc, v)
1353 }
1354 }
1355}