1#[cfg(feature = "rdf-star")]
2use crate::dataset::{ExpressionSubject, ExpressionTriple};
3use crate::dataset::{ExpressionTerm, InternalQuad, QueryableDataset};
4use crate::error::QueryEvaluationError;
5use crate::model::{QuerySolutionIter, QueryTripleIter};
6use crate::service::ServiceHandlerRegistry;
7use crate::CustomFunctionRegistry;
8use json_event_parser::{JsonEvent, WriterJsonSerializer};
9use md5::{Digest, Md5};
10use oxiri::Iri;
11use oxrdf::vocab::{rdf, xsd};
12use oxrdf::{BlankNode, Literal, NamedNode, Term, Triple, Variable};
13#[cfg(feature = "sep-0002")]
14use oxsdatatypes::{Date, Duration, Time, TimezoneOffset, YearMonthDuration};
15use oxsdatatypes::{DateTime, DayTimeDuration, Decimal, Double, Float, Integer};
16use rand::random;
17use regex::{Regex, RegexBuilder};
18use rustc_hash::{FxBuildHasher, FxHashMap, FxHashSet, FxHasher};
19use sha1::Sha1;
20use sha2::{Sha256, Sha384, Sha512};
21use spargebra::algebra::{AggregateFunction, Function, PropertyPathExpression};
22#[cfg(feature = "rdf-star")]
23use spargebra::term::GroundTriple;
24use spargebra::term::{
25 GroundTerm, GroundTermPattern, NamedNodePattern, TermPattern, TriplePattern,
26};
27use sparopt::algebra::{
28 AggregateExpression, Expression, GraphPattern, JoinAlgorithm, LeftJoinAlgorithm,
29 MinusAlgorithm, OrderExpression,
30};
31use std::borrow::Cow;
32use std::cell::{Cell, RefCell};
33use std::cmp::Ordering;
34use std::hash::{Hash, Hasher};
35use std::iter::{empty, once, Peekable};
36use std::rc::Rc;
37use std::sync::Arc;
38use std::{fmt, io};
39const REGEX_SIZE_LIMIT: usize = 1_000_000;
42
43struct EvalDataset<D: QueryableDataset> {
45 dataset: Rc<D>,
46}
47
48impl<D: QueryableDataset> EvalDataset<D> {
49 fn internal_quads_for_pattern(
50 &self,
51 subject: Option<&D::InternalTerm>,
52 predicate: Option<&D::InternalTerm>,
53 object: Option<&D::InternalTerm>,
54 graph_name: Option<Option<&D::InternalTerm>>,
55 ) -> impl Iterator<Item = Result<InternalQuad<D>, QueryEvaluationError>> + 'static {
56 self.dataset
57 .internal_quads_for_pattern(subject, predicate, object, graph_name)
58 .map(|r| r.map_err(|e| QueryEvaluationError::Dataset(Box::new(e))))
59 }
60
61 fn internal_named_graphs(
62 &self,
63 ) -> impl Iterator<Item = Result<D::InternalTerm, QueryEvaluationError>> {
64 self.dataset
65 .internal_named_graphs()
66 .map(|r| r.map_err(|e| QueryEvaluationError::Dataset(Box::new(e))))
67 }
68
69 fn contains_internal_graph_name(
70 &self,
71 graph_name: &D::InternalTerm,
72 ) -> Result<bool, QueryEvaluationError> {
73 self.dataset
74 .contains_internal_graph_name(graph_name)
75 .map_err(|e| QueryEvaluationError::Dataset(Box::new(e)))
76 }
77
78 fn internalize_term(&self, term: Term) -> Result<D::InternalTerm, QueryEvaluationError> {
79 self.dataset
80 .internalize_term(term)
81 .map_err(|e| QueryEvaluationError::Dataset(Box::new(e)))
82 }
83
84 fn externalize_term(&self, term: D::InternalTerm) -> Result<Term, QueryEvaluationError> {
85 self.dataset
86 .externalize_term(term)
87 .map_err(|e| QueryEvaluationError::Dataset(Box::new(e)))
88 }
89
90 fn externalize_expression_term(
91 &self,
92 term: D::InternalTerm,
93 ) -> Result<ExpressionTerm, QueryEvaluationError> {
94 self.dataset
95 .externalize_expression_term(term)
96 .map_err(|e| QueryEvaluationError::Dataset(Box::new(e)))
97 }
98
99 fn internalize_expression_term(
100 &self,
101 term: ExpressionTerm,
102 ) -> Result<D::InternalTerm, QueryEvaluationError> {
103 self.dataset
104 .internalize_expression_term(term)
105 .map_err(|e| QueryEvaluationError::Dataset(Box::new(e)))
106 }
107
108 fn internal_term_effective_boolean_value(
109 &self,
110 term: D::InternalTerm,
111 ) -> Result<Option<bool>, QueryEvaluationError> {
112 self.dataset
113 .internal_term_effective_boolean_value(term)
114 .map_err(|e| QueryEvaluationError::Dataset(Box::new(e)))
115 }
116}
117
118impl<D: QueryableDataset> Clone for EvalDataset<D> {
119 #[inline]
120 fn clone(&self) -> Self {
121 Self {
122 dataset: Rc::clone(&self.dataset),
123 }
124 }
125}
126
127pub struct InternalTuple<D: QueryableDataset> {
128 inner: Vec<Option<D::InternalTerm>>,
129}
130
131impl<D: QueryableDataset> InternalTuple<D> {
132 pub fn with_capacity(capacity: usize) -> Self {
133 Self {
134 inner: Vec::with_capacity(capacity),
135 }
136 }
137
138 pub fn capacity(&self) -> usize {
139 self.inner.capacity()
140 }
141
142 pub fn contains(&self, index: usize) -> bool {
143 self.inner.get(index).is_some_and(Option::is_some)
144 }
145
146 pub fn get(&self, index: usize) -> Option<&D::InternalTerm> {
147 self.inner.get(index).unwrap_or(&None).as_ref()
148 }
149
150 pub fn iter(&self) -> impl Iterator<Item = Option<D::InternalTerm>> + '_ {
151 self.inner.iter().cloned()
152 }
153
154 pub fn set(&mut self, index: usize, value: D::InternalTerm) {
155 if self.inner.len() <= index {
156 self.inner.resize(index + 1, None);
157 }
158 self.inner[index] = Some(value);
159 }
160
161 pub fn combine_with(&self, other: &Self) -> Option<Self> {
162 if self.inner.len() < other.inner.len() {
163 let mut result = other.inner.clone();
164 for (key, self_value) in self.inner.iter().enumerate() {
165 if let Some(self_value) = self_value {
166 match &other.inner[key] {
167 Some(other_value) => {
168 if self_value != other_value {
169 return None;
170 }
171 }
172 None => result[key] = Some(self_value.clone()),
173 }
174 }
175 }
176 Some(Self { inner: result })
177 } else {
178 let mut result = self.inner.clone();
179 for (key, other_value) in other.inner.iter().enumerate() {
180 if let Some(other_value) = other_value {
181 match &self.inner[key] {
182 Some(self_value) => {
183 if self_value != other_value {
184 return None;
185 }
186 }
187 None => result[key] = Some(other_value.clone()),
188 }
189 }
190 }
191 Some(Self { inner: result })
192 }
193 }
194}
195
196impl<D: QueryableDataset> Clone for InternalTuple<D> {
197 fn clone(&self) -> Self {
198 Self {
199 inner: self.inner.clone(),
200 }
201 }
202}
203
204impl<D: QueryableDataset> PartialEq for InternalTuple<D> {
205 #[inline]
206 fn eq(&self, other: &InternalTuple<D>) -> bool {
207 self.inner == other.inner
208 }
209}
210
211impl<D: QueryableDataset> Eq for InternalTuple<D> {}
212
213impl<D: QueryableDataset> Hash for InternalTuple<D> {
214 fn hash<H: Hasher>(&self, state: &mut H) {
215 self.inner.hash(state)
216 }
217}
218
219impl<D: QueryableDataset> IntoIterator for InternalTuple<D> {
220 type Item = Option<D::InternalTerm>;
221 type IntoIter = std::vec::IntoIter<Option<D::InternalTerm>>;
222
223 fn into_iter(self) -> Self::IntoIter {
224 self.inner.into_iter()
225 }
226}
227
228type InternalTuplesIterator<D> =
229 Box<dyn Iterator<Item = Result<InternalTuple<D>, QueryEvaluationError>>>;
230
231pub struct SimpleEvaluator<D: QueryableDataset> {
232 dataset: EvalDataset<D>,
233 base_iri: Option<Rc<Iri<String>>>,
234 now: DateTime,
235 service_handler: Rc<ServiceHandlerRegistry>,
236 custom_functions: Rc<CustomFunctionRegistry>,
237 run_stats: bool,
238}
239
240impl<D: QueryableDataset> SimpleEvaluator<D> {
241 pub fn new(
242 dataset: D,
243 base_iri: Option<Rc<Iri<String>>>,
244 service_handler: Rc<ServiceHandlerRegistry>,
245 custom_functions: Rc<CustomFunctionRegistry>,
246 run_stats: bool,
247 ) -> Self {
248 Self {
249 dataset: EvalDataset {
250 dataset: Rc::new(dataset),
251 },
252 base_iri,
253 now: DateTime::now(),
254 service_handler,
255 custom_functions,
256 run_stats,
257 }
258 }
259
260 pub fn evaluate_select(
261 &self,
262 pattern: &GraphPattern,
263 substitutions: impl IntoIterator<Item = (Variable, Term)>,
264 ) -> (
265 Result<QuerySolutionIter, QueryEvaluationError>,
266 Rc<EvalNodeWithStats>,
267 ) {
268 let mut variables = Vec::new();
269 let (eval, stats) = self.graph_pattern_evaluator(pattern, &mut variables);
270 let from = match encode_initial_bindings(&self.dataset, &variables, substitutions) {
271 Ok(from) => from,
272 Err(e) => return (Err(e), stats),
273 };
274 (
275 Ok(decode_bindings(
276 self.dataset.clone(),
277 eval(from),
278 Arc::from(variables),
279 )),
280 stats,
281 )
282 }
283
284 pub fn evaluate_ask(
285 &self,
286 pattern: &GraphPattern,
287 substitutions: impl IntoIterator<Item = (Variable, Term)>,
288 ) -> (Result<bool, QueryEvaluationError>, Rc<EvalNodeWithStats>) {
289 let mut variables = Vec::new();
290 let (eval, stats) = self.graph_pattern_evaluator(pattern, &mut variables);
291 let from = match encode_initial_bindings(&self.dataset, &variables, substitutions) {
292 Ok(from) => from,
293 Err(e) => return (Err(e), stats),
294 };
295 let mut error = None;
298 for solution in eval(from) {
299 if let Err(e) = solution {
300 error.get_or_insert(e);
302 } else {
303 return (Ok(true), stats);
305 }
306 }
307 (
308 if let Some(e) = error {
309 Err(e)
310 } else {
311 Ok(false)
312 },
313 stats,
314 )
315 }
316
317 pub fn evaluate_construct(
318 &self,
319 pattern: &GraphPattern,
320 template: &[TriplePattern],
321 substitutions: impl IntoIterator<Item = (Variable, Term)>,
322 ) -> (
323 Result<QueryTripleIter, QueryEvaluationError>,
324 Rc<EvalNodeWithStats>,
325 ) {
326 let mut variables = Vec::new();
327 let (eval, stats) = self.graph_pattern_evaluator(pattern, &mut variables);
328 let mut bnodes = Vec::new();
329 let template = template
330 .iter()
331 .filter_map(|t| {
332 Some(TripleTemplate {
333 subject: TripleTemplateValue::from_term_or_variable(
334 &t.subject,
335 &mut variables,
336 &mut bnodes,
337 )?,
338 predicate: TripleTemplateValue::from_named_node_or_variable(
339 &t.predicate,
340 &mut variables,
341 ),
342 object: TripleTemplateValue::from_term_or_variable(
343 &t.object,
344 &mut variables,
345 &mut bnodes,
346 )?,
347 })
348 })
349 .collect();
350 let from = match encode_initial_bindings(&self.dataset, &variables, substitutions) {
351 Ok(from) => from,
352 Err(e) => return (Err(e), stats),
353 };
354 (
355 Ok(QueryTripleIter::new(ConstructIterator {
356 eval: self.clone(),
357 iter: eval(from),
358 template,
359 buffered_results: Vec::default(),
360 already_emitted_results: FxHashSet::default(),
361 bnodes: Vec::default(),
362 })),
363 stats,
364 )
365 }
366
367 pub fn evaluate_describe(
368 &self,
369 pattern: &GraphPattern,
370 substitutions: impl IntoIterator<Item = (Variable, Term)>,
371 ) -> (
372 Result<QueryTripleIter, QueryEvaluationError>,
373 Rc<EvalNodeWithStats>,
374 ) {
375 let mut variables = Vec::new();
376 let (eval, stats) = self.graph_pattern_evaluator(pattern, &mut variables);
377 let from = match encode_initial_bindings(&self.dataset, &variables, substitutions) {
378 Ok(from) => from,
379 Err(e) => return (Err(e), stats),
380 };
381 (
382 Ok(QueryTripleIter::new(DescribeIterator {
383 eval: self.clone(),
384 tuples_to_describe: eval(from),
385 nodes_described: FxHashSet::default(),
386 nodes_to_describe: Vec::default(),
387 quads: Box::new(empty()),
388 })),
389 stats,
390 )
391 }
392
393 pub fn graph_pattern_evaluator(
394 &self,
395 pattern: &GraphPattern,
396 encoded_variables: &mut Vec<Variable>,
397 ) -> (
398 Rc<dyn Fn(InternalTuple<D>) -> InternalTuplesIterator<D>>,
399 Rc<EvalNodeWithStats>,
400 ) {
401 let mut stat_children = Vec::new();
402 let mut evaluator =
403 self.build_graph_pattern_evaluator(pattern, encoded_variables, &mut stat_children);
404 let stats = Rc::new(EvalNodeWithStats {
405 label: eval_node_label(pattern),
406 children: stat_children,
407 exec_count: Cell::new(0),
408 exec_duration: Cell::new(self.run_stats.then(DayTimeDuration::default)),
409 });
410 if self.run_stats {
411 let stats = Rc::clone(&stats);
412 evaluator = Rc::new(move |tuple| {
413 let start = Timer::now();
414 let inner = evaluator(tuple);
415 let duration = start.elapsed();
416 stats.exec_duration.set(
417 stats
418 .exec_duration
419 .get()
420 .and_then(|d| d.checked_add(duration?)),
421 );
422 Box::new(StatsIterator {
423 inner,
424 stats: Rc::clone(&stats),
425 })
426 })
427 }
428 (evaluator, stats)
429 }
430
431 fn build_graph_pattern_evaluator(
432 &self,
433 pattern: &GraphPattern,
434 encoded_variables: &mut Vec<Variable>,
435 stat_children: &mut Vec<Rc<EvalNodeWithStats>>,
436 ) -> Rc<dyn Fn(InternalTuple<D>) -> InternalTuplesIterator<D>> {
437 match pattern {
438 GraphPattern::Values {
439 variables,
440 bindings,
441 } => {
442 let encoding = variables
443 .iter()
444 .map(|v| encode_variable(encoded_variables, v))
445 .collect::<Vec<_>>();
446 match bindings
447 .iter()
448 .map(|row| {
449 let mut result = InternalTuple::with_capacity(variables.len());
450 for (key, value) in row.iter().enumerate() {
451 if let Some(term) = value {
452 result.set(
453 encoding[key],
454 match term {
455 GroundTerm::NamedNode(node) => {
456 self.encode_term(node.clone())
457 }
458 GroundTerm::Literal(literal) => {
459 self.encode_term(literal.clone())
460 }
461 #[cfg(feature = "rdf-star")]
462 GroundTerm::Triple(triple) => self.encode_triple(triple),
463 }?,
464 );
465 }
466 }
467 Ok(result)
468 })
469 .collect::<Result<Vec<_>, _>>()
470 {
471 Ok(encoded_tuples) => Rc::new(move |from| {
472 Box::new(
473 encoded_tuples
474 .iter()
475 .filter_map(move |t| t.combine_with(&from))
476 .map(Ok)
477 .collect::<Vec<_>>()
478 .into_iter(),
479 )
480 }),
481 Err(e) => error_evaluator(e),
482 }
483 }
484 GraphPattern::QuadPattern {
485 subject,
486 predicate,
487 object,
488 graph_name,
489 } => {
490 let subject_selector = match TupleSelector::from_ground_term_pattern(
491 subject,
492 encoded_variables,
493 &self.dataset,
494 ) {
495 Ok(selector) => selector,
496 Err(e) => return error_evaluator(e),
497 };
498 let predicate_selector = match TupleSelector::from_named_node_pattern(
499 predicate,
500 encoded_variables,
501 &self.dataset,
502 ) {
503 Ok(selector) => selector,
504 Err(e) => return error_evaluator(e),
505 };
506 let object_selector = match TupleSelector::from_ground_term_pattern(
507 object,
508 encoded_variables,
509 &self.dataset,
510 ) {
511 Ok(selector) => selector,
512 Err(e) => return error_evaluator(e),
513 };
514 let graph_name_selector = if let Some(graph_name) = graph_name.as_ref() {
515 match TupleSelector::from_named_node_pattern(
516 graph_name,
517 encoded_variables,
518 &self.dataset,
519 ) {
520 Ok(selector) => Some(selector),
521 Err(e) => return error_evaluator(e),
522 }
523 } else {
524 None
525 };
526 let dataset = self.dataset.clone();
527 Rc::new(move |from| {
528 let input_subject = match subject_selector.get_pattern_value(
529 &from,
530 #[cfg(feature = "rdf-star")]
531 &dataset,
532 ) {
533 Ok(value) => value,
534 Err(e) => return Box::new(once(Err(e))),
535 };
536 let input_predicate = match predicate_selector.get_pattern_value(
537 &from,
538 #[cfg(feature = "rdf-star")]
539 &dataset,
540 ) {
541 Ok(value) => value,
542 Err(e) => return Box::new(once(Err(e))),
543 };
544 let input_object = match object_selector.get_pattern_value(
545 &from,
546 #[cfg(feature = "rdf-star")]
547 &dataset,
548 ) {
549 Ok(value) => value,
550 Err(e) => return Box::new(once(Err(e))),
551 };
552 let input_graph_name = if let Some(graph_name_selector) = &graph_name_selector {
553 match graph_name_selector.get_pattern_value(
554 &from,
555 #[cfg(feature = "rdf-star")]
556 &dataset,
557 ) {
558 Ok(value) => value,
559 Err(e) => return Box::new(once(Err(e))),
560 }
561 .map(Some)
562 } else {
563 Some(None) };
565 let iter = dataset.internal_quads_for_pattern(
566 input_subject.as_ref(),
567 input_predicate.as_ref(),
568 input_object.as_ref(),
569 input_graph_name.as_ref().map(|g| g.as_ref()),
570 );
571 let subject_selector = subject_selector.clone();
572 let predicate_selector = predicate_selector.clone();
573 let object_selector = object_selector.clone();
574 let graph_name_selector = graph_name_selector.clone();
575 #[cfg(feature = "rdf-star")]
576 let dataset = dataset.clone();
577 Box::new(
578 iter.map(move |quad| {
579 let quad = quad?;
580 let mut new_tuple = from.clone();
581 if !put_pattern_value(
582 &subject_selector,
583 quad.subject,
584 &mut new_tuple,
585 #[cfg(feature = "rdf-star")]
586 &dataset,
587 )? {
588 return Ok(None);
589 }
590 if !put_pattern_value(
591 &predicate_selector,
592 quad.predicate,
593 &mut new_tuple,
594 #[cfg(feature = "rdf-star")]
595 &dataset,
596 )? {
597 return Ok(None);
598 }
599 if !put_pattern_value(
600 &object_selector,
601 quad.object,
602 &mut new_tuple,
603 #[cfg(feature = "rdf-star")]
604 &dataset,
605 )? {
606 return Ok(None);
607 }
608 if let Some(graph_name_selector) = &graph_name_selector {
609 let Some(quad_graph_name) = quad.graph_name else {
610 return Err(QueryEvaluationError::UnexpectedDefaultGraph);
611 };
612 if !put_pattern_value(
613 graph_name_selector,
614 quad_graph_name,
615 &mut new_tuple,
616 #[cfg(feature = "rdf-star")]
617 &dataset,
618 )? {
619 return Ok(None);
620 }
621 }
622 Ok(Some(new_tuple))
623 })
624 .filter_map(Result::transpose),
625 )
626 })
627 }
628 GraphPattern::Path {
629 subject,
630 path,
631 object,
632 graph_name,
633 } => {
634 let subject_selector = match TupleSelector::from_ground_term_pattern(
635 subject,
636 encoded_variables,
637 &self.dataset,
638 ) {
639 Ok(selector) => selector,
640 Err(e) => return error_evaluator(e),
641 };
642 let path = match self.encode_property_path(path) {
643 Ok(path) => path,
644 Err(e) => return error_evaluator(e),
645 };
646 let object_selector = match TupleSelector::from_ground_term_pattern(
647 object,
648 encoded_variables,
649 &self.dataset,
650 ) {
651 Ok(selector) => selector,
652 Err(e) => return error_evaluator(e),
653 };
654 let graph_name_selector = if let Some(graph_name) = graph_name.as_ref() {
655 match TupleSelector::from_named_node_pattern(
656 graph_name,
657 encoded_variables,
658 &self.dataset,
659 ) {
660 Ok(selector) => Some(selector),
661 Err(e) => return error_evaluator(e),
662 }
663 } else {
664 None
665 };
666 let dataset = self.dataset.clone();
667 Rc::new(move |from| {
668 let input_subject = match subject_selector.get_pattern_value(
669 &from,
670 #[cfg(feature = "rdf-star")]
671 &dataset,
672 ) {
673 Ok(value) => value,
674 Err(e) => return Box::new(once(Err(e))),
675 };
676 let path_eval = PathEvaluator {
677 dataset: dataset.clone(),
678 };
679 let input_object = match object_selector.get_pattern_value(
680 &from,
681 #[cfg(feature = "rdf-star")]
682 &dataset,
683 ) {
684 Ok(value) => value,
685 Err(e) => return Box::new(once(Err(e))),
686 };
687 let input_graph_name = if let Some(graph_name_selector) = &graph_name_selector {
688 match graph_name_selector.get_pattern_value(
689 &from,
690 #[cfg(feature = "rdf-star")]
691 &dataset,
692 ) {
693 Ok(value) => value,
694 Err(e) => return Box::new(once(Err(e))),
695 }
696 .map(Some)
697 } else {
698 Some(None) };
700 match (input_subject, input_object, input_graph_name) {
701 (Some(input_subject), Some(input_object), Some(input_graph_name)) => {
702 match path_eval.eval_closed_in_graph(
703 &path,
704 &input_subject,
705 &input_object,
706 input_graph_name.as_ref(),
707 ) {
708 Ok(true) => Box::new(once(Ok(from))),
709 Ok(false) => Box::new(empty()),
710 Err(e) => Box::new(once(Err(e))),
711 }
712 }
713 (Some(input_subject), None, Some(input_graph_name)) => {
714 let object_selector = object_selector.clone();
715 #[cfg(feature = "rdf-star")]
716 let dataset = dataset.clone();
717 Box::new(
718 path_eval
719 .eval_from_in_graph(
720 &path,
721 &input_subject,
722 input_graph_name.as_ref(),
723 )
724 .map(move |o| {
725 let o = o?;
726 let mut new_tuple = from.clone();
727 if !put_pattern_value(
728 &object_selector,
729 o,
730 &mut new_tuple,
731 #[cfg(feature = "rdf-star")]
732 &dataset,
733 )? {
734 return Ok(None);
735 }
736 Ok(Some(new_tuple))
737 })
738 .filter_map(Result::transpose),
739 )
740 }
741 (None, Some(input_object), Some(input_graph_name)) => {
742 let subject_selector = subject_selector.clone();
743 #[cfg(feature = "rdf-star")]
744 let dataset = dataset.clone();
745 Box::new(
746 path_eval
747 .eval_to_in_graph(
748 &path,
749 &input_object,
750 input_graph_name.as_ref(),
751 )
752 .map(move |s| {
753 let s = s?;
754 let mut new_tuple = from.clone();
755 if !put_pattern_value(
756 &subject_selector,
757 s,
758 &mut new_tuple,
759 #[cfg(feature = "rdf-star")]
760 &dataset,
761 )? {
762 return Ok(None);
763 }
764 Ok(Some(new_tuple))
765 })
766 .filter_map(Result::transpose),
767 )
768 }
769 (None, None, Some(input_graph_name)) => {
770 let subject_selector = subject_selector.clone();
771 let object_selector = object_selector.clone();
772 #[cfg(feature = "rdf-star")]
773 let dataset = dataset.clone();
774 Box::new(
775 path_eval
776 .eval_open_in_graph(&path, input_graph_name.as_ref())
777 .map(move |t| {
778 let (s, o) = t?;
779 let mut new_tuple = from.clone();
780 if !put_pattern_value(
781 &subject_selector,
782 s,
783 &mut new_tuple,
784 #[cfg(feature = "rdf-star")]
785 &dataset,
786 )? {
787 return Ok(None);
788 }
789 if !put_pattern_value(
790 &object_selector,
791 o,
792 &mut new_tuple,
793 #[cfg(feature = "rdf-star")]
794 &dataset,
795 )? {
796 return Ok(None);
797 }
798 Ok(Some(new_tuple))
799 })
800 .filter_map(Result::transpose),
801 )
802 }
803 (Some(input_subject), Some(input_object), None) => {
804 let graph_name_selector = graph_name_selector.clone();
805 #[cfg(feature = "rdf-star")]
806 let dataset = dataset.clone();
807 Box::new(
808 path_eval
809 .eval_closed_in_unknown_graph(
810 &path,
811 &input_subject,
812 &input_object,
813 )
814 .map(move |g| {
815 let g = g?;
816 let mut new_tuple = from.clone();
817 if let Some(graph_name_selector) = &graph_name_selector {
818 let Some(g) = g else {
819 return Err(
820 QueryEvaluationError::UnexpectedDefaultGraph,
821 );
822 };
823 if !put_pattern_value(
824 graph_name_selector,
825 g,
826 &mut new_tuple,
827 #[cfg(feature = "rdf-star")]
828 &dataset,
829 )? {
830 return Ok(None);
831 }
832 }
833 Ok(Some(new_tuple))
834 })
835 .filter_map(Result::transpose),
836 )
837 }
838 (Some(input_subject), None, None) => {
839 let object_selector = object_selector.clone();
840 let graph_name_selector = graph_name_selector.clone();
841 #[cfg(feature = "rdf-star")]
842 let dataset = dataset.clone();
843 Box::new(
844 path_eval
845 .eval_from_in_unknown_graph(&path, &input_subject)
846 .map(move |t| {
847 let (o, g) = t?;
848 let mut new_tuple = from.clone();
849 if !put_pattern_value(
850 &object_selector,
851 o,
852 &mut new_tuple,
853 #[cfg(feature = "rdf-star")]
854 &dataset,
855 )? {
856 return Ok(None);
857 }
858 if let Some(graph_name_selector) = &graph_name_selector {
859 let Some(g) = g else {
860 return Err(
861 QueryEvaluationError::UnexpectedDefaultGraph,
862 );
863 };
864 if !put_pattern_value(
865 graph_name_selector,
866 g,
867 &mut new_tuple,
868 #[cfg(feature = "rdf-star")]
869 &dataset,
870 )? {
871 return Ok(None);
872 }
873 }
874 Ok(Some(new_tuple))
875 })
876 .filter_map(Result::transpose),
877 )
878 }
879 (None, Some(input_object), None) => {
880 let subject_selector = subject_selector.clone();
881 let graph_name_selector = graph_name_selector.clone();
882 #[cfg(feature = "rdf-star")]
883 let dataset = dataset.clone();
884 Box::new(
885 path_eval
886 .eval_to_in_unknown_graph(&path, &input_object)
887 .map(move |t| {
888 let (s, g) = t?;
889 let mut new_tuple = from.clone();
890 if !put_pattern_value(
891 &subject_selector,
892 s,
893 &mut new_tuple,
894 #[cfg(feature = "rdf-star")]
895 &dataset,
896 )? {
897 return Ok(None);
898 }
899 if let Some(graph_name_selector) = &graph_name_selector {
900 let Some(g) = g else {
901 return Err(
902 QueryEvaluationError::UnexpectedDefaultGraph,
903 );
904 };
905 if !put_pattern_value(
906 graph_name_selector,
907 g,
908 &mut new_tuple,
909 #[cfg(feature = "rdf-star")]
910 &dataset,
911 )? {
912 return Ok(None);
913 }
914 }
915 Ok(Some(new_tuple))
916 })
917 .filter_map(Result::transpose),
918 )
919 }
920 (None, None, None) => {
921 let subject_selector = subject_selector.clone();
922 let object_selector = object_selector.clone();
923 let graph_name_selector = graph_name_selector.clone();
924 #[cfg(feature = "rdf-star")]
925 let dataset = dataset.clone();
926 Box::new(
927 path_eval
928 .eval_open_in_unknown_graph(&path)
929 .map(move |t| {
930 let (s, o, g) = t?;
931 let mut new_tuple = from.clone();
932 if !put_pattern_value(
933 &subject_selector,
934 s,
935 &mut new_tuple,
936 #[cfg(feature = "rdf-star")]
937 &dataset,
938 )? {
939 return Ok(None);
940 }
941 if !put_pattern_value(
942 &object_selector,
943 o,
944 &mut new_tuple,
945 #[cfg(feature = "rdf-star")]
946 &dataset,
947 )? {
948 return Ok(None);
949 }
950 if let Some(graph_name_selector) = &graph_name_selector {
951 let Some(g) = g else {
952 return Err(
953 QueryEvaluationError::UnexpectedDefaultGraph,
954 );
955 };
956 if !put_pattern_value(
957 graph_name_selector,
958 g,
959 &mut new_tuple,
960 #[cfg(feature = "rdf-star")]
961 &dataset,
962 )? {
963 return Ok(None);
964 }
965 }
966 Ok(Some(new_tuple))
967 })
968 .filter_map(Result::transpose),
969 )
970 }
971 }
972 })
973 }
974 GraphPattern::Graph { graph_name } => {
975 let graph_name_selector = match TupleSelector::from_named_node_pattern(
976 graph_name,
977 encoded_variables,
978 &self.dataset,
979 ) {
980 Ok(selector) => selector,
981 Err(e) => return error_evaluator(e),
982 };
983 let dataset = self.dataset.clone();
984 Rc::new(move |from| {
985 let input_graph_name = match graph_name_selector.get_pattern_value(
986 &from,
987 #[cfg(feature = "rdf-star")]
988 &dataset,
989 ) {
990 Ok(value) => value,
991 Err(e) => return Box::new(once(Err(e))),
992 };
993 if let Some(input_graph_name) = input_graph_name {
994 match dataset.contains_internal_graph_name(&input_graph_name) {
995 Ok(true) => Box::new(once(Ok(from))),
996 Ok(false) => Box::new(empty()),
997 Err(e) => Box::new(once(Err(e))),
998 }
999 } else {
1000 let graph_name_selector = graph_name_selector.clone();
1001 #[cfg(feature = "rdf-star")]
1002 let dataset = dataset.clone();
1003 Box::new(
1004 dataset
1005 .internal_named_graphs()
1006 .map(move |graph_name| {
1007 let graph_name = graph_name?;
1008 let mut new_tuple = from.clone();
1009 if !put_pattern_value(
1010 &graph_name_selector,
1011 graph_name,
1012 &mut new_tuple,
1013 #[cfg(feature = "rdf-star")]
1014 &dataset,
1015 )? {
1016 return Ok(None);
1017 }
1018 Ok(Some(new_tuple))
1019 })
1020 .filter_map(Result::transpose),
1021 )
1022 }
1023 })
1024 }
1025 GraphPattern::Join {
1026 left,
1027 right,
1028 algorithm,
1029 } => {
1030 let (left, left_stats) = self.graph_pattern_evaluator(left, encoded_variables);
1031 stat_children.push(left_stats);
1032 let (right, right_stats) = self.graph_pattern_evaluator(right, encoded_variables);
1033 stat_children.push(right_stats);
1034
1035 match algorithm {
1036 JoinAlgorithm::HashBuildLeftProbeRight { keys } => {
1037 let build = left;
1038 let probe = right;
1039 if keys.is_empty() {
1040 Rc::new(move |from| {
1042 let mut errors = Vec::default();
1043 let built_values = build(from.clone())
1044 .filter_map(|result| match result {
1045 Ok(result) => Some(result),
1046 Err(error) => {
1047 errors.push(Err(error));
1048 None
1049 }
1050 })
1051 .collect::<Vec<_>>();
1052 if built_values.is_empty() && errors.is_empty() {
1053 return Box::new(empty());
1055 }
1056 let mut probe_iter = probe(from).peekable();
1057 if probe_iter.peek().is_none() {
1058 return Box::new(empty());
1060 }
1061 Box::new(CartesianProductJoinIterator {
1062 probe_iter,
1063 built: built_values,
1064 buffered_results: errors,
1065 })
1066 })
1067 } else {
1068 let keys = keys
1070 .iter()
1071 .map(|v| encode_variable(encoded_variables, v))
1072 .collect::<Vec<_>>();
1073 Rc::new(move |from| {
1074 let mut errors = Vec::default();
1075 let mut built_values = InternalTupleSet::new(keys.clone());
1076 built_values.extend(build(from.clone()).filter_map(|result| {
1077 match result {
1078 Ok(result) => Some(result),
1079 Err(error) => {
1080 errors.push(Err(error));
1081 None
1082 }
1083 }
1084 }));
1085 if built_values.is_empty() && errors.is_empty() {
1086 return Box::new(empty());
1088 }
1089 let mut probe_iter = probe(from).peekable();
1090 if probe_iter.peek().is_none() {
1091 return Box::new(empty());
1093 }
1094 Box::new(HashJoinIterator {
1095 probe_iter,
1096 built: built_values,
1097 buffered_results: errors,
1098 })
1099 })
1100 }
1101 }
1102 }
1103 }
1104 #[cfg(feature = "sep-0006")]
1105 GraphPattern::Lateral { left, right } => {
1106 let (left, left_stats) = self.graph_pattern_evaluator(left, encoded_variables);
1107 stat_children.push(left_stats);
1108
1109 if let GraphPattern::LeftJoin {
1110 left: nested_left,
1111 right: nested_right,
1112 expression,
1113 ..
1114 } = right.as_ref()
1115 {
1116 if nested_left.is_empty_singleton() {
1117 let right =
1119 GraphPattern::filter(nested_right.as_ref().clone(), expression.clone());
1120 let (right, right_stats) =
1121 self.graph_pattern_evaluator(&right, encoded_variables);
1122 stat_children.push(right_stats);
1123 return Rc::new(move |from| {
1124 Box::new(ForLoopLeftJoinIterator {
1125 right_evaluator: Rc::clone(&right),
1126 left_iter: left(from),
1127 current_right: Box::new(empty()),
1128 left_tuple_to_yield: None,
1129 })
1130 });
1131 }
1132 }
1133 let (right, right_stats) = self.graph_pattern_evaluator(right, encoded_variables);
1134 stat_children.push(right_stats);
1135 Rc::new(move |from| {
1136 let right = Rc::clone(&right);
1137 Box::new(left(from).flat_map(move |t| match t {
1138 Ok(t) => right(t),
1139 Err(e) => Box::new(once(Err(e))),
1140 }))
1141 })
1142 }
1143 GraphPattern::Minus {
1144 left,
1145 right,
1146 algorithm,
1147 } => {
1148 let (left, left_stats) = self.graph_pattern_evaluator(left, encoded_variables);
1149 stat_children.push(left_stats);
1150 let (right, right_stats) = self.graph_pattern_evaluator(right, encoded_variables);
1151 stat_children.push(right_stats);
1152
1153 match algorithm {
1154 MinusAlgorithm::HashBuildRightProbeLeft { keys } => {
1155 if keys.is_empty() {
1156 Rc::new(move |from| {
1157 let right: Vec<_> =
1158 right(from.clone()).filter_map(Result::ok).collect();
1159 if right.is_empty() {
1160 return left(from);
1161 }
1162 Box::new(left(from).filter(move |left_tuple| {
1163 if let Ok(left_tuple) = left_tuple {
1164 !right.iter().any(|right_tuple| {
1165 are_compatible_and_not_disjointed(
1166 left_tuple,
1167 right_tuple,
1168 )
1169 })
1170 } else {
1171 true
1172 }
1173 }))
1174 })
1175 } else {
1176 let keys = keys
1177 .iter()
1178 .map(|v| encode_variable(encoded_variables, v))
1179 .collect::<Vec<_>>();
1180 Rc::new(move |from| {
1181 let mut right_values = InternalTupleSet::new(keys.clone());
1182 right_values.extend(right(from.clone()).filter_map(Result::ok));
1183 if right_values.is_empty() {
1184 return left(from);
1185 }
1186 Box::new(left(from).filter(move |left_tuple| {
1187 if let Ok(left_tuple) = left_tuple {
1188 !right_values.get(left_tuple).iter().any(|right_tuple| {
1189 are_compatible_and_not_disjointed(
1190 left_tuple,
1191 right_tuple,
1192 )
1193 })
1194 } else {
1195 true
1196 }
1197 }))
1198 })
1199 }
1200 }
1201 }
1202 }
1203 GraphPattern::LeftJoin {
1204 left,
1205 right,
1206 expression,
1207 algorithm,
1208 } => {
1209 let (left, left_stats) = self.graph_pattern_evaluator(left, encoded_variables);
1210 stat_children.push(left_stats);
1211 let (right, right_stats) = self.graph_pattern_evaluator(right, encoded_variables);
1212 stat_children.push(right_stats);
1213 let expression = self.effective_boolean_value_expression_evaluator(
1214 expression,
1215 encoded_variables,
1216 stat_children,
1217 );
1218
1219 match algorithm {
1220 LeftJoinAlgorithm::HashBuildRightProbeLeft { keys } => {
1221 let keys = keys
1223 .iter()
1224 .map(|v| encode_variable(encoded_variables, v))
1225 .collect::<Vec<_>>();
1226 Rc::new(move |from| {
1227 let mut errors = Vec::default();
1228 let mut right_values = InternalTupleSet::new(keys.clone());
1229 right_values.extend(right(from.clone()).filter_map(
1230 |result| match result {
1231 Ok(result) => Some(result),
1232 Err(error) => {
1233 errors.push(Err(error));
1234 None
1235 }
1236 },
1237 ));
1238 if right_values.is_empty() && errors.is_empty() {
1239 return left(from);
1240 }
1241 Box::new(HashLeftJoinIterator {
1242 left_iter: left(from),
1243 right: right_values,
1244 buffered_results: errors,
1245 expression: Rc::clone(&expression),
1246 })
1247 })
1248 }
1249 }
1250 }
1251 GraphPattern::Filter { inner, expression } => {
1252 let (child, child_stats) = self.graph_pattern_evaluator(inner, encoded_variables);
1253 stat_children.push(child_stats);
1254 let expression = self.effective_boolean_value_expression_evaluator(
1255 expression,
1256 encoded_variables,
1257 stat_children,
1258 );
1259 Rc::new(move |from| {
1260 let expression = Rc::clone(&expression);
1261 Box::new(child(from).filter(move |tuple| match tuple {
1262 Ok(tuple) => expression(tuple).unwrap_or(false),
1263 Err(_) => true,
1264 }))
1265 })
1266 }
1267 GraphPattern::Union { inner } => {
1268 let children = inner
1269 .iter()
1270 .map(|child| {
1271 let (child, child_stats) =
1272 self.graph_pattern_evaluator(child, encoded_variables);
1273 stat_children.push(child_stats);
1274 child
1275 })
1276 .collect::<Vec<_>>();
1277
1278 Rc::new(move |from| {
1279 Box::new(UnionIterator {
1280 plans: children.clone(),
1281 input: from,
1282 current_iterator: Box::new(empty()),
1283 current_plan: 0,
1284 })
1285 })
1286 }
1287 GraphPattern::Extend {
1288 inner,
1289 variable,
1290 expression,
1291 } => {
1292 let (child, child_stats) = self.graph_pattern_evaluator(inner, encoded_variables);
1293 stat_children.push(child_stats);
1294
1295 let position = encode_variable(encoded_variables, variable);
1296 if let Some(expression) =
1297 self.internal_expression_evaluator(expression, encoded_variables, stat_children)
1298 {
1299 return Rc::new(move |from| {
1300 let expression = Rc::clone(&expression);
1301 Box::new(child(from).map(move |tuple| {
1302 let mut tuple = tuple?;
1303 if let Some(value) = expression(&tuple) {
1304 tuple.set(position, value);
1305 }
1306 Ok(tuple)
1307 }))
1308 });
1309 }
1310
1311 let expression =
1312 self.expression_evaluator(expression, encoded_variables, stat_children);
1313 let dataset = self.dataset.clone();
1314 Rc::new(move |from| {
1315 let expression = Rc::clone(&expression);
1316 let dataset = dataset.clone();
1317 Box::new(child(from).map(move |tuple| {
1318 let mut tuple = tuple?;
1319 if let Some(value) = expression(&tuple) {
1320 tuple.set(position, dataset.internalize_expression_term(value)?);
1321 }
1322 Ok(tuple)
1323 }))
1324 })
1325 }
1326 GraphPattern::OrderBy { inner, expression } => {
1327 let (child, child_stats) = self.graph_pattern_evaluator(inner, encoded_variables);
1328 stat_children.push(child_stats);
1329 let by = expression
1330 .iter()
1331 .map(|comp| match comp {
1332 OrderExpression::Asc(expression) => ComparatorFunction::Asc(
1333 self.expression_evaluator(expression, encoded_variables, stat_children),
1334 ),
1335 OrderExpression::Desc(expression) => ComparatorFunction::Desc(
1336 self.expression_evaluator(expression, encoded_variables, stat_children),
1337 ),
1338 })
1339 .collect::<Vec<_>>();
1340 Rc::new(move |from| {
1341 let mut errors = Vec::default();
1342 let mut values = child(from)
1343 .filter_map(|result| match result {
1344 Ok(result) => Some(result),
1345 Err(error) => {
1346 errors.push(Err(error));
1347 None
1348 }
1349 })
1350 .collect::<Vec<_>>();
1351 values.sort_unstable_by(|a, b| {
1352 for comp in &by {
1353 match comp {
1354 ComparatorFunction::Asc(expression) => {
1355 match cmp_terms(expression(a).as_ref(), expression(b).as_ref())
1356 {
1357 Ordering::Greater => return Ordering::Greater,
1358 Ordering::Less => return Ordering::Less,
1359 Ordering::Equal => (),
1360 }
1361 }
1362 ComparatorFunction::Desc(expression) => {
1363 match cmp_terms(expression(a).as_ref(), expression(b).as_ref())
1364 {
1365 Ordering::Greater => return Ordering::Less,
1366 Ordering::Less => return Ordering::Greater,
1367 Ordering::Equal => (),
1368 }
1369 }
1370 }
1371 }
1372 Ordering::Equal
1373 });
1374 Box::new(errors.into_iter().chain(values.into_iter().map(Ok)))
1375 })
1376 }
1377 GraphPattern::Distinct { inner } => {
1378 let (child, child_stats) = self.graph_pattern_evaluator(inner, encoded_variables);
1379 stat_children.push(child_stats);
1380 Rc::new(move |from| Box::new(hash_deduplicate(child(from))))
1381 }
1382 GraphPattern::Reduced { inner } => {
1383 let (child, child_stats) = self.graph_pattern_evaluator(inner, encoded_variables);
1384 stat_children.push(child_stats);
1385 Rc::new(move |from| {
1386 Box::new(ConsecutiveDeduplication {
1387 inner: child(from),
1388 current: None,
1389 })
1390 })
1391 }
1392 GraphPattern::Slice {
1393 inner,
1394 start,
1395 length,
1396 } => {
1397 let (mut child, child_stats) =
1398 self.graph_pattern_evaluator(inner, encoded_variables);
1399 stat_children.push(child_stats);
1400 #[allow(clippy::shadow_same)]
1401 let start = *start;
1402 if start > 0 {
1403 child = Rc::new(move |from| Box::new(child(from).skip(start)));
1404 }
1405 if let Some(length) = *length {
1406 child = Rc::new(move |from| Box::new(child(from).take(length)));
1407 }
1408 child
1409 }
1410 GraphPattern::Project { inner, variables } => {
1411 let mut inner_encoded_variables = variables.clone();
1412 let (child, child_stats) =
1413 self.graph_pattern_evaluator(inner, &mut inner_encoded_variables);
1414 stat_children.push(child_stats);
1415 let mapping = variables
1416 .iter()
1417 .enumerate()
1418 .map(|(new_variable, variable)| {
1419 (new_variable, encode_variable(encoded_variables, variable))
1420 })
1421 .collect::<Rc<[(usize, usize)]>>();
1422 Rc::new(move |from| {
1423 let mapping = Rc::clone(&mapping);
1424 let mut input_tuple = InternalTuple::with_capacity(mapping.len());
1425 for (input_key, output_key) in &*mapping {
1426 if let Some(value) = from.get(*output_key) {
1427 input_tuple.set(*input_key, value.clone());
1428 }
1429 }
1430 Box::new(child(input_tuple).filter_map(move |tuple| {
1431 match tuple {
1432 Ok(tuple) => {
1433 let mut output_tuple = from.clone();
1434 for (input_key, output_key) in &*mapping {
1435 if let Some(value) = tuple.get(*input_key) {
1436 if let Some(existing_value) = output_tuple.get(*output_key)
1437 {
1438 if existing_value != value {
1439 return None; }
1441 } else {
1442 output_tuple.set(*output_key, value.clone());
1443 }
1444 }
1445 }
1446 Some(Ok(output_tuple))
1447 }
1448 Err(e) => Some(Err(e)),
1449 }
1450 }))
1451 })
1452 }
1453 GraphPattern::Group {
1454 inner,
1455 aggregates,
1456 variables,
1457 } => {
1458 let (child, child_stats) = self.graph_pattern_evaluator(inner, encoded_variables);
1459 stat_children.push(child_stats);
1460 let key_variables = variables
1461 .iter()
1462 .map(|k| encode_variable(encoded_variables, k))
1463 .collect::<Rc<[_]>>();
1464 let accumulator_builders = aggregates
1465 .iter()
1466 .map(|(_, aggregate)| {
1467 self.accumulator_builder(aggregate, encoded_variables, stat_children)
1468 })
1469 .collect::<Vec<_>>();
1470 let accumulator_variables = aggregates
1471 .iter()
1472 .map(|(variable, _)| encode_variable(encoded_variables, variable))
1473 .collect::<Vec<_>>();
1474 let dataset = self.dataset.clone();
1475 Rc::new(move |from| {
1476 let tuple_size = from.capacity();
1477 let key_variables = Rc::clone(&key_variables);
1478 let mut errors = Vec::default();
1479 let mut accumulators_for_group = FxHashMap::<
1480 Vec<Option<D::InternalTerm>>,
1481 Vec<AccumulatorWrapper<D>>,
1482 >::default();
1483 if key_variables.is_empty() {
1484 accumulators_for_group.insert(
1486 Vec::new(),
1487 accumulator_builders.iter().map(|c| c()).collect::<Vec<_>>(),
1488 );
1489 }
1490 child(from)
1491 .filter_map(|result| match result {
1492 Ok(result) => Some(result),
1493 Err(error) => {
1494 errors.push(error);
1495 None
1496 }
1497 })
1498 .for_each(|tuple| {
1499 let key = key_variables
1501 .iter()
1502 .map(|v| tuple.get(*v).cloned())
1503 .collect();
1504
1505 let key_accumulators =
1506 accumulators_for_group.entry(key).or_insert_with(|| {
1507 accumulator_builders.iter().map(|c| c()).collect::<Vec<_>>()
1508 });
1509 for accumulator in key_accumulators {
1510 accumulator.add(&tuple);
1511 }
1512 });
1513 let accumulator_variables = accumulator_variables.clone();
1514 let dataset = dataset.clone();
1515 Box::new(
1516 errors
1517 .into_iter()
1518 .map(Err)
1519 .chain(accumulators_for_group.into_iter().map(
1520 move |(key, accumulators)| {
1521 let mut result = InternalTuple::with_capacity(tuple_size);
1522 for (variable, value) in key_variables.iter().zip(key) {
1523 if let Some(value) = value {
1524 result.set(*variable, value);
1525 }
1526 }
1527 for (accumulator, variable) in
1528 accumulators.into_iter().zip(&accumulator_variables)
1529 {
1530 if let Some(value) = accumulator.finish() {
1531 result.set(
1532 *variable,
1533 dataset.internalize_expression_term(value)?,
1534 );
1535 }
1536 }
1537 Ok(result)
1538 },
1539 )),
1540 )
1541 })
1542 }
1543 GraphPattern::Service {
1544 name,
1545 inner,
1546 silent,
1547 } => {
1548 #[allow(clippy::shadow_same)]
1549 let silent = *silent;
1550 let service_name = match TupleSelector::from_named_node_pattern(
1551 name,
1552 encoded_variables,
1553 &self.dataset,
1554 ) {
1555 Ok(service_name) => service_name,
1556 Err(e) => return error_evaluator(e),
1557 };
1558 self.build_graph_pattern_evaluator(inner, encoded_variables, &mut Vec::new()); let graph_pattern = spargebra::algebra::GraphPattern::from(inner.as_ref());
1560 let variables = Rc::from(encoded_variables.as_slice());
1561 let eval = self.clone();
1562 Rc::new(move |from| {
1563 match eval.evaluate_service(
1564 &service_name,
1565 &graph_pattern,
1566 Rc::clone(&variables),
1567 &from,
1568 ) {
1569 Ok(result) => Box::new(result.filter_map(move |binding| {
1570 binding
1571 .map(|binding| binding.combine_with(&from))
1572 .transpose()
1573 })),
1574 Err(e) => {
1575 if silent {
1576 Box::new(once(Ok(from)))
1577 } else {
1578 Box::new(once(Err(e)))
1579 }
1580 }
1581 }
1582 })
1583 }
1584 }
1585 }
1586
1587 fn evaluate_service(
1588 &self,
1589 service_name: &TupleSelector<D>,
1590 graph_pattern: &spargebra::algebra::GraphPattern,
1591 variables: Rc<[Variable]>,
1592 from: &InternalTuple<D>,
1593 ) -> Result<InternalTuplesIterator<D>, QueryEvaluationError> {
1594 let service_name = service_name
1595 .get_pattern_value(
1596 from,
1597 #[cfg(feature = "rdf-star")]
1598 &self.dataset,
1599 )?
1600 .ok_or(QueryEvaluationError::UnboundService)?;
1601 let service_name = match self.dataset.externalize_term(service_name)? {
1602 Term::NamedNode(service_name) => service_name,
1603 term => return Err(QueryEvaluationError::InvalidServiceName(term)),
1604 };
1605 let iter = self.service_handler.handle(
1606 service_name,
1607 graph_pattern.clone(),
1608 self.base_iri.as_ref().map(ToString::to_string),
1609 )?;
1610 Ok(encode_bindings(self.dataset.clone(), variables, iter))
1611 }
1612
1613 fn accumulator_builder(
1614 &self,
1615 expression: &AggregateExpression,
1616 encoded_variables: &mut Vec<Variable>,
1617 stat_children: &mut Vec<Rc<EvalNodeWithStats>>,
1618 ) -> Box<dyn Fn() -> AccumulatorWrapper<D>> {
1619 match expression {
1620 AggregateExpression::CountSolutions { distinct } => {
1621 if *distinct {
1622 Box::new(move || AccumulatorWrapper::CountDistinctTuple {
1623 count: 0,
1624 seen: FxHashSet::default(),
1625 })
1626 } else {
1627 Box::new(move || AccumulatorWrapper::CountTuple { count: 0 })
1628 }
1629 }
1630 AggregateExpression::FunctionCall {
1631 name,
1632 distinct,
1633 expr,
1634 } => match name {
1635 AggregateFunction::Count => {
1636 if let Some(evaluator) =
1637 self.internal_expression_evaluator(expr, encoded_variables, stat_children)
1638 {
1639 return if *distinct {
1640 Box::new(move || AccumulatorWrapper::CountDistinctInternal {
1641 evaluator: Rc::clone(&evaluator),
1642 seen: FxHashSet::default(),
1643 count: 0,
1644 })
1645 } else {
1646 Box::new(move || AccumulatorWrapper::CountInternal {
1647 evaluator: Rc::clone(&evaluator),
1648 count: 0,
1649 })
1650 };
1651 }
1652 let evaluator =
1653 self.expression_evaluator(expr, encoded_variables, stat_children);
1654 if *distinct {
1655 Box::new(move || AccumulatorWrapper::DistinctExpression {
1656 evaluator: Rc::clone(&evaluator),
1657 seen: FxHashSet::default(),
1658 accumulator: Some(Box::new(CountAccumulator::default())),
1659 })
1660 } else {
1661 Box::new(move || AccumulatorWrapper::Expression {
1662 evaluator: Rc::clone(&evaluator),
1663 accumulator: Some(Box::new(CountAccumulator::default())),
1664 })
1665 }
1666 }
1667 AggregateFunction::Sum => {
1668 let evaluator =
1669 self.expression_evaluator(expr, encoded_variables, stat_children);
1670 if *distinct {
1671 Box::new(move || AccumulatorWrapper::DistinctExpression {
1672 evaluator: Rc::clone(&evaluator),
1673 seen: FxHashSet::default(),
1674 accumulator: Some(Box::new(SumAccumulator::default())),
1675 })
1676 } else {
1677 Box::new(move || AccumulatorWrapper::Expression {
1678 evaluator: Rc::clone(&evaluator),
1679 accumulator: Some(Box::new(SumAccumulator::default())),
1680 })
1681 }
1682 }
1683 AggregateFunction::Min => {
1684 let evaluator =
1685 self.expression_evaluator(expr, encoded_variables, stat_children);
1686 if *distinct {
1687 Box::new(move || AccumulatorWrapper::DistinctExpression {
1688 evaluator: Rc::clone(&evaluator),
1689 seen: FxHashSet::default(),
1690 accumulator: Some(Box::new(MinAccumulator::default())),
1691 })
1692 } else {
1693 Box::new(move || AccumulatorWrapper::Expression {
1694 evaluator: Rc::clone(&evaluator),
1695 accumulator: Some(Box::new(MinAccumulator::default())),
1696 })
1697 }
1698 }
1699 AggregateFunction::Max => {
1700 let evaluator =
1701 self.expression_evaluator(expr, encoded_variables, stat_children);
1702 if *distinct {
1703 Box::new(move || AccumulatorWrapper::DistinctExpression {
1704 evaluator: Rc::clone(&evaluator),
1705 seen: FxHashSet::default(),
1706 accumulator: Some(Box::new(MaxAccumulator::default())),
1707 })
1708 } else {
1709 Box::new(move || AccumulatorWrapper::Expression {
1710 evaluator: Rc::clone(&evaluator),
1711 accumulator: Some(Box::new(MaxAccumulator::default())),
1712 })
1713 }
1714 }
1715 AggregateFunction::Avg => {
1716 let evaluator =
1717 self.expression_evaluator(expr, encoded_variables, stat_children);
1718 if *distinct {
1719 Box::new(move || AccumulatorWrapper::DistinctExpression {
1720 evaluator: Rc::clone(&evaluator),
1721 seen: FxHashSet::default(),
1722 accumulator: Some(Box::new(AvgAccumulator::default())),
1723 })
1724 } else {
1725 Box::new(move || AccumulatorWrapper::Expression {
1726 evaluator: Rc::clone(&evaluator),
1727 accumulator: Some(Box::new(AvgAccumulator::default())),
1728 })
1729 }
1730 }
1731 AggregateFunction::Sample => {
1732 let evaluator =
1733 self.expression_evaluator(expr, encoded_variables, stat_children);
1734 Box::new(move || AccumulatorWrapper::Sample {
1735 evaluator: Rc::clone(&evaluator),
1736 value: None,
1737 })
1738 }
1739 AggregateFunction::GroupConcat { separator } => {
1740 let separator = Rc::from(separator.as_deref().unwrap_or(" "));
1741 let evaluator =
1742 self.expression_evaluator(expr, encoded_variables, stat_children);
1743 if *distinct {
1744 Box::new(move || AccumulatorWrapper::DistinctExpression {
1745 evaluator: Rc::clone(&evaluator),
1746 seen: FxHashSet::default(),
1747 accumulator: Some(Box::new(GroupConcatAccumulator::new(Rc::clone(
1748 &separator,
1749 )))),
1750 })
1751 } else {
1752 Box::new(move || AccumulatorWrapper::Expression {
1753 evaluator: Rc::clone(&evaluator),
1754 accumulator: Some(Box::new(GroupConcatAccumulator::new(Rc::clone(
1755 &separator,
1756 )))),
1757 })
1758 }
1759 }
1760 AggregateFunction::Custom(_) => Box::new(move || AccumulatorWrapper::Failing),
1761 },
1762 }
1763 }
1764
1765 fn internal_expression_evaluator(
1769 &self,
1770 expression: &Expression,
1771 encoded_variables: &mut Vec<Variable>,
1772 stat_children: &mut Vec<Rc<EvalNodeWithStats>>,
1773 ) -> Option<Rc<dyn Fn(&InternalTuple<D>) -> Option<D::InternalTerm>>> {
1774 Some(match expression {
1775 Expression::NamedNode(t) => {
1776 let t = self.encode_term(t.clone()).ok();
1777 Rc::new(move |_| t.clone())
1778 }
1779 Expression::Literal(t) => {
1780 let t = self.encode_term(t.clone()).ok();
1781 Rc::new(move |_| t.clone())
1782 }
1783 Expression::Variable(v) => {
1784 let v = encode_variable(encoded_variables, v);
1785 Rc::new(move |tuple| tuple.get(v).cloned())
1786 }
1787 Expression::Coalesce(l) => {
1788 let l = l
1789 .iter()
1790 .map(|e| {
1791 self.internal_expression_evaluator(e, encoded_variables, stat_children)
1792 })
1793 .collect::<Option<Vec<_>>>()?;
1794 Rc::new(move |tuple| {
1795 for e in &l {
1796 if let Some(result) = e(tuple) {
1797 return Some(result);
1798 }
1799 }
1800 None
1801 })
1802 }
1803 Expression::If(a, b, c) => {
1804 let a = self.effective_boolean_value_expression_evaluator(
1805 a,
1806 encoded_variables,
1807 stat_children,
1808 );
1809 let b = self.internal_expression_evaluator(b, encoded_variables, stat_children)?;
1810 let c = self.internal_expression_evaluator(c, encoded_variables, stat_children)?;
1811 Rc::new(move |tuple| if a(tuple)? { b(tuple) } else { c(tuple) })
1812 }
1813 Expression::Or(_)
1814 | Expression::And(_)
1815 | Expression::Equal(_, _)
1816 | Expression::SameTerm(_, _)
1817 | Expression::Greater(_, _)
1818 | Expression::GreaterOrEqual(_, _)
1819 | Expression::Less(_, _)
1820 | Expression::LessOrEqual(_, _)
1821 | Expression::Add(_, _)
1822 | Expression::Subtract(_, _)
1823 | Expression::Multiply(_, _)
1824 | Expression::Divide(_, _)
1825 | Expression::UnaryPlus(_)
1826 | Expression::UnaryMinus(_)
1827 | Expression::Not(_)
1828 | Expression::Exists(_)
1829 | Expression::Bound(_)
1830 | Expression::FunctionCall(_, _) => return None, })
1832 }
1833
1834 fn effective_boolean_value_expression_evaluator(
1836 &self,
1837 expression: &Expression,
1838 encoded_variables: &mut Vec<Variable>,
1839 stat_children: &mut Vec<Rc<EvalNodeWithStats>>,
1840 ) -> Rc<dyn Fn(&InternalTuple<D>) -> Option<bool>> {
1841 if let Some(eval) =
1843 self.internal_expression_evaluator(expression, encoded_variables, stat_children)
1844 {
1845 let dataset = self.dataset.clone();
1846 return Rc::new(move |tuple| {
1847 dataset
1848 .internal_term_effective_boolean_value(eval(tuple)?)
1849 .ok()?
1850 });
1851 }
1852 let eval = self.expression_evaluator(expression, encoded_variables, stat_children);
1853 Rc::new(move |tuple| eval(tuple)?.effective_boolean_value())
1854 }
1855
1856 fn expression_evaluator(
1858 &self,
1859 expression: &Expression,
1860 encoded_variables: &mut Vec<Variable>,
1861 stat_children: &mut Vec<Rc<EvalNodeWithStats>>,
1862 ) -> Rc<dyn Fn(&InternalTuple<D>) -> Option<ExpressionTerm>> {
1863 match expression {
1864 Expression::NamedNode(t) => {
1865 let t = ExpressionTerm::from(Term::from(t.clone()));
1866 Rc::new(move |_| Some(t.clone()))
1867 }
1868 Expression::Literal(t) => {
1869 let t = ExpressionTerm::from(Term::from(t.clone()));
1870 Rc::new(move |_| Some(t.clone()))
1871 }
1872 Expression::Variable(v) => {
1873 let v = encode_variable(encoded_variables, v);
1874 let dataset = self.dataset.clone();
1875 Rc::new(move |tuple| {
1876 tuple
1877 .get(v)
1878 .cloned()
1879 .and_then(|t| dataset.externalize_expression_term(t).ok())
1880 })
1881 }
1882 Expression::Bound(v) => {
1883 let v = encode_variable(encoded_variables, v);
1884 Rc::new(move |tuple| Some(tuple.contains(v).into()))
1885 }
1886 Expression::Exists(plan) => {
1887 let (eval, stats) = self.graph_pattern_evaluator(plan, encoded_variables);
1888 stat_children.push(stats);
1889 Rc::new(move |tuple| Some(eval(tuple.clone()).next().is_some().into()))
1890 }
1891 Expression::Or(inner) => {
1892 let children = inner
1893 .iter()
1894 .map(|i| {
1895 self.effective_boolean_value_expression_evaluator(
1896 i,
1897 encoded_variables,
1898 stat_children,
1899 )
1900 })
1901 .collect::<Rc<[_]>>();
1902 Rc::new(move |tuple| {
1903 let mut error = false;
1904 for child in &*children {
1905 match child(tuple) {
1906 Some(true) => return Some(true.into()),
1907 Some(false) => (),
1908 None => error = true,
1909 }
1910 }
1911 if error {
1912 None
1913 } else {
1914 Some(false.into())
1915 }
1916 })
1917 }
1918 Expression::And(inner) => {
1919 let children = inner
1920 .iter()
1921 .map(|i| {
1922 self.effective_boolean_value_expression_evaluator(
1923 i,
1924 encoded_variables,
1925 stat_children,
1926 )
1927 })
1928 .collect::<Rc<[_]>>();
1929 Rc::new(move |tuple| {
1930 let mut error = false;
1931 for child in &*children {
1932 match child(tuple) {
1933 Some(true) => (),
1934 Some(false) => return Some(false.into()),
1935 None => error = true,
1936 }
1937 }
1938 if error {
1939 None
1940 } else {
1941 Some(true.into())
1942 }
1943 })
1944 }
1945 Expression::Equal(a, b) => {
1946 let a = self.expression_evaluator(a, encoded_variables, stat_children);
1947 let b = self.expression_evaluator(b, encoded_variables, stat_children);
1948 Rc::new(move |tuple| equals(&a(tuple)?, &b(tuple)?).map(Into::into))
1949 }
1950 Expression::SameTerm(a, b) => {
1951 if let (Some(a), Some(b)) = (
1952 self.internal_expression_evaluator(a, encoded_variables, stat_children),
1953 self.internal_expression_evaluator(b, encoded_variables, stat_children),
1954 ) {
1955 return Rc::new(move |tuple| Some((a(tuple)? == b(tuple)?).into()));
1956 };
1957 let a = self.expression_evaluator(a, encoded_variables, stat_children);
1958 let b = self.expression_evaluator(b, encoded_variables, stat_children);
1959 Rc::new(move |tuple| Some((a(tuple)? == b(tuple)?).into()))
1961 }
1962 Expression::Greater(a, b) => {
1963 let a = self.expression_evaluator(a, encoded_variables, stat_children);
1964 let b = self.expression_evaluator(b, encoded_variables, stat_children);
1965 Rc::new(move |tuple| {
1966 Some((partial_cmp(&a(tuple)?, &b(tuple)?)? == Ordering::Greater).into())
1967 })
1968 }
1969 Expression::GreaterOrEqual(a, b) => {
1970 let a = self.expression_evaluator(a, encoded_variables, stat_children);
1971 let b = self.expression_evaluator(b, encoded_variables, stat_children);
1972 Rc::new(move |tuple| {
1973 Some(
1974 match partial_cmp(&a(tuple)?, &b(tuple)?)? {
1975 Ordering::Greater | Ordering::Equal => true,
1976 Ordering::Less => false,
1977 }
1978 .into(),
1979 )
1980 })
1981 }
1982 Expression::Less(a, b) => {
1983 let a = self.expression_evaluator(a, encoded_variables, stat_children);
1984 let b = self.expression_evaluator(b, encoded_variables, stat_children);
1985 Rc::new(move |tuple| {
1986 Some((partial_cmp(&a(tuple)?, &b(tuple)?)? == Ordering::Less).into())
1987 })
1988 }
1989 Expression::LessOrEqual(a, b) => {
1990 let a = self.expression_evaluator(a, encoded_variables, stat_children);
1991 let b = self.expression_evaluator(b, encoded_variables, stat_children);
1992 Rc::new(move |tuple| {
1993 Some(
1994 match partial_cmp(&a(tuple)?, &b(tuple)?)? {
1995 Ordering::Less | Ordering::Equal => true,
1996 Ordering::Greater => false,
1997 }
1998 .into(),
1999 )
2000 })
2001 }
2002 Expression::Add(a, b) => {
2003 let a = self.expression_evaluator(a, encoded_variables, stat_children);
2004 let b = self.expression_evaluator(b, encoded_variables, stat_children);
2005 Rc::new(move |tuple| {
2006 Some(match NumericBinaryOperands::new(a(tuple)?, b(tuple)?)? {
2007 NumericBinaryOperands::Float(v1, v2) => {
2008 ExpressionTerm::FloatLiteral(v1 + v2)
2009 }
2010 NumericBinaryOperands::Double(v1, v2) => {
2011 ExpressionTerm::DoubleLiteral(v1 + v2)
2012 }
2013 NumericBinaryOperands::Integer(v1, v2) => {
2014 ExpressionTerm::IntegerLiteral(v1.checked_add(v2)?)
2015 }
2016 NumericBinaryOperands::Decimal(v1, v2) => {
2017 ExpressionTerm::DecimalLiteral(v1.checked_add(v2)?)
2018 }
2019 #[cfg(feature = "sep-0002")]
2020 NumericBinaryOperands::Duration(v1, v2) => {
2021 ExpressionTerm::DurationLiteral(v1.checked_add(v2)?)
2022 }
2023 #[cfg(feature = "sep-0002")]
2024 NumericBinaryOperands::YearMonthDuration(v1, v2) => {
2025 ExpressionTerm::YearMonthDurationLiteral(v1.checked_add(v2)?)
2026 }
2027 #[cfg(feature = "sep-0002")]
2028 NumericBinaryOperands::DayTimeDuration(v1, v2) => {
2029 ExpressionTerm::DayTimeDurationLiteral(v1.checked_add(v2)?)
2030 }
2031 #[cfg(feature = "sep-0002")]
2032 NumericBinaryOperands::DateTimeDuration(v1, v2) => {
2033 ExpressionTerm::DateTimeLiteral(v1.checked_add_duration(v2)?)
2034 }
2035 #[cfg(feature = "sep-0002")]
2036 NumericBinaryOperands::DateTimeYearMonthDuration(v1, v2) => {
2037 ExpressionTerm::DateTimeLiteral(v1.checked_add_year_month_duration(v2)?)
2038 }
2039 #[cfg(feature = "sep-0002")]
2040 NumericBinaryOperands::DateTimeDayTimeDuration(v1, v2) => {
2041 ExpressionTerm::DateTimeLiteral(v1.checked_add_day_time_duration(v2)?)
2042 }
2043 #[cfg(feature = "sep-0002")]
2044 NumericBinaryOperands::DateDuration(v1, v2) => {
2045 ExpressionTerm::DateLiteral(v1.checked_add_duration(v2)?)
2046 }
2047 #[cfg(feature = "sep-0002")]
2048 NumericBinaryOperands::DateYearMonthDuration(v1, v2) => {
2049 ExpressionTerm::DateLiteral(v1.checked_add_year_month_duration(v2)?)
2050 }
2051 #[cfg(feature = "sep-0002")]
2052 NumericBinaryOperands::DateDayTimeDuration(v1, v2) => {
2053 ExpressionTerm::DateLiteral(v1.checked_add_day_time_duration(v2)?)
2054 }
2055 #[cfg(feature = "sep-0002")]
2056 NumericBinaryOperands::TimeDuration(v1, v2) => {
2057 ExpressionTerm::TimeLiteral(v1.checked_add_duration(v2)?)
2058 }
2059 #[cfg(feature = "sep-0002")]
2060 NumericBinaryOperands::TimeDayTimeDuration(v1, v2) => {
2061 ExpressionTerm::TimeLiteral(v1.checked_add_day_time_duration(v2)?)
2062 }
2063 #[cfg(feature = "sep-0002")]
2064 NumericBinaryOperands::DateTime(_, _)
2065 | NumericBinaryOperands::Time(_, _)
2066 | NumericBinaryOperands::Date(_, _) => return None,
2067 })
2068 })
2069 }
2070 Expression::Subtract(a, b) => {
2071 let a = self.expression_evaluator(a, encoded_variables, stat_children);
2072 let b = self.expression_evaluator(b, encoded_variables, stat_children);
2073 Rc::new(move |tuple| {
2074 Some(match NumericBinaryOperands::new(a(tuple)?, b(tuple)?)? {
2075 NumericBinaryOperands::Float(v1, v2) => {
2076 ExpressionTerm::FloatLiteral(v1 - v2)
2077 }
2078 NumericBinaryOperands::Double(v1, v2) => {
2079 ExpressionTerm::DoubleLiteral(v1 - v2)
2080 }
2081 NumericBinaryOperands::Integer(v1, v2) => {
2082 ExpressionTerm::IntegerLiteral(v1.checked_sub(v2)?)
2083 }
2084 NumericBinaryOperands::Decimal(v1, v2) => {
2085 ExpressionTerm::DecimalLiteral(v1.checked_sub(v2)?)
2086 }
2087 #[cfg(feature = "sep-0002")]
2088 NumericBinaryOperands::DateTime(v1, v2) => {
2089 ExpressionTerm::DayTimeDurationLiteral(v1.checked_sub(v2)?)
2090 }
2091 #[cfg(feature = "sep-0002")]
2092 NumericBinaryOperands::Date(v1, v2) => {
2093 ExpressionTerm::DayTimeDurationLiteral(v1.checked_sub(v2)?)
2094 }
2095 #[cfg(feature = "sep-0002")]
2096 NumericBinaryOperands::Time(v1, v2) => {
2097 ExpressionTerm::DayTimeDurationLiteral(v1.checked_sub(v2)?)
2098 }
2099 #[cfg(feature = "sep-0002")]
2100 NumericBinaryOperands::Duration(v1, v2) => {
2101 ExpressionTerm::DurationLiteral(v1.checked_sub(v2)?)
2102 }
2103 #[cfg(feature = "sep-0002")]
2104 NumericBinaryOperands::YearMonthDuration(v1, v2) => {
2105 ExpressionTerm::YearMonthDurationLiteral(v1.checked_sub(v2)?)
2106 }
2107 #[cfg(feature = "sep-0002")]
2108 NumericBinaryOperands::DayTimeDuration(v1, v2) => {
2109 ExpressionTerm::DayTimeDurationLiteral(v1.checked_sub(v2)?)
2110 }
2111 #[cfg(feature = "sep-0002")]
2112 NumericBinaryOperands::DateTimeDuration(v1, v2) => {
2113 ExpressionTerm::DateTimeLiteral(v1.checked_sub_duration(v2)?)
2114 }
2115 #[cfg(feature = "sep-0002")]
2116 NumericBinaryOperands::DateTimeYearMonthDuration(v1, v2) => {
2117 ExpressionTerm::DateTimeLiteral(v1.checked_sub_year_month_duration(v2)?)
2118 }
2119 #[cfg(feature = "sep-0002")]
2120 NumericBinaryOperands::DateTimeDayTimeDuration(v1, v2) => {
2121 ExpressionTerm::DateTimeLiteral(v1.checked_sub_day_time_duration(v2)?)
2122 }
2123 #[cfg(feature = "sep-0002")]
2124 NumericBinaryOperands::DateDuration(v1, v2) => {
2125 ExpressionTerm::DateLiteral(v1.checked_sub_duration(v2)?)
2126 }
2127 #[cfg(feature = "sep-0002")]
2128 NumericBinaryOperands::DateYearMonthDuration(v1, v2) => {
2129 ExpressionTerm::DateLiteral(v1.checked_sub_year_month_duration(v2)?)
2130 }
2131 #[cfg(feature = "sep-0002")]
2132 NumericBinaryOperands::DateDayTimeDuration(v1, v2) => {
2133 ExpressionTerm::DateLiteral(v1.checked_sub_day_time_duration(v2)?)
2134 }
2135 #[cfg(feature = "sep-0002")]
2136 NumericBinaryOperands::TimeDuration(v1, v2) => {
2137 ExpressionTerm::TimeLiteral(v1.checked_sub_duration(v2)?)
2138 }
2139 #[cfg(feature = "sep-0002")]
2140 NumericBinaryOperands::TimeDayTimeDuration(v1, v2) => {
2141 ExpressionTerm::TimeLiteral(v1.checked_sub_day_time_duration(v2)?)
2142 }
2143 })
2144 })
2145 }
2146 Expression::Multiply(a, b) => {
2147 let a = self.expression_evaluator(a, encoded_variables, stat_children);
2148 let b = self.expression_evaluator(b, encoded_variables, stat_children);
2149 Rc::new(move |tuple| {
2150 Some(match NumericBinaryOperands::new(a(tuple)?, b(tuple)?)? {
2151 NumericBinaryOperands::Float(v1, v2) => {
2152 ExpressionTerm::FloatLiteral(v1 * v2)
2153 }
2154 NumericBinaryOperands::Double(v1, v2) => {
2155 ExpressionTerm::DoubleLiteral(v1 * v2)
2156 }
2157 NumericBinaryOperands::Integer(v1, v2) => {
2158 ExpressionTerm::IntegerLiteral(v1.checked_mul(v2)?)
2159 }
2160 NumericBinaryOperands::Decimal(v1, v2) => {
2161 ExpressionTerm::DecimalLiteral(v1.checked_mul(v2)?)
2162 }
2163 #[cfg(feature = "sep-0002")]
2164 _ => return None,
2165 })
2166 })
2167 }
2168 Expression::Divide(a, b) => {
2169 let a = self.expression_evaluator(a, encoded_variables, stat_children);
2170 let b = self.expression_evaluator(b, encoded_variables, stat_children);
2171 Rc::new(move |tuple| {
2172 Some(match NumericBinaryOperands::new(a(tuple)?, b(tuple)?)? {
2173 NumericBinaryOperands::Float(v1, v2) => {
2174 ExpressionTerm::FloatLiteral(v1 / v2)
2175 }
2176 NumericBinaryOperands::Double(v1, v2) => {
2177 ExpressionTerm::DoubleLiteral(v1 / v2)
2178 }
2179 NumericBinaryOperands::Integer(v1, v2) => {
2180 ExpressionTerm::DecimalLiteral(Decimal::from(v1).checked_div(v2)?)
2181 }
2182 NumericBinaryOperands::Decimal(v1, v2) => {
2183 ExpressionTerm::DecimalLiteral(v1.checked_div(v2)?)
2184 }
2185 #[cfg(feature = "sep-0002")]
2186 _ => return None,
2187 })
2188 })
2189 }
2190 Expression::UnaryPlus(e) => {
2191 let e = self.expression_evaluator(e, encoded_variables, stat_children);
2192 Rc::new(move |tuple| {
2193 Some(match e(tuple)? {
2194 ExpressionTerm::FloatLiteral(value) => ExpressionTerm::FloatLiteral(value),
2195 ExpressionTerm::DoubleLiteral(value) => {
2196 ExpressionTerm::DoubleLiteral(value)
2197 }
2198 ExpressionTerm::IntegerLiteral(value) => {
2199 ExpressionTerm::IntegerLiteral(value)
2200 }
2201 ExpressionTerm::DecimalLiteral(value) => {
2202 ExpressionTerm::DecimalLiteral(value)
2203 }
2204 #[cfg(feature = "sep-0002")]
2205 ExpressionTerm::DurationLiteral(value) => {
2206 ExpressionTerm::DurationLiteral(value)
2207 }
2208 #[cfg(feature = "sep-0002")]
2209 ExpressionTerm::YearMonthDurationLiteral(value) => {
2210 ExpressionTerm::YearMonthDurationLiteral(value)
2211 }
2212 #[cfg(feature = "sep-0002")]
2213 ExpressionTerm::DayTimeDurationLiteral(value) => {
2214 ExpressionTerm::DayTimeDurationLiteral(value)
2215 }
2216 _ => return None,
2217 })
2218 })
2219 }
2220 Expression::UnaryMinus(e) => {
2221 let e = self.expression_evaluator(e, encoded_variables, stat_children);
2222 Rc::new(move |tuple| {
2223 Some(match e(tuple)? {
2224 ExpressionTerm::FloatLiteral(value) => ExpressionTerm::FloatLiteral(-value),
2225 ExpressionTerm::DoubleLiteral(value) => {
2226 ExpressionTerm::DoubleLiteral(-value)
2227 }
2228 ExpressionTerm::IntegerLiteral(value) => {
2229 ExpressionTerm::IntegerLiteral(value.checked_neg()?)
2230 }
2231 ExpressionTerm::DecimalLiteral(value) => {
2232 ExpressionTerm::DecimalLiteral(value.checked_neg()?)
2233 }
2234 #[cfg(feature = "sep-0002")]
2235 ExpressionTerm::DurationLiteral(value) => {
2236 ExpressionTerm::DurationLiteral(value.checked_neg()?)
2237 }
2238 #[cfg(feature = "sep-0002")]
2239 ExpressionTerm::YearMonthDurationLiteral(value) => {
2240 ExpressionTerm::YearMonthDurationLiteral(value.checked_neg()?)
2241 }
2242 #[cfg(feature = "sep-0002")]
2243 ExpressionTerm::DayTimeDurationLiteral(value) => {
2244 ExpressionTerm::DayTimeDurationLiteral(value.checked_neg()?)
2245 }
2246 _ => return None,
2247 })
2248 })
2249 }
2250 Expression::Not(e) => {
2251 let e = self.effective_boolean_value_expression_evaluator(
2252 e,
2253 encoded_variables,
2254 stat_children,
2255 );
2256 Rc::new(move |tuple| Some((!e(tuple)?).into()))
2257 }
2258 Expression::Coalesce(l) => {
2259 let l: Vec<_> = l
2260 .iter()
2261 .map(|e| self.expression_evaluator(e, encoded_variables, stat_children))
2262 .collect();
2263 Rc::new(move |tuple| {
2264 for e in &l {
2265 if let Some(result) = e(tuple) {
2266 return Some(result);
2267 }
2268 }
2269 None
2270 })
2271 }
2272 Expression::If(a, b, c) => {
2273 let a = self.effective_boolean_value_expression_evaluator(
2274 a,
2275 encoded_variables,
2276 stat_children,
2277 );
2278 let b = self.expression_evaluator(b, encoded_variables, stat_children);
2279 let c = self.expression_evaluator(c, encoded_variables, stat_children);
2280 Rc::new(move |tuple| if a(tuple)? { b(tuple) } else { c(tuple) })
2281 }
2282 Expression::FunctionCall(function, parameters) => match function {
2283 Function::Str => {
2284 let e =
2285 self.expression_evaluator(¶meters[0], encoded_variables, stat_children);
2286 Rc::new(move |tuple| {
2287 Some(ExpressionTerm::StringLiteral(match e(tuple)?.into() {
2288 Term::NamedNode(term) => term.into_string(),
2289 Term::BlankNode(_) => return None,
2290 Term::Literal(term) => term.destruct().0,
2291 #[cfg(feature = "rdf-star")]
2292 Term::Triple(_) => return None,
2293 }))
2294 })
2295 }
2296 Function::Lang => {
2297 let e =
2298 self.expression_evaluator(¶meters[0], encoded_variables, stat_children);
2299 Rc::new(move |tuple| {
2300 Some(ExpressionTerm::StringLiteral(match e(tuple)? {
2301 ExpressionTerm::LangStringLiteral { language, .. } => language,
2302 ExpressionTerm::NamedNode(_) | ExpressionTerm::BlankNode(_) => {
2303 return None
2304 }
2305 #[cfg(feature = "rdf-star")]
2306 ExpressionTerm::Triple(_) => return None,
2307 _ => String::new(),
2308 }))
2309 })
2310 }
2311 Function::LangMatches => {
2312 let language_tag =
2313 self.expression_evaluator(¶meters[0], encoded_variables, stat_children);
2314 let language_range =
2315 self.expression_evaluator(¶meters[1], encoded_variables, stat_children);
2316 Rc::new(move |tuple| {
2317 let ExpressionTerm::StringLiteral(mut language_tag) = language_tag(tuple)?
2318 else {
2319 return None;
2320 };
2321 language_tag.make_ascii_lowercase();
2322 let ExpressionTerm::StringLiteral(mut language_range) =
2323 language_range(tuple)?
2324 else {
2325 return None;
2326 };
2327 language_range.make_ascii_lowercase();
2328 Some(
2329 if &*language_range == "*" {
2330 !language_tag.is_empty()
2331 } else {
2332 !ZipLongest::new(language_range.split('-'), language_tag.split('-'))
2333 .any(|parts| match parts {
2334 (Some(range_subtag), Some(language_subtag)) => {
2335 range_subtag != language_subtag
2336 }
2337 (Some(_), None) => true,
2338 (None, _) => false,
2339 })
2340 }
2341 .into(),
2342 )
2343 })
2344 }
2345 Function::Datatype => {
2346 let e =
2347 self.expression_evaluator(¶meters[0], encoded_variables, stat_children);
2348 Rc::new(move |tuple| {
2349 Some(ExpressionTerm::NamedNode(match e(tuple)? {
2350 ExpressionTerm::StringLiteral(_) => xsd::STRING.into(),
2351 ExpressionTerm::LangStringLiteral { .. } => rdf::LANG_STRING.into(),
2352 ExpressionTerm::BooleanLiteral(_) => xsd::BOOLEAN.into(),
2353 ExpressionTerm::IntegerLiteral(_) => xsd::INTEGER.into(),
2354 ExpressionTerm::DecimalLiteral(_) => xsd::DECIMAL.into(),
2355 ExpressionTerm::FloatLiteral(_) => xsd::FLOAT.into(),
2356 ExpressionTerm::DoubleLiteral(_) => xsd::DOUBLE.into(),
2357 ExpressionTerm::DateTimeLiteral(_) => xsd::DATE_TIME.into(),
2358 #[cfg(feature = "sep-0002")]
2359 ExpressionTerm::DateLiteral(_) => xsd::DATE.into(),
2360 #[cfg(feature = "sep-0002")]
2361 ExpressionTerm::TimeLiteral(_) => xsd::TIME.into(),
2362 #[cfg(feature = "calendar-ext")]
2363 ExpressionTerm::GYearLiteral(_) => xsd::G_YEAR.into(),
2364 #[cfg(feature = "calendar-ext")]
2365 ExpressionTerm::GYearMonthLiteral(_) => xsd::G_YEAR_MONTH.into(),
2366 #[cfg(feature = "calendar-ext")]
2367 ExpressionTerm::GMonthLiteral(_) => xsd::G_MONTH.into(),
2368 #[cfg(feature = "calendar-ext")]
2369 ExpressionTerm::GMonthDayLiteral(_) => xsd::G_MONTH_DAY.into(),
2370 #[cfg(feature = "calendar-ext")]
2371 ExpressionTerm::GDayLiteral(_) => xsd::G_DAY.into(),
2372 #[cfg(feature = "sep-0002")]
2373 ExpressionTerm::DurationLiteral(_) => xsd::DURATION.into(),
2374 #[cfg(feature = "sep-0002")]
2375 ExpressionTerm::YearMonthDurationLiteral(_) => {
2376 xsd::YEAR_MONTH_DURATION.into()
2377 }
2378 #[cfg(feature = "sep-0002")]
2379 ExpressionTerm::DayTimeDurationLiteral(_) => {
2380 xsd::DAY_TIME_DURATION.into()
2381 }
2382 ExpressionTerm::OtherTypedLiteral { datatype, .. } => datatype,
2383 ExpressionTerm::NamedNode(_) | ExpressionTerm::BlankNode(_) => {
2384 return None
2385 }
2386 #[cfg(feature = "rdf-star")]
2387 ExpressionTerm::Triple(_) => return None,
2388 }))
2389 })
2390 }
2391 Function::Iri => {
2392 let e =
2393 self.expression_evaluator(¶meters[0], encoded_variables, stat_children);
2394 let base_iri = self.base_iri.clone();
2395 Rc::new(move |tuple| {
2396 Some(ExpressionTerm::NamedNode(match e(tuple)? {
2397 ExpressionTerm::NamedNode(iri) => iri,
2398 ExpressionTerm::StringLiteral(iri) => if let Some(base_iri) = &base_iri
2399 {
2400 base_iri.resolve(&iri)
2401 } else {
2402 Iri::parse(iri)
2403 }
2404 .ok()?
2405 .into(),
2406 _ => return None,
2407 }))
2408 })
2409 }
2410 Function::BNode => match parameters.first() {
2411 Some(id) => {
2412 let id = self.expression_evaluator(id, encoded_variables, stat_children);
2413 Rc::new(move |tuple| {
2414 let ExpressionTerm::StringLiteral(id) = id(tuple)? else {
2415 return None;
2416 };
2417 Some(ExpressionTerm::BlankNode(BlankNode::new(id).ok()?))
2418 })
2419 }
2420 None => Rc::new(|_| Some(ExpressionTerm::BlankNode(BlankNode::default()))),
2421 },
2422 Function::Rand => {
2423 Rc::new(|_| Some(ExpressionTerm::DoubleLiteral(random::<f64>().into())))
2424 }
2425 Function::Abs => {
2426 let e =
2427 self.expression_evaluator(¶meters[0], encoded_variables, stat_children);
2428 Rc::new(move |tuple| match e(tuple)? {
2429 ExpressionTerm::IntegerLiteral(value) => {
2430 Some(ExpressionTerm::IntegerLiteral(value.checked_abs()?))
2431 }
2432 ExpressionTerm::DecimalLiteral(value) => {
2433 Some(ExpressionTerm::DecimalLiteral(value.checked_abs()?))
2434 }
2435 ExpressionTerm::FloatLiteral(value) => {
2436 Some(ExpressionTerm::FloatLiteral(value.abs()))
2437 }
2438 ExpressionTerm::DoubleLiteral(value) => {
2439 Some(ExpressionTerm::DoubleLiteral(value.abs()))
2440 }
2441 _ => None,
2442 })
2443 }
2444 Function::Ceil => {
2445 let e =
2446 self.expression_evaluator(¶meters[0], encoded_variables, stat_children);
2447 Rc::new(move |tuple| match e(tuple)? {
2448 ExpressionTerm::IntegerLiteral(value) => {
2449 Some(ExpressionTerm::IntegerLiteral(value))
2450 }
2451 ExpressionTerm::DecimalLiteral(value) => {
2452 Some(ExpressionTerm::DecimalLiteral(value.checked_ceil()?))
2453 }
2454 ExpressionTerm::FloatLiteral(value) => {
2455 Some(ExpressionTerm::FloatLiteral(value.ceil()))
2456 }
2457 ExpressionTerm::DoubleLiteral(value) => {
2458 Some(ExpressionTerm::DoubleLiteral(value.ceil()))
2459 }
2460 _ => None,
2461 })
2462 }
2463 Function::Floor => {
2464 let e =
2465 self.expression_evaluator(¶meters[0], encoded_variables, stat_children);
2466 Rc::new(move |tuple| match e(tuple)? {
2467 ExpressionTerm::IntegerLiteral(value) => {
2468 Some(ExpressionTerm::IntegerLiteral(value))
2469 }
2470 ExpressionTerm::DecimalLiteral(value) => {
2471 Some(ExpressionTerm::DecimalLiteral(value.checked_floor()?))
2472 }
2473 ExpressionTerm::FloatLiteral(value) => {
2474 Some(ExpressionTerm::FloatLiteral(value.floor()))
2475 }
2476 ExpressionTerm::DoubleLiteral(value) => {
2477 Some(ExpressionTerm::DoubleLiteral(value.floor()))
2478 }
2479 _ => None,
2480 })
2481 }
2482 Function::Round => {
2483 let e =
2484 self.expression_evaluator(¶meters[0], encoded_variables, stat_children);
2485 Rc::new(move |tuple| match e(tuple)? {
2486 ExpressionTerm::IntegerLiteral(value) => {
2487 Some(ExpressionTerm::IntegerLiteral(value))
2488 }
2489 ExpressionTerm::DecimalLiteral(value) => {
2490 Some(ExpressionTerm::DecimalLiteral(value.checked_round()?))
2491 }
2492 ExpressionTerm::FloatLiteral(value) => {
2493 Some(ExpressionTerm::FloatLiteral(value.round()))
2494 }
2495 ExpressionTerm::DoubleLiteral(value) => {
2496 Some(ExpressionTerm::DoubleLiteral(value.round()))
2497 }
2498 _ => None,
2499 })
2500 }
2501 Function::Concat => {
2502 let l: Vec<_> = parameters
2503 .iter()
2504 .map(|e| self.expression_evaluator(e, encoded_variables, stat_children))
2505 .collect();
2506 Rc::new(move |tuple| {
2507 let mut result = String::default();
2508 let mut language = None;
2509 for e in &l {
2510 let (value, e_language) = to_string_and_language(e(tuple)?)?;
2511 if let Some(lang) = &language {
2512 if *lang != e_language {
2513 language = Some(None)
2514 }
2515 } else {
2516 language = Some(e_language)
2517 }
2518 result += &value
2519 }
2520 Some(build_plain_literal(result, language.flatten()))
2521 })
2522 }
2523 Function::SubStr => {
2524 let source =
2525 self.expression_evaluator(¶meters[0], encoded_variables, stat_children);
2526 let starting_loc =
2527 self.expression_evaluator(¶meters[1], encoded_variables, stat_children);
2528 let length = parameters
2529 .get(2)
2530 .map(|l| self.expression_evaluator(l, encoded_variables, stat_children));
2531 Rc::new(move |tuple| {
2532 let (source, language) = to_string_and_language(source(tuple)?)?;
2533
2534 let starting_location: usize =
2535 if let ExpressionTerm::IntegerLiteral(v) = starting_loc(tuple)? {
2536 usize::try_from(i64::from(v)).ok()?
2537 } else {
2538 return None;
2539 };
2540 let length = if let Some(length) = &length {
2541 if let ExpressionTerm::IntegerLiteral(v) = length(tuple)? {
2542 Some(usize::try_from(i64::from(v)).ok()?)
2543 } else {
2544 return None;
2545 }
2546 } else {
2547 None
2548 };
2549
2550 let mut start_iter = source
2552 .char_indices()
2553 .skip(starting_location.checked_sub(1)?)
2554 .peekable();
2555 let result = if let Some((start_position, _)) = start_iter.peek().copied() {
2556 if let Some(length) = length {
2557 let mut end_iter = start_iter.skip(length).peekable();
2558 if let Some((end_position, _)) = end_iter.peek() {
2559 &source[start_position..*end_position]
2560 } else {
2561 &source[start_position..]
2562 }
2563 } else {
2564 &source[start_position..]
2565 }
2566 } else {
2567 ""
2568 };
2569 Some(build_plain_literal(result.into(), language))
2570 })
2571 }
2572 Function::StrLen => {
2573 let arg =
2574 self.expression_evaluator(¶meters[0], encoded_variables, stat_children);
2575 Rc::new(move |tuple| {
2576 let (string, _) = to_string_and_language(arg(tuple)?)?;
2577 Some(ExpressionTerm::IntegerLiteral(
2578 i64::try_from(string.chars().count()).ok()?.into(),
2579 ))
2580 })
2581 }
2582 Function::Replace => {
2583 let arg =
2584 self.expression_evaluator(¶meters[0], encoded_variables, stat_children);
2585 let replacement =
2586 self.expression_evaluator(¶meters[2], encoded_variables, stat_children);
2587 if let Some(regex) =
2588 compile_static_pattern_if_exists(¶meters[1], parameters.get(3))
2589 {
2590 Rc::new(move |tuple| {
2591 let (text, language) = to_string_and_language(arg(tuple)?)?;
2592 let ExpressionTerm::StringLiteral(replacement) = replacement(tuple)?
2593 else {
2594 return None;
2595 };
2596 Some(build_plain_literal(
2597 match regex.replace_all(&text, &replacement) {
2598 Cow::Owned(replaced) => replaced,
2599 Cow::Borrowed(_) => text,
2600 },
2601 language,
2602 ))
2603 })
2604 } else {
2605 let pattern = self.expression_evaluator(
2606 ¶meters[1],
2607 encoded_variables,
2608 stat_children,
2609 );
2610 let flags = parameters.get(3).map(|flags| {
2611 self.expression_evaluator(flags, encoded_variables, stat_children)
2612 });
2613 Rc::new(move |tuple| {
2614 let ExpressionTerm::StringLiteral(pattern) = pattern(tuple)? else {
2615 return None;
2616 };
2617 let options = if let Some(flags) = &flags {
2618 let ExpressionTerm::StringLiteral(options) = flags(tuple)? else {
2619 return None;
2620 };
2621 Some(options)
2622 } else {
2623 None
2624 };
2625 let regex = compile_pattern(&pattern, options.as_deref())?;
2626 let (text, language) = to_string_and_language(arg(tuple)?)?;
2627 let ExpressionTerm::StringLiteral(replacement) = replacement(tuple)?
2628 else {
2629 return None;
2630 };
2631 Some(build_plain_literal(
2632 match regex.replace_all(&text, &replacement) {
2633 Cow::Owned(replaced) => replaced,
2634 Cow::Borrowed(_) => text,
2635 },
2636 language,
2637 ))
2638 })
2639 }
2640 }
2641 Function::UCase => {
2642 let e =
2643 self.expression_evaluator(¶meters[0], encoded_variables, stat_children);
2644 Rc::new(move |tuple| {
2645 let (value, language) = to_string_and_language(e(tuple)?)?;
2646 Some(build_plain_literal(value.to_uppercase(), language))
2647 })
2648 }
2649 Function::LCase => {
2650 let e =
2651 self.expression_evaluator(¶meters[0], encoded_variables, stat_children);
2652 Rc::new(move |tuple| {
2653 let (value, language) = to_string_and_language(e(tuple)?)?;
2654 Some(build_plain_literal(value.to_lowercase(), language))
2655 })
2656 }
2657 Function::StrStarts => {
2658 let arg1 =
2659 self.expression_evaluator(¶meters[0], encoded_variables, stat_children);
2660 let arg2 =
2661 self.expression_evaluator(¶meters[1], encoded_variables, stat_children);
2662 Rc::new(move |tuple| {
2663 let (arg1, arg2, _) =
2664 to_argument_compatible_strings(arg1(tuple)?, arg2(tuple)?)?;
2665 Some(arg1.starts_with(arg2.as_str()).into())
2666 })
2667 }
2668 Function::EncodeForUri => {
2669 let ltrl =
2670 self.expression_evaluator(¶meters[0], encoded_variables, stat_children);
2671 Rc::new(move |tuple| {
2672 let (ltlr, _) = to_string_and_language(ltrl(tuple)?)?;
2673 let mut result = Vec::with_capacity(ltlr.len());
2674 for c in ltlr.bytes() {
2675 match c {
2676 b'A'..=b'Z'
2677 | b'a'..=b'z'
2678 | b'0'..=b'9'
2679 | b'-'
2680 | b'_'
2681 | b'.'
2682 | b'~' => result.push(c),
2683 _ => {
2684 result.push(b'%');
2685 let high = c / 16;
2686 let low = c % 16;
2687 result.push(if high < 10 {
2688 b'0' + high
2689 } else {
2690 b'A' + (high - 10)
2691 });
2692 result.push(if low < 10 {
2693 b'0' + low
2694 } else {
2695 b'A' + (low - 10)
2696 });
2697 }
2698 }
2699 }
2700 Some(ExpressionTerm::StringLiteral(
2701 String::from_utf8(result).ok()?,
2702 ))
2703 })
2704 }
2705 Function::StrEnds => {
2706 let arg1 =
2707 self.expression_evaluator(¶meters[0], encoded_variables, stat_children);
2708 let arg2 =
2709 self.expression_evaluator(¶meters[1], encoded_variables, stat_children);
2710 Rc::new(move |tuple| {
2711 let (arg1, arg2, _) =
2712 to_argument_compatible_strings(arg1(tuple)?, arg2(tuple)?)?;
2713 Some(arg1.ends_with(arg2.as_str()).into())
2714 })
2715 }
2716 Function::Contains => {
2717 let arg1 =
2718 self.expression_evaluator(¶meters[0], encoded_variables, stat_children);
2719 let arg2 =
2720 self.expression_evaluator(¶meters[1], encoded_variables, stat_children);
2721 Rc::new(move |tuple| {
2722 let (arg1, arg2, _) =
2723 to_argument_compatible_strings(arg1(tuple)?, arg2(tuple)?)?;
2724 Some(arg1.contains(arg2.as_str()).into())
2725 })
2726 }
2727 Function::StrBefore => {
2728 let arg1 =
2729 self.expression_evaluator(¶meters[0], encoded_variables, stat_children);
2730 let arg2 =
2731 self.expression_evaluator(¶meters[1], encoded_variables, stat_children);
2732 Rc::new(move |tuple| {
2733 let (arg1, arg2, language) =
2734 to_argument_compatible_strings(arg1(tuple)?, arg2(tuple)?)?;
2735 Some(if let Some(position) = arg1.find(arg2.as_str()) {
2736 build_plain_literal(arg1[..position].into(), language)
2737 } else {
2738 ExpressionTerm::StringLiteral(String::new())
2739 })
2740 })
2741 }
2742 Function::StrAfter => {
2743 let arg1 =
2744 self.expression_evaluator(¶meters[0], encoded_variables, stat_children);
2745 let arg2 =
2746 self.expression_evaluator(¶meters[1], encoded_variables, stat_children);
2747 Rc::new(move |tuple| {
2748 let (arg1, arg2, language) =
2749 to_argument_compatible_strings(arg1(tuple)?, arg2(tuple)?)?;
2750 Some(if let Some(position) = arg1.find(arg2.as_str()) {
2751 build_plain_literal(arg1[position + arg2.len()..].into(), language)
2752 } else {
2753 ExpressionTerm::StringLiteral(String::new())
2754 })
2755 })
2756 }
2757 Function::Year => {
2758 let e =
2759 self.expression_evaluator(¶meters[0], encoded_variables, stat_children);
2760 Rc::new(move |tuple| {
2761 Some(ExpressionTerm::IntegerLiteral(
2762 match e(tuple)? {
2763 ExpressionTerm::DateTimeLiteral(date_time) => date_time.year(),
2764 #[cfg(feature = "sep-0002")]
2765 ExpressionTerm::DateLiteral(date) => date.year(),
2766 #[cfg(feature = "calendar-ext")]
2767 ExpressionTerm::GYearMonthLiteral(year_month) => year_month.year(),
2768 #[cfg(feature = "calendar-ext")]
2769 ExpressionTerm::GYearLiteral(year) => year.year(),
2770 _ => return None,
2771 }
2772 .into(),
2773 ))
2774 })
2775 }
2776 Function::Month => {
2777 let e =
2778 self.expression_evaluator(¶meters[0], encoded_variables, stat_children);
2779 Rc::new(move |tuple| {
2780 Some(ExpressionTerm::IntegerLiteral(
2781 match e(tuple)? {
2782 ExpressionTerm::DateTimeLiteral(date_time) => date_time.month(),
2783 #[cfg(feature = "sep-0002")]
2784 ExpressionTerm::DateLiteral(date) => date.month(),
2785 #[cfg(feature = "calendar-ext")]
2786 ExpressionTerm::GYearMonthLiteral(year_month) => year_month.month(),
2787 #[cfg(feature = "calendar-ext")]
2788 ExpressionTerm::GMonthDayLiteral(month_day) => month_day.month(),
2789 #[cfg(feature = "calendar-ext")]
2790 ExpressionTerm::GMonthLiteral(month) => month.month(),
2791 _ => return None,
2792 }
2793 .into(),
2794 ))
2795 })
2796 }
2797 Function::Day => {
2798 let e =
2799 self.expression_evaluator(¶meters[0], encoded_variables, stat_children);
2800 Rc::new(move |tuple| {
2801 Some(ExpressionTerm::IntegerLiteral(
2802 match e(tuple)? {
2803 ExpressionTerm::DateTimeLiteral(date_time) => date_time.day(),
2804 #[cfg(feature = "sep-0002")]
2805 ExpressionTerm::DateLiteral(date) => date.day(),
2806 #[cfg(feature = "calendar-ext")]
2807 ExpressionTerm::GMonthDayLiteral(month_day) => month_day.day(),
2808 #[cfg(feature = "calendar-ext")]
2809 ExpressionTerm::GDayLiteral(day) => day.day(),
2810 _ => return None,
2811 }
2812 .into(),
2813 ))
2814 })
2815 }
2816 Function::Hours => {
2817 let e =
2818 self.expression_evaluator(¶meters[0], encoded_variables, stat_children);
2819 Rc::new(move |tuple| {
2820 Some(ExpressionTerm::IntegerLiteral(
2821 match e(tuple)? {
2822 ExpressionTerm::DateTimeLiteral(date_time) => date_time.hour(),
2823 #[cfg(feature = "sep-0002")]
2824 ExpressionTerm::TimeLiteral(time) => time.hour(),
2825 _ => return None,
2826 }
2827 .into(),
2828 ))
2829 })
2830 }
2831 Function::Minutes => {
2832 let e =
2833 self.expression_evaluator(¶meters[0], encoded_variables, stat_children);
2834 Rc::new(move |tuple| {
2835 Some(ExpressionTerm::IntegerLiteral(
2836 match e(tuple)? {
2837 ExpressionTerm::DateTimeLiteral(date_time) => date_time.minute(),
2838 #[cfg(feature = "sep-0002")]
2839 ExpressionTerm::TimeLiteral(time) => time.minute(),
2840 _ => return None,
2841 }
2842 .into(),
2843 ))
2844 })
2845 }
2846 Function::Seconds => {
2847 let e =
2848 self.expression_evaluator(¶meters[0], encoded_variables, stat_children);
2849 Rc::new(move |tuple| {
2850 Some(ExpressionTerm::DecimalLiteral(match e(tuple)? {
2851 ExpressionTerm::DateTimeLiteral(date_time) => date_time.second(),
2852 #[cfg(feature = "sep-0002")]
2853 ExpressionTerm::TimeLiteral(time) => time.second(),
2854 _ => return None,
2855 }))
2856 })
2857 }
2858 Function::Timezone => {
2859 let e =
2860 self.expression_evaluator(¶meters[0], encoded_variables, stat_children);
2861 Rc::new(move |tuple| {
2862 let result = match e(tuple)? {
2863 ExpressionTerm::DateTimeLiteral(date_time) => date_time.timezone(),
2864 #[cfg(feature = "sep-0002")]
2865 ExpressionTerm::TimeLiteral(time) => time.timezone(),
2866 #[cfg(feature = "sep-0002")]
2867 ExpressionTerm::DateLiteral(date) => date.timezone(),
2868 #[cfg(feature = "calendar-ext")]
2869 ExpressionTerm::GYearMonthLiteral(year_month) => year_month.timezone(),
2870 #[cfg(feature = "calendar-ext")]
2871 ExpressionTerm::GYearLiteral(year) => year.timezone(),
2872 #[cfg(feature = "calendar-ext")]
2873 ExpressionTerm::GMonthDayLiteral(month_day) => month_day.timezone(),
2874 #[cfg(feature = "calendar-ext")]
2875 ExpressionTerm::GDayLiteral(day) => day.timezone(),
2876 #[cfg(feature = "calendar-ext")]
2877 ExpressionTerm::GMonthLiteral(month) => month.timezone(),
2878 _ => None,
2879 }?;
2880 #[cfg(feature = "sep-0002")]
2881 {
2882 Some(ExpressionTerm::DayTimeDurationLiteral(result))
2883 }
2884 #[cfg(not(feature = "sep-0002"))]
2885 {
2886 Some(ExpressionTerm::OtherTypedLiteral {
2887 value: result.to_string(),
2888 datatype: xsd::DAY_TIME_DURATION.into(),
2889 })
2890 }
2891 })
2892 }
2893 Function::Tz => {
2894 let e =
2895 self.expression_evaluator(¶meters[0], encoded_variables, stat_children);
2896 Rc::new(move |tuple| {
2897 let timezone_offset = match e(tuple)? {
2898 ExpressionTerm::DateTimeLiteral(date_time) => {
2899 date_time.timezone_offset()
2900 }
2901 #[cfg(feature = "sep-0002")]
2902 ExpressionTerm::TimeLiteral(time) => time.timezone_offset(),
2903 #[cfg(feature = "sep-0002")]
2904 ExpressionTerm::DateLiteral(date) => date.timezone_offset(),
2905 #[cfg(feature = "calendar-ext")]
2906 ExpressionTerm::GYearMonthLiteral(year_month) => {
2907 year_month.timezone_offset()
2908 }
2909 #[cfg(feature = "calendar-ext")]
2910 ExpressionTerm::GYearLiteral(year) => year.timezone_offset(),
2911 #[cfg(feature = "calendar-ext")]
2912 ExpressionTerm::GMonthDayLiteral(month_day) => {
2913 month_day.timezone_offset()
2914 }
2915 #[cfg(feature = "calendar-ext")]
2916 ExpressionTerm::GDayLiteral(day) => day.timezone_offset(),
2917 #[cfg(feature = "calendar-ext")]
2918 ExpressionTerm::GMonthLiteral(month) => month.timezone_offset(),
2919 _ => return None,
2920 };
2921 Some(ExpressionTerm::StringLiteral(
2922 timezone_offset.map_or_else(String::new, |o| o.to_string()),
2923 ))
2924 })
2925 }
2926 #[cfg(feature = "sep-0002")]
2927 Function::Adjust => {
2928 let dt =
2929 self.expression_evaluator(¶meters[0], encoded_variables, stat_children);
2930 let tz =
2931 self.expression_evaluator(¶meters[1], encoded_variables, stat_children);
2932 Rc::new(move |tuple| {
2933 let timezone_offset = Some(
2934 match tz(tuple)? {
2935 ExpressionTerm::DayTimeDurationLiteral(tz) => {
2936 TimezoneOffset::try_from(tz)
2937 }
2938 ExpressionTerm::DurationLiteral(tz) => TimezoneOffset::try_from(tz),
2939 _ => return None,
2940 }
2941 .ok()?,
2942 );
2943 Some(match dt(tuple)? {
2944 ExpressionTerm::DateTimeLiteral(date_time) => {
2945 ExpressionTerm::DateTimeLiteral(date_time.adjust(timezone_offset)?)
2946 }
2947 ExpressionTerm::TimeLiteral(time) => {
2948 ExpressionTerm::TimeLiteral(time.adjust(timezone_offset)?)
2949 }
2950 ExpressionTerm::DateLiteral(date) => {
2951 ExpressionTerm::DateLiteral(date.adjust(timezone_offset)?)
2952 }
2953 #[cfg(feature = "calendar-ext")]
2954 ExpressionTerm::GYearMonthLiteral(year_month) => {
2955 ExpressionTerm::GYearMonthLiteral(
2956 year_month.adjust(timezone_offset)?,
2957 )
2958 }
2959 #[cfg(feature = "calendar-ext")]
2960 ExpressionTerm::GYearLiteral(year) => {
2961 ExpressionTerm::GYearLiteral(year.adjust(timezone_offset)?)
2962 }
2963 #[cfg(feature = "calendar-ext")]
2964 ExpressionTerm::GMonthDayLiteral(month_day) => {
2965 ExpressionTerm::GMonthDayLiteral(month_day.adjust(timezone_offset)?)
2966 }
2967 #[cfg(feature = "calendar-ext")]
2968 ExpressionTerm::GDayLiteral(day) => {
2969 ExpressionTerm::GDayLiteral(day.adjust(timezone_offset)?)
2970 }
2971 #[cfg(feature = "calendar-ext")]
2972 ExpressionTerm::GMonthLiteral(month) => {
2973 ExpressionTerm::GMonthLiteral(month.adjust(timezone_offset)?)
2974 }
2975 _ => return None,
2976 })
2977 })
2978 }
2979 Function::Now => {
2980 let now = self.now;
2981 Rc::new(move |_| Some(ExpressionTerm::DateTimeLiteral(now)))
2982 }
2983 Function::Uuid => Rc::new(move |_| {
2984 let mut buffer = String::with_capacity(44);
2985 buffer.push_str("urn:uuid:");
2986 generate_uuid(&mut buffer);
2987 Some(ExpressionTerm::NamedNode(NamedNode::new_unchecked(buffer)))
2988 }),
2989 Function::StrUuid => Rc::new(move |_| {
2990 let mut buffer = String::with_capacity(36);
2991 generate_uuid(&mut buffer);
2992 Some(ExpressionTerm::StringLiteral(buffer))
2993 }),
2994 Function::Md5 => self.hash::<Md5>(parameters, encoded_variables, stat_children),
2995 Function::Sha1 => self.hash::<Sha1>(parameters, encoded_variables, stat_children),
2996 Function::Sha256 => {
2997 self.hash::<Sha256>(parameters, encoded_variables, stat_children)
2998 }
2999 Function::Sha384 => {
3000 self.hash::<Sha384>(parameters, encoded_variables, stat_children)
3001 }
3002 Function::Sha512 => {
3003 self.hash::<Sha512>(parameters, encoded_variables, stat_children)
3004 }
3005 Function::StrLang => {
3006 let lexical_form =
3007 self.expression_evaluator(¶meters[0], encoded_variables, stat_children);
3008 let lang_tag =
3009 self.expression_evaluator(¶meters[1], encoded_variables, stat_children);
3010 Rc::new(move |tuple| {
3011 let ExpressionTerm::StringLiteral(value) = lexical_form(tuple)? else {
3012 return None;
3013 };
3014 let ExpressionTerm::StringLiteral(language) = lang_tag(tuple)? else {
3015 return None;
3016 };
3017 Some(
3018 Term::from(Literal::new_language_tagged_literal(value, language).ok()?)
3019 .into(),
3020 )
3021 })
3022 }
3023 Function::StrDt => {
3024 let lexical_form =
3025 self.expression_evaluator(¶meters[0], encoded_variables, stat_children);
3026 let datatype =
3027 self.expression_evaluator(¶meters[1], encoded_variables, stat_children);
3028 Rc::new(move |tuple| {
3029 let ExpressionTerm::StringLiteral(value) = lexical_form(tuple)? else {
3030 return None;
3031 };
3032 let ExpressionTerm::NamedNode(datatype) = datatype(tuple)? else {
3033 return None;
3034 };
3035 Some(Term::from(Literal::new_typed_literal(value, datatype)).into())
3036 })
3037 }
3038
3039 Function::IsIri => {
3040 let e =
3041 self.expression_evaluator(¶meters[0], encoded_variables, stat_children);
3042 Rc::new(move |tuple| {
3043 Some(matches!(e(tuple)?, ExpressionTerm::NamedNode(_)).into())
3044 })
3045 }
3046 Function::IsBlank => {
3047 let e =
3048 self.expression_evaluator(¶meters[0], encoded_variables, stat_children);
3049 Rc::new(move |tuple| {
3050 Some(matches!(e(tuple)?, ExpressionTerm::BlankNode(_)).into())
3051 })
3052 }
3053 Function::IsLiteral => {
3054 let e =
3055 self.expression_evaluator(¶meters[0], encoded_variables, stat_children);
3056 Rc::new(move |tuple| {
3057 Some(
3058 match e(tuple)? {
3059 ExpressionTerm::NamedNode(_) | ExpressionTerm::BlankNode(_) => {
3060 false
3061 }
3062 #[cfg(feature = "rdf-star")]
3063 ExpressionTerm::Triple(_) => false,
3064 _ => true,
3065 }
3066 .into(),
3067 )
3068 })
3069 }
3070 Function::IsNumeric => {
3071 let e =
3072 self.expression_evaluator(¶meters[0], encoded_variables, stat_children);
3073 Rc::new(move |tuple| {
3074 Some(
3075 matches!(
3076 e(tuple)?,
3077 ExpressionTerm::IntegerLiteral(_)
3078 | ExpressionTerm::DecimalLiteral(_)
3079 | ExpressionTerm::FloatLiteral(_)
3080 | ExpressionTerm::DoubleLiteral(_)
3081 )
3082 .into(),
3083 )
3084 })
3085 }
3086 Function::Regex => {
3087 let text =
3088 self.expression_evaluator(¶meters[0], encoded_variables, stat_children);
3089 if let Some(regex) =
3090 compile_static_pattern_if_exists(¶meters[1], parameters.get(2))
3091 {
3092 Rc::new(move |tuple| {
3093 let (text, _) = to_string_and_language(text(tuple)?)?;
3094 Some(regex.is_match(&text).into())
3095 })
3096 } else {
3097 let pattern = self.expression_evaluator(
3098 ¶meters[1],
3099 encoded_variables,
3100 stat_children,
3101 );
3102 let flags = parameters.get(2).map(|flags| {
3103 self.expression_evaluator(flags, encoded_variables, stat_children)
3104 });
3105 Rc::new(move |tuple| {
3106 let ExpressionTerm::StringLiteral(pattern) = pattern(tuple)? else {
3107 return None;
3108 };
3109 let options = if let Some(flags) = &flags {
3110 let ExpressionTerm::StringLiteral(options) = flags(tuple)? else {
3111 return None;
3112 };
3113 Some(options)
3114 } else {
3115 None
3116 };
3117 let regex = compile_pattern(&pattern, options.as_deref())?;
3118 let (text, _) = to_string_and_language(text(tuple)?)?;
3119 Some(regex.is_match(&text).into())
3120 })
3121 }
3122 }
3123 #[cfg(feature = "rdf-star")]
3124 Function::Triple => {
3125 let s =
3126 self.expression_evaluator(¶meters[0], encoded_variables, stat_children);
3127 let p =
3128 self.expression_evaluator(¶meters[1], encoded_variables, stat_children);
3129 let o =
3130 self.expression_evaluator(¶meters[2], encoded_variables, stat_children);
3131 Rc::new(move |tuple| {
3132 Some(ExpressionTriple::new(s(tuple)?, p(tuple)?, o(tuple)?)?.into())
3133 })
3134 }
3135 #[cfg(feature = "rdf-star")]
3136 Function::Subject => {
3137 let e =
3138 self.expression_evaluator(¶meters[0], encoded_variables, stat_children);
3139 Rc::new(move |tuple| {
3140 if let ExpressionTerm::Triple(t) = e(tuple)? {
3141 Some(t.subject.into())
3142 } else {
3143 None
3144 }
3145 })
3146 }
3147 #[cfg(feature = "rdf-star")]
3148 Function::Predicate => {
3149 let e =
3150 self.expression_evaluator(¶meters[0], encoded_variables, stat_children);
3151 Rc::new(move |tuple| {
3152 if let ExpressionTerm::Triple(t) = e(tuple)? {
3153 Some(t.predicate.into())
3154 } else {
3155 None
3156 }
3157 })
3158 }
3159 #[cfg(feature = "rdf-star")]
3160 Function::Object => {
3161 let e =
3162 self.expression_evaluator(¶meters[0], encoded_variables, stat_children);
3163 Rc::new(move |tuple| {
3164 if let ExpressionTerm::Triple(t) = e(tuple)? {
3165 Some(t.object)
3166 } else {
3167 None
3168 }
3169 })
3170 }
3171 #[cfg(feature = "rdf-star")]
3172 Function::IsTriple => {
3173 let e =
3174 self.expression_evaluator(¶meters[0], encoded_variables, stat_children);
3175 Rc::new(move |tuple| {
3176 Some(matches!(e(tuple)?, ExpressionTerm::Triple(_)).into())
3177 })
3178 }
3179 Function::Custom(function_name) => {
3180 if let Some(function) = self.custom_functions.get(function_name).cloned() {
3181 let args = parameters
3182 .iter()
3183 .map(|e| self.expression_evaluator(e, encoded_variables, stat_children))
3184 .collect::<Vec<_>>();
3185 return Rc::new(move |tuple| {
3186 let args = args
3187 .iter()
3188 .map(|f| Some(f(tuple)?.into()))
3189 .collect::<Option<Vec<Term>>>()?;
3190 Some(function(&args)?.into())
3191 });
3192 }
3193 match function_name.as_ref() {
3194 xsd::STRING => {
3195 let e = self.expression_evaluator(
3196 ¶meters[0],
3197 encoded_variables,
3198 stat_children,
3199 );
3200 Rc::new(move |tuple| {
3201 Some(ExpressionTerm::StringLiteral(match e(tuple)?.into() {
3202 Term::NamedNode(term) => term.into_string(),
3203 Term::BlankNode(_) => return None,
3204 Term::Literal(term) => term.destruct().0,
3205 #[cfg(feature = "rdf-star")]
3206 Term::Triple(_) => return None,
3207 }))
3208 })
3209 }
3210 xsd::BOOLEAN => {
3211 let e = self.expression_evaluator(
3212 ¶meters[0],
3213 encoded_variables,
3214 stat_children,
3215 );
3216 Rc::new(move |tuple| {
3217 Some(ExpressionTerm::BooleanLiteral(match e(tuple)? {
3218 ExpressionTerm::BooleanLiteral(value) => value,
3219 ExpressionTerm::FloatLiteral(value) => value.into(),
3220 ExpressionTerm::DoubleLiteral(value) => value.into(),
3221 ExpressionTerm::IntegerLiteral(value) => value.into(),
3222 ExpressionTerm::DecimalLiteral(value) => value.into(),
3223 ExpressionTerm::StringLiteral(value) => value.parse().ok()?,
3224 _ => return None,
3225 }))
3226 })
3227 }
3228 xsd::DOUBLE => {
3229 let e = self.expression_evaluator(
3230 ¶meters[0],
3231 encoded_variables,
3232 stat_children,
3233 );
3234 Rc::new(move |tuple| {
3235 Some(ExpressionTerm::DoubleLiteral(match e(tuple)? {
3236 ExpressionTerm::FloatLiteral(value) => value.into(),
3237 ExpressionTerm::DoubleLiteral(value) => value,
3238 ExpressionTerm::IntegerLiteral(value) => value.into(),
3239 ExpressionTerm::DecimalLiteral(value) => value.into(),
3240 ExpressionTerm::BooleanLiteral(value) => value.into(),
3241 ExpressionTerm::StringLiteral(value) => value.parse().ok()?,
3242 _ => return None,
3243 }))
3244 })
3245 }
3246 xsd::FLOAT => {
3247 let e = self.expression_evaluator(
3248 ¶meters[0],
3249 encoded_variables,
3250 stat_children,
3251 );
3252 Rc::new(move |tuple| {
3253 Some(ExpressionTerm::FloatLiteral(match e(tuple)? {
3254 ExpressionTerm::FloatLiteral(value) => value,
3255 ExpressionTerm::DoubleLiteral(value) => value.into(),
3256 ExpressionTerm::IntegerLiteral(value) => value.into(),
3257 ExpressionTerm::DecimalLiteral(value) => value.into(),
3258 ExpressionTerm::BooleanLiteral(value) => value.into(),
3259 ExpressionTerm::StringLiteral(value) => value.parse().ok()?,
3260 _ => return None,
3261 }))
3262 })
3263 }
3264 xsd::INTEGER => {
3265 let e = self.expression_evaluator(
3266 ¶meters[0],
3267 encoded_variables,
3268 stat_children,
3269 );
3270 Rc::new(move |tuple| {
3271 Some(ExpressionTerm::IntegerLiteral(match e(tuple)? {
3272 ExpressionTerm::FloatLiteral(value) => value.try_into().ok()?,
3273 ExpressionTerm::DoubleLiteral(value) => {
3274 value.try_into().ok()?
3275 }
3276 ExpressionTerm::IntegerLiteral(value) => value,
3277 ExpressionTerm::DecimalLiteral(value) => {
3278 value.try_into().ok()?
3279 }
3280 ExpressionTerm::BooleanLiteral(value) => value.into(),
3281 ExpressionTerm::StringLiteral(value) => value.parse().ok()?,
3282 _ => return None,
3283 }))
3284 })
3285 }
3286 xsd::DECIMAL => {
3287 let e = self.expression_evaluator(
3288 ¶meters[0],
3289 encoded_variables,
3290 stat_children,
3291 );
3292 Rc::new(move |tuple| {
3293 Some(ExpressionTerm::DecimalLiteral(match e(tuple)? {
3294 ExpressionTerm::FloatLiteral(value) => value.try_into().ok()?,
3295 ExpressionTerm::DoubleLiteral(value) => {
3296 value.try_into().ok()?
3297 }
3298 ExpressionTerm::IntegerLiteral(value) => value.into(),
3299 ExpressionTerm::DecimalLiteral(value) => value,
3300 ExpressionTerm::BooleanLiteral(value) => value.into(),
3301 ExpressionTerm::StringLiteral(value) => value.parse().ok()?,
3302 _ => return None,
3303 }))
3304 })
3305 }
3306 #[cfg(feature = "sep-0002")]
3307 xsd::DATE => {
3308 let e = self.expression_evaluator(
3309 ¶meters[0],
3310 encoded_variables,
3311 stat_children,
3312 );
3313 Rc::new(move |tuple| {
3314 Some(ExpressionTerm::DateLiteral(match e(tuple)? {
3315 ExpressionTerm::DateLiteral(value) => value,
3316 ExpressionTerm::DateTimeLiteral(value) => {
3317 value.try_into().ok()?
3318 }
3319 ExpressionTerm::StringLiteral(value) => value.parse().ok()?,
3320 _ => return None,
3321 }))
3322 })
3323 }
3324 #[cfg(feature = "sep-0002")]
3325 xsd::TIME => {
3326 let e = self.expression_evaluator(
3327 ¶meters[0],
3328 encoded_variables,
3329 stat_children,
3330 );
3331 Rc::new(move |tuple| {
3332 Some(ExpressionTerm::TimeLiteral(match e(tuple)? {
3333 ExpressionTerm::TimeLiteral(value) => value,
3334 ExpressionTerm::DateTimeLiteral(value) => value.into(),
3335 ExpressionTerm::StringLiteral(value) => value.parse().ok()?,
3336 _ => return None,
3337 }))
3338 })
3339 }
3340 xsd::DATE_TIME => {
3341 let e = self.expression_evaluator(
3342 ¶meters[0],
3343 encoded_variables,
3344 stat_children,
3345 );
3346 Rc::new(move |tuple| {
3347 Some(ExpressionTerm::DateTimeLiteral(match e(tuple)? {
3348 ExpressionTerm::DateTimeLiteral(value) => value,
3349 #[cfg(feature = "sep-0002")]
3350 ExpressionTerm::DateLiteral(value) => value.try_into().ok()?,
3351 ExpressionTerm::StringLiteral(value) => value.parse().ok()?,
3352 _ => return None,
3353 }))
3354 })
3355 }
3356 #[cfg(feature = "sep-0002")]
3357 xsd::DURATION => {
3358 let e = self.expression_evaluator(
3359 ¶meters[0],
3360 encoded_variables,
3361 stat_children,
3362 );
3363 Rc::new(move |tuple| {
3364 Some(ExpressionTerm::DurationLiteral(match e(tuple)? {
3365 ExpressionTerm::DurationLiteral(value) => value,
3366 ExpressionTerm::YearMonthDurationLiteral(value) => value.into(),
3367 ExpressionTerm::DayTimeDurationLiteral(value) => value.into(),
3368 ExpressionTerm::StringLiteral(value) => value.parse().ok()?,
3369 _ => return None,
3370 }))
3371 })
3372 }
3373 #[cfg(feature = "sep-0002")]
3374 xsd::YEAR_MONTH_DURATION => {
3375 let e = self.expression_evaluator(
3376 ¶meters[0],
3377 encoded_variables,
3378 stat_children,
3379 );
3380 Rc::new(move |tuple| {
3381 Some(ExpressionTerm::YearMonthDurationLiteral(match e(tuple)? {
3382 ExpressionTerm::DurationLiteral(value) => {
3383 value.try_into().ok()?
3384 }
3385 ExpressionTerm::YearMonthDurationLiteral(value) => value,
3386 ExpressionTerm::StringLiteral(value) => value.parse().ok()?,
3387 _ => return None,
3388 }))
3389 })
3390 }
3391 #[cfg(feature = "sep-0002")]
3392 xsd::DAY_TIME_DURATION => {
3393 let e = self.expression_evaluator(
3394 ¶meters[0],
3395 encoded_variables,
3396 stat_children,
3397 );
3398 Rc::new(move |tuple| {
3399 Some(ExpressionTerm::DayTimeDurationLiteral(match e(tuple)? {
3400 ExpressionTerm::DurationLiteral(value) => {
3401 value.try_into().ok()?
3402 }
3403 ExpressionTerm::DayTimeDurationLiteral(value) => value,
3404 ExpressionTerm::StringLiteral(value) => value.parse().ok()?,
3405 _ => return None,
3406 }))
3407 })
3408 }
3409 _ => Rc::new(|_| None),
3411 }
3412 }
3413 },
3414 }
3415 }
3416
3417 fn hash<H: Digest>(
3418 &self,
3419 parameters: &[Expression],
3420 encoded_variables: &mut Vec<Variable>,
3421 stat_children: &mut Vec<Rc<EvalNodeWithStats>>,
3422 ) -> Rc<dyn Fn(&InternalTuple<D>) -> Option<ExpressionTerm>> {
3423 let arg = self.expression_evaluator(¶meters[0], encoded_variables, stat_children);
3424 Rc::new(move |tuple| {
3425 let ExpressionTerm::StringLiteral(input) = arg(tuple)? else {
3426 return None;
3427 };
3428 let hash = hex::encode(H::new().chain_update(input.as_str()).finalize());
3429 Some(ExpressionTerm::StringLiteral(hash))
3430 })
3431 }
3432
3433 fn encode_term(&self, term: impl Into<Term>) -> Result<D::InternalTerm, QueryEvaluationError> {
3434 self.dataset.internalize_term(term.into())
3435 }
3436
3437 #[cfg(feature = "rdf-star")]
3438 fn encode_triple(
3439 &self,
3440 triple: &GroundTriple,
3441 ) -> Result<D::InternalTerm, QueryEvaluationError> {
3442 self.dataset.internalize_expression_term(
3443 ExpressionTriple::from(Triple::from(triple.clone())).into(),
3444 )
3445 }
3446
3447 fn encode_property_path(
3448 &self,
3449 path: &PropertyPathExpression,
3450 ) -> Result<Rc<PropertyPath<D>>, QueryEvaluationError> {
3451 Ok(Rc::new(match path {
3452 PropertyPathExpression::NamedNode(node) => {
3453 PropertyPath::Path(self.encode_term(node.clone())?)
3454 }
3455 PropertyPathExpression::Reverse(p) => {
3456 PropertyPath::Reverse(self.encode_property_path(p)?)
3457 }
3458 PropertyPathExpression::Sequence(a, b) => {
3459 PropertyPath::Sequence(self.encode_property_path(a)?, self.encode_property_path(b)?)
3460 }
3461 PropertyPathExpression::Alternative(a, b) => PropertyPath::Alternative(
3462 self.encode_property_path(a)?,
3463 self.encode_property_path(b)?,
3464 ),
3465 PropertyPathExpression::ZeroOrMore(p) => {
3466 PropertyPath::ZeroOrMore(self.encode_property_path(p)?)
3467 }
3468 PropertyPathExpression::OneOrMore(p) => {
3469 PropertyPath::OneOrMore(self.encode_property_path(p)?)
3470 }
3471 PropertyPathExpression::ZeroOrOne(p) => {
3472 PropertyPath::ZeroOrOne(self.encode_property_path(p)?)
3473 }
3474 PropertyPathExpression::NegatedPropertySet(ps) => PropertyPath::NegatedPropertySet(
3475 ps.iter()
3476 .map(|p| self.encode_term(p.clone()))
3477 .collect::<Result<Rc<[_]>, _>>()?,
3478 ),
3479 }))
3480 }
3481}
3482
3483impl<D: QueryableDataset> Clone for SimpleEvaluator<D> {
3484 fn clone(&self) -> Self {
3485 Self {
3486 dataset: self.dataset.clone(),
3487 base_iri: self.base_iri.clone(),
3488 now: self.now,
3489 service_handler: Rc::clone(&self.service_handler),
3490 custom_functions: Rc::clone(&self.custom_functions),
3491 run_stats: self.run_stats,
3492 }
3493 }
3494}
3495
3496fn to_string_and_language(term: ExpressionTerm) -> Option<(String, Option<String>)> {
3497 match term {
3498 ExpressionTerm::StringLiteral(value) => Some((value, None)),
3499 ExpressionTerm::LangStringLiteral { value, language } => Some((value, Some(language))),
3500 _ => None,
3501 }
3502}
3503
3504fn build_plain_literal(value: String, language: Option<String>) -> ExpressionTerm {
3505 if let Some(language) = language {
3506 ExpressionTerm::LangStringLiteral { value, language }
3507 } else {
3508 ExpressionTerm::StringLiteral(value)
3509 }
3510}
3511
3512fn to_argument_compatible_strings(
3513 arg1: ExpressionTerm,
3514 arg2: ExpressionTerm,
3515) -> Option<(String, String, Option<String>)> {
3516 let (value1, language1) = to_string_and_language(arg1)?;
3517 let (value2, language2) = to_string_and_language(arg2)?;
3518 (language2.is_none() || language1 == language2).then_some((value1, value2, language1))
3519}
3520
3521fn compile_static_pattern_if_exists(
3522 pattern: &Expression,
3523 options: Option<&Expression>,
3524) -> Option<Regex> {
3525 let static_pattern = if let Expression::Literal(pattern) = pattern {
3526 (pattern.datatype() == xsd::STRING).then(|| pattern.value())
3527 } else {
3528 None
3529 };
3530 let static_options = if let Some(options) = options {
3531 if let Expression::Literal(options) = options {
3532 (options.datatype() == xsd::STRING).then(|| Some(options.value()))
3533 } else {
3534 None
3535 }
3536 } else {
3537 Some(None)
3538 };
3539 if let (Some(static_pattern), Some(static_options)) = (static_pattern, static_options) {
3540 compile_pattern(static_pattern, static_options)
3541 } else {
3542 None
3543 }
3544}
3545
3546fn compile_pattern(pattern: &str, flags: Option<&str>) -> Option<Regex> {
3547 let mut pattern = Cow::Borrowed(pattern);
3548 let flags = flags.unwrap_or_default();
3549 if flags.contains('q') {
3550 pattern = regex::escape(&pattern).into();
3551 }
3552 let mut regex_builder = RegexBuilder::new(&pattern);
3553 regex_builder.size_limit(REGEX_SIZE_LIMIT);
3554 for flag in flags.chars() {
3555 match flag {
3556 's' => {
3557 regex_builder.dot_matches_new_line(true);
3558 }
3559 'm' => {
3560 regex_builder.multi_line(true);
3561 }
3562 'i' => {
3563 regex_builder.case_insensitive(true);
3564 }
3565 'x' => {
3566 regex_builder.ignore_whitespace(true);
3567 }
3568 'q' => (), _ => return None, }
3571 }
3572 regex_builder.build().ok()
3573}
3574
3575fn decode_bindings<D: QueryableDataset>(
3576 dataset: EvalDataset<D>,
3577 iter: InternalTuplesIterator<D>,
3578 variables: Arc<[Variable]>,
3579) -> QuerySolutionIter {
3580 let tuple_size = variables.len();
3581 QuerySolutionIter::new(
3582 Arc::clone(&variables),
3583 Box::new(iter.map(move |values| {
3584 let mut result = vec![None; tuple_size];
3585 for (i, value) in values?.iter().enumerate() {
3586 if let Some(term) = value {
3587 result[i] = Some(dataset.externalize_term(term)?)
3588 }
3589 }
3590 Ok((Arc::clone(&variables), result).into())
3591 })),
3592 )
3593}
3594
3595fn encode_bindings<D: QueryableDataset>(
3597 dataset: EvalDataset<D>,
3598 variables: Rc<[Variable]>,
3599 iter: QuerySolutionIter,
3600) -> InternalTuplesIterator<D> {
3601 Box::new(iter.map(move |solution| {
3602 let mut encoded_terms = InternalTuple::with_capacity(variables.len());
3603 for (variable, term) in &solution? {
3604 put_variable_value(
3605 variable,
3606 &variables,
3607 dataset.internalize_term(term.clone())?,
3608 &mut encoded_terms,
3609 );
3610 }
3611 Ok(encoded_terms)
3612 }))
3613}
3614
3615fn encode_initial_bindings<D: QueryableDataset>(
3616 dataset: &EvalDataset<D>,
3617 variables: &[Variable],
3618 values: impl IntoIterator<Item = (Variable, Term)>,
3619) -> Result<InternalTuple<D>, QueryEvaluationError> {
3620 let mut encoded_terms = InternalTuple::with_capacity(variables.len());
3621 for (variable, term) in values {
3622 if !put_variable_value(
3623 &variable,
3624 variables,
3625 dataset.internalize_term(term)?,
3626 &mut encoded_terms,
3627 ) {
3628 return Err(QueryEvaluationError::NotExistingSubstitutedVariable(
3629 variable,
3630 ));
3631 }
3632 }
3633 Ok(encoded_terms)
3634}
3635
3636fn put_variable_value<D: QueryableDataset>(
3637 selector: &Variable,
3638 variables: &[Variable],
3639 value: D::InternalTerm,
3640 tuple: &mut InternalTuple<D>,
3641) -> bool {
3642 for (i, v) in variables.iter().enumerate() {
3643 if selector == v {
3644 tuple.set(i, value);
3645 return true;
3646 }
3647 }
3648 false
3649}
3650
3651enum AccumulatorWrapper<D: QueryableDataset> {
3652 CountTuple {
3653 count: u64,
3654 },
3655 CountDistinctTuple {
3656 seen: FxHashSet<InternalTuple<D>>,
3657 count: u64,
3658 },
3659 CountInternal {
3660 evaluator: Rc<dyn Fn(&InternalTuple<D>) -> Option<D::InternalTerm>>,
3661 count: u64,
3662 },
3663 CountDistinctInternal {
3664 seen: FxHashSet<D::InternalTerm>,
3665 evaluator: Rc<dyn Fn(&InternalTuple<D>) -> Option<D::InternalTerm>>,
3666 count: u64,
3667 },
3668 Sample {
3669 evaluator: Rc<dyn Fn(&InternalTuple<D>) -> Option<ExpressionTerm>>,
3671 value: Option<ExpressionTerm>,
3672 },
3673 Expression {
3674 evaluator: Rc<dyn Fn(&InternalTuple<D>) -> Option<ExpressionTerm>>,
3675 accumulator: Option<Box<dyn Accumulator>>,
3676 },
3677 DistinctExpression {
3678 seen: FxHashSet<ExpressionTerm>,
3679 evaluator: Rc<dyn Fn(&InternalTuple<D>) -> Option<ExpressionTerm>>,
3680 accumulator: Option<Box<dyn Accumulator>>,
3681 },
3682 Failing,
3683}
3684
3685impl<D: QueryableDataset> AccumulatorWrapper<D> {
3686 fn add(&mut self, tuple: &InternalTuple<D>) {
3687 match self {
3688 Self::CountTuple { count } => {
3689 *count += 1;
3690 }
3691 Self::CountDistinctTuple { seen, count } => {
3692 if seen.insert(tuple.clone()) {
3693 *count += 1;
3694 }
3695 }
3696 Self::CountInternal { evaluator, count } => {
3697 if evaluator(tuple).is_some() {
3698 *count += 1;
3699 };
3700 }
3701 Self::CountDistinctInternal {
3702 seen,
3703 evaluator,
3704 count,
3705 } => {
3706 let Some(value) = evaluator(tuple) else {
3707 return;
3708 };
3709 if seen.insert(value) {
3710 *count += 1;
3711 }
3712 }
3713 Self::Sample { evaluator, value } => {
3714 if value.is_some() {
3715 return; }
3717 *value = evaluator(tuple);
3718 }
3719 Self::Expression {
3720 evaluator,
3721 accumulator,
3722 } => {
3723 if accumulator.is_none() {
3724 return; }
3726 let Some(value) = evaluator(tuple) else {
3727 *accumulator = None;
3728 return;
3729 };
3730 let Some(accumulator) = accumulator else {
3731 return;
3732 };
3733 accumulator.add(value);
3734 }
3735 Self::DistinctExpression {
3736 seen,
3737 evaluator,
3738 accumulator,
3739 } => {
3740 if accumulator.is_none() {
3741 return; }
3743 let Some(value) = evaluator(tuple) else {
3744 *accumulator = None;
3745 return;
3746 };
3747 let Some(accumulator) = accumulator else {
3748 return;
3749 };
3750 if seen.insert(value.clone()) {
3751 accumulator.add(value);
3752 }
3753 }
3754 Self::Failing => (),
3755 }
3756 }
3757
3758 fn finish(self) -> Option<ExpressionTerm> {
3759 match self {
3760 Self::CountTuple { count, .. }
3761 | Self::CountDistinctTuple { count, .. }
3762 | Self::CountInternal { count, .. }
3763 | Self::CountDistinctInternal { count, .. } => Some(ExpressionTerm::IntegerLiteral(
3764 i64::try_from(count).ok()?.into(),
3765 )),
3766 Self::Sample { value, .. } => value,
3767 Self::Expression { accumulator, .. } | Self::DistinctExpression { accumulator, .. } => {
3768 accumulator?.finish()
3769 }
3770 Self::Failing => None,
3771 }
3772 }
3773}
3774
3775trait Accumulator {
3776 fn add(&mut self, element: ExpressionTerm);
3777
3778 fn finish(&mut self) -> Option<ExpressionTerm>;
3779}
3780
3781#[derive(Default, Debug)]
3782struct CountAccumulator {
3783 count: i64,
3784}
3785
3786impl Accumulator for CountAccumulator {
3787 fn add(&mut self, _element: ExpressionTerm) {
3788 self.count += 1;
3789 }
3790
3791 fn finish(&mut self) -> Option<ExpressionTerm> {
3792 Some(ExpressionTerm::IntegerLiteral(self.count.into()))
3793 }
3794}
3795
3796struct SumAccumulator {
3797 sum: Option<ExpressionTerm>,
3798}
3799
3800impl Default for SumAccumulator {
3801 fn default() -> Self {
3802 Self {
3803 sum: Some(ExpressionTerm::IntegerLiteral(Integer::default())),
3804 }
3805 }
3806}
3807
3808impl Accumulator for SumAccumulator {
3809 fn add(&mut self, element: ExpressionTerm) {
3810 let Some(sum) = &self.sum else {
3811 return;
3812 };
3813 self.sum = if let Some(operands) = NumericBinaryOperands::new(sum.clone(), element) {
3814 match operands {
3816 NumericBinaryOperands::Float(v1, v2) => Some(ExpressionTerm::FloatLiteral(v1 + v2)),
3817 NumericBinaryOperands::Double(v1, v2) => {
3818 Some(ExpressionTerm::DoubleLiteral(v1 + v2))
3819 }
3820 NumericBinaryOperands::Integer(v1, v2) => {
3821 v1.checked_add(v2).map(ExpressionTerm::IntegerLiteral)
3822 }
3823 NumericBinaryOperands::Decimal(v1, v2) => {
3824 v1.checked_add(v2).map(ExpressionTerm::DecimalLiteral)
3825 }
3826 #[cfg(feature = "sep-0002")]
3827 _ => None,
3828 }
3829 } else {
3830 None
3831 };
3832 }
3833
3834 fn finish(&mut self) -> Option<ExpressionTerm> {
3835 self.sum.take()
3836 }
3837}
3838
3839#[derive(Default)]
3840struct AvgAccumulator {
3841 sum: SumAccumulator,
3842 count: i64,
3843}
3844
3845impl Accumulator for AvgAccumulator {
3846 fn add(&mut self, element: ExpressionTerm) {
3847 self.sum.add(element);
3848 self.count += 1;
3849 }
3850
3851 fn finish(&mut self) -> Option<ExpressionTerm> {
3852 let sum = self.sum.finish()?;
3853 if self.count == 0 {
3854 return Some(ExpressionTerm::IntegerLiteral(0.into()));
3855 }
3856 let count = Integer::from(self.count);
3858 match sum {
3859 ExpressionTerm::FloatLiteral(sum) => {
3860 Some(ExpressionTerm::FloatLiteral(sum / Float::from(count)))
3861 }
3862 ExpressionTerm::DoubleLiteral(sum) => {
3863 Some(ExpressionTerm::DoubleLiteral(sum / Double::from(count)))
3864 }
3865 ExpressionTerm::IntegerLiteral(sum) => Some(ExpressionTerm::DecimalLiteral(
3866 Decimal::from(sum).checked_div(count)?,
3867 )),
3868 ExpressionTerm::DecimalLiteral(sum) => {
3869 Some(ExpressionTerm::DecimalLiteral(sum.checked_div(count)?))
3870 }
3871 _ => None,
3872 }
3873 }
3874}
3875
3876#[derive(Default)]
3877#[allow(clippy::option_option)]
3878struct MinAccumulator {
3879 min: Option<Option<ExpressionTerm>>,
3880}
3881
3882impl Accumulator for MinAccumulator {
3883 fn add(&mut self, element: ExpressionTerm) {
3884 if let Some(min) = &self.min {
3885 if cmp_terms(Some(&element), min.as_ref()) == Ordering::Less {
3886 self.min = Some(Some(element));
3887 }
3888 } else {
3889 self.min = Some(Some(element))
3890 }
3891 }
3892
3893 fn finish(&mut self) -> Option<ExpressionTerm> {
3894 self.min.clone().and_then(|v| v)
3895 }
3896}
3897
3898#[derive(Default)]
3899#[allow(clippy::option_option)]
3900struct MaxAccumulator {
3901 max: Option<Option<ExpressionTerm>>,
3902}
3903
3904impl Accumulator for MaxAccumulator {
3905 fn add(&mut self, element: ExpressionTerm) {
3906 if let Some(max) = &self.max {
3907 if cmp_terms(Some(&element), max.as_ref()) == Ordering::Greater {
3908 self.max = Some(Some(element))
3909 }
3910 } else {
3911 self.max = Some(Some(element))
3912 }
3913 }
3914
3915 fn finish(&mut self) -> Option<ExpressionTerm> {
3916 self.max.clone().and_then(|v| v)
3917 }
3918}
3919
3920#[allow(clippy::option_option)]
3921struct GroupConcatAccumulator {
3922 concat: Option<String>,
3923 language: Option<Option<String>>,
3924 separator: Rc<str>,
3925}
3926
3927impl GroupConcatAccumulator {
3928 fn new(separator: Rc<str>) -> Self {
3929 Self {
3930 concat: Some(String::new()),
3931 language: None,
3932 separator,
3933 }
3934 }
3935}
3936
3937impl Accumulator for GroupConcatAccumulator {
3938 fn add(&mut self, element: ExpressionTerm) {
3939 let Some(concat) = self.concat.as_mut() else {
3940 return;
3941 };
3942 let Some((value, e_language)) = to_string_and_language(element) else {
3943 self.concat = None;
3944 return;
3945 };
3946 if let Some(lang) = &self.language {
3947 if *lang != e_language {
3948 self.language = Some(None)
3949 }
3950 concat.push_str(&self.separator);
3951 } else {
3952 self.language = Some(e_language)
3953 }
3954 concat.push_str(&value);
3955 }
3956
3957 fn finish(&mut self) -> Option<ExpressionTerm> {
3958 self.concat
3959 .take()
3960 .map(|result| build_plain_literal(result, self.language.take().flatten()))
3961 }
3962}
3963
3964fn encode_variable(variables: &mut Vec<Variable>, variable: &Variable) -> usize {
3965 if let Some(key) = slice_key(variables, variable) {
3966 key
3967 } else {
3968 variables.push(variable.clone());
3969 variables.len() - 1
3970 }
3971}
3972
3973fn bnode_key(blank_nodes: &mut Vec<BlankNode>, blank_node: &BlankNode) -> usize {
3974 if let Some(key) = slice_key(blank_nodes, blank_node) {
3975 key
3976 } else {
3977 blank_nodes.push(blank_node.clone());
3978 blank_nodes.len() - 1
3979 }
3980}
3981
3982fn slice_key<T: Eq>(slice: &[T], element: &T) -> Option<usize> {
3983 for (i, item) in slice.iter().enumerate() {
3984 if item == element {
3985 return Some(i);
3986 }
3987 }
3988 None
3989}
3990
3991fn equals(a: &ExpressionTerm, b: &ExpressionTerm) -> Option<bool> {
3993 match a {
3994 ExpressionTerm::NamedNode(_)
3995 | ExpressionTerm::BlankNode(_)
3996 | ExpressionTerm::LangStringLiteral { .. } => Some(a == b),
3997 ExpressionTerm::StringLiteral(a) => match b {
3998 ExpressionTerm::StringLiteral(b) => Some(a == b),
3999 ExpressionTerm::OtherTypedLiteral { .. } => None,
4000 _ => Some(false),
4001 },
4002 ExpressionTerm::OtherTypedLiteral { .. } => match b {
4003 ExpressionTerm::OtherTypedLiteral { .. } if a == b => Some(true),
4004 ExpressionTerm::NamedNode(_)
4005 | ExpressionTerm::BlankNode(_)
4006 | ExpressionTerm::LangStringLiteral { .. } => Some(false),
4007 #[cfg(feature = "rdf-star")]
4008 ExpressionTerm::Triple(_) => Some(false),
4009 _ => None,
4010 },
4011 ExpressionTerm::BooleanLiteral(a) => match b {
4012 ExpressionTerm::BooleanLiteral(b) => Some(a == b),
4013 ExpressionTerm::OtherTypedLiteral { .. } => None,
4014 _ => Some(false),
4015 },
4016 ExpressionTerm::FloatLiteral(a) => match b {
4017 ExpressionTerm::FloatLiteral(b) => Some(a == b),
4018 ExpressionTerm::DoubleLiteral(b) => Some(Double::from(*a) == *b),
4019 ExpressionTerm::IntegerLiteral(b) => Some(*a == (*b).into()),
4020 ExpressionTerm::DecimalLiteral(b) => Some(*a == (*b).into()),
4021 ExpressionTerm::OtherTypedLiteral { .. } => None,
4022 _ => Some(false),
4023 },
4024 ExpressionTerm::DoubleLiteral(a) => match b {
4025 ExpressionTerm::FloatLiteral(b) => Some(*a == (*b).into()),
4026 ExpressionTerm::DoubleLiteral(b) => Some(a == b),
4027 ExpressionTerm::IntegerLiteral(b) => Some(*a == (*b).into()),
4028 ExpressionTerm::DecimalLiteral(b) => Some(*a == (*b).into()),
4029 ExpressionTerm::OtherTypedLiteral { .. } => None,
4030 _ => Some(false),
4031 },
4032 ExpressionTerm::IntegerLiteral(a) => match b {
4033 ExpressionTerm::FloatLiteral(b) => Some(Float::from(*a) == *b),
4034 ExpressionTerm::DoubleLiteral(b) => Some(Double::from(*a) == *b),
4035 ExpressionTerm::IntegerLiteral(b) => Some(a == b),
4036 ExpressionTerm::DecimalLiteral(b) => Some(Decimal::from(*a) == *b),
4037 ExpressionTerm::OtherTypedLiteral { .. } => None,
4038 _ => Some(false),
4039 },
4040 ExpressionTerm::DecimalLiteral(a) => match b {
4041 ExpressionTerm::FloatLiteral(b) => Some(Float::from(*a) == *b),
4042 ExpressionTerm::DoubleLiteral(b) => Some(Double::from(*a) == *b),
4043 ExpressionTerm::IntegerLiteral(b) => Some(*a == (*b).into()),
4044 ExpressionTerm::DecimalLiteral(b) => Some(a == b),
4045 ExpressionTerm::OtherTypedLiteral { .. } => None,
4046 _ => Some(false),
4047 },
4048 ExpressionTerm::DateTimeLiteral(a) => match b {
4049 ExpressionTerm::DateTimeLiteral(b) => Some(a == b),
4050 ExpressionTerm::OtherTypedLiteral { .. } => None,
4051 _ => Some(false),
4052 },
4053 #[cfg(feature = "sep-0002")]
4054 ExpressionTerm::TimeLiteral(a) => match b {
4055 ExpressionTerm::TimeLiteral(b) => Some(a == b),
4056 ExpressionTerm::OtherTypedLiteral { .. } => None,
4057 _ => Some(false),
4058 },
4059 #[cfg(feature = "sep-0002")]
4060 ExpressionTerm::DateLiteral(a) => match b {
4061 ExpressionTerm::DateLiteral(b) => Some(a == b),
4062 ExpressionTerm::OtherTypedLiteral { .. } => None,
4063 _ => Some(false),
4064 },
4065 #[cfg(feature = "calendar-ext")]
4066 ExpressionTerm::GYearMonthLiteral(a) => match b {
4067 ExpressionTerm::GYearMonthLiteral(b) => Some(a == b),
4068 ExpressionTerm::OtherTypedLiteral { .. } => None,
4069 _ => Some(false),
4070 },
4071 #[cfg(feature = "calendar-ext")]
4072 ExpressionTerm::GYearLiteral(a) => match b {
4073 ExpressionTerm::GYearLiteral(b) => Some(a == b),
4074 ExpressionTerm::OtherTypedLiteral { .. } => None,
4075 _ => Some(false),
4076 },
4077 #[cfg(feature = "calendar-ext")]
4078 ExpressionTerm::GMonthDayLiteral(a) => match b {
4079 ExpressionTerm::GMonthDayLiteral(b) => Some(a == b),
4080 ExpressionTerm::OtherTypedLiteral { .. } => None,
4081 _ => Some(false),
4082 },
4083 #[cfg(feature = "calendar-ext")]
4084 ExpressionTerm::GDayLiteral(a) => match b {
4085 ExpressionTerm::GDayLiteral(b) => Some(a == b),
4086 ExpressionTerm::OtherTypedLiteral { .. } => None,
4087 _ => Some(false),
4088 },
4089 #[cfg(feature = "calendar-ext")]
4090 ExpressionTerm::GMonthLiteral(a) => match b {
4091 ExpressionTerm::GMonthLiteral(b) => Some(a == b),
4092 ExpressionTerm::OtherTypedLiteral { .. } => None,
4093 _ => Some(false),
4094 },
4095 #[cfg(feature = "sep-0002")]
4096 ExpressionTerm::DurationLiteral(a) => match b {
4097 ExpressionTerm::DurationLiteral(b) => Some(a == b),
4098 ExpressionTerm::YearMonthDurationLiteral(b) => Some(a == b),
4099 ExpressionTerm::DayTimeDurationLiteral(b) => Some(a == b),
4100 ExpressionTerm::OtherTypedLiteral { .. } => None,
4101 _ => Some(false),
4102 },
4103 #[cfg(feature = "sep-0002")]
4104 ExpressionTerm::YearMonthDurationLiteral(a) => match b {
4105 ExpressionTerm::DurationLiteral(b) => Some(a == b),
4106 ExpressionTerm::YearMonthDurationLiteral(b) => Some(a == b),
4107 ExpressionTerm::DayTimeDurationLiteral(b) => Some(a == b),
4108 ExpressionTerm::OtherTypedLiteral { .. } => None,
4109 _ => Some(false),
4110 },
4111 #[cfg(feature = "sep-0002")]
4112 ExpressionTerm::DayTimeDurationLiteral(a) => match b {
4113 ExpressionTerm::DurationLiteral(b) => Some(a == b),
4114 ExpressionTerm::YearMonthDurationLiteral(b) => Some(a == b),
4115 ExpressionTerm::DayTimeDurationLiteral(b) => Some(a == b),
4116 ExpressionTerm::OtherTypedLiteral { .. } => None,
4117 _ => Some(false),
4118 },
4119 #[cfg(feature = "rdf-star")]
4120 ExpressionTerm::Triple(a) => {
4121 if let ExpressionTerm::Triple(b) = b {
4122 triple_equals(a, b)
4123 } else {
4124 Some(false)
4125 }
4126 }
4127 }
4128}
4129
4130#[cfg(feature = "rdf-star")]
4131fn triple_equals(a: &ExpressionTriple, b: &ExpressionTriple) -> Option<bool> {
4132 Some(
4133 match &a.subject {
4134 ExpressionSubject::NamedNode(_) | ExpressionSubject::BlankNode(_) => {
4135 a.subject == b.subject
4136 }
4137 ExpressionSubject::Triple(a) => {
4138 if let ExpressionSubject::Triple(b) = &b.subject {
4139 triple_equals(a, b)?
4140 } else {
4141 false
4142 }
4143 }
4144 } && a.predicate == b.predicate
4145 && equals(&a.object, &b.object)?,
4146 )
4147}
4148
4149fn cmp_terms(a: Option<&ExpressionTerm>, b: Option<&ExpressionTerm>) -> Ordering {
4151 match (a, b) {
4152 (Some(a), Some(b)) => {
4153 match a {
4154 ExpressionTerm::BlankNode(a) => match b {
4155 ExpressionTerm::BlankNode(b) => a.as_str().cmp(b.as_str()),
4156 _ => Ordering::Less,
4157 },
4158 ExpressionTerm::NamedNode(a) => match b {
4159 ExpressionTerm::BlankNode(_) => Ordering::Greater,
4160 ExpressionTerm::NamedNode(b) => a.as_str().cmp(b.as_str()),
4161 _ => Ordering::Less,
4162 },
4163 #[cfg(feature = "rdf-star")]
4164 ExpressionTerm::Triple(a) => match b {
4165 ExpressionTerm::Triple(b) => cmp_triples(a, b),
4166 _ => Ordering::Greater,
4167 },
4168 _ => match b {
4169 ExpressionTerm::NamedNode(_) | ExpressionTerm::BlankNode(_) => {
4170 Ordering::Greater
4171 }
4172 #[cfg(feature = "rdf-star")]
4173 ExpressionTerm::Triple(_) => Ordering::Less,
4174 _ => {
4175 if let Some(ord) = partial_cmp_literals(a, b) {
4176 ord
4177 } else if let (Term::Literal(a), Term::Literal(b)) =
4178 (a.clone().into(), b.clone().into())
4179 {
4180 (a.value(), a.datatype(), a.language()).cmp(&(
4181 b.value(),
4182 b.datatype(),
4183 b.language(),
4184 ))
4185 } else {
4186 Ordering::Equal }
4188 }
4189 },
4190 }
4191 }
4192 (Some(_), None) => Ordering::Greater,
4193 (None, Some(_)) => Ordering::Less,
4194 (None, None) => Ordering::Equal,
4195 }
4196}
4197
4198#[cfg(feature = "rdf-star")]
4199fn cmp_triples(a: &ExpressionTriple, b: &ExpressionTriple) -> Ordering {
4200 match match &a.subject {
4201 ExpressionSubject::BlankNode(a) => match &b.subject {
4202 ExpressionSubject::BlankNode(b) => a.as_str().cmp(b.as_str()),
4203 ExpressionSubject::NamedNode(_) => Ordering::Less,
4204 #[cfg(feature = "rdf-star")]
4205 ExpressionSubject::Triple(_) => Ordering::Less,
4206 },
4207 ExpressionSubject::NamedNode(a) => match &b.subject {
4208 ExpressionSubject::BlankNode(_) => Ordering::Greater,
4209 ExpressionSubject::NamedNode(b) => a.as_str().cmp(b.as_str()),
4210 #[cfg(feature = "rdf-star")]
4211 ExpressionSubject::Triple(_) => Ordering::Less,
4212 },
4213 ExpressionSubject::Triple(a) => match &b.subject {
4214 ExpressionSubject::Triple(b) => cmp_triples(a, b),
4215 _ => Ordering::Greater,
4216 },
4217 } {
4218 Ordering::Equal => match a.predicate.as_str().cmp(b.predicate.as_str()) {
4219 Ordering::Equal => cmp_terms(Some(&a.object), Some(&b.object)),
4220 o => o,
4221 },
4222 o => o,
4223 }
4224}
4225
4226fn partial_cmp(a: &ExpressionTerm, b: &ExpressionTerm) -> Option<Ordering> {
4228 if a == b {
4229 return Some(Ordering::Equal);
4230 }
4231 #[cfg(feature = "rdf-star")]
4232 if let ExpressionTerm::Triple(a) = a {
4233 return if let ExpressionTerm::Triple(b) = b {
4234 partial_cmp_triples(a, b)
4235 } else {
4236 None
4237 };
4238 }
4239 partial_cmp_literals(a, b)
4240}
4241
4242fn partial_cmp_literals(a: &ExpressionTerm, b: &ExpressionTerm) -> Option<Ordering> {
4243 match a {
4244 ExpressionTerm::StringLiteral(a) => {
4245 if let ExpressionTerm::StringLiteral(b) = b {
4246 a.partial_cmp(b)
4247 } else {
4248 None
4249 }
4250 }
4251 ExpressionTerm::LangStringLiteral {
4252 value: va,
4253 language: la,
4254 } => {
4255 if let ExpressionTerm::LangStringLiteral {
4256 value: vb,
4257 language: lb,
4258 } = b
4259 {
4260 if la == lb {
4261 va.partial_cmp(vb)
4262 } else {
4263 None
4264 }
4265 } else {
4266 None
4267 }
4268 }
4269 ExpressionTerm::FloatLiteral(a) => match b {
4270 ExpressionTerm::FloatLiteral(b) => a.partial_cmp(b),
4271 ExpressionTerm::DoubleLiteral(b) => Double::from(*a).partial_cmp(b),
4272 ExpressionTerm::IntegerLiteral(b) => a.partial_cmp(&Float::from(*b)),
4273 ExpressionTerm::DecimalLiteral(b) => a.partial_cmp(&(*b).into()),
4274 _ => None,
4275 },
4276 ExpressionTerm::DoubleLiteral(a) => match b {
4277 ExpressionTerm::FloatLiteral(b) => a.partial_cmp(&(*b).into()),
4278 ExpressionTerm::DoubleLiteral(b) => a.partial_cmp(b),
4279 ExpressionTerm::IntegerLiteral(b) => a.partial_cmp(&Double::from(*b)),
4280 ExpressionTerm::DecimalLiteral(b) => a.partial_cmp(&(*b).into()),
4281 _ => None,
4282 },
4283 ExpressionTerm::IntegerLiteral(a) => match b {
4284 ExpressionTerm::FloatLiteral(b) => Float::from(*a).partial_cmp(b),
4285 ExpressionTerm::DoubleLiteral(b) => Double::from(*a).partial_cmp(b),
4286 ExpressionTerm::IntegerLiteral(b) => a.partial_cmp(b),
4287 ExpressionTerm::DecimalLiteral(b) => Decimal::from(*a).partial_cmp(b),
4288 _ => None,
4289 },
4290 ExpressionTerm::DecimalLiteral(a) => match b {
4291 ExpressionTerm::FloatLiteral(b) => Float::from(*a).partial_cmp(b),
4292 ExpressionTerm::DoubleLiteral(b) => Double::from(*a).partial_cmp(b),
4293 ExpressionTerm::IntegerLiteral(b) => a.partial_cmp(&Decimal::from(*b)),
4294 ExpressionTerm::DecimalLiteral(b) => a.partial_cmp(b),
4295 _ => None,
4296 },
4297 ExpressionTerm::DateTimeLiteral(a) => {
4298 if let ExpressionTerm::DateTimeLiteral(b) = b {
4299 a.partial_cmp(b)
4300 } else {
4301 None
4302 }
4303 }
4304 #[cfg(feature = "sep-0002")]
4305 ExpressionTerm::TimeLiteral(a) => {
4306 if let ExpressionTerm::TimeLiteral(b) = b {
4307 a.partial_cmp(b)
4308 } else {
4309 None
4310 }
4311 }
4312 #[cfg(feature = "sep-0002")]
4313 ExpressionTerm::DateLiteral(a) => {
4314 if let ExpressionTerm::DateLiteral(b) = b {
4315 a.partial_cmp(b)
4316 } else {
4317 None
4318 }
4319 }
4320 #[cfg(feature = "calendar-ext")]
4321 ExpressionTerm::GYearMonthLiteral(a) => {
4322 if let ExpressionTerm::GYearMonthLiteral(b) = b {
4323 a.partial_cmp(b)
4324 } else {
4325 None
4326 }
4327 }
4328 #[cfg(feature = "calendar-ext")]
4329 ExpressionTerm::GYearLiteral(a) => {
4330 if let ExpressionTerm::GYearLiteral(b) = b {
4331 a.partial_cmp(b)
4332 } else {
4333 None
4334 }
4335 }
4336 #[cfg(feature = "calendar-ext")]
4337 ExpressionTerm::GMonthDayLiteral(a) => {
4338 if let ExpressionTerm::GMonthDayLiteral(b) = b {
4339 a.partial_cmp(b)
4340 } else {
4341 None
4342 }
4343 }
4344 #[cfg(feature = "calendar-ext")]
4345 ExpressionTerm::GDayLiteral(a) => {
4346 if let ExpressionTerm::GDayLiteral(b) = b {
4347 a.partial_cmp(b)
4348 } else {
4349 None
4350 }
4351 }
4352 #[cfg(feature = "calendar-ext")]
4353 ExpressionTerm::GMonthLiteral(a) => {
4354 if let ExpressionTerm::GMonthLiteral(b) = b {
4355 a.partial_cmp(b)
4356 } else {
4357 None
4358 }
4359 }
4360 #[cfg(feature = "sep-0002")]
4361 ExpressionTerm::DurationLiteral(a) => match b {
4362 ExpressionTerm::DurationLiteral(b) => a.partial_cmp(b),
4363 ExpressionTerm::YearMonthDurationLiteral(b) => a.partial_cmp(b),
4364 ExpressionTerm::DayTimeDurationLiteral(b) => a.partial_cmp(b),
4365 _ => None,
4366 },
4367 #[cfg(feature = "sep-0002")]
4368 ExpressionTerm::YearMonthDurationLiteral(a) => match b {
4369 ExpressionTerm::DurationLiteral(b) => a.partial_cmp(b),
4370 ExpressionTerm::YearMonthDurationLiteral(b) => a.partial_cmp(b),
4371 ExpressionTerm::DayTimeDurationLiteral(b) => a.partial_cmp(b),
4372 _ => None,
4373 },
4374 #[cfg(feature = "sep-0002")]
4375 ExpressionTerm::DayTimeDurationLiteral(a) => match b {
4376 ExpressionTerm::DurationLiteral(b) => a.partial_cmp(b),
4377 ExpressionTerm::YearMonthDurationLiteral(b) => a.partial_cmp(b),
4378 ExpressionTerm::DayTimeDurationLiteral(b) => a.partial_cmp(b),
4379 _ => None,
4380 },
4381 _ => None,
4382 }
4383}
4384
4385#[cfg(feature = "rdf-star")]
4386fn partial_cmp_triples(a: &ExpressionTriple, b: &ExpressionTriple) -> Option<Ordering> {
4387 match (&a.subject, &b.subject) {
4389 (ExpressionSubject::NamedNode(a), ExpressionSubject::NamedNode(b)) => {
4390 if a != b {
4391 return None;
4392 }
4393 }
4394 (ExpressionSubject::BlankNode(a), ExpressionSubject::BlankNode(b)) => {
4395 if a != b {
4396 return None;
4397 }
4398 }
4399 (ExpressionSubject::Triple(a), ExpressionSubject::Triple(b)) => {
4400 match partial_cmp_triples(a, b)? {
4401 Ordering::Equal => (),
4402 o => return Some(o),
4403 }
4404 }
4405 _ => return None,
4406 }
4407 if a.predicate != b.predicate {
4408 return None;
4409 }
4410 partial_cmp(&a.object, &b.object)
4411}
4412
4413enum NumericBinaryOperands {
4414 Float(Float, Float),
4415 Double(Double, Double),
4416 Integer(Integer, Integer),
4417 Decimal(Decimal, Decimal),
4418 #[cfg(feature = "sep-0002")]
4419 Duration(Duration, Duration),
4420 #[cfg(feature = "sep-0002")]
4421 YearMonthDuration(YearMonthDuration, YearMonthDuration),
4422 #[cfg(feature = "sep-0002")]
4423 DayTimeDuration(DayTimeDuration, DayTimeDuration),
4424 #[cfg(feature = "sep-0002")]
4425 DateTime(DateTime, DateTime),
4426 #[cfg(feature = "sep-0002")]
4427 Time(Time, Time),
4428 #[cfg(feature = "sep-0002")]
4429 Date(Date, Date),
4430 #[cfg(feature = "sep-0002")]
4431 DateTimeDuration(DateTime, Duration),
4432 #[cfg(feature = "sep-0002")]
4433 DateTimeYearMonthDuration(DateTime, YearMonthDuration),
4434 #[cfg(feature = "sep-0002")]
4435 DateTimeDayTimeDuration(DateTime, DayTimeDuration),
4436 #[cfg(feature = "sep-0002")]
4437 DateDuration(Date, Duration),
4438 #[cfg(feature = "sep-0002")]
4439 DateYearMonthDuration(Date, YearMonthDuration),
4440 #[cfg(feature = "sep-0002")]
4441 DateDayTimeDuration(Date, DayTimeDuration),
4442 #[cfg(feature = "sep-0002")]
4443 TimeDuration(Time, Duration),
4444 #[cfg(feature = "sep-0002")]
4445 TimeDayTimeDuration(Time, DayTimeDuration),
4446}
4447
4448impl NumericBinaryOperands {
4449 fn new(a: ExpressionTerm, b: ExpressionTerm) -> Option<Self> {
4450 match (a, b) {
4451 (ExpressionTerm::FloatLiteral(v1), ExpressionTerm::FloatLiteral(v2)) => {
4452 Some(Self::Float(v1, v2))
4453 }
4454 (ExpressionTerm::FloatLiteral(v1), ExpressionTerm::DoubleLiteral(v2)) => {
4455 Some(Self::Double(v1.into(), v2))
4456 }
4457 (ExpressionTerm::FloatLiteral(v1), ExpressionTerm::IntegerLiteral(v2)) => {
4458 Some(Self::Float(v1, v2.into()))
4459 }
4460 (ExpressionTerm::FloatLiteral(v1), ExpressionTerm::DecimalLiteral(v2)) => {
4461 Some(Self::Float(v1, v2.into()))
4462 }
4463 (ExpressionTerm::DoubleLiteral(v1), ExpressionTerm::FloatLiteral(v2)) => {
4464 Some(Self::Double(v1, v2.into()))
4465 }
4466 (ExpressionTerm::DoubleLiteral(v1), ExpressionTerm::DoubleLiteral(v2)) => {
4467 Some(Self::Double(v1, v2))
4468 }
4469 (ExpressionTerm::DoubleLiteral(v1), ExpressionTerm::IntegerLiteral(v2)) => {
4470 Some(Self::Double(v1, v2.into()))
4471 }
4472 (ExpressionTerm::DoubleLiteral(v1), ExpressionTerm::DecimalLiteral(v2)) => {
4473 Some(Self::Double(v1, v2.into()))
4474 }
4475 (ExpressionTerm::IntegerLiteral(v1), ExpressionTerm::FloatLiteral(v2)) => {
4476 Some(Self::Float(v1.into(), v2))
4477 }
4478 (ExpressionTerm::IntegerLiteral(v1), ExpressionTerm::DoubleLiteral(v2)) => {
4479 Some(Self::Double(v1.into(), v2))
4480 }
4481 (ExpressionTerm::IntegerLiteral(v1), ExpressionTerm::IntegerLiteral(v2)) => {
4482 Some(Self::Integer(v1, v2))
4483 }
4484 (ExpressionTerm::IntegerLiteral(v1), ExpressionTerm::DecimalLiteral(v2)) => {
4485 Some(Self::Decimal(v1.into(), v2))
4486 }
4487 (ExpressionTerm::DecimalLiteral(v1), ExpressionTerm::FloatLiteral(v2)) => {
4488 Some(Self::Float(v1.into(), v2))
4489 }
4490 (ExpressionTerm::DecimalLiteral(v1), ExpressionTerm::DoubleLiteral(v2)) => {
4491 Some(Self::Double(v1.into(), v2))
4492 }
4493 (ExpressionTerm::DecimalLiteral(v1), ExpressionTerm::IntegerLiteral(v2)) => {
4494 Some(Self::Decimal(v1, v2.into()))
4495 }
4496 (ExpressionTerm::DecimalLiteral(v1), ExpressionTerm::DecimalLiteral(v2)) => {
4497 Some(Self::Decimal(v1, v2))
4498 }
4499 #[cfg(feature = "sep-0002")]
4500 (ExpressionTerm::DurationLiteral(v1), ExpressionTerm::DurationLiteral(v2)) => {
4501 Some(Self::Duration(v1, v2))
4502 }
4503 #[cfg(feature = "sep-0002")]
4504 (ExpressionTerm::DurationLiteral(v1), ExpressionTerm::YearMonthDurationLiteral(v2)) => {
4505 Some(Self::Duration(v1, v2.into()))
4506 }
4507 #[cfg(feature = "sep-0002")]
4508 (ExpressionTerm::DurationLiteral(v1), ExpressionTerm::DayTimeDurationLiteral(v2)) => {
4509 Some(Self::Duration(v1, v2.into()))
4510 }
4511 #[cfg(feature = "sep-0002")]
4512 (ExpressionTerm::YearMonthDurationLiteral(v1), ExpressionTerm::DurationLiteral(v2)) => {
4513 Some(Self::Duration(v1.into(), v2))
4514 }
4515 #[cfg(feature = "sep-0002")]
4516 (
4517 ExpressionTerm::YearMonthDurationLiteral(v1),
4518 ExpressionTerm::YearMonthDurationLiteral(v2),
4519 ) => Some(Self::YearMonthDuration(v1, v2)),
4520 #[cfg(feature = "sep-0002")]
4521 (
4522 ExpressionTerm::YearMonthDurationLiteral(v1),
4523 ExpressionTerm::DayTimeDurationLiteral(v2),
4524 ) => Some(Self::Duration(v1.into(), v2.into())),
4525 #[cfg(feature = "sep-0002")]
4526 (ExpressionTerm::DayTimeDurationLiteral(v1), ExpressionTerm::DurationLiteral(v2)) => {
4527 Some(Self::Duration(v1.into(), v2))
4528 }
4529 #[cfg(feature = "sep-0002")]
4530 (
4531 ExpressionTerm::DayTimeDurationLiteral(v1),
4532 ExpressionTerm::YearMonthDurationLiteral(v2),
4533 ) => Some(Self::Duration(v1.into(), v2.into())),
4534 #[cfg(feature = "sep-0002")]
4535 (
4536 ExpressionTerm::DayTimeDurationLiteral(v1),
4537 ExpressionTerm::DayTimeDurationLiteral(v2),
4538 ) => Some(Self::DayTimeDuration(v1, v2)),
4539 #[cfg(feature = "sep-0002")]
4540 (ExpressionTerm::DateTimeLiteral(v1), ExpressionTerm::DateTimeLiteral(v2)) => {
4541 Some(Self::DateTime(v1, v2))
4542 }
4543 #[cfg(feature = "sep-0002")]
4544 (ExpressionTerm::DateLiteral(v1), ExpressionTerm::DateLiteral(v2)) => {
4545 Some(Self::Date(v1, v2))
4546 }
4547 #[cfg(feature = "sep-0002")]
4548 (ExpressionTerm::TimeLiteral(v1), ExpressionTerm::TimeLiteral(v2)) => {
4549 Some(Self::Time(v1, v2))
4550 }
4551 #[cfg(feature = "sep-0002")]
4552 (ExpressionTerm::DateTimeLiteral(v1), ExpressionTerm::DurationLiteral(v2)) => {
4553 Some(Self::DateTimeDuration(v1, v2))
4554 }
4555 #[cfg(feature = "sep-0002")]
4556 (ExpressionTerm::DateTimeLiteral(v1), ExpressionTerm::YearMonthDurationLiteral(v2)) => {
4557 Some(Self::DateTimeYearMonthDuration(v1, v2))
4558 }
4559 #[cfg(feature = "sep-0002")]
4560 (ExpressionTerm::DateTimeLiteral(v1), ExpressionTerm::DayTimeDurationLiteral(v2)) => {
4561 Some(Self::DateTimeDayTimeDuration(v1, v2))
4562 }
4563 #[cfg(feature = "sep-0002")]
4564 (ExpressionTerm::DateLiteral(v1), ExpressionTerm::DurationLiteral(v2)) => {
4565 Some(Self::DateDuration(v1, v2))
4566 }
4567 #[cfg(feature = "sep-0002")]
4568 (ExpressionTerm::DateLiteral(v1), ExpressionTerm::YearMonthDurationLiteral(v2)) => {
4569 Some(Self::DateYearMonthDuration(v1, v2))
4570 }
4571 #[cfg(feature = "sep-0002")]
4572 (ExpressionTerm::DateLiteral(v1), ExpressionTerm::DayTimeDurationLiteral(v2)) => {
4573 Some(Self::DateDayTimeDuration(v1, v2))
4574 }
4575 #[cfg(feature = "sep-0002")]
4576 (ExpressionTerm::TimeLiteral(v1), ExpressionTerm::DurationLiteral(v2)) => {
4577 Some(Self::TimeDuration(v1, v2))
4578 }
4579 #[cfg(feature = "sep-0002")]
4580 (ExpressionTerm::TimeLiteral(v1), ExpressionTerm::DayTimeDurationLiteral(v2)) => {
4581 Some(Self::TimeDayTimeDuration(v1, v2))
4582 }
4583 _ => None,
4584 }
4585 }
4586}
4587
4588enum TupleSelector<D: QueryableDataset> {
4589 Constant(D::InternalTerm),
4590 Variable(usize),
4591 #[cfg(feature = "rdf-star")]
4592 TriplePattern(Rc<TripleTupleSelector<D>>),
4593}
4594
4595impl<D: QueryableDataset> TupleSelector<D> {
4596 fn from_ground_term_pattern(
4597 term_pattern: &GroundTermPattern,
4598 variables: &mut Vec<Variable>,
4599 dataset: &EvalDataset<D>,
4600 ) -> Result<Self, QueryEvaluationError> {
4601 Ok(match term_pattern {
4602 GroundTermPattern::Variable(variable) => {
4603 Self::Variable(encode_variable(variables, variable))
4604 }
4605 GroundTermPattern::NamedNode(term) => {
4606 Self::Constant(dataset.internalize_term(term.as_ref().into())?)
4607 }
4608 GroundTermPattern::Literal(term) => {
4609 Self::Constant(dataset.internalize_term(term.as_ref().into())?)
4610 }
4611 #[cfg(feature = "rdf-star")]
4612 GroundTermPattern::Triple(triple) => {
4613 match (
4614 Self::from_ground_term_pattern(&triple.subject, variables, dataset)?,
4615 Self::from_named_node_pattern(&triple.predicate, variables, dataset)?,
4616 Self::from_ground_term_pattern(&triple.object, variables, dataset)?,
4617 ) {
4618 (
4619 Self::Constant(subject),
4620 Self::Constant(predicate),
4621 Self::Constant(object),
4622 ) => Self::Constant(
4623 dataset.internalize_expression_term(
4624 ExpressionTriple::new(
4625 dataset.externalize_expression_term(subject)?,
4626 dataset.externalize_expression_term(predicate)?,
4627 dataset.externalize_expression_term(object)?,
4628 )
4629 .ok_or_else(|| QueryEvaluationError::InvalidStorageTripleTerm)?
4630 .into(),
4631 )?,
4632 ),
4633 (subject, predicate, object) => {
4634 Self::TriplePattern(Rc::new(TripleTupleSelector {
4635 subject,
4636 predicate,
4637 object,
4638 }))
4639 }
4640 }
4641 }
4642 })
4643 }
4644
4645 fn from_named_node_pattern(
4646 named_node_pattern: &NamedNodePattern,
4647 variables: &mut Vec<Variable>,
4648 dataset: &EvalDataset<D>,
4649 ) -> Result<Self, QueryEvaluationError> {
4650 Ok(match named_node_pattern {
4651 NamedNodePattern::Variable(variable) => {
4652 Self::Variable(encode_variable(variables, variable))
4653 }
4654 NamedNodePattern::NamedNode(term) => {
4655 Self::Constant(dataset.internalize_term(term.as_ref().into())?)
4656 }
4657 })
4658 }
4659
4660 #[cfg_attr(not(feature = "rdf-star"), allow(clippy::unnecessary_wraps))]
4661 fn get_pattern_value(
4662 &self,
4663 tuple: &InternalTuple<D>,
4664 #[cfg(feature = "rdf-star")] dataset: &EvalDataset<D>,
4665 ) -> Result<Option<D::InternalTerm>, QueryEvaluationError> {
4666 Ok(match self {
4667 Self::Constant(c) => Some(c.clone()),
4668 Self::Variable(v) => tuple.get(*v).cloned(),
4669 #[cfg(feature = "rdf-star")]
4670 Self::TriplePattern(triple) => {
4671 let Some(subject) = triple.subject.get_pattern_value(tuple, dataset)? else {
4672 return Ok(None);
4673 };
4674 let Some(predicate) = triple.predicate.get_pattern_value(tuple, dataset)? else {
4675 return Ok(None);
4676 };
4677 let Some(object) = triple.object.get_pattern_value(tuple, dataset)? else {
4678 return Ok(None);
4679 };
4680 Some(
4681 dataset.internalize_expression_term(
4682 ExpressionTriple::new(
4683 dataset.externalize_expression_term(subject)?,
4684 dataset.externalize_expression_term(predicate)?,
4685 dataset.externalize_expression_term(object)?,
4686 )
4687 .ok_or(QueryEvaluationError::InvalidStorageTripleTerm)?
4688 .into(),
4689 )?,
4690 )
4691 }
4692 })
4693 }
4694}
4695
4696impl<D: QueryableDataset> Clone for TupleSelector<D> {
4697 fn clone(&self) -> Self {
4698 match self {
4699 Self::Constant(c) => Self::Constant(c.clone()),
4700 Self::Variable(v) => Self::Variable(*v),
4701 #[cfg(feature = "rdf-star")]
4702 Self::TriplePattern(t) => Self::TriplePattern(Rc::clone(t)),
4703 }
4704 }
4705}
4706
4707#[cfg(feature = "rdf-star")]
4708struct TripleTupleSelector<D: QueryableDataset> {
4709 subject: TupleSelector<D>,
4710 predicate: TupleSelector<D>,
4711 object: TupleSelector<D>,
4712}
4713
4714#[cfg_attr(not(feature = "rdf-star"), allow(clippy::unnecessary_wraps))]
4715fn put_pattern_value<D: QueryableDataset>(
4716 selector: &TupleSelector<D>,
4717 value: D::InternalTerm,
4718 tuple: &mut InternalTuple<D>,
4719 #[cfg(feature = "rdf-star")] dataset: &EvalDataset<D>,
4720) -> Result<bool, QueryEvaluationError> {
4721 Ok(match selector {
4722 TupleSelector::Constant(c) => *c == value,
4723 TupleSelector::Variable(v) => {
4724 if let Some(old) = tuple.get(*v) {
4725 value == *old
4726 } else {
4727 tuple.set(*v, value);
4728 true
4729 }
4730 }
4731 #[cfg(feature = "rdf-star")]
4732 TupleSelector::TriplePattern(triple) => {
4733 let ExpressionTerm::Triple(value) = dataset.externalize_expression_term(value)? else {
4734 return Ok(false);
4735 };
4736 put_pattern_value(
4737 &triple.subject,
4738 dataset.internalize_expression_term(value.subject.into())?,
4739 tuple,
4740 dataset,
4741 )? && put_pattern_value(
4742 &triple.predicate,
4743 dataset.internalize_expression_term(value.predicate.into())?,
4744 tuple,
4745 dataset,
4746 )? && put_pattern_value(
4747 &triple.object,
4748 dataset.internalize_expression_term(value.object)?,
4749 tuple,
4750 dataset,
4751 )?
4752 }
4753 })
4754}
4755
4756pub fn are_compatible_and_not_disjointed<D: QueryableDataset>(
4757 a: &InternalTuple<D>,
4758 b: &InternalTuple<D>,
4759) -> bool {
4760 let mut found_intersection = false;
4761 for (a_value, b_value) in a.iter().zip(b.iter()) {
4762 if let (Some(a_value), Some(b_value)) = (a_value, b_value) {
4763 if a_value != b_value {
4764 return false;
4765 }
4766 found_intersection = true;
4767 }
4768 }
4769 found_intersection
4770}
4771
4772pub enum PropertyPath<D: QueryableDataset> {
4773 Path(D::InternalTerm),
4774 Reverse(Rc<Self>),
4775 Sequence(Rc<Self>, Rc<Self>),
4776 Alternative(Rc<Self>, Rc<Self>),
4777 ZeroOrMore(Rc<Self>),
4778 OneOrMore(Rc<Self>),
4779 ZeroOrOne(Rc<Self>),
4780 NegatedPropertySet(Rc<[D::InternalTerm]>),
4781}
4782
4783struct PathEvaluator<D: QueryableDataset> {
4784 dataset: EvalDataset<D>,
4785}
4786
4787impl<D: QueryableDataset> PathEvaluator<D> {
4788 fn eval_closed_in_graph(
4789 &self,
4790 path: &PropertyPath<D>,
4791 start: &D::InternalTerm,
4792 end: &D::InternalTerm,
4793 graph_name: Option<&D::InternalTerm>,
4794 ) -> Result<bool, QueryEvaluationError> {
4795 Ok(match path {
4796 PropertyPath::Path(p) => self
4797 .dataset
4798 .internal_quads_for_pattern(Some(start), Some(p), Some(end), Some(graph_name))
4799 .next()
4800 .transpose()?
4801 .is_some(),
4802 PropertyPath::Reverse(p) => self.eval_closed_in_graph(p, end, start, graph_name)?,
4803 PropertyPath::Sequence(a, b) => self
4804 .eval_from_in_graph(a, start, graph_name)
4805 .find_map(|middle| {
4806 middle
4807 .and_then(|middle| {
4808 Ok(self
4809 .eval_closed_in_graph(b, &middle, end, graph_name)?
4810 .then_some(()))
4811 })
4812 .transpose()
4813 })
4814 .transpose()?
4815 .is_some(),
4816 PropertyPath::Alternative(a, b) => {
4817 self.eval_closed_in_graph(a, start, end, graph_name)?
4818 || self.eval_closed_in_graph(b, start, end, graph_name)?
4819 }
4820 PropertyPath::ZeroOrMore(p) => {
4821 if start == end {
4822 self.is_subject_or_object_in_graph(start, graph_name)?
4823 } else {
4824 look_in_transitive_closure(
4825 self.eval_from_in_graph(p, start, graph_name),
4826 move |e| self.eval_from_in_graph(p, &e, graph_name),
4827 end,
4828 )?
4829 }
4830 }
4831 PropertyPath::OneOrMore(p) => look_in_transitive_closure(
4832 self.eval_from_in_graph(p, start, graph_name),
4833 move |e| self.eval_from_in_graph(p, &e, graph_name),
4834 end,
4835 )?,
4836 PropertyPath::ZeroOrOne(p) => {
4837 if start == end {
4838 self.is_subject_or_object_in_graph(start, graph_name)
4839 } else {
4840 self.eval_closed_in_graph(p, start, end, graph_name)
4841 }?
4842 }
4843 PropertyPath::NegatedPropertySet(ps) => self
4844 .dataset
4845 .internal_quads_for_pattern(Some(start), None, Some(end), Some(graph_name))
4846 .find_map(move |t| match t {
4847 Ok(t) => {
4848 if ps.contains(&t.predicate) {
4849 None
4850 } else {
4851 Some(Ok(()))
4852 }
4853 }
4854 Err(e) => Some(Err(e)),
4855 })
4856 .transpose()?
4857 .is_some(),
4858 })
4859 }
4860
4861 fn eval_closed_in_unknown_graph(
4862 &self,
4863 path: &PropertyPath<D>,
4864 start: &D::InternalTerm,
4865 end: &D::InternalTerm,
4866 ) -> Box<dyn Iterator<Item = Result<Option<D::InternalTerm>, QueryEvaluationError>>> {
4867 match path {
4868 PropertyPath::Path(p) => Box::new(
4869 self.dataset
4870 .internal_quads_for_pattern(Some(start), Some(p), Some(end), None)
4871 .map(|t| Ok(t?.graph_name)),
4872 ),
4873 PropertyPath::Reverse(p) => self.eval_closed_in_unknown_graph(p, end, start),
4874 PropertyPath::Sequence(a, b) => {
4875 let eval = self.clone();
4876 let b = Rc::clone(b);
4877 let end = end.clone();
4878 Box::new(self.eval_from_in_unknown_graph(a, start).flat_map_ok(
4879 move |(middle, graph_name)| {
4880 eval.eval_closed_in_graph(&b, &middle, &end, graph_name.as_ref())
4881 .map(|is_found| is_found.then_some(graph_name))
4882 .transpose()
4883 },
4884 ))
4885 }
4886 PropertyPath::Alternative(a, b) => Box::new(hash_deduplicate(
4887 self.eval_closed_in_unknown_graph(a, start, end)
4888 .chain(self.eval_closed_in_unknown_graph(b, start, end)),
4889 )),
4890 PropertyPath::ZeroOrMore(p) => {
4891 let eval = self.clone();
4892 let start2 = start.clone();
4893 let end = end.clone();
4894 let p = Rc::clone(p);
4895 self.run_if_term_is_a_dataset_node(start, move |graph_name| {
4896 look_in_transitive_closure(
4897 Some(Ok(start2.clone())),
4898 |e| eval.eval_from_in_graph(&p, &e, graph_name.as_ref()),
4899 &end,
4900 )
4901 .map(|is_found| is_found.then_some(graph_name))
4902 .transpose()
4903 })
4904 }
4905 PropertyPath::OneOrMore(p) => {
4906 let eval = self.clone();
4907 let end = end.clone();
4908 let p = Rc::clone(p);
4909 Box::new(
4910 self.eval_from_in_unknown_graph(&p, start)
4911 .filter_map(move |r| {
4912 r.and_then(|(start, graph_name)| {
4913 look_in_transitive_closure(
4914 Some(Ok(start)),
4915 |e| eval.eval_from_in_graph(&p, &e, graph_name.as_ref()),
4916 &end,
4917 )
4918 .map(|is_found| is_found.then_some(graph_name))
4919 })
4920 .transpose()
4921 }),
4922 )
4923 }
4924 PropertyPath::ZeroOrOne(p) => {
4925 if start == end {
4926 self.run_if_term_is_a_dataset_node(start, |graph_name| Some(Ok(graph_name)))
4927 } else {
4928 let eval = self.clone();
4929 let start2 = start.clone();
4930 let end = end.clone();
4931 let p = Rc::clone(p);
4932 self.run_if_term_is_a_dataset_node(start, move |graph_name| {
4933 eval.eval_closed_in_graph(&p, &start2, &end, graph_name.as_ref())
4934 .map(|is_found| is_found.then_some(graph_name))
4935 .transpose()
4936 })
4937 }
4938 }
4939 PropertyPath::NegatedPropertySet(ps) => {
4940 let ps = Rc::clone(ps);
4941 Box::new(
4942 self.dataset
4943 .internal_quads_for_pattern(Some(start), None, Some(end), None)
4944 .filter_map(move |t| match t {
4945 Ok(t) => {
4946 if ps.contains(&t.predicate) {
4947 None
4948 } else {
4949 Some(Ok(t.graph_name))
4950 }
4951 }
4952 Err(e) => Some(Err(e)),
4953 }),
4954 )
4955 }
4956 }
4957 }
4958
4959 fn eval_from_in_graph(
4960 &self,
4961 path: &PropertyPath<D>,
4962 start: &D::InternalTerm,
4963 graph_name: Option<&D::InternalTerm>,
4964 ) -> Box<dyn Iterator<Item = Result<D::InternalTerm, QueryEvaluationError>>> {
4965 match path {
4966 PropertyPath::Path(p) => Box::new(
4967 self.dataset
4968 .internal_quads_for_pattern(Some(start), Some(p), None, Some(graph_name))
4969 .map(|t| Ok(t?.object)),
4970 ),
4971 PropertyPath::Reverse(p) => self.eval_to_in_graph(p, start, graph_name),
4972 PropertyPath::Sequence(a, b) => {
4973 let eval = self.clone();
4974 let b = Rc::clone(b);
4975 let graph_name2 = graph_name.cloned();
4976 Box::new(
4977 self.eval_from_in_graph(a, start, graph_name)
4978 .flat_map_ok(move |middle| {
4979 eval.eval_from_in_graph(&b, &middle, graph_name2.as_ref())
4980 }),
4981 )
4982 }
4983 PropertyPath::Alternative(a, b) => Box::new(hash_deduplicate(
4984 self.eval_from_in_graph(a, start, graph_name)
4985 .chain(self.eval_from_in_graph(b, start, graph_name)),
4986 )),
4987 PropertyPath::ZeroOrMore(p) => {
4988 self.run_if_term_is_a_graph_node(start, graph_name, || {
4989 let eval = self.clone();
4990 let p = Rc::clone(p);
4991 let graph_name2 = graph_name.cloned();
4992 transitive_closure(Some(Ok(start.clone())), move |e| {
4993 eval.eval_from_in_graph(&p, &e, graph_name2.as_ref())
4994 })
4995 })
4996 }
4997 PropertyPath::OneOrMore(p) => {
4998 let eval = self.clone();
4999 let p = Rc::clone(p);
5000 let graph_name2 = graph_name.cloned();
5001 Box::new(transitive_closure(
5002 self.eval_from_in_graph(&p, start, graph_name),
5003 move |e| eval.eval_from_in_graph(&p, &e, graph_name2.as_ref()),
5004 ))
5005 }
5006 PropertyPath::ZeroOrOne(p) => {
5007 self.run_if_term_is_a_graph_node(start, graph_name, || {
5008 hash_deduplicate(
5009 once(Ok(start.clone()))
5010 .chain(self.eval_from_in_graph(p, start, graph_name)),
5011 )
5012 })
5013 }
5014 PropertyPath::NegatedPropertySet(ps) => {
5015 let ps = Rc::clone(ps);
5016 Box::new(
5017 self.dataset
5018 .internal_quads_for_pattern(Some(start), None, None, Some(graph_name))
5019 .filter_map(move |t| match t {
5020 Ok(t) => {
5021 if ps.contains(&t.predicate) {
5022 None
5023 } else {
5024 Some(Ok(t.object))
5025 }
5026 }
5027 Err(e) => Some(Err(e)),
5028 }),
5029 )
5030 }
5031 }
5032 }
5033
5034 fn eval_from_in_unknown_graph(
5035 &self,
5036 path: &PropertyPath<D>,
5037 start: &D::InternalTerm,
5038 ) -> Box<
5039 dyn Iterator<
5040 Item = Result<(D::InternalTerm, Option<D::InternalTerm>), QueryEvaluationError>,
5041 >,
5042 > {
5043 match path {
5044 PropertyPath::Path(p) => Box::new(
5045 self.dataset
5046 .internal_quads_for_pattern(Some(start), Some(p), None, None)
5047 .map(|t| {
5048 let t = t?;
5049 Ok((t.object, t.graph_name))
5050 }),
5051 ),
5052 PropertyPath::Reverse(p) => self.eval_to_in_unknown_graph(p, start),
5053 PropertyPath::Sequence(a, b) => {
5054 let eval = self.clone();
5055 let b = Rc::clone(b);
5056 Box::new(self.eval_from_in_unknown_graph(a, start).flat_map_ok(
5057 move |(middle, graph_name)| {
5058 eval.eval_from_in_graph(&b, &middle, graph_name.as_ref())
5059 .map(move |end| Ok((end?, graph_name.clone())))
5060 },
5061 ))
5062 }
5063 PropertyPath::Alternative(a, b) => Box::new(hash_deduplicate(
5064 self.eval_from_in_unknown_graph(a, start)
5065 .chain(self.eval_from_in_unknown_graph(b, start)),
5066 )),
5067 PropertyPath::ZeroOrMore(p) => {
5068 let start2 = start.clone();
5069 let eval = self.clone();
5070 let p = Rc::clone(p);
5071 self.run_if_term_is_a_dataset_node(start, move |graph_name| {
5072 let eval = eval.clone();
5073 let p = Rc::clone(&p);
5074 let graph_name2 = graph_name.clone();
5075 transitive_closure(Some(Ok(start2.clone())), move |e| {
5076 eval.eval_from_in_graph(&p, &e, graph_name2.as_ref())
5077 })
5078 .map(move |e| Ok((e?, graph_name.clone())))
5079 })
5080 }
5081 PropertyPath::OneOrMore(p) => {
5082 let eval = self.clone();
5083 let p = Rc::clone(p);
5084 Box::new(transitive_closure(
5085 self.eval_from_in_unknown_graph(&p, start),
5086 move |(e, graph_name)| {
5087 eval.eval_from_in_graph(&p, &e, graph_name.as_ref())
5088 .map(move |e| Ok((e?, graph_name.clone())))
5089 },
5090 ))
5091 }
5092 PropertyPath::ZeroOrOne(p) => {
5093 let eval = self.clone();
5094 let start2 = start.clone();
5095 let p = Rc::clone(p);
5096 self.run_if_term_is_a_dataset_node(start, move |graph_name| {
5097 hash_deduplicate(once(Ok(start2.clone())).chain(eval.eval_from_in_graph(
5098 &p,
5099 &start2,
5100 graph_name.as_ref(),
5101 )))
5102 .map(move |e| Ok((e?, graph_name.clone())))
5103 })
5104 }
5105 PropertyPath::NegatedPropertySet(ps) => {
5106 let ps = Rc::clone(ps);
5107 Box::new(
5108 self.dataset
5109 .internal_quads_for_pattern(Some(start), None, None, None)
5110 .filter_map(move |t| match t {
5111 Ok(t) => {
5112 if ps.contains(&t.predicate) {
5113 None
5114 } else {
5115 Some(Ok((t.object, t.graph_name)))
5116 }
5117 }
5118 Err(e) => Some(Err(e)),
5119 }),
5120 )
5121 }
5122 }
5123 }
5124
5125 fn eval_to_in_graph(
5126 &self,
5127 path: &PropertyPath<D>,
5128 end: &D::InternalTerm,
5129 graph_name: Option<&D::InternalTerm>,
5130 ) -> Box<dyn Iterator<Item = Result<D::InternalTerm, QueryEvaluationError>>> {
5131 match path {
5132 PropertyPath::Path(p) => Box::new(
5133 self.dataset
5134 .internal_quads_for_pattern(None, Some(p), Some(end), Some(graph_name))
5135 .map(|t| Ok(t?.subject)),
5136 ),
5137 PropertyPath::Reverse(p) => self.eval_from_in_graph(p, end, graph_name),
5138 PropertyPath::Sequence(a, b) => {
5139 let eval = self.clone();
5140 let a = Rc::clone(a);
5141 let graph_name2 = graph_name.cloned();
5142 Box::new(
5143 self.eval_to_in_graph(b, end, graph_name)
5144 .flat_map_ok(move |middle| {
5145 eval.eval_to_in_graph(&a, &middle, graph_name2.as_ref())
5146 }),
5147 )
5148 }
5149 PropertyPath::Alternative(a, b) => Box::new(hash_deduplicate(
5150 self.eval_to_in_graph(a, end, graph_name)
5151 .chain(self.eval_to_in_graph(b, end, graph_name)),
5152 )),
5153 PropertyPath::ZeroOrMore(p) => {
5154 self.run_if_term_is_a_graph_node(end, graph_name, || {
5155 let eval = self.clone();
5156 let p = Rc::clone(p);
5157 let graph_name2 = graph_name.cloned();
5158 transitive_closure(Some(Ok(end.clone())), move |e| {
5159 eval.eval_to_in_graph(&p, &e, graph_name2.as_ref())
5160 })
5161 })
5162 }
5163 PropertyPath::OneOrMore(p) => {
5164 let eval = self.clone();
5165 let p = Rc::clone(p);
5166 let graph_name2 = graph_name.cloned();
5167 Box::new(transitive_closure(
5168 self.eval_to_in_graph(&p, end, graph_name),
5169 move |e| eval.eval_to_in_graph(&p, &e, graph_name2.as_ref()),
5170 ))
5171 }
5172 PropertyPath::ZeroOrOne(p) => self.run_if_term_is_a_graph_node(end, graph_name, || {
5173 hash_deduplicate(
5174 once(Ok(end.clone())).chain(self.eval_to_in_graph(p, end, graph_name)),
5175 )
5176 }),
5177 PropertyPath::NegatedPropertySet(ps) => {
5178 let ps = Rc::clone(ps);
5179 Box::new(
5180 self.dataset
5181 .internal_quads_for_pattern(None, None, Some(end), Some(graph_name))
5182 .filter_map(move |t| match t {
5183 Ok(t) => {
5184 if ps.contains(&t.predicate) {
5185 None
5186 } else {
5187 Some(Ok(t.subject))
5188 }
5189 }
5190 Err(e) => Some(Err(e)),
5191 }),
5192 )
5193 }
5194 }
5195 }
5196
5197 fn eval_to_in_unknown_graph(
5198 &self,
5199 path: &PropertyPath<D>,
5200 end: &D::InternalTerm,
5201 ) -> Box<
5202 dyn Iterator<
5203 Item = Result<(D::InternalTerm, Option<D::InternalTerm>), QueryEvaluationError>,
5204 >,
5205 > {
5206 match path {
5207 PropertyPath::Path(p) => Box::new(
5208 self.dataset
5209 .internal_quads_for_pattern(None, Some(p), Some(end), None)
5210 .map(|t| {
5211 let t = t?;
5212 Ok((t.subject, t.graph_name))
5213 }),
5214 ),
5215 PropertyPath::Reverse(p) => self.eval_from_in_unknown_graph(p, end),
5216 PropertyPath::Sequence(a, b) => {
5217 let eval = self.clone();
5218 let a = Rc::clone(a);
5219 Box::new(self.eval_to_in_unknown_graph(b, end).flat_map_ok(
5220 move |(middle, graph_name)| {
5221 eval.eval_to_in_graph(&a, &middle, graph_name.as_ref())
5222 .map(move |start| Ok((start?, graph_name.clone())))
5223 },
5224 ))
5225 }
5226 PropertyPath::Alternative(a, b) => Box::new(hash_deduplicate(
5227 self.eval_to_in_unknown_graph(a, end)
5228 .chain(self.eval_to_in_unknown_graph(b, end)),
5229 )),
5230 PropertyPath::ZeroOrMore(p) => {
5231 let end2 = end.clone();
5232 let eval = self.clone();
5233 let p = Rc::clone(p);
5234 self.run_if_term_is_a_dataset_node(end, move |graph_name| {
5235 let eval = eval.clone();
5236 let p = Rc::clone(&p);
5237 let graph_name2 = graph_name.clone();
5238 transitive_closure(Some(Ok(end2.clone())), move |e| {
5239 eval.eval_to_in_graph(&p, &e, graph_name2.as_ref())
5240 })
5241 .map(move |e| Ok((e?, graph_name.clone())))
5242 })
5243 }
5244 PropertyPath::OneOrMore(p) => {
5245 let eval = self.clone();
5246 let p = Rc::clone(p);
5247 Box::new(transitive_closure(
5248 self.eval_to_in_unknown_graph(&p, end),
5249 move |(e, graph_name)| {
5250 eval.eval_to_in_graph(&p, &e, graph_name.as_ref())
5251 .map(move |e| Ok((e?, graph_name.clone())))
5252 },
5253 ))
5254 }
5255 PropertyPath::ZeroOrOne(p) => {
5256 let eval = self.clone();
5257 let end2 = end.clone();
5258 let p = Rc::clone(p);
5259 self.run_if_term_is_a_dataset_node(end, move |graph_name| {
5260 hash_deduplicate(once(Ok(end2.clone())).chain(eval.eval_to_in_graph(
5261 &p,
5262 &end2,
5263 graph_name.as_ref(),
5264 )))
5265 .map(move |e| Ok((e?, graph_name.clone())))
5266 })
5267 }
5268 PropertyPath::NegatedPropertySet(ps) => {
5269 let ps = Rc::clone(ps);
5270 Box::new(
5271 self.dataset
5272 .internal_quads_for_pattern(None, None, Some(end), None)
5273 .filter_map(move |t| match t {
5274 Ok(t) => {
5275 if ps.contains(&t.predicate) {
5276 None
5277 } else {
5278 Some(Ok((t.subject, t.graph_name)))
5279 }
5280 }
5281 Err(e) => Some(Err(e)),
5282 }),
5283 )
5284 }
5285 }
5286 }
5287
5288 fn eval_open_in_graph(
5289 &self,
5290 path: &PropertyPath<D>,
5291 graph_name: Option<&D::InternalTerm>,
5292 ) -> Box<dyn Iterator<Item = Result<(D::InternalTerm, D::InternalTerm), QueryEvaluationError>>>
5293 {
5294 match path {
5295 PropertyPath::Path(p) => Box::new(
5296 self.dataset
5297 .internal_quads_for_pattern(None, Some(p), None, Some(graph_name))
5298 .map(|t| {
5299 let t = t?;
5300 Ok((t.subject, t.object))
5301 }),
5302 ),
5303 PropertyPath::Reverse(p) => Box::new(
5304 self.eval_open_in_graph(p, graph_name)
5305 .map(|t| t.map(|(s, o)| (o, s))),
5306 ),
5307 PropertyPath::Sequence(a, b) => {
5308 let eval = self.clone();
5309 let b = Rc::clone(b);
5310 let graph_name2 = graph_name.cloned();
5311 Box::new(self.eval_open_in_graph(a, graph_name).flat_map_ok(
5312 move |(start, middle)| {
5313 eval.eval_from_in_graph(&b, &middle, graph_name2.as_ref())
5314 .map(move |end| Ok((start.clone(), end?)))
5315 },
5316 ))
5317 }
5318 PropertyPath::Alternative(a, b) => Box::new(hash_deduplicate(
5319 self.eval_open_in_graph(a, graph_name)
5320 .chain(self.eval_open_in_graph(b, graph_name)),
5321 )),
5322 PropertyPath::ZeroOrMore(p) => {
5323 let eval = self.clone();
5324 let p = Rc::clone(p);
5325 let graph_name2 = graph_name.cloned();
5326 Box::new(transitive_closure(
5327 self.get_subject_or_object_identity_pairs_in_graph(graph_name),
5328 move |(start, middle)| {
5329 eval.eval_from_in_graph(&p, &middle, graph_name2.as_ref())
5330 .map(move |end| Ok((start.clone(), end?)))
5331 },
5332 ))
5333 }
5334 PropertyPath::OneOrMore(p) => {
5335 let eval = self.clone();
5336 let p = Rc::clone(p);
5337 let graph_name2 = graph_name.cloned();
5338 Box::new(transitive_closure(
5339 self.eval_open_in_graph(&p, graph_name),
5340 move |(start, middle)| {
5341 eval.eval_from_in_graph(&p, &middle, graph_name2.as_ref())
5342 .map(move |end| Ok((start.clone(), end?)))
5343 },
5344 ))
5345 }
5346 PropertyPath::ZeroOrOne(p) => Box::new(hash_deduplicate(
5347 self.get_subject_or_object_identity_pairs_in_graph(graph_name)
5348 .chain(self.eval_open_in_graph(p, graph_name)),
5349 )),
5350 PropertyPath::NegatedPropertySet(ps) => {
5351 let ps = Rc::clone(ps);
5352 Box::new(
5353 self.dataset
5354 .internal_quads_for_pattern(None, None, None, Some(graph_name))
5355 .filter_map(move |t| match t {
5356 Ok(t) => {
5357 if ps.contains(&t.predicate) {
5358 None
5359 } else {
5360 Some(Ok((t.subject, t.object)))
5361 }
5362 }
5363 Err(e) => Some(Err(e)),
5364 }),
5365 )
5366 }
5367 }
5368 }
5369
5370 fn eval_open_in_unknown_graph(
5371 &self,
5372 path: &PropertyPath<D>,
5373 ) -> Box<
5374 dyn Iterator<
5375 Item = Result<
5376 (D::InternalTerm, D::InternalTerm, Option<D::InternalTerm>),
5377 QueryEvaluationError,
5378 >,
5379 >,
5380 > {
5381 match path {
5382 PropertyPath::Path(p) => Box::new(
5383 self.dataset
5384 .internal_quads_for_pattern(None, Some(p), None, None)
5385 .map(|t| {
5386 let t = t?;
5387 Ok((t.subject, t.object, t.graph_name))
5388 }),
5389 ),
5390 PropertyPath::Reverse(p) => Box::new(
5391 self.eval_open_in_unknown_graph(p)
5392 .map(|t| t.map(|(s, o, g)| (o, s, g))),
5393 ),
5394 PropertyPath::Sequence(a, b) => {
5395 let eval = self.clone();
5396 let b = Rc::clone(b);
5397 Box::new(self.eval_open_in_unknown_graph(a).flat_map_ok(
5398 move |(start, middle, graph_name)| {
5399 eval.eval_from_in_graph(&b, &middle, graph_name.as_ref())
5400 .map(move |end| Ok((start.clone(), end?, graph_name.clone())))
5401 },
5402 ))
5403 }
5404 PropertyPath::Alternative(a, b) => Box::new(hash_deduplicate(
5405 self.eval_open_in_unknown_graph(a)
5406 .chain(self.eval_open_in_unknown_graph(b)),
5407 )),
5408 PropertyPath::ZeroOrMore(p) => {
5409 let eval = self.clone();
5410 let p = Rc::clone(p);
5411 Box::new(transitive_closure(
5412 self.get_subject_or_object_identity_pairs_in_dataset(),
5413 move |(start, middle, graph_name)| {
5414 eval.eval_from_in_graph(&p, &middle, graph_name.as_ref())
5415 .map(move |end| Ok((start.clone(), end?, graph_name.clone())))
5416 },
5417 ))
5418 }
5419 PropertyPath::OneOrMore(p) => {
5420 let eval = self.clone();
5421 let p = Rc::clone(p);
5422 Box::new(transitive_closure(
5423 self.eval_open_in_unknown_graph(&p),
5424 move |(start, middle, graph_name)| {
5425 eval.eval_from_in_graph(&p, &middle, graph_name.as_ref())
5426 .map(move |end| Ok((start.clone(), end?, graph_name.clone())))
5427 },
5428 ))
5429 }
5430 PropertyPath::ZeroOrOne(p) => Box::new(hash_deduplicate(
5431 self.get_subject_or_object_identity_pairs_in_dataset()
5432 .chain(self.eval_open_in_unknown_graph(p)),
5433 )),
5434 PropertyPath::NegatedPropertySet(ps) => {
5435 let ps = Rc::clone(ps);
5436 Box::new(
5437 self.dataset
5438 .internal_quads_for_pattern(None, None, None, None)
5439 .filter_map(move |t| match t {
5440 Ok(t) => {
5441 if ps.contains(&t.predicate) {
5442 None
5443 } else {
5444 Some(Ok((t.subject, t.object, t.graph_name)))
5445 }
5446 }
5447 Err(e) => Some(Err(e)),
5448 }),
5449 )
5450 }
5451 }
5452 }
5453
5454 fn get_subject_or_object_identity_pairs_in_graph(
5455 &self,
5456 graph_name: Option<&D::InternalTerm>,
5457 ) -> impl Iterator<Item = Result<(D::InternalTerm, D::InternalTerm), QueryEvaluationError>>
5458 {
5459 self.dataset
5460 .internal_quads_for_pattern(None, None, None, Some(graph_name))
5461 .flat_map_ok(|t| {
5462 [
5463 Ok((t.subject.clone(), t.subject)),
5464 Ok((t.object.clone(), t.object)),
5465 ]
5466 })
5467 }
5468
5469 fn get_subject_or_object_identity_pairs_in_dataset(
5470 &self,
5471 ) -> impl Iterator<
5472 Item = Result<
5473 (D::InternalTerm, D::InternalTerm, Option<D::InternalTerm>),
5474 QueryEvaluationError,
5475 >,
5476 > {
5477 self.dataset
5478 .internal_quads_for_pattern(None, None, None, None)
5479 .flat_map_ok(|t| {
5480 [
5481 Ok((t.subject.clone(), t.subject, t.graph_name.clone())),
5482 Ok((t.object.clone(), t.object, t.graph_name)),
5483 ]
5484 })
5485 }
5486
5487 fn run_if_term_is_a_graph_node<
5488 T: 'static,
5489 I: Iterator<Item = Result<T, QueryEvaluationError>> + 'static,
5490 >(
5491 &self,
5492 term: &D::InternalTerm,
5493 graph_name: Option<&D::InternalTerm>,
5494 f: impl FnOnce() -> I,
5495 ) -> Box<dyn Iterator<Item = Result<T, QueryEvaluationError>>> {
5496 match self.is_subject_or_object_in_graph(term, graph_name) {
5497 Ok(true) => Box::new(f()),
5498 Ok(false) => {
5499 Box::new(empty()) }
5501 Err(error) => Box::new(once(Err(error))),
5502 }
5503 }
5504
5505 fn is_subject_or_object_in_graph(
5506 &self,
5507 term: &D::InternalTerm,
5508 graph_name: Option<&D::InternalTerm>,
5509 ) -> Result<bool, QueryEvaluationError> {
5510 Ok(self
5511 .dataset
5512 .internal_quads_for_pattern(Some(term), None, None, Some(graph_name))
5513 .next()
5514 .transpose()?
5515 .is_some()
5516 || self
5517 .dataset
5518 .internal_quads_for_pattern(None, None, Some(term), Some(graph_name))
5519 .next()
5520 .transpose()?
5521 .is_some())
5522 }
5523
5524 fn run_if_term_is_a_dataset_node<
5525 T: 'static,
5526 I: IntoIterator<Item = Result<T, QueryEvaluationError>> + 'static,
5527 >(
5528 &self,
5529 term: &D::InternalTerm,
5530 f: impl FnMut(Option<D::InternalTerm>) -> I + 'static,
5531 ) -> Box<dyn Iterator<Item = Result<T, QueryEvaluationError>>> {
5532 match self
5533 .find_graphs_where_the_node_is_in(term)
5534 .collect::<Result<FxHashSet<_>, _>>()
5535 {
5536 Ok(graph_names) => Box::new(graph_names.into_iter().flat_map(f)),
5537 Err(error) => Box::new(once(Err(error))),
5538 }
5539 }
5540
5541 fn find_graphs_where_the_node_is_in(
5542 &self,
5543 term: &D::InternalTerm,
5544 ) -> impl Iterator<Item = Result<Option<D::InternalTerm>, QueryEvaluationError>> {
5545 self.dataset
5546 .internal_quads_for_pattern(Some(term), None, None, None)
5547 .chain(
5548 self.dataset
5549 .internal_quads_for_pattern(None, None, Some(term), None),
5550 )
5551 .map(|q| Ok(q?.graph_name))
5552 }
5553}
5554
5555impl<D: QueryableDataset> Clone for PathEvaluator<D> {
5556 fn clone(&self) -> Self {
5557 Self {
5558 dataset: self.dataset.clone(),
5559 }
5560 }
5561}
5562
5563struct CartesianProductJoinIterator<D: QueryableDataset> {
5564 probe_iter: Peekable<InternalTuplesIterator<D>>,
5565 built: Vec<InternalTuple<D>>,
5566 buffered_results: Vec<Result<InternalTuple<D>, QueryEvaluationError>>,
5567}
5568
5569impl<D: QueryableDataset> Iterator for CartesianProductJoinIterator<D> {
5570 type Item = Result<InternalTuple<D>, QueryEvaluationError>;
5571
5572 fn next(&mut self) -> Option<Self::Item> {
5573 loop {
5574 if let Some(result) = self.buffered_results.pop() {
5575 return Some(result);
5576 }
5577 let probe_tuple = match self.probe_iter.next()? {
5578 Ok(probe_tuple) => probe_tuple,
5579 Err(error) => return Some(Err(error)),
5580 };
5581 for built_tuple in &self.built {
5582 if let Some(result_tuple) = probe_tuple.combine_with(built_tuple) {
5583 self.buffered_results.push(Ok(result_tuple))
5584 }
5585 }
5586 }
5587 }
5588
5589 fn size_hint(&self) -> (usize, Option<usize>) {
5590 let (min, max) = self.probe_iter.size_hint();
5591 (
5592 min.saturating_mul(self.built.len()),
5593 max.map(|v| v.saturating_mul(self.built.len())),
5594 )
5595 }
5596}
5597
5598struct HashJoinIterator<D: QueryableDataset> {
5599 probe_iter: Peekable<InternalTuplesIterator<D>>,
5600 built: InternalTupleSet<D>,
5601 buffered_results: Vec<Result<InternalTuple<D>, QueryEvaluationError>>,
5602}
5603
5604impl<D: QueryableDataset> Iterator for HashJoinIterator<D> {
5605 type Item = Result<InternalTuple<D>, QueryEvaluationError>;
5606
5607 fn next(&mut self) -> Option<Self::Item> {
5608 loop {
5609 if let Some(result) = self.buffered_results.pop() {
5610 return Some(result);
5611 }
5612 let probe_tuple = match self.probe_iter.next()? {
5613 Ok(probe_tuple) => probe_tuple,
5614 Err(error) => return Some(Err(error)),
5615 };
5616 self.buffered_results.extend(
5617 self.built
5618 .get(&probe_tuple)
5619 .iter()
5620 .filter_map(|built_tuple| probe_tuple.combine_with(built_tuple).map(Ok)),
5621 )
5622 }
5623 }
5624
5625 fn size_hint(&self) -> (usize, Option<usize>) {
5626 (
5627 0,
5628 self.probe_iter
5629 .size_hint()
5630 .1
5631 .map(|v| v.saturating_mul(self.built.len())),
5632 )
5633 }
5634}
5635
5636struct HashLeftJoinIterator<D: QueryableDataset> {
5637 left_iter: InternalTuplesIterator<D>,
5638 right: InternalTupleSet<D>,
5639 buffered_results: Vec<Result<InternalTuple<D>, QueryEvaluationError>>,
5640 expression: Rc<dyn Fn(&InternalTuple<D>) -> Option<bool>>,
5641}
5642
5643impl<D: QueryableDataset> Iterator for HashLeftJoinIterator<D> {
5644 type Item = Result<InternalTuple<D>, QueryEvaluationError>;
5645
5646 fn next(&mut self) -> Option<Self::Item> {
5647 loop {
5648 if let Some(result) = self.buffered_results.pop() {
5649 return Some(result);
5650 }
5651 let left_tuple = match self.left_iter.next()? {
5652 Ok(left_tuple) => left_tuple,
5653 Err(error) => return Some(Err(error)),
5654 };
5655 self.buffered_results.extend(
5656 self.right
5657 .get(&left_tuple)
5658 .iter()
5659 .filter_map(|right_tuple| left_tuple.combine_with(right_tuple))
5660 .filter(|tuple| (self.expression)(tuple).unwrap_or(false))
5661 .map(Ok),
5662 );
5663 if self.buffered_results.is_empty() {
5664 return Some(Ok(left_tuple));
5666 }
5667 }
5668 }
5669
5670 fn size_hint(&self) -> (usize, Option<usize>) {
5671 (
5672 0,
5673 self.left_iter
5674 .size_hint()
5675 .1
5676 .map(|v| v.saturating_mul(self.right.len())),
5677 )
5678 }
5679}
5680
5681#[cfg(feature = "sep-0006")]
5682struct ForLoopLeftJoinIterator<D: QueryableDataset> {
5683 right_evaluator: Rc<dyn Fn(InternalTuple<D>) -> InternalTuplesIterator<D>>,
5684 left_iter: InternalTuplesIterator<D>,
5685 current_right: InternalTuplesIterator<D>,
5686 left_tuple_to_yield: Option<InternalTuple<D>>,
5687}
5688
5689#[cfg(feature = "sep-0006")]
5690impl<D: QueryableDataset> Iterator for ForLoopLeftJoinIterator<D> {
5691 type Item = Result<InternalTuple<D>, QueryEvaluationError>;
5692
5693 fn next(&mut self) -> Option<Self::Item> {
5694 loop {
5695 if let Some(tuple) = self.current_right.next() {
5696 if tuple.is_ok() {
5697 self.left_tuple_to_yield = None;
5699 }
5700 return Some(tuple);
5701 }
5702 if let Some(left_tuple) = self.left_tuple_to_yield.take() {
5703 return Some(Ok(left_tuple));
5704 }
5705 let left_tuple = match self.left_iter.next()? {
5706 Ok(left_tuple) => left_tuple,
5707 Err(error) => return Some(Err(error)),
5708 };
5709 self.current_right = (self.right_evaluator)(left_tuple.clone());
5710 self.left_tuple_to_yield = Some(left_tuple);
5711 }
5712 }
5713}
5714
5715struct UnionIterator<D: QueryableDataset> {
5716 plans: Vec<Rc<dyn Fn(InternalTuple<D>) -> InternalTuplesIterator<D>>>,
5717 input: InternalTuple<D>,
5718 current_iterator: InternalTuplesIterator<D>,
5719 current_plan: usize,
5720}
5721
5722impl<D: QueryableDataset> Iterator for UnionIterator<D> {
5723 type Item = Result<InternalTuple<D>, QueryEvaluationError>;
5724
5725 fn next(&mut self) -> Option<Self::Item> {
5726 loop {
5727 if let Some(tuple) = self.current_iterator.next() {
5728 return Some(tuple);
5729 }
5730 if self.current_plan >= self.plans.len() {
5731 return None;
5732 }
5733 self.current_iterator = self.plans[self.current_plan](self.input.clone());
5734 self.current_plan += 1;
5735 }
5736 }
5737}
5738
5739struct ConsecutiveDeduplication<D: QueryableDataset> {
5740 inner: InternalTuplesIterator<D>,
5741 current: Option<InternalTuple<D>>,
5742}
5743
5744impl<D: QueryableDataset> Iterator for ConsecutiveDeduplication<D> {
5745 type Item = Result<InternalTuple<D>, QueryEvaluationError>;
5746
5747 fn next(&mut self) -> Option<Self::Item> {
5748 loop {
5750 if let Some(next) = self.inner.next() {
5751 match next {
5752 Ok(next) => match self.current.take() {
5753 Some(current) if current != next => {
5754 self.current = Some(next);
5756 return Some(Ok(current));
5757 }
5758 _ => {
5759 self.current = Some(next);
5761 }
5762 },
5763 Err(error) => return Some(Err(error)), }
5765 } else {
5766 return self.current.take().map(Ok);
5767 }
5768 }
5769 }
5770
5771 fn size_hint(&self) -> (usize, Option<usize>) {
5772 let (min, max) = self.inner.size_hint();
5773 ((min != 0).into(), max)
5774 }
5775}
5776
5777struct ConstructIterator<D: QueryableDataset> {
5778 eval: SimpleEvaluator<D>,
5779 iter: InternalTuplesIterator<D>,
5780 template: Vec<TripleTemplate>,
5781 buffered_results: Vec<Result<Triple, QueryEvaluationError>>,
5782 already_emitted_results: FxHashSet<Triple>,
5783 bnodes: Vec<BlankNode>,
5784}
5785
5786impl<D: QueryableDataset> Iterator for ConstructIterator<D> {
5787 type Item = Result<Triple, QueryEvaluationError>;
5788
5789 fn next(&mut self) -> Option<Self::Item> {
5790 loop {
5791 if let Some(result) = self.buffered_results.pop() {
5792 return Some(result);
5793 }
5794 {
5795 let tuple = match self.iter.next()? {
5796 Ok(tuple) => tuple,
5797 Err(error) => return Some(Err(error)),
5798 };
5799 for template in &self.template {
5800 if let (Some(subject), Some(predicate), Some(object)) = (
5801 get_triple_template_value(
5802 &template.subject,
5803 &tuple,
5804 &mut self.bnodes,
5805 &self.eval.dataset,
5806 )
5807 .and_then(|t| t.try_into().ok()),
5808 get_triple_template_value(
5809 &template.predicate,
5810 &tuple,
5811 &mut self.bnodes,
5812 &self.eval.dataset,
5813 )
5814 .and_then(|t| t.try_into().ok()),
5815 get_triple_template_value(
5816 &template.object,
5817 &tuple,
5818 &mut self.bnodes,
5819 &self.eval.dataset,
5820 ),
5821 ) {
5822 let triple = Triple {
5823 subject,
5824 predicate,
5825 object,
5826 };
5827 #[cfg(feature = "rdf-star")]
5830 let new_triple = triple.subject.is_blank_node()
5831 || triple.subject.is_triple()
5832 || triple.object.is_blank_node()
5833 || triple.object.is_triple()
5834 || self.already_emitted_results.insert(triple.clone());
5835 #[cfg(not(feature = "rdf-star"))]
5836 let new_triple = triple.subject.is_blank_node()
5837 || triple.object.is_blank_node()
5838 || self.already_emitted_results.insert(triple.clone());
5839 if new_triple {
5840 self.buffered_results.push(Ok(triple));
5841 if self.already_emitted_results.len() > 1024 * 1024 {
5842 self.already_emitted_results.clear();
5844 }
5845 }
5846 }
5847 }
5848 self.bnodes.clear(); }
5850 }
5851 }
5852
5853 fn size_hint(&self) -> (usize, Option<usize>) {
5854 let (min, max) = self.iter.size_hint();
5855 (
5856 min.saturating_mul(self.template.len()),
5857 max.map(|v| v.saturating_mul(self.template.len())),
5858 )
5859 }
5860}
5861
5862pub struct TripleTemplate {
5863 pub subject: TripleTemplateValue,
5864 pub predicate: TripleTemplateValue,
5865 pub object: TripleTemplateValue,
5866}
5867
5868pub enum TripleTemplateValue {
5869 Constant(Term),
5870 BlankNode(usize),
5871 Variable(usize),
5872 #[cfg(feature = "rdf-star")]
5873 Triple(Box<TripleTemplate>),
5874}
5875
5876impl TripleTemplateValue {
5877 #[cfg_attr(not(feature = "rdf-star"), allow(clippy::unnecessary_wraps))]
5878 fn from_term_or_variable(
5879 term_or_variable: &TermPattern,
5880 variables: &mut Vec<Variable>,
5881 bnodes: &mut Vec<BlankNode>,
5882 ) -> Option<Self> {
5883 Some(match term_or_variable {
5884 TermPattern::Variable(variable) => Self::Variable(encode_variable(variables, variable)),
5885 TermPattern::NamedNode(node) => Self::Constant(node.clone().into()),
5886 TermPattern::BlankNode(bnode) => Self::BlankNode(bnode_key(bnodes, bnode)),
5887 TermPattern::Literal(literal) => Self::Constant(literal.clone().into()),
5888 #[cfg(feature = "rdf-star")]
5889 TermPattern::Triple(triple) => {
5890 match (
5891 Self::from_term_or_variable(&triple.subject, variables, bnodes)?,
5892 Self::from_named_node_or_variable(&triple.predicate, variables),
5893 Self::from_term_or_variable(&triple.object, variables, bnodes)?,
5894 ) {
5895 (
5896 Self::Constant(subject),
5897 Self::Constant(predicate),
5898 Self::Constant(object),
5899 ) => Self::Constant(
5900 Triple {
5901 subject: subject.try_into().ok()?,
5902 predicate: predicate.try_into().ok()?,
5903 object,
5904 }
5905 .into(),
5906 ),
5907 (subject, predicate, object) => {
5908 TripleTemplateValue::Triple(Box::new(TripleTemplate {
5909 subject,
5910 predicate,
5911 object,
5912 }))
5913 }
5914 }
5915 }
5916 })
5917 }
5918
5919 fn from_named_node_or_variable(
5920 named_node_or_variable: &NamedNodePattern,
5921 variables: &mut Vec<Variable>,
5922 ) -> TripleTemplateValue {
5923 match named_node_or_variable {
5924 NamedNodePattern::Variable(variable) => {
5925 Self::Variable(encode_variable(variables, variable))
5926 }
5927 NamedNodePattern::NamedNode(term) => Self::Constant(term.clone().into()),
5928 }
5929 }
5930}
5931
5932fn get_triple_template_value<D: QueryableDataset>(
5933 selector: &TripleTemplateValue,
5934 tuple: &InternalTuple<D>,
5935 bnodes: &mut Vec<BlankNode>,
5936 dataset: &EvalDataset<D>,
5937) -> Option<Term> {
5938 match selector {
5939 TripleTemplateValue::Constant(term) => Some(term.clone()),
5940 TripleTemplateValue::Variable(v) => {
5941 tuple
5942 .get(*v)
5943 .and_then(|t| dataset.externalize_term(t.clone()).ok()) }
5945 TripleTemplateValue::BlankNode(bnode) => {
5946 if *bnode >= bnodes.len() {
5947 bnodes.resize_with(*bnode + 1, BlankNode::default)
5948 }
5949 Some(bnodes[*bnode].clone().into())
5950 }
5951 #[cfg(feature = "rdf-star")]
5952 TripleTemplateValue::Triple(triple) => Some(
5953 Triple {
5954 subject: get_triple_template_value(&triple.subject, tuple, bnodes, dataset)?
5955 .try_into()
5956 .ok()?,
5957 predicate: get_triple_template_value(&triple.predicate, tuple, bnodes, dataset)?
5958 .try_into()
5959 .ok()?,
5960 object: get_triple_template_value(&triple.object, tuple, bnodes, dataset)?,
5961 }
5962 .into(),
5963 ),
5964 }
5965}
5966
5967struct DescribeIterator<D: QueryableDataset> {
5968 eval: SimpleEvaluator<D>,
5969 tuples_to_describe: InternalTuplesIterator<D>,
5970 nodes_described: FxHashSet<D::InternalTerm>,
5971 nodes_to_describe: Vec<D::InternalTerm>,
5972 quads: Box<dyn Iterator<Item = Result<InternalQuad<D>, QueryEvaluationError>>>,
5973}
5974
5975impl<D: QueryableDataset> Iterator for DescribeIterator<D> {
5976 type Item = Result<Triple, QueryEvaluationError>;
5977
5978 fn next(&mut self) -> Option<Self::Item> {
5979 loop {
5980 if let Some(quad) = self.quads.next() {
5981 let quad = match quad {
5982 Ok(quad) => quad,
5983 Err(error) => return Some(Err(error)),
5984 };
5985 let subject = match self.eval.dataset.externalize_term(quad.subject) {
5987 Ok(t) => t,
5988 Err(e) => return Some(Err(e)),
5989 };
5990 let predicate = match self.eval.dataset.externalize_term(quad.predicate) {
5991 Ok(t) => t,
5992 Err(e) => return Some(Err(e)),
5993 };
5994 let object = match self.eval.dataset.externalize_term(quad.object.clone()) {
5995 Ok(t) => t,
5996 Err(e) => return Some(Err(e)),
5997 };
5998 if object.is_blank_node() && self.nodes_described.insert(quad.object.clone()) {
6000 self.nodes_to_describe.push(quad.object);
6001 }
6002 return Some(Ok(Triple {
6003 subject: subject.try_into().ok()?,
6004 predicate: predicate.try_into().ok()?,
6005 object,
6006 }));
6007 }
6008 if let Some(node_to_describe) = self.nodes_to_describe.pop() {
6009 self.quads = Box::new(self.eval.dataset.internal_quads_for_pattern(
6011 Some(&node_to_describe),
6012 None,
6013 None,
6014 Some(None),
6015 ));
6016 } else {
6017 let tuple = match self.tuples_to_describe.next()? {
6018 Ok(tuple) => tuple,
6019 Err(error) => return Some(Err(error)),
6020 };
6021 for node in tuple.into_iter().flatten() {
6022 if self.nodes_described.insert(node.clone()) {
6023 self.nodes_to_describe.push(node);
6024 }
6025 }
6026 }
6027 }
6028 }
6029}
6030
6031struct ZipLongest<T1, T2, I1: Iterator<Item = T1>, I2: Iterator<Item = T2>> {
6032 a: I1,
6033 b: I2,
6034}
6035
6036impl<T1, T2, I1: Iterator<Item = T1>, I2: Iterator<Item = T2>> ZipLongest<T1, T2, I1, I2> {
6037 fn new(a: I1, b: I2) -> Self {
6038 Self { a, b }
6039 }
6040}
6041
6042impl<T1, T2, I1: Iterator<Item = T1>, I2: Iterator<Item = T2>> Iterator
6043 for ZipLongest<T1, T2, I1, I2>
6044{
6045 type Item = (Option<T1>, Option<T2>);
6046
6047 fn next(&mut self) -> Option<Self::Item> {
6048 match (self.a.next(), self.b.next()) {
6049 (None, None) => None,
6050 r => Some(r),
6051 }
6052 }
6053}
6054
6055fn transitive_closure<T: Clone + Eq + Hash, E, NI: Iterator<Item = Result<T, E>>>(
6056 start: impl IntoIterator<Item = Result<T, E>>,
6057 mut next: impl FnMut(T) -> NI,
6058) -> impl Iterator<Item = Result<T, E>> {
6059 let mut errors = Vec::new();
6060 let mut todo = start
6061 .into_iter()
6062 .filter_map(|e| match e {
6063 Ok(e) => Some(e),
6064 Err(e) => {
6065 errors.push(e);
6066 None
6067 }
6068 })
6069 .collect::<Vec<_>>();
6070 let mut all = todo.iter().cloned().collect::<FxHashSet<_>>();
6071 while let Some(e) = todo.pop() {
6072 for e in next(e) {
6073 match e {
6074 Ok(e) => {
6075 if all.insert(e.clone()) {
6076 todo.push(e)
6077 }
6078 }
6079 Err(e) => errors.push(e),
6080 }
6081 }
6082 }
6083 errors.into_iter().map(Err).chain(all.into_iter().map(Ok))
6084}
6085
6086fn look_in_transitive_closure<T: Clone + Eq + Hash, E, NI: Iterator<Item = Result<T, E>>>(
6087 start: impl IntoIterator<Item = Result<T, E>>,
6088 mut next: impl FnMut(T) -> NI,
6089 target: &T,
6090) -> Result<bool, E> {
6091 let mut todo = start.into_iter().collect::<Result<Vec<_>, _>>()?;
6092 let mut all = todo.iter().cloned().collect::<FxHashSet<_>>();
6093 while let Some(e) = todo.pop() {
6094 if e == *target {
6095 return Ok(true);
6096 }
6097 for e in next(e) {
6098 let e = e?;
6099 if all.insert(e.clone()) {
6100 todo.push(e);
6101 }
6102 }
6103 }
6104 Ok(false)
6105}
6106
6107fn hash_deduplicate<T: Eq + Hash + Clone, E>(
6108 iter: impl Iterator<Item = Result<T, E>>,
6109) -> impl Iterator<Item = Result<T, E>> {
6110 let mut already_seen = FxHashSet::with_capacity_and_hasher(iter.size_hint().0, FxBuildHasher);
6111 iter.filter(move |e| {
6112 if let Ok(e) = e {
6113 if already_seen.contains(e) {
6114 false
6115 } else {
6116 already_seen.insert(e.clone());
6117 true
6118 }
6119 } else {
6120 true
6121 }
6122 })
6123}
6124
6125trait ResultIterator<T, E>: Iterator<Item = Result<T, E>> + Sized {
6126 fn flat_map_ok<O, F: FnMut(T) -> U, U: IntoIterator<Item = Result<O, E>>>(
6127 self,
6128 f: F,
6129 ) -> FlatMapOk<T, E, O, Self, F, U>;
6130}
6131
6132impl<T, E, I: Iterator<Item = Result<T, E>> + Sized> ResultIterator<T, E> for I {
6133 #[inline]
6134 fn flat_map_ok<O, F: FnMut(T) -> U, U: IntoIterator<Item = Result<O, E>>>(
6135 self,
6136 f: F,
6137 ) -> FlatMapOk<T, E, O, Self, F, U> {
6138 FlatMapOk {
6139 inner: self,
6140 f,
6141 current: None,
6142 }
6143 }
6144}
6145
6146struct FlatMapOk<
6147 T,
6148 E,
6149 O,
6150 I: Iterator<Item = Result<T, E>>,
6151 F: FnMut(T) -> U,
6152 U: IntoIterator<Item = Result<O, E>>,
6153> {
6154 inner: I,
6155 f: F,
6156 current: Option<U::IntoIter>,
6157}
6158
6159impl<
6160 T,
6161 E,
6162 O,
6163 I: Iterator<Item = Result<T, E>>,
6164 F: FnMut(T) -> U,
6165 U: IntoIterator<Item = Result<O, E>>,
6166 > Iterator for FlatMapOk<T, E, O, I, F, U>
6167{
6168 type Item = Result<O, E>;
6169
6170 #[inline]
6171 fn next(&mut self) -> Option<Self::Item> {
6172 loop {
6173 if let Some(current) = &mut self.current {
6174 if let Some(next) = current.next() {
6175 return Some(next);
6176 }
6177 }
6178 self.current = None;
6179 match self.inner.next()? {
6180 Ok(e) => self.current = Some((self.f)(e).into_iter()),
6181 Err(error) => return Some(Err(error)),
6182 }
6183 }
6184 }
6185}
6186
6187fn generate_uuid(buffer: &mut String) {
6188 let mut uuid = random::<u128>().to_le_bytes();
6189 uuid[6] = (uuid[6] & 0x0F) | 0x40;
6190 uuid[8] = (uuid[8] & 0x3F) | 0x80;
6191
6192 write_hexa_bytes(&uuid[0..4], buffer);
6193 buffer.push('-');
6194 write_hexa_bytes(&uuid[4..6], buffer);
6195 buffer.push('-');
6196 write_hexa_bytes(&uuid[6..8], buffer);
6197 buffer.push('-');
6198 write_hexa_bytes(&uuid[8..10], buffer);
6199 buffer.push('-');
6200 write_hexa_bytes(&uuid[10..16], buffer);
6201}
6202
6203fn write_hexa_bytes(bytes: &[u8], buffer: &mut String) {
6204 for b in bytes {
6205 let high = b / 16;
6206 buffer.push(char::from(if high < 10 {
6207 b'0' + high
6208 } else {
6209 b'a' + (high - 10)
6210 }));
6211 let low = b % 16;
6212 buffer.push(char::from(if low < 10 {
6213 b'0' + low
6214 } else {
6215 b'a' + (low - 10)
6216 }));
6217 }
6218}
6219
6220fn error_evaluator<D: QueryableDataset>(
6221 error: QueryEvaluationError,
6222) -> Rc<dyn Fn(InternalTuple<D>) -> InternalTuplesIterator<D>> {
6223 let e = RefCell::new(Some(error));
6224 Rc::new(move |_| {
6225 if let Some(e) = e.replace(None) {
6226 Box::new(once(Err(e)))
6227 } else {
6228 Box::new(empty())
6229 }
6230 })
6231}
6232
6233enum ComparatorFunction<D: QueryableDataset> {
6234 Asc(Rc<dyn Fn(&InternalTuple<D>) -> Option<ExpressionTerm>>),
6235 Desc(Rc<dyn Fn(&InternalTuple<D>) -> Option<ExpressionTerm>>),
6236}
6237
6238struct InternalTupleSet<D: QueryableDataset> {
6239 key: Vec<usize>,
6240 map: FxHashMap<u64, Vec<InternalTuple<D>>>,
6241 len: usize,
6242}
6243
6244impl<D: QueryableDataset> InternalTupleSet<D> {
6245 fn new(key: Vec<usize>) -> Self {
6246 Self {
6247 key,
6248 map: FxHashMap::default(),
6249 len: 0,
6250 }
6251 }
6252
6253 fn insert(&mut self, tuple: InternalTuple<D>) {
6254 self.map
6255 .entry(self.tuple_key(&tuple))
6256 .or_default()
6257 .push(tuple);
6258 self.len += 1;
6259 }
6260
6261 fn get(&self, tuple: &InternalTuple<D>) -> &[InternalTuple<D>] {
6262 self.map.get(&self.tuple_key(tuple)).map_or(&[], |v| v)
6263 }
6264
6265 fn tuple_key(&self, tuple: &InternalTuple<D>) -> u64 {
6266 let mut hasher = FxHasher::default();
6267 for v in &self.key {
6268 if let Some(val) = tuple.get(*v) {
6269 val.hash(&mut hasher);
6270 }
6271 }
6272 hasher.finish()
6273 }
6274
6275 fn len(&self) -> usize {
6276 self.len
6277 }
6278
6279 fn is_empty(&self) -> bool {
6280 self.len == 0
6281 }
6282}
6283
6284impl<D: QueryableDataset> Extend<InternalTuple<D>> for InternalTupleSet<D> {
6285 fn extend<T: IntoIterator<Item = InternalTuple<D>>>(&mut self, iter: T) {
6286 let iter = iter.into_iter();
6287 self.map.reserve(iter.size_hint().0);
6288 for tuple in iter {
6289 self.insert(tuple);
6290 }
6291 }
6292}
6293
6294struct StatsIterator<D: QueryableDataset> {
6295 inner: InternalTuplesIterator<D>,
6296 stats: Rc<EvalNodeWithStats>,
6297}
6298
6299impl<D: QueryableDataset> Iterator for StatsIterator<D> {
6300 type Item = Result<InternalTuple<D>, QueryEvaluationError>;
6301
6302 fn next(&mut self) -> Option<Self::Item> {
6303 let start = Timer::now();
6304 let result = self.inner.next();
6305 let duration = start.elapsed()?;
6306 self.stats.exec_duration.set(
6307 self.stats
6308 .exec_duration
6309 .get()
6310 .and_then(|d| d.checked_add(duration)),
6311 );
6312 if matches!(result, Some(Ok(_))) {
6313 self.stats.exec_count.set(self.stats.exec_count.get() + 1);
6314 }
6315 result
6316 }
6317}
6318
6319pub struct EvalNodeWithStats {
6320 pub label: String,
6321 pub children: Vec<Rc<EvalNodeWithStats>>,
6322 pub exec_count: Cell<usize>,
6323 pub exec_duration: Cell<Option<DayTimeDuration>>,
6324}
6325
6326impl EvalNodeWithStats {
6327 pub fn json_node(
6328 &self,
6329 serializer: &mut WriterJsonSerializer<impl io::Write>,
6330 with_stats: bool,
6331 ) -> io::Result<()> {
6332 serializer.serialize_event(JsonEvent::StartObject)?;
6333 serializer.serialize_event(JsonEvent::ObjectKey("name".into()))?;
6334 serializer.serialize_event(JsonEvent::String((&self.label).into()))?;
6335 if with_stats {
6336 serializer.serialize_event(JsonEvent::ObjectKey("number of results".into()))?;
6337 serializer
6338 .serialize_event(JsonEvent::Number(self.exec_count.get().to_string().into()))?;
6339 if let Some(duration) = self.exec_duration.get() {
6340 serializer.serialize_event(JsonEvent::ObjectKey("duration in seconds".into()))?;
6341 serializer
6342 .serialize_event(JsonEvent::Number(duration.as_seconds().to_string().into()))?;
6343 }
6344 }
6345 serializer.serialize_event(JsonEvent::ObjectKey("children".into()))?;
6346 serializer.serialize_event(JsonEvent::StartArray)?;
6347 for child in &self.children {
6348 child.json_node(serializer, with_stats)?;
6349 }
6350 serializer.serialize_event(JsonEvent::EndArray)?;
6351 serializer.serialize_event(JsonEvent::EndObject)
6352 }
6353}
6354
6355impl fmt::Debug for EvalNodeWithStats {
6356 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6357 let mut obj = f.debug_struct("Node");
6358 obj.field("name", &self.label);
6359 if let Some(exec_duration) = self.exec_duration.get() {
6360 obj.field("number of results", &self.exec_count.get());
6361 obj.field(
6362 "duration in seconds",
6363 &f32::from(Float::from(exec_duration.as_seconds())),
6364 );
6365 }
6366 if !self.children.is_empty() {
6367 obj.field("children", &self.children);
6368 }
6369 obj.finish()
6370 }
6371}
6372
6373fn eval_node_label(node: &GraphPattern) -> String {
6374 match node {
6375 GraphPattern::Distinct { .. } => "Distinct(Hash)".to_owned(),
6376 GraphPattern::Extend {
6377 expression,
6378 variable,
6379 ..
6380 } => format!(
6381 "Extend({} -> {variable})",
6382 spargebra::algebra::Expression::from(expression)
6383 ),
6384 GraphPattern::Filter { expression, .. } => format!(
6385 "Filter({})",
6386 spargebra::algebra::Expression::from(expression)
6387 ),
6388 GraphPattern::Graph { graph_name } => format!("Graph({graph_name})"),
6389 GraphPattern::Group {
6390 variables,
6391 aggregates,
6392 ..
6393 } => {
6394 format!(
6395 "Aggregate({})",
6396 format_list(variables.iter().map(ToString::to_string).chain(
6397 aggregates.iter().map(|(v, agg)| format!(
6398 "{} -> {v}",
6399 spargebra::algebra::AggregateExpression::from(agg)
6400 ))
6401 ))
6402 )
6403 }
6404 GraphPattern::Join { algorithm, .. } => match algorithm {
6405 JoinAlgorithm::HashBuildLeftProbeRight { keys } => format!(
6406 "LeftJoin(HashBuildLeftProbeRight, keys = {})",
6407 format_list(keys)
6408 ),
6409 },
6410 #[cfg(feature = "sep-0006")]
6411 GraphPattern::Lateral { right, .. } => {
6412 if let GraphPattern::LeftJoin {
6413 left: nested_left,
6414 expression,
6415 ..
6416 } = right.as_ref()
6417 {
6418 if nested_left.is_empty_singleton() {
6419 return format!(
6421 "ForLoopLeftJoin(expression = {})",
6422 spargebra::algebra::Expression::from(expression)
6423 );
6424 }
6425 }
6426 "Lateral".to_owned()
6427 }
6428 GraphPattern::LeftJoin {
6429 algorithm,
6430 expression,
6431 ..
6432 } => match algorithm {
6433 LeftJoinAlgorithm::HashBuildRightProbeLeft { keys } => format!(
6434 "LeftJoin(HashBuildRightProbeLeft, keys = {}, expression = {})",
6435 format_list(keys),
6436 spargebra::algebra::Expression::from(expression)
6437 ),
6438 },
6439 GraphPattern::Minus { algorithm, .. } => match algorithm {
6440 MinusAlgorithm::HashBuildRightProbeLeft { keys } => format!(
6441 "AntiJoin(HashBuildRightProbeLeft, keys = {})",
6442 format_list(keys)
6443 ),
6444 },
6445 GraphPattern::OrderBy { expression, .. } => {
6446 format!(
6447 "Sort({})",
6448 format_list(
6449 expression
6450 .iter()
6451 .map(spargebra::algebra::OrderExpression::from)
6452 )
6453 )
6454 }
6455 GraphPattern::Path {
6456 subject,
6457 path,
6458 object,
6459 graph_name,
6460 } => {
6461 if let Some(graph_name) = graph_name {
6462 format!("Path({subject} {path} {object} {graph_name})")
6463 } else {
6464 format!("Path({subject} {path} {object})")
6465 }
6466 }
6467 GraphPattern::Project { variables, .. } => {
6468 format!("Project({})", format_list(variables))
6469 }
6470 GraphPattern::QuadPattern {
6471 subject,
6472 predicate,
6473 object,
6474 graph_name,
6475 } => {
6476 if let Some(graph_name) = graph_name {
6477 format!("QuadPattern({subject} {predicate} {object} {graph_name})")
6478 } else {
6479 format!("QuadPattern({subject} {predicate} {object})")
6480 }
6481 }
6482 GraphPattern::Reduced { .. } => "Reduced".to_owned(),
6483 GraphPattern::Service { name, silent, .. } => {
6484 if *silent {
6485 format!("Service({name}, Silent)")
6486 } else {
6487 format!("Service({name})")
6488 }
6489 }
6490 GraphPattern::Slice { start, length, .. } => {
6491 if let Some(length) = length {
6492 format!("Slice(start = {start}, length = {length})")
6493 } else {
6494 format!("Slice(start = {start})")
6495 }
6496 }
6497 GraphPattern::Union { .. } => "Union".to_owned(),
6498 GraphPattern::Values { variables, .. } => {
6499 format!("StaticBindings({})", format_list(variables))
6500 }
6501 }
6502}
6503
6504fn format_list<T: ToString>(values: impl IntoIterator<Item = T>) -> String {
6505 values
6506 .into_iter()
6507 .map(|v| v.to_string())
6508 .collect::<Vec<_>>()
6509 .join(", ")
6510}
6511
6512pub struct Timer {
6513 start: DateTime,
6514}
6515
6516impl Timer {
6517 pub fn now() -> Self {
6518 Self {
6519 start: DateTime::now(),
6520 }
6521 }
6522
6523 pub fn elapsed(&self) -> Option<DayTimeDuration> {
6524 DateTime::now().checked_sub(self.start)
6525 }
6526}
6527
6528#[cfg(test)]
6529mod tests {
6530 use super::*;
6531
6532 #[test]
6533 fn uuid() {
6534 let mut buffer = String::default();
6535 generate_uuid(&mut buffer);
6536 assert!(
6537 Regex::new("^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$")
6538 .unwrap()
6539 .is_match(&buffer),
6540 "{buffer} is not a valid UUID"
6541 );
6542 }
6543}