Spargebra: Uses oxrdf terms

pull/190/head
Tpt 3 years ago
parent 621c134ed7
commit 967dbacad7
  1. 1
      Cargo.lock
  2. 2
      Cargo.toml
  3. 2
      lib/Cargo.toml
  4. 2
      lib/oxrdf/src/blank_node.rs
  5. 20
      lib/oxrdf/src/literal.rs
  6. 6
      lib/oxrdf/src/named_node.rs
  7. 107
      lib/oxrdf/src/triple.rs
  8. 5
      lib/spargebra/Cargo.toml
  9. 2
      lib/spargebra/README.md
  10. 72
      lib/spargebra/src/algebra.rs
  11. 0
      lib/spargebra/src/lib.rs
  12. 103
      lib/spargebra/src/parser.rs
  13. 0
      lib/spargebra/src/query.rs
  14. 627
      lib/spargebra/src/term.rs
  15. 6
      lib/spargebra/src/update.rs
  16. 18
      lib/src/sparql/algebra.rs
  17. 10
      lib/src/sparql/mod.rs
  18. 109
      lib/src/sparql/plan_builder.rs
  19. 149
      lib/src/sparql/update.rs

1
Cargo.lock generated

@ -1556,6 +1556,7 @@ version = "0.1.0"
dependencies = [ dependencies = [
"oxilangtag", "oxilangtag",
"oxiri", "oxiri",
"oxrdf",
"peg", "peg",
"rand", "rand",
] ]

@ -3,10 +3,10 @@ members = [
"js", "js",
"lib", "lib",
"lib/oxrdf", "lib/oxrdf",
"lib/spargebra",
"python", "python",
"rocksdb-sys", "rocksdb-sys",
"server", "server",
"spargebra",
"testsuite" "testsuite"
] ]

@ -43,7 +43,7 @@ sophia_api = { version = "0.7", optional = true }
json-event-parser = "0.1" json-event-parser = "0.1"
num_cpus = "1" num_cpus = "1"
oxrdf = { version = "0.1", path="oxrdf", features = ["rdf-star"] } oxrdf = { version = "0.1", path="oxrdf", features = ["rdf-star"] }
spargebra = { version = "0.1", path="../spargebra", features = ["rdf-star"] } spargebra = { version = "0.1", path="spargebra", features = ["rdf-star"] }
[target.'cfg(not(target_arch = "wasm32"))'.dependencies] [target.'cfg(not(target_arch = "wasm32"))'.dependencies]
libc = "0.2" libc = "0.2"

@ -184,7 +184,7 @@ impl<'a> BlankNodeRef<'a> {
/// use oxrdf::BlankNode; /// use oxrdf::BlankNode;
/// ///
/// assert_eq!(BlankNode::new_from_unique_id(128).as_ref().unique_id(), Some(128)); /// assert_eq!(BlankNode::new_from_unique_id(128).as_ref().unique_id(), Some(128));
/// assert_eq!(BlankNode::new("128")?.as_ref().unique_id(), None); /// assert_eq!(BlankNode::new("foo")?.as_ref().unique_id(), None);
/// # Result::<_,oxrdf::BlankNodeIdParseError>::Ok(()) /// # Result::<_,oxrdf::BlankNodeIdParseError>::Ok(())
/// ``` /// ```
#[inline] #[inline]

@ -8,7 +8,7 @@ use std::fmt;
use std::fmt::Write; use std::fmt::Write;
use std::option::Option; use std::option::Option;
/// An owned RDF [literal](https://www.w3.org/TR/rdf11-concepts/#dfn-literal) /// An owned RDF [literal](https://www.w3.org/TR/rdf11-concepts/#dfn-literal).
/// ///
/// The default string formatter is returning an N-Triples, Turtle and SPARQL compatible representation: /// The default string formatter is returning an N-Triples, Turtle and SPARQL compatible representation:
/// ``` /// ```
@ -43,13 +43,13 @@ enum LiteralContent {
} }
impl Literal { impl Literal {
/// Builds an RDF [simple literal](https://www.w3.org/TR/rdf11-concepts/#dfn-simple-literal) /// Builds an RDF [simple literal](https://www.w3.org/TR/rdf11-concepts/#dfn-simple-literal).
#[inline] #[inline]
pub fn new_simple_literal(value: impl Into<String>) -> Self { pub fn new_simple_literal(value: impl Into<String>) -> Self {
Self(LiteralContent::String(value.into())) Self(LiteralContent::String(value.into()))
} }
/// Builds an RDF [literal](https://www.w3.org/TR/rdf11-concepts/#dfn-literal) with a [datatype](https://www.w3.org/TR/rdf11-concepts/#dfn-datatype-iri) /// Builds an RDF [literal](https://www.w3.org/TR/rdf11-concepts/#dfn-literal) with a [datatype](https://www.w3.org/TR/rdf11-concepts/#dfn-datatype-iri).
#[inline] #[inline]
pub fn new_typed_literal(value: impl Into<String>, datatype: impl Into<NamedNode>) -> Self { pub fn new_typed_literal(value: impl Into<String>, datatype: impl Into<NamedNode>) -> Self {
let value = value.into(); let value = value.into();
@ -61,7 +61,7 @@ impl Literal {
}) })
} }
/// Builds an RDF [language-tagged string](https://www.w3.org/TR/rdf11-concepts/#dfn-language-tagged-string) /// Builds an RDF [language-tagged string](https://www.w3.org/TR/rdf11-concepts/#dfn-language-tagged-string).
#[inline] #[inline]
pub fn new_language_tagged_literal( pub fn new_language_tagged_literal(
value: impl Into<String>, value: impl Into<String>,
@ -75,7 +75,7 @@ impl Literal {
)) ))
} }
/// Builds an RDF [language-tagged string](https://www.w3.org/TR/rdf11-concepts/#dfn-language-tagged-string) /// Builds an RDF [language-tagged string](https://www.w3.org/TR/rdf11-concepts/#dfn-language-tagged-string).
/// ///
/// It is the responsibility of the caller to check that `language` /// It is the responsibility of the caller to check that `language`
/// is valid [BCP47](https://tools.ietf.org/html/bcp47) language tag, /// is valid [BCP47](https://tools.ietf.org/html/bcp47) language tag,
@ -93,7 +93,7 @@ impl Literal {
}) })
} }
/// The literal [lexical form](https://www.w3.org/TR/rdf11-concepts/#dfn-lexical-form) /// The literal [lexical form](https://www.w3.org/TR/rdf11-concepts/#dfn-lexical-form).
#[inline] #[inline]
pub fn value(&self) -> &str { pub fn value(&self) -> &str {
self.as_ref().value() self.as_ref().value()
@ -293,7 +293,7 @@ impl From<f64> for Literal {
} }
} }
/// A borrowed RDF [literal](https://www.w3.org/TR/rdf11-concepts/#dfn-literal) /// A borrowed RDF [literal](https://www.w3.org/TR/rdf11-concepts/#dfn-literal).
/// ///
/// The default string formatter is returning an N-Triples, Turtle and SPARQL compatible representation: /// The default string formatter is returning an N-Triples, Turtle and SPARQL compatible representation:
/// ``` /// ```
@ -327,13 +327,13 @@ enum LiteralRefContent<'a> {
} }
impl<'a> LiteralRef<'a> { impl<'a> LiteralRef<'a> {
/// Builds an RDF [simple literal](https://www.w3.org/TR/rdf11-concepts/#dfn-simple-literal) /// Builds an RDF [simple literal](https://www.w3.org/TR/rdf11-concepts/#dfn-simple-literal).
#[inline] #[inline]
pub fn new_simple_literal(value: &'a str) -> Self { pub fn new_simple_literal(value: &'a str) -> Self {
LiteralRef(LiteralRefContent::String(value)) LiteralRef(LiteralRefContent::String(value))
} }
/// Builds an RDF [literal](https://www.w3.org/TR/rdf11-concepts/#dfn-literal) with a [datatype](https://www.w3.org/TR/rdf11-concepts/#dfn-datatype-iri) /// Builds an RDF [literal](https://www.w3.org/TR/rdf11-concepts/#dfn-literal) with a [datatype](https://www.w3.org/TR/rdf11-concepts/#dfn-datatype-iri).
#[inline] #[inline]
pub fn new_typed_literal(value: &'a str, datatype: impl Into<NamedNodeRef<'a>>) -> Self { pub fn new_typed_literal(value: &'a str, datatype: impl Into<NamedNodeRef<'a>>) -> Self {
let datatype = datatype.into(); let datatype = datatype.into();
@ -344,7 +344,7 @@ impl<'a> LiteralRef<'a> {
}) })
} }
/// Builds an RDF [language-tagged string](https://www.w3.org/TR/rdf11-concepts/#dfn-language-tagged-string) /// Builds an RDF [language-tagged string](https://www.w3.org/TR/rdf11-concepts/#dfn-language-tagged-string).
/// ///
/// It is the responsibility of the caller to check that `language` /// It is the responsibility of the caller to check that `language`
/// is valid [BCP47](https://tools.ietf.org/html/bcp47) language tag, /// is valid [BCP47](https://tools.ietf.org/html/bcp47) language tag,

@ -1,7 +1,7 @@
use oxiri::{Iri, IriParseError}; use oxiri::{Iri, IriParseError};
use std::fmt; use std::fmt;
/// An owned RDF [IRI](https://www.w3.org/TR/rdf11-concepts/#dfn-iri) /// An owned RDF [IRI](https://www.w3.org/TR/rdf11-concepts/#dfn-iri).
/// ///
/// The default string formatter is returning an N-Triples, Turtle and SPARQL compatible representation: /// The default string formatter is returning an N-Triples, Turtle and SPARQL compatible representation:
/// ``` /// ```
@ -19,7 +19,7 @@ pub struct NamedNode {
} }
impl NamedNode { impl NamedNode {
/// Builds and validate an RDF [IRI](https://www.w3.org/TR/rdf11-concepts/#dfn-iri) /// Builds and validate an RDF [IRI](https://www.w3.org/TR/rdf11-concepts/#dfn-iri).
pub fn new(iri: impl Into<String>) -> Result<Self, IriParseError> { pub fn new(iri: impl Into<String>) -> Result<Self, IriParseError> {
Ok(Self::new_from_iri(Iri::parse(iri.into())?)) Ok(Self::new_from_iri(Iri::parse(iri.into())?))
} }
@ -90,7 +90,7 @@ impl PartialEq<NamedNode> for &str {
} }
} }
/// A borrowed RDF [IRI](https://www.w3.org/TR/rdf11-concepts/#dfn-iri) /// A borrowed RDF [IRI](https://www.w3.org/TR/rdf11-concepts/#dfn-iri).
/// ///
/// The default string formatter is returning an N-Triples, Turtle and SPARQL compatible representation: /// The default string formatter is returning an N-Triples, Turtle and SPARQL compatible representation:
/// ``` /// ```

@ -694,21 +694,36 @@ impl<'a> From<TermRef<'a>> for Term {
} }
} }
/// An owned [RDF triple](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-triple) /// An owned [RDF triple](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-triple).
///
/// The default string formatter is returning an N-Triples, Turtle and SPARQL compatible representation:
/// ```
/// use oxrdf::{Triple, NamedNode};
///
/// assert_eq!(
/// "<http://example.com/s> <http://example.com/p> <http://example.com/o>",
/// Triple {
/// subject: NamedNode::new("http://example.com/s")?.into(),
/// predicate: NamedNode::new("http://example.com/p")?,
/// object: NamedNode::new("http://example.com/o")?.into(),
/// }.to_string()
/// );
/// # Result::<_,oxrdf::IriParseError>::Ok(())
/// ```
#[derive(Eq, PartialEq, Debug, Clone, Hash)] #[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub struct Triple { pub struct Triple {
/// The [subject](https://www.w3.org/TR/rdf11-concepts/#dfn-subject) of this triple /// The [subject](https://www.w3.org/TR/rdf11-concepts/#dfn-subject) of this triple.
pub subject: Subject, pub subject: Subject,
/// The [predicate](https://www.w3.org/TR/rdf11-concepts/#dfn-predicate) of this triple /// The [predicate](https://www.w3.org/TR/rdf11-concepts/#dfn-predicate) of this triple.
pub predicate: NamedNode, pub predicate: NamedNode,
/// The [object](https://www.w3.org/TR/rdf11-concepts/#dfn-object) of this triple /// The [object](https://www.w3.org/TR/rdf11-concepts/#dfn-object) of this triple.
pub object: Term, pub object: Term,
} }
impl Triple { impl Triple {
/// Builds an RDF [triple](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-triple) /// Builds an RDF [triple](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-triple).
#[inline] #[inline]
pub fn new( pub fn new(
subject: impl Into<Subject>, subject: impl Into<Subject>,
@ -722,7 +737,7 @@ impl Triple {
} }
} }
/// Encodes that this triple is in a [RDF dataset](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-dataset) /// Encodes that this triple is in a [RDF dataset](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-dataset).
#[inline] #[inline]
pub fn in_graph(self, graph_name: impl Into<GraphName>) -> Quad { pub fn in_graph(self, graph_name: impl Into<GraphName>) -> Quad {
Quad { Quad {
@ -750,21 +765,37 @@ impl fmt::Display for Triple {
} }
} }
/// A borrowed [RDF triple](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-triple) /// A borrowed [RDF triple](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-triple).
///
/// The default string formatter is returning an N-Triples, Turtle and SPARQL compatible representation:
/// ```
/// use oxrdf::{TripleRef, NamedNodeRef};
///
/// assert_eq!(
/// "<http://example.com/s> <http://example.com/p> <http://example.com/o>",
/// TripleRef {
/// subject: NamedNodeRef::new("http://example.com/s")?.into(),
/// predicate: NamedNodeRef::new("http://example.com/p")?,
/// object: NamedNodeRef::new("http://example.com/o")?.into(),
/// }.to_string()
/// );
/// # Result::<_,oxrdf::IriParseError>::Ok(())
/// ```
#[derive(Eq, PartialEq, Debug, Clone, Copy, Hash)] #[derive(Eq, PartialEq, Debug, Clone, Copy, Hash)]
pub struct TripleRef<'a> { pub struct TripleRef<'a> {
/// The [subject](https://www.w3.org/TR/rdf11-concepts/#dfn-subject) of this triple /// The [subject](https://www.w3.org/TR/rdf11-concepts/#dfn-subject) of this triple.
pub subject: SubjectRef<'a>, pub subject: SubjectRef<'a>,
/// The [predicate](https://www.w3.org/TR/rdf11-concepts/#dfn-predicate) of this triple /// The [predicate](https://www.w3.org/TR/rdf11-concepts/#dfn-predicate) of this triple.
pub predicate: NamedNodeRef<'a>, pub predicate: NamedNodeRef<'a>,
/// The [object](https://www.w3.org/TR/rdf11-concepts/#dfn-object) of this triple /// The [object](https://www.w3.org/TR/rdf11-concepts/#dfn-object) of this triple.
pub object: TermRef<'a>, pub object: TermRef<'a>,
} }
impl<'a> TripleRef<'a> { impl<'a> TripleRef<'a> {
/// Builds an RDF [triple](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-triple) /// Builds an RDF [triple](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-triple).
#[inline] #[inline]
pub fn new( pub fn new(
subject: impl Into<SubjectRef<'a>>, subject: impl Into<SubjectRef<'a>>,
@ -778,7 +809,7 @@ impl<'a> TripleRef<'a> {
} }
} }
/// Encodes that this triple is in a [RDF dataset](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-dataset) /// Encodes that this triple is in a [RDF dataset](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-dataset).
#[inline] #[inline]
pub fn in_graph(self, graph_name: impl Into<GraphNameRef<'a>>) -> QuadRef<'a> { pub fn in_graph(self, graph_name: impl Into<GraphNameRef<'a>>) -> QuadRef<'a> {
QuadRef { QuadRef {
@ -978,16 +1009,32 @@ impl<'a> From<GraphNameRef<'a>> for GraphName {
} }
} }
/// An owned [triple](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-triple) in a [RDF dataset](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-dataset) /// An owned [triple](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-triple) in a [RDF dataset](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-dataset).
///
/// The default string formatter is returning an N-Quads compatible representation:
/// ```
/// use oxrdf::{Quad, NamedNode};
///
/// assert_eq!(
/// "<http://example.com/s> <http://example.com/p> <http://example.com/o> <http://example.com/g>",
/// Quad {
/// subject: NamedNode::new("http://example.com/s")?.into(),
/// predicate: NamedNode::new("http://example.com/p")?,
/// object: NamedNode::new("http://example.com/o")?.into(),
/// graph_name: NamedNode::new("http://example.com/g")?.into(),
/// }.to_string()
/// );
/// # Result::<_,oxrdf::IriParseError>::Ok(())
/// ```
#[derive(Eq, PartialEq, Debug, Clone, Hash)] #[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub struct Quad { pub struct Quad {
/// The [subject](https://www.w3.org/TR/rdf11-concepts/#dfn-subject) of this triple /// The [subject](https://www.w3.org/TR/rdf11-concepts/#dfn-subject) of this triple.
pub subject: Subject, pub subject: Subject,
/// The [predicate](https://www.w3.org/TR/rdf11-concepts/#dfn-predicate) of this triple /// The [predicate](https://www.w3.org/TR/rdf11-concepts/#dfn-predicate) of this triple.
pub predicate: NamedNode, pub predicate: NamedNode,
/// The [object](https://www.w3.org/TR/rdf11-concepts/#dfn-object) of this triple /// The [object](https://www.w3.org/TR/rdf11-concepts/#dfn-object) of this triple.
pub object: Term, pub object: Term,
/// The name of the RDF [graph](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-graph) in which the triple is. /// The name of the RDF [graph](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-graph) in which the triple is.
@ -995,7 +1042,7 @@ pub struct Quad {
} }
impl Quad { impl Quad {
/// Builds an RDF [triple](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-triple) in a [RDF dataset](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-dataset) /// Builds an RDF [triple](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-triple) in a [RDF dataset](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-dataset).
#[inline] #[inline]
pub fn new( pub fn new(
subject: impl Into<Subject>, subject: impl Into<Subject>,
@ -1040,16 +1087,32 @@ impl From<Quad> for Triple {
} }
} }
/// A borrowed [triple](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-triple) in a [RDF dataset](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-dataset) /// A borrowed [triple](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-triple) in a [RDF dataset](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-dataset).
///
/// The default string formatter is returning an N-Quads compatible representation:
/// ```
/// use oxrdf::{QuadRef, NamedNodeRef};
///
/// assert_eq!(
/// "<http://example.com/s> <http://example.com/p> <http://example.com/o> <http://example.com/g>",
/// QuadRef {
/// subject: NamedNodeRef::new("http://example.com/s")?.into(),
/// predicate: NamedNodeRef::new("http://example.com/p")?,
/// object: NamedNodeRef::new("http://example.com/o")?.into(),
/// graph_name: NamedNodeRef::new("http://example.com/g")?.into(),
/// }.to_string()
/// );
/// # Result::<_,oxrdf::IriParseError>::Ok(())
/// ```
#[derive(Eq, PartialEq, Debug, Clone, Copy, Hash)] #[derive(Eq, PartialEq, Debug, Clone, Copy, Hash)]
pub struct QuadRef<'a> { pub struct QuadRef<'a> {
/// The [subject](https://www.w3.org/TR/rdf11-concepts/#dfn-subject) of this triple /// The [subject](https://www.w3.org/TR/rdf11-concepts/#dfn-subject) of this triple.
pub subject: SubjectRef<'a>, pub subject: SubjectRef<'a>,
/// The [predicate](https://www.w3.org/TR/rdf11-concepts/#dfn-predicate) of this triple /// The [predicate](https://www.w3.org/TR/rdf11-concepts/#dfn-predicate) of this triple.
pub predicate: NamedNodeRef<'a>, pub predicate: NamedNodeRef<'a>,
/// The [object](https://www.w3.org/TR/rdf11-concepts/#dfn-object) of this triple /// The [object](https://www.w3.org/TR/rdf11-concepts/#dfn-object) of this triple.
pub object: TermRef<'a>, pub object: TermRef<'a>,
/// The name of the RDF [graph](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-graph) in which the triple is. /// The name of the RDF [graph](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-graph) in which the triple is.
@ -1057,7 +1120,7 @@ pub struct QuadRef<'a> {
} }
impl<'a> QuadRef<'a> { impl<'a> QuadRef<'a> {
/// Builds an RDF [triple](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-triple) in a [RDF dataset](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-dataset) /// Builds an RDF [triple](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-triple) in a [RDF dataset](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-dataset).
#[inline] #[inline]
pub fn new( pub fn new(
subject: impl Into<SubjectRef<'a>>, subject: impl Into<SubjectRef<'a>>,

@ -5,7 +5,7 @@ authors = ["Tpt <thomas@pellissier-tanon.fr>"]
license = "MIT OR Apache-2.0" license = "MIT OR Apache-2.0"
readme = "README.md" readme = "README.md"
keywords = ["SPARQL"] keywords = ["SPARQL"]
repository = "https://github.com/oxigraph/oxigraph/tree/v0.3/spargebra" repository = "https://github.com/oxigraph/oxigraph/tree/master/lib/spargebra"
homepage = "https://oxigraph.org/" homepage = "https://oxigraph.org/"
description = """ description = """
A SPARQL parser A SPARQL parser
@ -14,13 +14,14 @@ edition = "2021"
[features] [features]
default = [] default = []
rdf-star = [] rdf-star = ["oxrdf/rdf-star"]
[dependencies] [dependencies]
peg = "0.7" peg = "0.7"
rand = "0.8" rand = "0.8"
oxiri = "0.1" oxiri = "0.1"
oxilangtag = "0.1" oxilangtag = "0.1"
oxrdf = { version = "0.1", path="../oxrdf" }
[package.metadata.docs.rs] [package.metadata.docs.rs]
all-features = true all-features = true

@ -1,5 +1,5 @@
Spargebra Spargebra
======== =========
[![Latest Version](https://img.shields.io/crates/v/spargebra.svg)](https://crates.io/crates/spargebra) [![Latest Version](https://img.shields.io/crates/v/spargebra.svg)](https://crates.io/crates/spargebra)
[![Released API docs](https://docs.rs/spargebra/badge.svg)](https://docs.rs/spargebra) [![Released API docs](https://docs.rs/spargebra/badge.svg)](https://docs.rs/spargebra)

@ -1,7 +1,7 @@
//! [SPARQL 1.1 Query Algebra](https://www.w3.org/TR/sparql11-query/#sparqlQuery) representation //! [SPARQL 1.1 Query Algebra](https://www.w3.org/TR/sparql11-query/#sparqlQuery) representation
use crate::term::print_quoted_str;
use crate::term::*; use crate::term::*;
use oxrdf::LiteralRef;
use std::fmt; use std::fmt;
/// A [property path expression](https://www.w3.org/TR/sparql11-query/#defn_PropertyPathExpr) /// A [property path expression](https://www.w3.org/TR/sparql11-query/#defn_PropertyPathExpr)
@ -21,7 +21,7 @@ impl PropertyPathExpression {
/// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html). /// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
pub(crate) fn fmt_sse(&self, f: &mut impl fmt::Write) -> fmt::Result { pub(crate) fn fmt_sse(&self, f: &mut impl fmt::Write) -> fmt::Result {
match self { match self {
Self::NamedNode(p) => p.fmt_sse(f), Self::NamedNode(p) => write!(f, "{}", p),
Self::Reverse(p) => { Self::Reverse(p) => {
write!(f, "(reverse ")?; write!(f, "(reverse ")?;
p.fmt_sse(f)?; p.fmt_sse(f)?;
@ -59,8 +59,7 @@ impl PropertyPathExpression {
Self::NegatedPropertySet(p) => { Self::NegatedPropertySet(p) => {
write!(f, "(notoneof")?; write!(f, "(notoneof")?;
for p in p { for p in p {
write!(f, " ")?; write!(f, " {}", p)?;
p.fmt_sse(f)?;
} }
write!(f, ")") write!(f, ")")
} }
@ -150,9 +149,9 @@ impl Expression {
/// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html). /// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
pub(crate) fn fmt_sse(&self, f: &mut impl fmt::Write) -> fmt::Result { pub(crate) fn fmt_sse(&self, f: &mut impl fmt::Write) -> fmt::Result {
match self { match self {
Self::NamedNode(node) => node.fmt_sse(f), Self::NamedNode(node) => write!(f, "{}", node),
Self::Literal(l) => l.fmt_sse(f), Self::Literal(l) => write!(f, "{}", l),
Self::Variable(var) => var.fmt_sse(f), Self::Variable(var) => write!(f, "{}", var),
Self::Or(a, b) => fmt_sse_binary_expression(f, "||", a, b), Self::Or(a, b) => fmt_sse_binary_expression(f, "||", a, b),
Self::And(a, b) => fmt_sse_binary_expression(f, "&&", a, b), Self::And(a, b) => fmt_sse_binary_expression(f, "&&", a, b),
Self::Equal(a, b) => fmt_sse_binary_expression(f, "=", a, b), Self::Equal(a, b) => fmt_sse_binary_expression(f, "=", a, b),
@ -192,9 +191,7 @@ impl Expression {
write!(f, ")") write!(f, ")")
} }
Self::Bound(v) => { Self::Bound(v) => {
write!(f, "(bound ")?; write!(f, "(bound {})", v)
v.fmt_sse(f)?;
write!(f, ")")
} }
Self::If(a, b, c) => { Self::If(a, b, c) => {
write!(f, "(if ")?; write!(f, "(if ")?;
@ -442,7 +439,7 @@ impl Function {
Self::Object => write!(f, "object"), Self::Object => write!(f, "object"),
#[cfg(feature = "rdf-star")] #[cfg(feature = "rdf-star")]
Self::IsTriple => write!(f, "istriple"), Self::IsTriple => write!(f, "istriple"),
Self::Custom(iri) => iri.fmt_sse(f), Self::Custom(iri) => write!(f, "{}", iri),
} }
} }
} }
@ -658,9 +655,7 @@ impl GraphPattern {
variable, variable,
expression, expression,
} => { } => {
write!(f, "(extend ((")?; write!(f, "(extend (({} ", variable)?;
variable.fmt_sse(f)?;
write!(f, " ")?;
expression.fmt_sse(f)?; expression.fmt_sse(f)?;
write!(f, ")) ")?; write!(f, ")) ")?;
inner.fmt_sse(f)?; inner.fmt_sse(f)?;
@ -697,7 +692,7 @@ impl GraphPattern {
if i > 0 { if i > 0 {
write!(f, " ")?; write!(f, " ")?;
} }
v.fmt_sse(f)?; write!(f, "{}", v)?;
} }
write!(f, ") (")?; write!(f, ") (")?;
for (i, (v, a)) in aggregates.iter().enumerate() { for (i, (v, a)) in aggregates.iter().enumerate() {
@ -706,9 +701,7 @@ impl GraphPattern {
} }
write!(f, "(")?; write!(f, "(")?;
a.fmt_sse(f)?; a.fmt_sse(f)?;
write!(f, " ")?; write!(f, " {})", v)?;
v.fmt_sse(f)?;
write!(f, ")")?;
} }
write!(f, ") ")?; write!(f, ") ")?;
inner.fmt_sse(f)?; inner.fmt_sse(f)?;
@ -720,19 +713,14 @@ impl GraphPattern {
} => { } => {
write!(f, "(table (vars")?; write!(f, "(table (vars")?;
for var in variables { for var in variables {
write!(f, " ")?; write!(f, " {}", var)?;
var.fmt_sse(f)?;
} }
write!(f, ")")?; write!(f, ")")?;
for row in bindings { for row in bindings {
write!(f, " (row")?; write!(f, " (row")?;
for (value, var) in row.iter().zip(variables) { for (value, var) in row.iter().zip(variables) {
if let Some(value) = value { if let Some(value) = value {
write!(f, " (")?; write!(f, " ({} {})", var, value)?;
var.fmt_sse(f)?;
write!(f, " ")?;
value.fmt_sse(f)?;
write!(f, ")")?;
} }
} }
write!(f, ")")?; write!(f, ")")?;
@ -757,7 +745,7 @@ impl GraphPattern {
if i > 0 { if i > 0 {
write!(f, " ")?; write!(f, " ")?;
} }
v.fmt_sse(f)?; write!(f, "{}", v)?;
} }
write!(f, ") ")?; write!(f, ") ")?;
inner.fmt_sse(f)?; inner.fmt_sse(f)?;
@ -1213,8 +1201,7 @@ impl AggregateExpression {
} }
expr.fmt_sse(f)?; expr.fmt_sse(f)?;
if let Some(separator) = separator { if let Some(separator) = separator {
write!(f, " ")?; write!(f, " {}", LiteralRef::new_simple_literal(separator))?;
print_quoted_str(separator, f)?;
} }
write!(f, ")") write!(f, ")")
} }
@ -1223,8 +1210,7 @@ impl AggregateExpression {
expr, expr,
distinct, distinct,
} => { } => {
write!(f, "(")?; write!(f, "({}", name)?;
name.fmt_sse(f)?;
if *distinct { if *distinct {
write!(f, " distinct")?; write!(f, " distinct")?;
} }
@ -1294,16 +1280,22 @@ impl fmt::Display for AggregateExpression {
} => { } => {
if *distinct { if *distinct {
if let Some(separator) = separator { if let Some(separator) = separator {
write!(f, "GROUP_CONCAT(DISTINCT {}; SEPARATOR = ", expr)?; write!(
print_quoted_str(separator, f)?; f,
write!(f, ")") "GROUP_CONCAT(DISTINCT {}; SEPARATOR = {})",
expr,
LiteralRef::new_simple_literal(separator)
)
} else { } else {
write!(f, "GROUP_CONCAT(DISTINCT {})", expr) write!(f, "GROUP_CONCAT(DISTINCT {})", expr)
} }
} else if let Some(separator) = separator { } else if let Some(separator) = separator {
write!(f, "GROUP_CONCAT({}; SEPARATOR = ", expr)?; write!(
print_quoted_str(separator, f)?; f,
write!(f, ")") "GROUP_CONCAT({}; SEPARATOR = {})",
expr,
LiteralRef::new_simple_literal(separator)
)
} else { } else {
write!(f, "GROUP_CONCAT({})", expr) write!(f, "GROUP_CONCAT({})", expr)
} }
@ -1374,16 +1366,14 @@ impl QueryDataset {
if i > 0 { if i > 0 {
write!(f, " ")?; write!(f, " ")?;
} }
graph_name.fmt_sse(f)?; write!(f, "{}", graph_name)?;
} }
if let Some(named) = &self.named { if let Some(named) = &self.named {
for (i, graph_name) in named.iter().enumerate() { for (i, graph_name) in named.iter().enumerate() {
if !self.default.is_empty() || i > 0 { if !self.default.is_empty() || i > 0 {
write!(f, " ")?; write!(f, " ")?;
} }
write!(f, "(named ")?; write!(f, "(named {})", graph_name)?;
graph_name.fmt_sse(f)?;
write!(f, ")")?;
} }
} }
write!(f, ")") write!(f, ")")
@ -1419,7 +1409,7 @@ impl GraphTarget {
/// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html). /// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
pub(crate) fn fmt_sse(&self, f: &mut impl fmt::Write) -> fmt::Result { pub(crate) fn fmt_sse(&self, f: &mut impl fmt::Write) -> fmt::Result {
match self { match self {
Self::NamedNode(node) => node.fmt_sse(f), Self::NamedNode(node) => write!(f, "{}", node),
Self::DefaultGraph => write!(f, "default"), Self::DefaultGraph => write!(f, "default"),
Self::NamedGraphs => write!(f, "named"), Self::NamedGraphs => write!(f, "named"),
Self::AllGraphs => write!(f, "all"), Self::AllGraphs => write!(f, "all"),

@ -4,6 +4,7 @@ use crate::term::*;
use crate::update::*; use crate::update::*;
use oxilangtag::LanguageTag; use oxilangtag::LanguageTag;
use oxiri::{Iri, IriParseError}; use oxiri::{Iri, IriParseError};
use oxrdf::vocab::{rdf, xsd};
use peg::parser; use peg::parser;
use peg::str::LineCol; use peg::str::LineCol;
use rand::random; use rand::random;
@ -200,7 +201,7 @@ fn add_to_triple_or_path_patterns(
if !object.annotations.is_empty() { if !object.annotations.is_empty() {
return Err("Annotations are not allowed on property paths"); return Err("Annotations are not allowed on property paths");
} }
let middle = bnode(); let middle = BlankNode::default();
add_to_triple_or_path_patterns( add_to_triple_or_path_patterns(
subject, subject,
*a, *a,
@ -618,17 +619,17 @@ fn are_variables_bound(expression: &Expression, variables: &HashSet<Variable>) -
fn copy_graph(from: impl Into<GraphName>, to: impl Into<GraphNamePattern>) -> GraphUpdateOperation { fn copy_graph(from: impl Into<GraphName>, to: impl Into<GraphNamePattern>) -> GraphUpdateOperation {
let bgp = GraphPattern::Bgp { let bgp = GraphPattern::Bgp {
patterns: vec![TriplePattern::new( patterns: vec![TriplePattern::new(
Variable { name: "s".into() }, Variable::new_unchecked("s"),
Variable { name: "p".into() }, Variable::new_unchecked("p"),
Variable { name: "o".into() }, Variable::new_unchecked("o"),
)], )],
}; };
GraphUpdateOperation::DeleteInsert { GraphUpdateOperation::DeleteInsert {
delete: Vec::new(), delete: Vec::new(),
insert: vec![QuadPattern::new( insert: vec![QuadPattern::new(
Variable { name: "s".into() }, Variable::new_unchecked("s"),
Variable { name: "p".into() }, Variable::new_unchecked("p"),
Variable { name: "o".into() }, Variable::new_unchecked("o"),
to, to,
)], )],
using: None, using: None,
@ -882,20 +883,8 @@ pub fn unescape_pn_local(input: &str) -> Cow<'_, str> {
unescape_characters(input, &UNESCAPE_PN_CHARACTERS, &UNESCAPE_PN_REPLACEMENT) unescape_characters(input, &UNESCAPE_PN_CHARACTERS, &UNESCAPE_PN_REPLACEMENT)
} }
fn iri(value: impl Into<String>) -> NamedNode {
NamedNode { iri: value.into() }
}
fn bnode() -> BlankNode {
BlankNode {
id: format!("{:x}", random::<u128>()),
}
}
fn variable() -> Variable { fn variable() -> Variable {
Variable { Variable::new_unchecked(format!("{:x}", random::<u128>()))
name: format!("{:x}", random::<u128>()),
}
} }
parser! { parser! {
@ -1155,7 +1144,7 @@ parser! {
if from == to { if from == to {
Vec::new() // identity case Vec::new() // identity case
} else { } else {
let bgp = GraphPattern::Bgp { patterns: vec![TriplePattern::new(Variable { name: "s".into() }, Variable { name: "p".into() }, Variable { name: "o".into() })] }; let bgp = GraphPattern::Bgp { patterns: vec![TriplePattern::new(Variable::new_unchecked("s"), Variable::new_unchecked("p"), Variable::new_unchecked("o"))] };
vec![copy_graph(from, to)] vec![copy_graph(from, to)]
} }
} }
@ -1166,7 +1155,7 @@ parser! {
if from == to { if from == to {
Vec::new() // identity case Vec::new() // identity case
} else { } else {
let bgp = GraphPattern::Bgp { patterns: vec![TriplePattern::new(Variable { name: "s".into() }, Variable { name: "p".into() }, Variable { name: "o".into() })] }; let bgp = GraphPattern::Bgp { patterns: vec![TriplePattern::new(Variable::new_unchecked("s"), Variable::new_unchecked("p"), Variable::new_unchecked("o"))] };
vec![GraphUpdateOperation::Drop { silent: true, graph: to.clone().into() }, copy_graph(from.clone(), to), GraphUpdateOperation::Drop { silent, graph: from.into() }] vec![GraphUpdateOperation::Drop { silent: true, graph: to.clone().into() }, copy_graph(from.clone(), to), GraphUpdateOperation::Drop { silent, graph: from.into() }]
} }
} }
@ -1177,7 +1166,7 @@ parser! {
if from == to { if from == to {
Vec::new() // identity case Vec::new() // identity case
} else { } else {
let bgp = GraphPattern::Bgp { patterns: vec![TriplePattern::new(Variable { name: "s".into() }, Variable { name: "p".into() }, Variable{ name: "o".into() })] }; let bgp = GraphPattern::Bgp { patterns: vec![TriplePattern::new(Variable::new_unchecked("s"), Variable::new_unchecked("p"), Variable::new_unchecked("o"))] };
vec![GraphUpdateOperation::Drop { silent: true, graph: to.clone().into() }, copy_graph(from, to)] vec![GraphUpdateOperation::Drop { silent: true, graph: to.clone().into() }, copy_graph(from, to)]
} }
} }
@ -1557,7 +1546,7 @@ parser! {
} }
//[78] //[78]
rule Verb() -> NamedNodePattern = VarOrIri() / "a" { iri("http://www.w3.org/1999/02/22-rdf-syntax-ns#type").into() } rule Verb() -> NamedNodePattern = VarOrIri() / "a" { rdf::TYPE.into_owned().into() }
//[79] //[79]
rule ObjectList() -> FocusedTriplePattern<Vec<AnnotatedTerm>> = o:ObjectList_item() **<1,> ("," _) { rule ObjectList() -> FocusedTriplePattern<Vec<AnnotatedTerm>> = o:ObjectList_item() **<1,> ("," _) {
@ -1717,7 +1706,7 @@ parser! {
//[94] //[94]
rule PathPrimary() -> PropertyPathExpression = rule PathPrimary() -> PropertyPathExpression =
v:iri() { v.into() } / v:iri() { v.into() } /
"a" { iri("http://www.w3.org/1999/02/22-rdf-syntax-ns#type").into() } / "a" { rdf::TYPE.into_owned().into() } /
"!" _ p:PathNegatedPropertySet() { p } / "!" _ p:PathNegatedPropertySet() { p } /
"(" _ p:Path() _ ")" { p } "(" _ p:Path() _ ")" { p }
@ -1754,9 +1743,9 @@ parser! {
//[96] //[96]
rule PathOneInPropertySet() -> Either<NamedNode,NamedNode> = rule PathOneInPropertySet() -> Either<NamedNode,NamedNode> =
"^" _ v:iri() { Either::Right(v) } / "^" _ v:iri() { Either::Right(v) } /
"^" _ "a" { Either::Right(iri("http://www.w3.org/1999/02/22-rdf-syntax-ns#type")) } / "^" _ "a" { Either::Right(rdf::TYPE.into()) } /
v:iri() { Either::Left(v) } / v:iri() { Either::Left(v) } /
"a" { Either::Left(iri("http://www.w3.org/1999/02/22-rdf-syntax-ns#type")) } "a" { Either::Left(rdf::TYPE.into()) }
//[98] //[98]
rule TriplesNode() -> FocusedTriplePattern<TermPattern> = Collection() / BlankNodePropertyList() rule TriplesNode() -> FocusedTriplePattern<TermPattern> = Collection() / BlankNodePropertyList()
@ -1764,7 +1753,7 @@ parser! {
//[99] //[99]
rule BlankNodePropertyList() -> FocusedTriplePattern<TermPattern> = "[" _ po:PropertyListNotEmpty() _ "]" {? rule BlankNodePropertyList() -> FocusedTriplePattern<TermPattern> = "[" _ po:PropertyListNotEmpty() _ "]" {?
let mut patterns = po.patterns; let mut patterns = po.patterns;
let mut bnode = TermPattern::from(bnode()); let mut bnode = TermPattern::from(BlankNode::default());
for (p, os) in po.focus { for (p, os) in po.focus {
for o in os { for o in os {
add_to_triple_patterns(bnode.clone(), p.clone(), o, &mut patterns)?; add_to_triple_patterns(bnode.clone(), p.clone(), o, &mut patterns)?;
@ -1782,7 +1771,7 @@ parser! {
//[101] //[101]
rule BlankNodePropertyListPath() -> FocusedTripleOrPathPattern<TermPattern> = "[" _ po:PropertyListPathNotEmpty() _ "]" {? rule BlankNodePropertyListPath() -> FocusedTripleOrPathPattern<TermPattern> = "[" _ po:PropertyListPathNotEmpty() _ "]" {?
let mut patterns: Vec<TripleOrPathPattern> = Vec::new(); let mut patterns: Vec<TripleOrPathPattern> = Vec::new();
let mut bnode = TermPattern::from(bnode()); let mut bnode = TermPattern::from(BlankNode::default());
for (p, os) in po.focus { for (p, os) in po.focus {
for o in os { for o in os {
add_to_triple_or_path_patterns(bnode.clone(), p.clone(), o, &mut patterns)?; add_to_triple_or_path_patterns(bnode.clone(), p.clone(), o, &mut patterns)?;
@ -1797,11 +1786,11 @@ parser! {
//[102] //[102]
rule Collection() -> FocusedTriplePattern<TermPattern> = "(" _ o:Collection_item()+ ")" { rule Collection() -> FocusedTriplePattern<TermPattern> = "(" _ o:Collection_item()+ ")" {
let mut patterns: Vec<TriplePattern> = Vec::new(); let mut patterns: Vec<TriplePattern> = Vec::new();
let mut current_list_node = TermPattern::from(iri("http://www.w3.org/1999/02/22-rdf-syntax-ns#nil")); let mut current_list_node = TermPattern::from(rdf::NIL.into_owned());
for objWithPatterns in o.into_iter().rev() { for objWithPatterns in o.into_iter().rev() {
let new_blank_node = TermPattern::from(bnode()); let new_blank_node = TermPattern::from(BlankNode::default());
patterns.push(TriplePattern::new(new_blank_node.clone(), iri("http://www.w3.org/1999/02/22-rdf-syntax-ns#first"), objWithPatterns.focus.clone())); patterns.push(TriplePattern::new(new_blank_node.clone(), rdf::FIRST.into_owned(), objWithPatterns.focus.clone()));
patterns.push(TriplePattern::new(new_blank_node.clone(), iri("http://www.w3.org/1999/02/22-rdf-syntax-ns#rest"), current_list_node)); patterns.push(TriplePattern::new(new_blank_node.clone(), rdf::REST.into_owned(), current_list_node));
current_list_node = new_blank_node; current_list_node = new_blank_node;
patterns.extend_from_slice(&objWithPatterns.patterns); patterns.extend_from_slice(&objWithPatterns.patterns);
} }
@ -1815,11 +1804,11 @@ parser! {
//[103] //[103]
rule CollectionPath() -> FocusedTripleOrPathPattern<TermPattern> = "(" _ o:CollectionPath_item()+ _ ")" { rule CollectionPath() -> FocusedTripleOrPathPattern<TermPattern> = "(" _ o:CollectionPath_item()+ _ ")" {
let mut patterns: Vec<TripleOrPathPattern> = Vec::new(); let mut patterns: Vec<TripleOrPathPattern> = Vec::new();
let mut current_list_node = TermPattern::from(iri("http://www.w3.org/1999/02/22-rdf-syntax-ns#nil")); let mut current_list_node = TermPattern::from(rdf::NIL.into_owned());
for objWithPatterns in o.into_iter().rev() { for objWithPatterns in o.into_iter().rev() {
let new_blank_node = TermPattern::from(bnode()); let new_blank_node = TermPattern::from(BlankNode::default());
patterns.push(TriplePattern::new(new_blank_node.clone(), iri("http://www.w3.org/1999/02/22-rdf-syntax-ns#first"), objWithPatterns.focus.clone()).into()); patterns.push(TriplePattern::new(new_blank_node.clone(), rdf::FIRST.into_owned(), objWithPatterns.focus.clone()).into());
patterns.push(TriplePattern::new(new_blank_node.clone(), iri("http://www.w3.org/1999/02/22-rdf-syntax-ns#rest"), current_list_node).into()); patterns.push(TriplePattern::new(new_blank_node.clone(), rdf::REST.into_owned(), current_list_node).into());
current_list_node = new_blank_node; current_list_node = new_blank_node;
patterns.extend(objWithPatterns.patterns); patterns.extend(objWithPatterns.patterns);
} }
@ -1851,7 +1840,7 @@ parser! {
i:iri() { i.into() } i:iri() { i.into() }
//[108] //[108]
rule Var() -> Variable = name:(VAR1() / VAR2()) { Variable { name: name.into() } } rule Var() -> Variable = name:(VAR1() / VAR2()) { Variable::new_unchecked(name) }
//[109] //[109]
rule GraphTerm() -> Term = rule GraphTerm() -> Term =
@ -1860,7 +1849,7 @@ parser! {
l:NumericLiteral() { l.into() } / l:NumericLiteral() { l.into() } /
l:BooleanLiteral() { l.into() } / l:BooleanLiteral() { l.into() } /
b:BlankNode() { b.into() } / b:BlankNode() { b.into() } /
NIL() { iri("http://www.w3.org/1999/02/22-rdf-syntax-ns#nil").into() } NIL() { rdf::NIL.into_owned().into() }
//[110] //[110]
rule Expression() -> Expression = e:ConditionalOrExpression() {e} rule Expression() -> Expression = e:ConditionalOrExpression() {e}
@ -2078,43 +2067,43 @@ parser! {
//[129] //[129]
rule RDFLiteral() -> Literal = rule RDFLiteral() -> Literal =
value:String() _ "^^" _ datatype:iri() { Literal::Typed { value, datatype } } / value:String() _ "^^" _ datatype:iri() { Literal::new_typed_literal(value, datatype) } /
value:String() _ language:LANGTAG() { Literal::LanguageTaggedString { value, language: language.into_inner() } } / value:String() _ language:LANGTAG() { Literal::new_language_tagged_literal_unchecked(value, language.into_inner()) } /
value:String() { Literal::Simple { value } } value:String() { Literal::new_simple_literal(value) }
//[130] //[130]
rule NumericLiteral() -> Literal = NumericLiteralUnsigned() / NumericLiteralPositive() / NumericLiteralNegative() rule NumericLiteral() -> Literal = NumericLiteralUnsigned() / NumericLiteralPositive() / NumericLiteralNegative()
//[131] //[131]
rule NumericLiteralUnsigned() -> Literal = rule NumericLiteralUnsigned() -> Literal =
d:$(DOUBLE()) { Literal::Typed { value: d.into(), datatype: iri("http://www.w3.org/2001/XMLSchema#double") } } / d:$(DOUBLE()) { Literal::new_typed_literal(d, xsd::DOUBLE) } /
d:$(DECIMAL()) { Literal::Typed { value: d.into(), datatype: iri("http://www.w3.org/2001/XMLSchema#decimal") } } / d:$(DECIMAL()) { Literal::new_typed_literal(d, xsd::DECIMAL) } /
i:$(INTEGER()) { Literal::Typed { value: i.into(), datatype: iri("http://www.w3.org/2001/XMLSchema#integer") } } i:$(INTEGER()) { Literal::new_typed_literal(i, xsd::INTEGER) }
//[132] //[132]
rule NumericLiteralPositive() -> Literal = rule NumericLiteralPositive() -> Literal =
d:$(DOUBLE_POSITIVE()) { Literal::Typed { value: d.into(), datatype: iri("http://www.w3.org/2001/XMLSchema#double") } } / d:$(DOUBLE_POSITIVE()) { Literal::new_typed_literal(d, xsd::DOUBLE) } /
d:$(DECIMAL_POSITIVE()) { Literal::Typed { value: d.into(), datatype: iri("http://www.w3.org/2001/XMLSchema#decimal") } } / d:$(DECIMAL_POSITIVE()) { Literal::new_typed_literal(d, xsd::DECIMAL) } /
i:$(INTEGER_POSITIVE()) { Literal::Typed { value: i.into(), datatype: iri("http://www.w3.org/2001/XMLSchema#integer") } } i:$(INTEGER_POSITIVE()) { Literal::new_typed_literal(i, xsd::INTEGER) }
//[133] //[133]
rule NumericLiteralNegative() -> Literal = rule NumericLiteralNegative() -> Literal =
d:$(DOUBLE_NEGATIVE()) { Literal::Typed { value: d.into(), datatype: iri("http://www.w3.org/2001/XMLSchema#double") } } / d:$(DOUBLE_NEGATIVE()) { Literal::new_typed_literal(d, xsd::DOUBLE) } /
d:$(DECIMAL_NEGATIVE()) { Literal::Typed { value: d.into(), datatype: iri("http://www.w3.org/2001/XMLSchema#decimal") } } / d:$(DECIMAL_NEGATIVE()) { Literal::new_typed_literal(d, xsd::DECIMAL) } /
i:$(INTEGER_NEGATIVE()) { Literal::Typed { value: i.into(), datatype: iri("http://www.w3.org/2001/XMLSchema#integer") } } i:$(INTEGER_NEGATIVE()) { Literal::new_typed_literal(i, xsd::INTEGER) }
//[134] //[134]
rule BooleanLiteral() -> Literal = rule BooleanLiteral() -> Literal =
"true" { Literal::Typed { value: "true".into(), datatype: iri("http://www.w3.org/2001/XMLSchema#boolean") } } / "true" { Literal::new_typed_literal("true", xsd::BOOLEAN) } /
"false" { Literal::Typed { value: "false".into(), datatype: iri("http://www.w3.org/2001/XMLSchema#boolean") } } "false" { Literal::new_typed_literal("false", xsd::BOOLEAN) }
//[135] //[135]
rule String() -> String = STRING_LITERAL_LONG1() / STRING_LITERAL_LONG2() / STRING_LITERAL1() / STRING_LITERAL2() rule String() -> String = STRING_LITERAL_LONG1() / STRING_LITERAL_LONG2() / STRING_LITERAL1() / STRING_LITERAL2()
//[136] //[136]
rule iri() -> NamedNode = i:(IRIREF() / PrefixedName()) { rule iri() -> NamedNode = i:(IRIREF() / PrefixedName()) {
iri(i.into_inner()) NamedNode::new_unchecked(i.into_inner())
} }
//[137] //[137]
@ -2127,14 +2116,14 @@ parser! {
//[138] //[138]
rule BlankNode() -> BlankNode = id:BLANK_NODE_LABEL() {? rule BlankNode() -> BlankNode = id:BLANK_NODE_LABEL() {?
let node = BlankNode { id: id.to_owned() }; let node = BlankNode::new_unchecked(id);
if state.used_bnodes.contains(&node) { if state.used_bnodes.contains(&node) {
Err("Already used blank node id") Err("Already used blank node id")
} else { } else {
state.currently_used_bnodes.insert(node.clone()); state.currently_used_bnodes.insert(node.clone());
Ok(node) Ok(node)
} }
} / ANON() { bnode() } } / ANON() { BlankNode::default() }
//[139] //[139]
rule IRIREF() -> Iri<String> = "<" i:$((!['>'] [_])*) ">" {? rule IRIREF() -> Iri<String> = "<" i:$((!['>'] [_])*) ">" {?
@ -2285,7 +2274,7 @@ parser! {
object: o object: o
}) })
} }
rule EmbTriple_p() -> NamedNode = i: iri() { i } / "a" { iri("http://www.w3.org/1999/02/22-rdf-syntax-ns#type") } rule EmbTriple_p() -> NamedNode = i: iri() { i } / "a" { rdf::TYPE.into() }
//[176] //[176]
rule EmbSubjectOrObject() -> TermPattern = rule EmbSubjectOrObject() -> TermPattern =

@ -1,243 +1,9 @@
//! Data structures for [RDF 1.1 Concepts](https://www.w3.org/TR/rdf11-concepts/) like IRI, literal or triples. //! Data structures for [RDF 1.1 Concepts](https://www.w3.org/TR/rdf11-concepts/) like IRI, literal or triples.
pub use oxrdf::{BlankNode, Literal, NamedNode, Subject, Term, Triple, Variable};
use std::fmt; use std::fmt;
use std::fmt::Write; use std::fmt::Write;
/// An RDF [IRI](https://www.w3.org/TR/rdf11-concepts/#dfn-iri).
///
/// The default string formatter is returning an N-Triples, Turtle and SPARQL compatible representation.
///
/// ```
/// use spargebra::term::NamedNode;
///
/// assert_eq!(
/// "<http://example.com/foo>",
/// NamedNode { iri: "http://example.com/foo".into() }.to_string()
/// )
/// ```
#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Hash)]
pub struct NamedNode {
/// The [IRI](https://www.w3.org/TR/rdf11-concepts/#dfn-iri) itself.
pub iri: String,
}
impl NamedNode {
/// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
pub(crate) fn fmt_sse(&self, f: &mut impl Write) -> fmt::Result {
write!(f, "<{}>", self.iri)
}
}
impl fmt::Display for NamedNode {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "<{}>", self.iri)
}
}
impl TryFrom<NamedNodePattern> for NamedNode {
type Error = ();
#[inline]
fn try_from(pattern: NamedNodePattern) -> Result<Self, ()> {
match pattern {
NamedNodePattern::NamedNode(t) => Ok(t),
NamedNodePattern::Variable(_) => Err(()),
}
}
}
/// An RDF [blank node](https://www.w3.org/TR/rdf11-concepts/#dfn-blank-node).
///
///
/// The default string formatter is returning an N-Triples, Turtle and SPARQL compatible representation.
///
/// ```
/// use spargebra::term::BlankNode;
///
/// assert_eq!(
/// "_:a1",
/// BlankNode { id: "a1".into() }.to_string()
/// )
/// ```
#[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub struct BlankNode {
/// The [blank node identifier](https://www.w3.org/TR/rdf11-concepts/#dfn-blank-node-identifier).
pub id: String,
}
impl BlankNode {
/// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
pub(crate) fn fmt_sse(&self, f: &mut impl Write) -> fmt::Result {
write!(f, "_:{}", self.id)
}
}
impl fmt::Display for BlankNode {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "_:{}", self.id)
}
}
/// An RDF [literal](https://www.w3.org/TR/rdf11-concepts/#dfn-literal).
///
/// The default string formatter is returning an N-Triples, Turtle and SPARQL compatible representation.
///
/// The language tags should be lowercased [as suggested by the RDF specification](https://www.w3.org/TR/rdf11-concepts/#dfn-language-tagged-string).
///
/// ```
/// use spargebra::term::NamedNode;
/// use spargebra::term::Literal;
///
/// assert_eq!(
/// "\"foo\\nbar\"",
/// Literal::Simple { value: "foo\nbar".into() }.to_string()
/// );
///
/// assert_eq!(
/// "\"1999-01-01\"^^<http://www.w3.org/2001/XMLSchema#date>",
/// Literal::Typed { value: "1999-01-01".into(), datatype: NamedNode { iri: "http://www.w3.org/2001/XMLSchema#date".into() }}.to_string()
/// );
///
/// assert_eq!(
/// "\"foo\"@en",
/// Literal::LanguageTaggedString { value: "foo".into(), language: "en".into() }.to_string()
/// );
/// ```
#[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub enum Literal {
/// A [simple literal](https://www.w3.org/TR/rdf11-concepts/#dfn-simple-literal) without datatype or language form.
Simple {
/// The [lexical form](https://www.w3.org/TR/rdf11-concepts/#dfn-lexical-form).
value: String,
},
/// A [language-tagged string](https://www.w3.org/TR/rdf11-concepts/#dfn-language-tagged-string)
LanguageTaggedString {
/// The [lexical form](https://www.w3.org/TR/rdf11-concepts/#dfn-lexical-form).
value: String,
/// The [language tag](https://www.w3.org/TR/rdf11-concepts/#dfn-language-tag).
language: String,
},
/// A literal with an explicit datatype
Typed {
/// The [lexical form](https://www.w3.org/TR/rdf11-concepts/#dfn-lexical-form).
value: String,
/// The [datatype IRI](https://www.w3.org/TR/rdf11-concepts/#dfn-datatype-iri).
datatype: NamedNode,
},
}
impl Literal {
/// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
pub(crate) fn fmt_sse(&self, f: &mut impl Write) -> fmt::Result {
match self {
Literal::Simple { value } => print_quoted_str(value, f),
Literal::LanguageTaggedString { value, language } => {
print_quoted_str(value, f)?;
write!(f, "@{}", language)
}
Literal::Typed { value, datatype } => {
print_quoted_str(value, f)?;
write!(f, "^^{}", datatype)
}
}
}
}
impl fmt::Display for Literal {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Literal::Simple { value } => print_quoted_str(value, f),
Literal::LanguageTaggedString { value, language } => {
print_quoted_str(value, f)?;
write!(f, "@{}", language)
}
Literal::Typed { value, datatype } => {
print_quoted_str(value, f)?;
write!(f, "^^{}", datatype)
}
}
}
}
/// The union of [IRIs](https://www.w3.org/TR/rdf11-concepts/#dfn-iri) and [blank nodes](https://www.w3.org/TR/rdf11-concepts/#dfn-blank-node).
///
/// The default string formatter is returning an N-Triples, Turtle and SPARQL compatible representation.
#[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub enum Subject {
NamedNode(NamedNode),
BlankNode(BlankNode),
#[cfg(feature = "rdf-star")]
Triple(Box<Triple>),
}
impl Subject {
/// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
pub(crate) fn fmt_sse(&self, f: &mut impl Write) -> fmt::Result {
match self {
Self::NamedNode(node) => node.fmt_sse(f),
Self::BlankNode(node) => node.fmt_sse(f),
#[cfg(feature = "rdf-star")]
Self::Triple(triple) => triple.fmt_sse(f),
}
}
}
impl fmt::Display for Subject {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::NamedNode(node) => node.fmt(f),
Self::BlankNode(node) => node.fmt(f),
#[cfg(feature = "rdf-star")]
Self::Triple(triple) => write!(
f,
"<<{} {} {}>>",
triple.subject, triple.predicate, triple.object
),
}
}
}
impl From<NamedNode> for Subject {
#[inline]
fn from(node: NamedNode) -> Self {
Self::NamedNode(node)
}
}
impl From<BlankNode> for Subject {
#[inline]
fn from(node: BlankNode) -> Self {
Self::BlankNode(node)
}
}
#[cfg(feature = "rdf-star")]
impl From<Triple> for Subject {
#[inline]
fn from(triple: Triple) -> Self {
Self::Triple(Box::new(triple))
}
}
impl TryFrom<TermPattern> for Subject {
type Error = ();
#[inline]
fn try_from(term: TermPattern) -> Result<Self, ()> {
match term {
TermPattern::NamedNode(t) => Ok(t.into()),
TermPattern::BlankNode(t) => Ok(t.into()),
#[cfg(feature = "rdf-star")]
TermPattern::Triple(t) => Ok(Triple::try_from(*t)?.into()),
TermPattern::Literal(_) | TermPattern::Variable(_) => Err(()),
}
}
}
/// The union of [IRIs](https://www.w3.org/TR/rdf11-concepts/#dfn-iri) and [triples](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-triple). /// The union of [IRIs](https://www.w3.org/TR/rdf11-concepts/#dfn-iri) and [triples](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-triple).
/// ///
/// The default string formatter is returning an N-Triples, Turtle and SPARQL compatible representation. /// The default string formatter is returning an N-Triples, Turtle and SPARQL compatible representation.
@ -248,17 +14,6 @@ pub enum GroundSubject {
Triple(Box<GroundTriple>), Triple(Box<GroundTriple>),
} }
impl GroundSubject {
/// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
pub(crate) fn fmt_sse(&self, f: &mut impl Write) -> fmt::Result {
match self {
Self::NamedNode(node) => node.fmt_sse(f),
#[cfg(feature = "rdf-star")]
Self::Triple(triple) => triple.fmt_sse(f),
}
}
}
impl fmt::Display for GroundSubject { impl fmt::Display for GroundSubject {
#[inline] #[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
@ -317,107 +72,6 @@ impl TryFrom<GroundTerm> for GroundSubject {
} }
} }
/// An RDF [term](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-term).
///
/// It is the union of [IRIs](https://www.w3.org/TR/rdf11-concepts/#dfn-iri), [blank nodes](https://www.w3.org/TR/rdf11-concepts/#dfn-blank-node) and [literals](https://www.w3.org/TR/rdf11-concepts/#dfn-literal).
///
/// The default string formatter is returning an N-Triples, Turtle and SPARQL compatible representation.
#[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub enum Term {
NamedNode(NamedNode),
BlankNode(BlankNode),
Literal(Literal),
#[cfg(feature = "rdf-star")]
Triple(Box<Triple>),
}
impl Term {
/// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
pub(crate) fn fmt_sse(&self, f: &mut impl Write) -> fmt::Result {
match self {
Self::NamedNode(node) => node.fmt_sse(f),
Self::BlankNode(node) => node.fmt_sse(f),
Self::Literal(literal) => literal.fmt_sse(f),
#[cfg(feature = "rdf-star")]
Self::Triple(triple) => triple.fmt_sse(f),
}
}
}
impl fmt::Display for Term {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::NamedNode(node) => node.fmt(f),
Self::BlankNode(node) => node.fmt(f),
Self::Literal(literal) => literal.fmt(f),
#[cfg(feature = "rdf-star")]
Self::Triple(triple) => write!(
f,
"<<{} {} {}>>",
triple.subject, triple.predicate, triple.object
),
}
}
}
impl From<NamedNode> for Term {
#[inline]
fn from(node: NamedNode) -> Self {
Self::NamedNode(node)
}
}
impl From<BlankNode> for Term {
#[inline]
fn from(node: BlankNode) -> Self {
Self::BlankNode(node)
}
}
impl From<Literal> for Term {
#[inline]
fn from(literal: Literal) -> Self {
Self::Literal(literal)
}
}
#[cfg(feature = "rdf-star")]
impl From<Triple> for Term {
#[inline]
fn from(triple: Triple) -> Self {
Self::Triple(Box::new(triple))
}
}
impl From<Subject> for Term {
#[inline]
fn from(resource: Subject) -> Self {
match resource {
Subject::NamedNode(node) => node.into(),
Subject::BlankNode(node) => node.into(),
#[cfg(feature = "rdf-star")]
Subject::Triple(t) => (*t).into(),
}
}
}
impl TryFrom<TermPattern> for Term {
type Error = ();
#[inline]
fn try_from(pattern: TermPattern) -> Result<Self, ()> {
match pattern {
TermPattern::NamedNode(t) => Ok(t.into()),
TermPattern::BlankNode(t) => Ok(t.into()),
TermPattern::Literal(t) => Ok(t.into()),
#[cfg(feature = "rdf-star")]
TermPattern::Triple(t) => Ok(Triple::try_from(*t)?.into()),
TermPattern::Variable(_) => Err(()),
}
}
}
/// The union of [IRIs](https://www.w3.org/TR/rdf11-concepts/#dfn-iri), [literals](https://www.w3.org/TR/rdf11-concepts/#dfn-literal) and [triples](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-triple). /// The union of [IRIs](https://www.w3.org/TR/rdf11-concepts/#dfn-iri), [literals](https://www.w3.org/TR/rdf11-concepts/#dfn-literal) and [triples](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-triple).
/// ///
/// The default string formatter is returning an N-Triples, Turtle and SPARQL compatible representation. /// The default string formatter is returning an N-Triples, Turtle and SPARQL compatible representation.
@ -429,18 +83,6 @@ pub enum GroundTerm {
Triple(Box<GroundTriple>), Triple(Box<GroundTriple>),
} }
impl GroundTerm {
/// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
pub(crate) fn fmt_sse(&self, f: &mut impl Write) -> fmt::Result {
match self {
Self::NamedNode(node) => node.fmt_sse(f),
Self::Literal(literal) => literal.fmt_sse(f),
#[cfg(feature = "rdf-star")]
Self::Triple(triple) => triple.fmt_sse(f),
}
}
}
impl fmt::Display for GroundTerm { impl fmt::Display for GroundTerm {
#[inline] #[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
@ -494,79 +136,22 @@ impl TryFrom<Term> for GroundTerm {
} }
} }
/// A [RDF triple](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-triple).
///
/// The default string formatter is returning a N-Quads representation.
///
/// ```
/// use spargebra::term::NamedNode;
/// use spargebra::term::Triple;
///
/// assert_eq!(
/// "<http://example.com/foo> <http://schema.org/sameAs> <http://example.com/foo>",
/// Triple {
/// subject: NamedNode { iri: "http://example.com/foo".into() }.into(),
/// predicate: NamedNode { iri: "http://schema.org/sameAs".into() },
/// object: NamedNode { iri: "http://example.com/foo".into() }.into(),
/// }.to_string()
/// )
/// ```
#[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub struct Triple {
pub subject: Subject,
pub predicate: NamedNode,
pub object: Term,
}
impl Triple {
/// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
pub(crate) fn fmt_sse(&self, f: &mut impl Write) -> fmt::Result {
write!(f, "(triple ")?;
self.subject.fmt_sse(f)?;
write!(f, " ")?;
self.predicate.fmt_sse(f)?;
write!(f, " ")?;
self.object.fmt_sse(f)?;
write!(f, ")")
}
}
impl fmt::Display for Triple {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{} {} {}", self.subject, self.predicate, self.object)
}
}
impl TryFrom<TriplePattern> for Triple {
type Error = ();
#[inline]
fn try_from(triple: TriplePattern) -> Result<Self, ()> {
Ok(Self {
subject: triple.subject.try_into()?,
predicate: triple.predicate.try_into()?,
object: triple.object.try_into()?,
})
}
}
/// A [RDF triple](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-triple) without blank nodes. /// A [RDF triple](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-triple) without blank nodes.
/// ///
/// The default string formatter is returning a N-Quads representation. /// The default string formatter is returning a N-Quads representation.
/// ///
/// ``` /// ```
/// use spargebra::term::NamedNode; /// use spargebra::term::{NamedNode, GroundTriple};
/// use spargebra::term::GroundTriple;
/// ///
/// assert_eq!( /// assert_eq!(
/// "<http://example.com/foo> <http://schema.org/sameAs> <http://example.com/foo>", /// "<http://example.com/s> <http://example.com/p> <http://example.com/o>",
/// GroundTriple { /// GroundTriple {
/// subject: NamedNode { iri: "http://example.com/foo".into() }.into(), /// subject: NamedNode::new("http://example.com/s")?.into(),
/// predicate: NamedNode { iri: "http://schema.org/sameAs".into() }, /// predicate: NamedNode::new("http://example.com/p")?,
/// object: NamedNode { iri: "http://example.com/foo".into() }.into(), /// object: NamedNode::new("http://example.com/o")?.into(),
/// }.to_string() /// }.to_string()
/// ) /// );
/// # Result::<_,oxrdf::IriParseError>::Ok(())
/// ``` /// ```
#[derive(Eq, PartialEq, Debug, Clone, Hash)] #[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub struct GroundTriple { pub struct GroundTriple {
@ -575,19 +160,6 @@ pub struct GroundTriple {
pub object: GroundTerm, pub object: GroundTerm,
} }
impl GroundTriple {
/// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
pub(crate) fn fmt_sse(&self, f: &mut impl Write) -> fmt::Result {
write!(f, "(triple ")?;
self.subject.fmt_sse(f)?;
write!(f, " ")?;
self.predicate.fmt_sse(f)?;
write!(f, " ")?;
self.object.fmt_sse(f)?;
write!(f, ")")
}
}
impl fmt::Display for GroundTriple { impl fmt::Display for GroundTriple {
#[inline] #[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
@ -621,7 +193,7 @@ impl GraphName {
/// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html). /// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
pub(crate) fn fmt_sse(&self, f: &mut impl Write) -> fmt::Result { pub(crate) fn fmt_sse(&self, f: &mut impl Write) -> fmt::Result {
match self { match self {
Self::NamedNode(node) => node.fmt_sse(f), Self::NamedNode(node) => write!(f, "{}", node),
Self::DefaultGraph => write!(f, "default"), Self::DefaultGraph => write!(f, "default"),
} }
} }
@ -662,18 +234,18 @@ impl TryFrom<GraphNamePattern> for GraphName {
/// The default string formatter is returning a N-Quads representation. /// The default string formatter is returning a N-Quads representation.
/// ///
/// ``` /// ```
/// use spargebra::term::NamedNode; /// use spargebra::term::{NamedNode, Quad};
/// use spargebra::term::Quad;
/// ///
/// assert_eq!( /// assert_eq!(
/// "<http://example.com/foo> <http://schema.org/sameAs> <http://example.com/foo> <http://example.com/>", /// "<http://example.com/s> <http://example.com/p> <http://example.com/o> <http://example.com/g>",
/// Quad { /// Quad {
/// subject: NamedNode { iri: "http://example.com/foo".into() }.into(), /// subject: NamedNode::new("http://example.com/s")?.into(),
/// predicate: NamedNode { iri: "http://schema.org/sameAs".into() }, /// predicate: NamedNode::new("http://example.com/p")?,
/// object: NamedNode { iri: "http://example.com/foo".into() }.into(), /// object: NamedNode::new("http://example.com/o")?.into(),
/// graph_name: NamedNode { iri: "http://example.com/".into() }.into(), /// graph_name: NamedNode::new("http://example.com/g")?.into(),
/// }.to_string() /// }.to_string()
/// ) /// );
/// # Result::<_,oxrdf::IriParseError>::Ok(())
/// ``` /// ```
#[derive(Eq, PartialEq, Debug, Clone, Hash)] #[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub struct Quad { pub struct Quad {
@ -691,13 +263,11 @@ impl Quad {
self.graph_name.fmt_sse(f)?; self.graph_name.fmt_sse(f)?;
write!(f, " (")?; write!(f, " (")?;
} }
write!(f, "(triple ")?; write!(
self.subject.fmt_sse(f)?; f,
write!(f, " ")?; "(triple {} {} {})",
self.predicate.fmt_sse(f)?; self.subject, self.predicate, self.object
write!(f, " ")?; )?;
self.object.fmt_sse(f)?;
write!(f, ")")?;
if self.graph_name != GraphName::DefaultGraph { if self.graph_name != GraphName::DefaultGraph {
write!(f, "))")?; write!(f, "))")?;
} }
@ -739,18 +309,18 @@ impl TryFrom<QuadPattern> for Quad {
/// The default string formatter is returning a N-Quads representation. /// The default string formatter is returning a N-Quads representation.
/// ///
/// ``` /// ```
/// use spargebra::term::NamedNode; /// use spargebra::term::{NamedNode, GroundQuad};
/// use spargebra::term::GroundQuad;
/// ///
/// assert_eq!( /// assert_eq!(
/// "<http://example.com/foo> <http://schema.org/sameAs> <http://example.com/foo> <http://example.com/>", /// "<http://example.com/s> <http://example.com/p> <http://example.com/o> <http://example.com/g>",
/// GroundQuad { /// GroundQuad {
/// subject: NamedNode { iri: "http://example.com/foo".into() }.into(), /// subject: NamedNode::new("http://example.com/s")?.into(),
/// predicate: NamedNode { iri: "http://schema.org/sameAs".into() }, /// predicate: NamedNode::new("http://example.com/p")?,
/// object: NamedNode { iri: "http://example.com/foo".into() }.into(), /// object: NamedNode::new("http://example.com/o")?.into(),
/// graph_name: NamedNode { iri: "http://example.com/".into() }.into(), /// graph_name: NamedNode::new("http://example.com/g")?.into(),
/// }.to_string() /// }.to_string()
/// ) /// );
/// # Result::<_,oxrdf::IriParseError>::Ok(())
/// ``` /// ```
#[derive(Eq, PartialEq, Debug, Clone, Hash)] #[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub struct GroundQuad { pub struct GroundQuad {
@ -768,13 +338,11 @@ impl GroundQuad {
self.graph_name.fmt_sse(f)?; self.graph_name.fmt_sse(f)?;
write!(f, " (")?; write!(f, " (")?;
} }
write!(f, "(triple ")?; write!(
self.subject.fmt_sse(f)?; f,
write!(f, " ")?; "(triple {} {} {})",
self.predicate.fmt_sse(f)?; self.subject, self.predicate, self.object
write!(f, " ")?; )?;
self.object.fmt_sse(f)?;
write!(f, ")")?;
if self.graph_name != GraphName::DefaultGraph { if self.graph_name != GraphName::DefaultGraph {
write!(f, "))")?; write!(f, "))")?;
} }
@ -811,35 +379,6 @@ impl TryFrom<Quad> for GroundQuad {
} }
} }
/// A [SPARQL query variable](https://www.w3.org/TR/sparql11-query/#sparqlQueryVariables).
///
/// ```
/// use spargebra::term::Variable;
///
/// assert_eq!(
/// "?foo",
/// Variable { name: "foo".into() }.to_string()
/// );
/// ```
#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Hash)]
pub struct Variable {
pub name: String,
}
impl Variable {
/// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
pub(crate) fn fmt_sse(&self, f: &mut impl Write) -> fmt::Result {
write!(f, "?{}", self.name)
}
}
impl fmt::Display for Variable {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "?{}", self.name)
}
}
/// The union of [IRIs](https://www.w3.org/TR/rdf11-concepts/#dfn-iri) and [variables](https://www.w3.org/TR/sparql11-query/#sparqlQueryVariables). /// The union of [IRIs](https://www.w3.org/TR/rdf11-concepts/#dfn-iri) and [variables](https://www.w3.org/TR/sparql11-query/#sparqlQueryVariables).
#[derive(Eq, PartialEq, Debug, Clone, Hash)] #[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub enum NamedNodePattern { pub enum NamedNodePattern {
@ -851,8 +390,8 @@ impl NamedNodePattern {
/// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html). /// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
pub(crate) fn fmt_sse(&self, f: &mut impl Write) -> fmt::Result { pub(crate) fn fmt_sse(&self, f: &mut impl Write) -> fmt::Result {
match self { match self {
Self::NamedNode(node) => node.fmt_sse(f), Self::NamedNode(node) => write!(f, "{}", node),
Self::Variable(var) => var.fmt_sse(f), Self::Variable(var) => write!(f, "{}", var),
} }
} }
} }
@ -881,6 +420,18 @@ impl From<Variable> for NamedNodePattern {
} }
} }
impl TryFrom<NamedNodePattern> for NamedNode {
type Error = ();
#[inline]
fn try_from(pattern: NamedNodePattern) -> Result<Self, ()> {
match pattern {
NamedNodePattern::NamedNode(t) => Ok(t),
NamedNodePattern::Variable(_) => Err(()),
}
}
}
/// The union of [terms](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-term) and [variables](https://www.w3.org/TR/sparql11-query/#sparqlQueryVariables). /// The union of [terms](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-term) and [variables](https://www.w3.org/TR/sparql11-query/#sparqlQueryVariables).
#[derive(Eq, PartialEq, Debug, Clone, Hash)] #[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub enum TermPattern { pub enum TermPattern {
@ -896,12 +447,12 @@ impl TermPattern {
/// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html). /// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
pub(crate) fn fmt_sse(&self, f: &mut impl Write) -> fmt::Result { pub(crate) fn fmt_sse(&self, f: &mut impl Write) -> fmt::Result {
match self { match self {
Self::NamedNode(term) => term.fmt_sse(f), Self::NamedNode(term) => write!(f, "{}", term),
Self::BlankNode(term) => term.fmt_sse(f), Self::BlankNode(term) => write!(f, "{}", term),
Self::Literal(term) => term.fmt_sse(f), Self::Literal(term) => write!(f, "{}", term),
#[cfg(feature = "rdf-star")] #[cfg(feature = "rdf-star")]
Self::Triple(triple) => triple.fmt_sse(f), Self::Triple(triple) => triple.fmt_sse(f),
Self::Variable(var) => var.fmt_sse(f), Self::Variable(var) => write!(f, "{}", var),
} }
} }
} }
@ -990,6 +541,36 @@ impl From<NamedNodePattern> for TermPattern {
} }
} }
impl TryFrom<TermPattern> for Subject {
type Error = ();
#[inline]
fn try_from(term: TermPattern) -> Result<Self, ()> {
match term {
TermPattern::NamedNode(t) => Ok(t.into()),
TermPattern::BlankNode(t) => Ok(t.into()),
#[cfg(feature = "rdf-star")]
TermPattern::Triple(t) => Ok(Triple::try_from(*t)?.into()),
TermPattern::Literal(_) | TermPattern::Variable(_) => Err(()),
}
}
}
impl TryFrom<TermPattern> for Term {
type Error = ();
#[inline]
fn try_from(pattern: TermPattern) -> Result<Self, ()> {
match pattern {
TermPattern::NamedNode(t) => Ok(t.into()),
TermPattern::BlankNode(t) => Ok(t.into()),
TermPattern::Literal(t) => Ok(t.into()),
#[cfg(feature = "rdf-star")]
TermPattern::Triple(t) => Ok(Triple::try_from(*t)?.into()),
TermPattern::Variable(_) => Err(()),
}
}
}
/// The union of [terms](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-term) and [variables](https://www.w3.org/TR/sparql11-query/#sparqlQueryVariables) without blank nodes. /// The union of [terms](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-term) and [variables](https://www.w3.org/TR/sparql11-query/#sparqlQueryVariables) without blank nodes.
#[derive(Eq, PartialEq, Debug, Clone, Hash)] #[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub enum GroundTermPattern { pub enum GroundTermPattern {
@ -1003,9 +584,9 @@ impl GroundTermPattern {
/// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html). /// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
pub(crate) fn fmt_sse(&self, f: &mut impl Write) -> fmt::Result { pub(crate) fn fmt_sse(&self, f: &mut impl Write) -> fmt::Result {
match self { match self {
Self::NamedNode(term) => term.fmt_sse(f), Self::NamedNode(term) => write!(f, "{}", term),
Self::Literal(term) => term.fmt_sse(f), Self::Literal(term) => write!(f, "{}", term),
Self::Variable(var) => var.fmt_sse(f), Self::Variable(var) => write!(f, "{}", var),
Self::Triple(triple) => triple.fmt_sse(f), Self::Triple(triple) => triple.fmt_sse(f),
} }
} }
@ -1111,9 +692,9 @@ impl GraphNamePattern {
/// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html). /// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
pub(crate) fn fmt_sse(&self, f: &mut impl Write) -> fmt::Result { pub(crate) fn fmt_sse(&self, f: &mut impl Write) -> fmt::Result {
match self { match self {
Self::NamedNode(node) => node.fmt_sse(f), Self::NamedNode(node) => write!(f, "{}", node),
Self::DefaultGraph => write!(f, "default"), Self::DefaultGraph => write!(f, "default"),
Self::Variable(var) => var.fmt_sse(f), Self::Variable(var) => write!(f, "{}", var),
} }
} }
} }
@ -1216,7 +797,20 @@ impl From<Triple> for TriplePattern {
} }
} }
/// A [triple pattern](https://www.w3.org/TR/sparql11-query/#defn_TriplePattern) without blank nodes impl TryFrom<TriplePattern> for Triple {
type Error = ();
#[inline]
fn try_from(triple: TriplePattern) -> Result<Self, ()> {
Ok(Self {
subject: triple.subject.try_into()?,
predicate: triple.predicate.try_into()?,
object: triple.object.try_into()?,
})
}
}
/// A [triple pattern](https://www.w3.org/TR/sparql11-query/#defn_TriplePattern) without blank nodes.
#[derive(Eq, PartialEq, Debug, Clone, Hash)] #[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub struct GroundTriplePattern { pub struct GroundTriplePattern {
pub subject: GroundTermPattern, pub subject: GroundTermPattern,
@ -1330,7 +924,7 @@ impl fmt::Display for QuadPattern {
} }
} }
/// A [triple pattern](https://www.w3.org/TR/sparql11-query/#defn_TriplePattern) in a specific graph without blank nodes /// A [triple pattern](https://www.w3.org/TR/sparql11-query/#defn_TriplePattern) in a specific graph without blank nodes.
#[derive(Eq, PartialEq, Debug, Clone, Hash)] #[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub struct GroundQuadPattern { pub struct GroundQuadPattern {
pub subject: GroundTermPattern, pub subject: GroundTermPattern,
@ -1389,18 +983,3 @@ impl TryFrom<QuadPattern> for GroundQuadPattern {
}) })
} }
} }
#[inline]
pub(crate) fn print_quoted_str(string: &str, f: &mut impl Write) -> fmt::Result {
f.write_char('"')?;
for c in string.chars() {
match c {
'\n' => f.write_str("\\n"),
'\r' => f.write_str("\\r"),
'"' => f.write_str("\\\""),
'\\' => f.write_str("\\\\"),
c => f.write_char(c),
}?;
}
f.write_char('"')
}

@ -191,8 +191,7 @@ impl GraphUpdateOperation {
if *silent { if *silent {
write!(f, "silent ")?; write!(f, "silent ")?;
} }
source.fmt_sse(f)?; write!(f, "{} ", source)?;
write!(f, " ")?;
destination.fmt_sse(f)?; destination.fmt_sse(f)?;
write!(f, ")") write!(f, ")")
} }
@ -209,8 +208,7 @@ impl GraphUpdateOperation {
if *silent { if *silent {
write!(f, "silent ")?; write!(f, "silent ")?;
} }
graph.fmt_sse(f)?; write!(f, "{})", graph)
write!(f, ")")
} }
GraphUpdateOperation::Drop { silent, graph } => { GraphUpdateOperation::Drop { silent, graph } => {
write!(f, "(drop ")?; write!(f, "(drop ")?;

@ -188,19 +188,11 @@ impl QueryDataset {
fn from_algebra(inner: &Option<spargebra::algebra::QueryDataset>) -> Self { fn from_algebra(inner: &Option<spargebra::algebra::QueryDataset>) -> Self {
if let Some(inner) = inner { if let Some(inner) = inner {
Self { Self {
default: Some( default: Some(inner.default.iter().map(|g| g.clone().into()).collect()),
inner named: inner
.default .named
.iter() .as_ref()
.map(|g| NamedNode::new_unchecked(&g.iri).into()) .map(|named| named.iter().map(|g| g.clone().into()).collect()),
.collect(),
),
named: inner.named.as_ref().map(|named| {
named
.iter()
.map(|g| NamedNode::new_unchecked(&g.iri).into())
.collect()
}),
} }
} else { } else {
Self { Self {

@ -52,15 +52,7 @@ pub(crate) fn evaluate_query(
options.service_handler(), options.service_handler(),
Rc::new(options.custom_functions), Rc::new(options.custom_functions),
) )
.evaluate_select_plan( .evaluate_select_plan(&plan, Rc::new(variables)))
&plan,
Rc::new(
variables
.into_iter()
.map(|v| Variable::new_unchecked(v.name))
.collect(),
),
))
} }
spargebra::Query::Ask { spargebra::Query::Ask {
pattern, base_iri, .. pattern, base_iri, ..

@ -1,9 +1,10 @@
use crate::model::{LiteralRef, NamedNode as OxNamedNode, NamedNodeRef, Term as OxTerm}; use crate::model::Term as OxTerm;
use crate::sparql::dataset::DatasetView; use crate::sparql::dataset::DatasetView;
use crate::sparql::error::EvaluationError; use crate::sparql::error::EvaluationError;
use crate::sparql::plan::*; use crate::sparql::plan::*;
use crate::storage::numeric_encoder::{EncodedTerm, EncodedTriple}; use crate::storage::numeric_encoder::{EncodedTerm, EncodedTriple};
use oxrdf::Variable as OxVariable; use oxrdf::vocab::xsd;
use oxrdf::TermRef;
use rand::random; use rand::random;
use spargebra::algebra::*; use spargebra::algebra::*;
use spargebra::term::*; use spargebra::term::*;
@ -13,7 +14,7 @@ use std::rc::Rc;
pub struct PlanBuilder<'a> { pub struct PlanBuilder<'a> {
dataset: &'a DatasetView, dataset: &'a DatasetView,
custom_functions: &'a HashMap<OxNamedNode, Rc<dyn Fn(&[OxTerm]) -> Option<OxTerm>>>, custom_functions: &'a HashMap<NamedNode, Rc<dyn Fn(&[OxTerm]) -> Option<OxTerm>>>,
} }
impl<'a> PlanBuilder<'a> { impl<'a> PlanBuilder<'a> {
@ -21,7 +22,7 @@ impl<'a> PlanBuilder<'a> {
dataset: &'a DatasetView, dataset: &'a DatasetView,
pattern: &GraphPattern, pattern: &GraphPattern,
is_cardinality_meaningful: bool, is_cardinality_meaningful: bool,
custom_functions: &'a HashMap<OxNamedNode, Rc<dyn Fn(&[OxTerm]) -> Option<OxTerm>>>, custom_functions: &'a HashMap<NamedNode, Rc<dyn Fn(&[OxTerm]) -> Option<OxTerm>>>,
) -> Result<(PlanNode, Vec<Variable>), EvaluationError> { ) -> Result<(PlanNode, Vec<Variable>), EvaluationError> {
let mut variables = Vec::default(); let mut variables = Vec::default();
let plan = PlanBuilder { let plan = PlanBuilder {
@ -49,7 +50,7 @@ impl<'a> PlanBuilder<'a> {
dataset: &'a DatasetView, dataset: &'a DatasetView,
template: &[TriplePattern], template: &[TriplePattern],
mut variables: Vec<Variable>, mut variables: Vec<Variable>,
custom_functions: &'a HashMap<OxNamedNode, Rc<dyn Fn(&[OxTerm]) -> Option<OxTerm>>>, custom_functions: &'a HashMap<NamedNode, Rc<dyn Fn(&[OxTerm]) -> Option<OxTerm>>>,
) -> Vec<TripleTemplate> { ) -> Vec<TripleTemplate> {
PlanBuilder { PlanBuilder {
dataset, dataset,
@ -168,12 +169,7 @@ impl<'a> PlanBuilder<'a> {
let service_name = self.pattern_value_from_named_node_or_variable(name, variables); let service_name = self.pattern_value_from_named_node_or_variable(name, variables);
PlanNode::Service { PlanNode::Service {
service_name, service_name,
variables: Rc::new( variables: Rc::new(variables.clone()),
variables
.iter()
.map(|v| OxVariable::new_unchecked(v.name.clone()))
.collect(),
),
child: Box::new(child), child: Box::new(child),
graph_pattern: Rc::new(inner.as_ref().clone()), graph_pattern: Rc::new(inner.as_ref().clone()),
silent: *silent, silent: *silent,
@ -295,9 +291,7 @@ impl<'a> PlanBuilder<'a> {
fn build_for_path(&mut self, path: &PropertyPathExpression) -> PlanPropertyPath { fn build_for_path(&mut self, path: &PropertyPathExpression) -> PlanPropertyPath {
match path { match path {
PropertyPathExpression::NamedNode(p) => { PropertyPathExpression::NamedNode(p) => PlanPropertyPath::Path(self.build_term(p)),
PlanPropertyPath::Path(self.build_named_node(p))
}
PropertyPathExpression::Reverse(p) => { PropertyPathExpression::Reverse(p) => {
PlanPropertyPath::Reverse(Rc::new(self.build_for_path(p))) PlanPropertyPath::Reverse(Rc::new(self.build_for_path(p)))
} }
@ -319,7 +313,7 @@ impl<'a> PlanBuilder<'a> {
PlanPropertyPath::ZeroOrOne(Rc::new(self.build_for_path(p))) PlanPropertyPath::ZeroOrOne(Rc::new(self.build_for_path(p)))
} }
PropertyPathExpression::NegatedPropertySet(p) => PlanPropertyPath::NegatedPropertySet( PropertyPathExpression::NegatedPropertySet(p) => PlanPropertyPath::NegatedPropertySet(
Rc::new(p.iter().map(|p| self.build_named_node(p)).collect()), Rc::new(p.iter().map(|p| self.build_term(p)).collect()),
), ),
} }
} }
@ -331,8 +325,8 @@ impl<'a> PlanBuilder<'a> {
graph_name: &PatternValue, graph_name: &PatternValue,
) -> Result<PlanExpression, EvaluationError> { ) -> Result<PlanExpression, EvaluationError> {
Ok(match expression { Ok(match expression {
Expression::NamedNode(node) => PlanExpression::Constant(self.build_named_node(node)), Expression::NamedNode(node) => PlanExpression::Constant(self.build_term(node)),
Expression::Literal(l) => PlanExpression::Constant(self.build_literal(l)), Expression::Literal(l) => PlanExpression::Constant(self.build_term(l)),
Expression::Variable(v) => PlanExpression::Variable(variable_key(variables, v)), Expression::Variable(v) => PlanExpression::Variable(variable_key(variables, v)),
Expression::Or(a, b) => PlanExpression::Or( Expression::Or(a, b) => PlanExpression::Or(
Box::new(self.build_for_expression(a, variables, graph_name)?), Box::new(self.build_for_expression(a, variables, graph_name)?),
@ -639,16 +633,15 @@ impl<'a> PlanBuilder<'a> {
self.build_for_expression(&parameters[0], variables, graph_name)?, self.build_for_expression(&parameters[0], variables, graph_name)?,
)), )),
Function::Custom(name) => { Function::Custom(name) => {
let ox_name = OxNamedNode::new(&name.iri).map_err(EvaluationError::wrap)?; if self.custom_functions.contains_key(name) {
if self.custom_functions.contains_key(&ox_name) {
PlanExpression::CustomFunction( PlanExpression::CustomFunction(
ox_name, name.clone(),
parameters parameters
.iter() .iter()
.map(|p| self.build_for_expression(p, variables, graph_name)) .map(|p| self.build_for_expression(p, variables, graph_name))
.collect::<Result<Vec<_>, EvaluationError>>()?, .collect::<Result<Vec<_>, EvaluationError>>()?,
) )
} else if name.iri == "http://www.w3.org/2001/XMLSchema#boolean" { } else if name.as_ref() == xsd::BOOLEAN {
self.build_cast( self.build_cast(
parameters, parameters,
PlanExpression::BooleanCast, PlanExpression::BooleanCast,
@ -656,7 +649,7 @@ impl<'a> PlanBuilder<'a> {
graph_name, graph_name,
"boolean", "boolean",
)? )?
} else if name.iri == "http://www.w3.org/2001/XMLSchema#double" { } else if name.as_ref() == xsd::DOUBLE {
self.build_cast( self.build_cast(
parameters, parameters,
PlanExpression::DoubleCast, PlanExpression::DoubleCast,
@ -664,7 +657,7 @@ impl<'a> PlanBuilder<'a> {
graph_name, graph_name,
"double", "double",
)? )?
} else if name.iri == "http://www.w3.org/2001/XMLSchema#float" { } else if name.as_ref() == xsd::FLOAT {
self.build_cast( self.build_cast(
parameters, parameters,
PlanExpression::FloatCast, PlanExpression::FloatCast,
@ -672,7 +665,7 @@ impl<'a> PlanBuilder<'a> {
graph_name, graph_name,
"float", "float",
)? )?
} else if name.iri == "http://www.w3.org/2001/XMLSchema#decimal" { } else if name.as_ref() == xsd::DECIMAL {
self.build_cast( self.build_cast(
parameters, parameters,
PlanExpression::DecimalCast, PlanExpression::DecimalCast,
@ -680,7 +673,7 @@ impl<'a> PlanBuilder<'a> {
graph_name, graph_name,
"decimal", "decimal",
)? )?
} else if name.iri == "http://www.w3.org/2001/XMLSchema#integer" { } else if name.as_ref() == xsd::INTEGER {
self.build_cast( self.build_cast(
parameters, parameters,
PlanExpression::IntegerCast, PlanExpression::IntegerCast,
@ -688,7 +681,7 @@ impl<'a> PlanBuilder<'a> {
graph_name, graph_name,
"integer", "integer",
)? )?
} else if name.iri == "http://www.w3.org/2001/XMLSchema#date" { } else if name.as_ref() == xsd::DATE {
self.build_cast( self.build_cast(
parameters, parameters,
PlanExpression::DateCast, PlanExpression::DateCast,
@ -696,7 +689,7 @@ impl<'a> PlanBuilder<'a> {
graph_name, graph_name,
"date", "date",
)? )?
} else if name.iri == "http://www.w3.org/2001/XMLSchema#time" { } else if name.as_ref() == xsd::TIME {
self.build_cast( self.build_cast(
parameters, parameters,
PlanExpression::TimeCast, PlanExpression::TimeCast,
@ -704,7 +697,7 @@ impl<'a> PlanBuilder<'a> {
graph_name, graph_name,
"time", "time",
)? )?
} else if name.iri == "http://www.w3.org/2001/XMLSchema#dateTime" { } else if name.as_ref() == xsd::DATE_TIME {
self.build_cast( self.build_cast(
parameters, parameters,
PlanExpression::DateTimeCast, PlanExpression::DateTimeCast,
@ -712,7 +705,7 @@ impl<'a> PlanBuilder<'a> {
graph_name, graph_name,
"dateTime", "dateTime",
)? )?
} else if name.iri == "http://www.w3.org/2001/XMLSchema#duration" { } else if name.as_ref() == xsd::DURATION {
self.build_cast( self.build_cast(
parameters, parameters,
PlanExpression::DurationCast, PlanExpression::DurationCast,
@ -720,7 +713,7 @@ impl<'a> PlanBuilder<'a> {
graph_name, graph_name,
"duration", "duration",
)? )?
} else if name.iri == "http://www.w3.org/2001/XMLSchema#yearMonthDuration" { } else if name.as_ref() == xsd::YEAR_MONTH_DURATION {
self.build_cast( self.build_cast(
parameters, parameters,
PlanExpression::YearMonthDurationCast, PlanExpression::YearMonthDurationCast,
@ -728,7 +721,7 @@ impl<'a> PlanBuilder<'a> {
graph_name, graph_name,
"yearMonthDuration", "yearMonthDuration",
)? )?
} else if name.iri == "http://www.w3.org/2001/XMLSchema#dayTimeDuration" { } else if name.as_ref() == xsd::DAY_TIME_DURATION {
self.build_cast( self.build_cast(
parameters, parameters,
PlanExpression::DayTimeDurationCast, PlanExpression::DayTimeDurationCast,
@ -736,7 +729,7 @@ impl<'a> PlanBuilder<'a> {
graph_name, graph_name,
"dayTimeDuration", "dayTimeDuration",
)? )?
} else if name.iri == "http://www.w3.org/2001/XMLSchema#string" { } else if name.as_ref() == xsd::STRING {
self.build_cast( self.build_cast(
parameters, parameters,
PlanExpression::StringCast, PlanExpression::StringCast,
@ -814,17 +807,15 @@ impl<'a> PlanBuilder<'a> {
TermPattern::Variable(variable) => { TermPattern::Variable(variable) => {
PatternValue::Variable(variable_key(variables, variable)) PatternValue::Variable(variable_key(variables, variable))
} }
TermPattern::NamedNode(node) => PatternValue::Constant(self.build_named_node(node)), TermPattern::NamedNode(node) => PatternValue::Constant(self.build_term(node)),
TermPattern::BlankNode(bnode) => { TermPattern::BlankNode(bnode) => {
PatternValue::Variable(variable_key( PatternValue::Variable(variable_key(
variables, variables,
&Variable { &Variable::new_unchecked(bnode.as_str()),
name: bnode.id.clone(),
},
)) ))
//TODO: very bad hack to convert bnode to variable //TODO: very bad hack to convert bnode to variable
} }
TermPattern::Literal(literal) => PatternValue::Constant(self.build_literal(literal)), TermPattern::Literal(literal) => PatternValue::Constant(self.build_term(literal)),
TermPattern::Triple(triple) => { TermPattern::Triple(triple) => {
match ( match (
self.pattern_value_from_term_or_variable(&triple.subject, variables), self.pattern_value_from_term_or_variable(&triple.subject, variables),
@ -862,7 +853,7 @@ impl<'a> PlanBuilder<'a> {
) -> PatternValue { ) -> PatternValue {
match named_node_or_variable { match named_node_or_variable {
NamedNodePattern::NamedNode(named_node) => { NamedNodePattern::NamedNode(named_node) => {
PatternValue::Constant(self.build_named_node(named_node)) PatternValue::Constant(self.build_term(named_node))
} }
NamedNodePattern::Variable(variable) => { NamedNodePattern::Variable(variable) => {
PatternValue::Variable(variable_key(variables, variable)) PatternValue::Variable(variable_key(variables, variable))
@ -888,8 +879,8 @@ impl<'a> PlanBuilder<'a> {
result.set( result.set(
bindings_variables_keys[key], bindings_variables_keys[key],
match term { match term {
GroundTerm::NamedNode(node) => self.build_named_node(node), GroundTerm::NamedNode(node) => self.build_term(node),
GroundTerm::Literal(literal) => self.build_literal(literal), GroundTerm::Literal(literal) => self.build_term(literal),
GroundTerm::Triple(triple) => self.build_triple(triple), GroundTerm::Triple(triple) => self.build_triple(triple),
}, },
); );
@ -992,14 +983,12 @@ impl<'a> PlanBuilder<'a> {
TermPattern::Variable(variable) => { TermPattern::Variable(variable) => {
TripleTemplateValue::Variable(variable_key(variables, variable)) TripleTemplateValue::Variable(variable_key(variables, variable))
} }
TermPattern::NamedNode(node) => { TermPattern::NamedNode(node) => TripleTemplateValue::Constant(self.build_term(node)),
TripleTemplateValue::Constant(self.build_named_node(node))
}
TermPattern::BlankNode(bnode) => { TermPattern::BlankNode(bnode) => {
TripleTemplateValue::BlankNode(bnode_key(bnodes, bnode)) TripleTemplateValue::BlankNode(bnode_key(bnodes, bnode))
} }
TermPattern::Literal(literal) => { TermPattern::Literal(literal) => {
TripleTemplateValue::Constant(self.build_literal(literal)) TripleTemplateValue::Constant(self.build_term(literal))
} }
TermPattern::Triple(triple) => match ( TermPattern::Triple(triple) => match (
self.template_value_from_term_or_variable(&triple.subject, variables, bnodes), self.template_value_from_term_or_variable(&triple.subject, variables, bnodes),
@ -1039,7 +1028,7 @@ impl<'a> PlanBuilder<'a> {
TripleTemplateValue::Variable(variable_key(variables, variable)) TripleTemplateValue::Variable(variable_key(variables, variable))
} }
NamedNodePattern::NamedNode(term) => { NamedNodePattern::NamedNode(term) => {
TripleTemplateValue::Constant(self.build_named_node(term)) TripleTemplateValue::Constant(self.build_term(term))
} }
} }
} }
@ -1073,9 +1062,7 @@ impl<'a> PlanBuilder<'a> {
}) { }) {
to_id to_id
} else { } else {
to.push(Variable { to.push(Variable::new_unchecked(format!("{:x}", random::<u128>())));
name: format!("{:x}", random::<u128>()),
});
to.len() - 1 to.len() - 1
} }
} }
@ -1326,34 +1313,20 @@ impl<'a> PlanBuilder<'a> {
} }
} }
fn build_named_node(&mut self, node: &NamedNode) -> EncodedTerm { fn build_term<'b>(&mut self, term: impl Into<TermRef<'b>>) -> EncodedTerm {
self.dataset self.dataset.encode_term(term)
.encode_term(NamedNodeRef::new_unchecked(node.iri.as_str()))
}
fn build_literal(&mut self, literal: &Literal) -> EncodedTerm {
self.dataset.encode_term(match literal {
Literal::Simple { value } => LiteralRef::new_simple_literal(value),
Literal::LanguageTaggedString { value, language } => {
LiteralRef::new_language_tagged_literal_unchecked(value, language.as_str())
}
Literal::Typed { value, datatype } => LiteralRef::new_typed_literal(
value,
NamedNodeRef::new_unchecked(datatype.iri.as_str()),
),
})
} }
fn build_triple(&mut self, triple: &GroundTriple) -> EncodedTerm { fn build_triple(&mut self, triple: &GroundTriple) -> EncodedTerm {
EncodedTriple::new( EncodedTriple::new(
match &triple.subject { match &triple.subject {
GroundSubject::NamedNode(node) => self.build_named_node(node), GroundSubject::NamedNode(node) => self.build_term(node),
GroundSubject::Triple(triple) => self.build_triple(triple), GroundSubject::Triple(triple) => self.build_triple(triple),
}, },
self.build_named_node(&triple.predicate), self.build_term(&triple.predicate),
match &triple.object { match &triple.object {
GroundTerm::NamedNode(node) => self.build_named_node(node), GroundTerm::NamedNode(node) => self.build_term(node),
GroundTerm::Literal(literal) => self.build_literal(literal), GroundTerm::Literal(literal) => self.build_term(literal),
GroundTerm::Triple(triple) => self.build_triple(triple), GroundTerm::Triple(triple) => self.build_triple(triple),
}, },
) )

@ -1,9 +1,6 @@
use crate::io::read::ParserError; use crate::io::read::ParserError;
use crate::io::{GraphFormat, GraphParser}; use crate::io::{GraphFormat, GraphParser};
use crate::model::{ use crate::model::{GraphName as OxGraphName, GraphNameRef, Quad as OxQuad};
BlankNode as OxBlankNode, GraphName as OxGraphName, GraphNameRef, Literal as OxLiteral,
NamedNode as OxNamedNode, NamedNodeRef, Quad as OxQuad, Term as OxTerm, Triple as OxTriple,
};
use crate::sparql::algebra::QueryDataset; use crate::sparql::algebra::QueryDataset;
use crate::sparql::dataset::DatasetView; use crate::sparql::dataset::DatasetView;
use crate::sparql::eval::SimpleEvaluator; use crate::sparql::eval::SimpleEvaluator;
@ -17,9 +14,8 @@ use oxiri::Iri;
use spargebra::algebra::{GraphPattern, GraphTarget}; use spargebra::algebra::{GraphPattern, GraphTarget};
use spargebra::term::{ use spargebra::term::{
BlankNode, GraphName, GraphNamePattern, GroundQuad, GroundQuadPattern, GroundSubject, BlankNode, GraphName, GraphNamePattern, GroundQuad, GroundQuadPattern, GroundSubject,
GroundTerm, GroundTermPattern, GroundTriple, GroundTriplePattern, Literal, NamedNode, GroundTerm, GroundTermPattern, GroundTriple, GroundTriplePattern, NamedNode, NamedNodePattern,
NamedNodePattern, Quad, QuadPattern, Subject, Term, TermPattern, Triple, TriplePattern, Quad, QuadPattern, Subject, Term, TermPattern, Triple, TriplePattern, Variable,
Variable,
}; };
use spargebra::GraphUpdateOperation; use spargebra::GraphUpdateOperation;
use std::collections::HashMap; use std::collections::HashMap;
@ -159,7 +155,7 @@ impl SimpleUpdateEvaluator<'_> {
fn eval_load(&mut self, from: &NamedNode, to: &GraphName) -> Result<(), EvaluationError> { fn eval_load(&mut self, from: &NamedNode, to: &GraphName) -> Result<(), EvaluationError> {
let (content_type, body) = self.client.get( let (content_type, body) = self.client.get(
&from.iri, from.as_str(),
"application/n-triples, text/turtle, application/rdf+xml", "application/n-triples, text/turtle, application/rdf+xml",
)?; )?;
let format = GraphFormat::from_media_type(&content_type).ok_or_else(|| { let format = GraphFormat::from_media_type(&content_type).ok_or_else(|| {
@ -169,7 +165,7 @@ impl SimpleUpdateEvaluator<'_> {
)) ))
})?; })?;
let to_graph_name = match to { let to_graph_name = match to {
GraphName::NamedNode(graph_name) => NamedNodeRef::new_unchecked(&graph_name.iri).into(), GraphName::NamedNode(graph_name) => graph_name.into(),
GraphName::DefaultGraph => GraphNameRef::DefaultGraph, GraphName::DefaultGraph => GraphNameRef::DefaultGraph,
}; };
let mut parser = GraphParser::from_format(format); let mut parser = GraphParser::from_format(format);
@ -186,7 +182,6 @@ impl SimpleUpdateEvaluator<'_> {
} }
fn eval_create(&mut self, graph_name: &NamedNode, silent: bool) -> Result<(), EvaluationError> { fn eval_create(&mut self, graph_name: &NamedNode, silent: bool) -> Result<(), EvaluationError> {
let graph_name = NamedNodeRef::new_unchecked(&graph_name.iri);
if self.transaction.insert_named_graph(graph_name.into())? || silent { if self.transaction.insert_named_graph(graph_name.into())? || silent {
Ok(()) Ok(())
} else { } else {
@ -200,11 +195,10 @@ impl SimpleUpdateEvaluator<'_> {
fn eval_clear(&mut self, graph: &GraphTarget, silent: bool) -> Result<(), EvaluationError> { fn eval_clear(&mut self, graph: &GraphTarget, silent: bool) -> Result<(), EvaluationError> {
match graph { match graph {
GraphTarget::NamedNode(graph_name) => { GraphTarget::NamedNode(graph_name) => {
let graph_name = NamedNodeRef::new_unchecked(&graph_name.iri);
if self if self
.transaction .transaction
.reader() .reader()
.contains_named_graph(&graph_name.into())? .contains_named_graph(&graph_name.as_ref().into())?
{ {
Ok(self.transaction.clear_graph(graph_name.into())?) Ok(self.transaction.clear_graph(graph_name.into())?)
} else if silent { } else if silent {
@ -228,7 +222,6 @@ impl SimpleUpdateEvaluator<'_> {
fn eval_drop(&mut self, graph: &GraphTarget, silent: bool) -> Result<(), EvaluationError> { fn eval_drop(&mut self, graph: &GraphTarget, silent: bool) -> Result<(), EvaluationError> {
match graph { match graph {
GraphTarget::NamedNode(graph_name) => { GraphTarget::NamedNode(graph_name) => {
let graph_name = NamedNodeRef::new_unchecked(&graph_name.iri);
if self.transaction.remove_named_graph(graph_name.into())? || silent { if self.transaction.remove_named_graph(graph_name.into())? || silent {
Ok(()) Ok(())
} else { } else {
@ -246,96 +239,80 @@ impl SimpleUpdateEvaluator<'_> {
} }
} }
fn convert_quad(quad: &Quad, bnodes: &mut HashMap<BlankNode, OxBlankNode>) -> OxQuad { fn convert_quad(quad: &Quad, bnodes: &mut HashMap<BlankNode, BlankNode>) -> OxQuad {
OxQuad { OxQuad {
subject: match &quad.subject { subject: match &quad.subject {
Subject::NamedNode(subject) => Self::convert_named_node(subject).into(), Subject::NamedNode(subject) => subject.clone().into(),
Subject::BlankNode(subject) => Self::convert_blank_node(subject, bnodes).into(), Subject::BlankNode(subject) => Self::convert_blank_node(subject, bnodes).into(),
Subject::Triple(subject) => Self::convert_triple(subject, bnodes).into(), Subject::Triple(subject) => Self::convert_triple(subject, bnodes).into(),
}, },
predicate: Self::convert_named_node(&quad.predicate), predicate: quad.predicate.clone(),
object: match &quad.object { object: match &quad.object {
Term::NamedNode(object) => Self::convert_named_node(object).into(), Term::NamedNode(object) => object.clone().into(),
Term::BlankNode(object) => Self::convert_blank_node(object, bnodes).into(), Term::BlankNode(object) => Self::convert_blank_node(object, bnodes).into(),
Term::Literal(object) => Self::convert_literal(object).into(), Term::Literal(object) => object.clone().into(),
Term::Triple(subject) => Self::convert_triple(subject, bnodes).into(), Term::Triple(subject) => Self::convert_triple(subject, bnodes).into(),
}, },
graph_name: match &quad.graph_name { graph_name: match &quad.graph_name {
GraphName::NamedNode(graph_name) => Self::convert_named_node(graph_name).into(), GraphName::NamedNode(graph_name) => graph_name.clone().into(),
GraphName::DefaultGraph => OxGraphName::DefaultGraph, GraphName::DefaultGraph => OxGraphName::DefaultGraph,
}, },
} }
} }
fn convert_triple(triple: &Triple, bnodes: &mut HashMap<BlankNode, OxBlankNode>) -> OxTriple { fn convert_triple(triple: &Triple, bnodes: &mut HashMap<BlankNode, BlankNode>) -> Triple {
OxTriple { Triple {
subject: match &triple.subject { subject: match &triple.subject {
Subject::NamedNode(subject) => Self::convert_named_node(subject).into(), Subject::NamedNode(subject) => subject.clone().into(),
Subject::BlankNode(subject) => Self::convert_blank_node(subject, bnodes).into(), Subject::BlankNode(subject) => Self::convert_blank_node(subject, bnodes).into(),
Subject::Triple(subject) => Self::convert_triple(subject, bnodes).into(), Subject::Triple(subject) => Self::convert_triple(subject, bnodes).into(),
}, },
predicate: Self::convert_named_node(&triple.predicate), predicate: triple.predicate.clone(),
object: match &triple.object { object: match &triple.object {
Term::NamedNode(object) => Self::convert_named_node(object).into(), Term::NamedNode(object) => object.clone().into(),
Term::BlankNode(object) => Self::convert_blank_node(object, bnodes).into(), Term::BlankNode(object) => Self::convert_blank_node(object, bnodes).into(),
Term::Literal(object) => Self::convert_literal(object).into(), Term::Literal(object) => object.clone().into(),
Term::Triple(subject) => Self::convert_triple(subject, bnodes).into(), Term::Triple(subject) => Self::convert_triple(subject, bnodes).into(),
}, },
} }
} }
fn convert_named_node(node: &NamedNode) -> OxNamedNode {
OxNamedNode::new_unchecked(&node.iri)
}
fn convert_blank_node( fn convert_blank_node(
node: &BlankNode, node: &BlankNode,
bnodes: &mut HashMap<BlankNode, OxBlankNode>, bnodes: &mut HashMap<BlankNode, BlankNode>,
) -> OxBlankNode { ) -> BlankNode {
bnodes.entry(node.clone()).or_default().clone() bnodes.entry(node.clone()).or_default().clone()
} }
fn convert_literal(literal: &Literal) -> OxLiteral {
match literal {
Literal::Simple { value } => OxLiteral::new_simple_literal(value),
Literal::LanguageTaggedString { value, language } => {
OxLiteral::new_language_tagged_literal_unchecked(value, language)
}
Literal::Typed { value, datatype } => {
OxLiteral::new_typed_literal(value, NamedNodeRef::new_unchecked(&datatype.iri))
}
}
}
fn convert_ground_quad(quad: &GroundQuad) -> OxQuad { fn convert_ground_quad(quad: &GroundQuad) -> OxQuad {
OxQuad { OxQuad {
subject: match &quad.subject { subject: match &quad.subject {
GroundSubject::NamedNode(subject) => Self::convert_named_node(subject).into(), GroundSubject::NamedNode(subject) => subject.clone().into(),
GroundSubject::Triple(subject) => Self::convert_ground_triple(subject).into(), GroundSubject::Triple(subject) => Self::convert_ground_triple(subject).into(),
}, },
predicate: Self::convert_named_node(&quad.predicate), predicate: quad.predicate.clone(),
object: match &quad.object { object: match &quad.object {
GroundTerm::NamedNode(object) => Self::convert_named_node(object).into(), GroundTerm::NamedNode(object) => object.clone().into(),
GroundTerm::Literal(object) => Self::convert_literal(object).into(), GroundTerm::Literal(object) => object.clone().into(),
GroundTerm::Triple(subject) => Self::convert_ground_triple(subject).into(), GroundTerm::Triple(subject) => Self::convert_ground_triple(subject).into(),
}, },
graph_name: match &quad.graph_name { graph_name: match &quad.graph_name {
GraphName::NamedNode(graph_name) => Self::convert_named_node(graph_name).into(), GraphName::NamedNode(graph_name) => graph_name.clone().into(),
GraphName::DefaultGraph => OxGraphName::DefaultGraph, GraphName::DefaultGraph => OxGraphName::DefaultGraph,
}, },
} }
} }
fn convert_ground_triple(triple: &GroundTriple) -> OxTriple { fn convert_ground_triple(triple: &GroundTriple) -> Triple {
OxTriple { Triple {
subject: match &triple.subject { subject: match &triple.subject {
GroundSubject::NamedNode(subject) => Self::convert_named_node(subject).into(), GroundSubject::NamedNode(subject) => subject.clone().into(),
GroundSubject::Triple(subject) => Self::convert_ground_triple(subject).into(), GroundSubject::Triple(subject) => Self::convert_ground_triple(subject).into(),
}, },
predicate: Self::convert_named_node(&triple.predicate), predicate: triple.predicate.clone(),
object: match &triple.object { object: match &triple.object {
GroundTerm::NamedNode(object) => Self::convert_named_node(object).into(), GroundTerm::NamedNode(object) => object.clone().into(),
GroundTerm::Literal(object) => Self::convert_literal(object).into(), GroundTerm::Literal(object) => object.clone().into(),
GroundTerm::Triple(subject) => Self::convert_ground_triple(subject).into(), GroundTerm::Triple(subject) => Self::convert_ground_triple(subject).into(),
}, },
} }
@ -346,7 +323,7 @@ impl SimpleUpdateEvaluator<'_> {
variables: &[Variable], variables: &[Variable],
values: &EncodedTuple, values: &EncodedTuple,
dataset: &DatasetView, dataset: &DatasetView,
bnodes: &mut HashMap<BlankNode, OxBlankNode>, bnodes: &mut HashMap<BlankNode, BlankNode>,
) -> Result<Option<OxQuad>, EvaluationError> { ) -> Result<Option<OxQuad>, EvaluationError> {
Ok(Some(OxQuad { Ok(Some(OxQuad {
subject: match Self::convert_term_or_var( subject: match Self::convert_term_or_var(
@ -356,10 +333,10 @@ impl SimpleUpdateEvaluator<'_> {
dataset, dataset,
bnodes, bnodes,
)? { )? {
Some(OxTerm::NamedNode(node)) => node.into(), Some(Term::NamedNode(node)) => node.into(),
Some(OxTerm::BlankNode(node)) => node.into(), Some(Term::BlankNode(node)) => node.into(),
Some(OxTerm::Triple(triple)) => triple.into(), Some(Term::Triple(triple)) => triple.into(),
Some(OxTerm::Literal(_)) | None => return Ok(None), Some(Term::Literal(_)) | None => return Ok(None),
}, },
predicate: if let Some(predicate) = predicate: if let Some(predicate) =
Self::convert_named_node_or_var(&quad.predicate, variables, values, dataset)? Self::convert_named_node_or_var(&quad.predicate, variables, values, dataset)?
@ -390,12 +367,12 @@ impl SimpleUpdateEvaluator<'_> {
variables: &[Variable], variables: &[Variable],
values: &EncodedTuple, values: &EncodedTuple,
dataset: &DatasetView, dataset: &DatasetView,
bnodes: &mut HashMap<BlankNode, OxBlankNode>, bnodes: &mut HashMap<BlankNode, BlankNode>,
) -> Result<Option<OxTerm>, EvaluationError> { ) -> Result<Option<Term>, EvaluationError> {
Ok(match term { Ok(match term {
TermPattern::NamedNode(term) => Some(Self::convert_named_node(term).into()), TermPattern::NamedNode(term) => Some(term.clone().into()),
TermPattern::BlankNode(bnode) => Some(Self::convert_blank_node(bnode, bnodes).into()), TermPattern::BlankNode(bnode) => Some(Self::convert_blank_node(bnode, bnodes).into()),
TermPattern::Literal(term) => Some(Self::convert_literal(term).into()), TermPattern::Literal(term) => Some(term.clone().into()),
TermPattern::Triple(triple) => { TermPattern::Triple(triple) => {
Self::convert_triple_pattern(triple, variables, values, dataset, bnodes)? Self::convert_triple_pattern(triple, variables, values, dataset, bnodes)?
.map(|t| t.into()) .map(|t| t.into())
@ -411,9 +388,9 @@ impl SimpleUpdateEvaluator<'_> {
variables: &[Variable], variables: &[Variable],
values: &EncodedTuple, values: &EncodedTuple,
dataset: &DatasetView, dataset: &DatasetView,
) -> Result<Option<OxNamedNode>, EvaluationError> { ) -> Result<Option<NamedNode>, EvaluationError> {
Ok(match term { Ok(match term {
NamedNodePattern::NamedNode(term) => Some(Self::convert_named_node(term)), NamedNodePattern::NamedNode(term) => Some(term.clone()),
NamedNodePattern::Variable(v) => Self::lookup_variable(v, variables, values) NamedNodePattern::Variable(v) => Self::lookup_variable(v, variables, values)
.map(|node| dataset.decode_named_node(&node)) .map(|node| dataset.decode_named_node(&node))
.transpose()?, .transpose()?,
@ -427,7 +404,7 @@ impl SimpleUpdateEvaluator<'_> {
dataset: &DatasetView, dataset: &DatasetView,
) -> Result<Option<OxGraphName>, EvaluationError> { ) -> Result<Option<OxGraphName>, EvaluationError> {
match term { match term {
GraphNamePattern::NamedNode(term) => Ok(Some(Self::convert_named_node(term).into())), GraphNamePattern::NamedNode(term) => Ok(Some(term.clone().into())),
GraphNamePattern::DefaultGraph => Ok(Some(OxGraphName::DefaultGraph)), GraphNamePattern::DefaultGraph => Ok(Some(OxGraphName::DefaultGraph)),
GraphNamePattern::Variable(v) => Self::lookup_variable(v, variables, values) GraphNamePattern::Variable(v) => Self::lookup_variable(v, variables, values)
.map(|node| { .map(|node| {
@ -446,9 +423,9 @@ impl SimpleUpdateEvaluator<'_> {
variables: &[Variable], variables: &[Variable],
values: &EncodedTuple, values: &EncodedTuple,
dataset: &DatasetView, dataset: &DatasetView,
bnodes: &mut HashMap<BlankNode, OxBlankNode>, bnodes: &mut HashMap<BlankNode, BlankNode>,
) -> Result<Option<OxTriple>, EvaluationError> { ) -> Result<Option<Triple>, EvaluationError> {
Ok(Some(OxTriple { Ok(Some(Triple {
subject: match Self::convert_term_or_var( subject: match Self::convert_term_or_var(
&triple.subject, &triple.subject,
variables, variables,
@ -456,10 +433,10 @@ impl SimpleUpdateEvaluator<'_> {
dataset, dataset,
bnodes, bnodes,
)? { )? {
Some(OxTerm::NamedNode(node)) => node.into(), Some(Term::NamedNode(node)) => node.into(),
Some(OxTerm::BlankNode(node)) => node.into(), Some(Term::BlankNode(node)) => node.into(),
Some(OxTerm::Triple(triple)) => triple.into(), Some(Term::Triple(triple)) => triple.into(),
Some(OxTerm::Literal(_)) | None => return Ok(None), Some(Term::Literal(_)) | None => return Ok(None),
}, },
predicate: if let Some(predicate) = predicate: if let Some(predicate) =
Self::convert_named_node_or_var(&triple.predicate, variables, values, dataset)? Self::convert_named_node_or_var(&triple.predicate, variables, values, dataset)?
@ -491,10 +468,10 @@ impl SimpleUpdateEvaluator<'_> {
values, values,
dataset, dataset,
)? { )? {
Some(OxTerm::NamedNode(node)) => node.into(), Some(Term::NamedNode(node)) => node.into(),
Some(OxTerm::BlankNode(node)) => node.into(), Some(Term::BlankNode(node)) => node.into(),
Some(OxTerm::Triple(triple)) => triple.into(), Some(Term::Triple(triple)) => triple.into(),
Some(OxTerm::Literal(_)) | None => return Ok(None), Some(Term::Literal(_)) | None => return Ok(None),
}, },
predicate: if let Some(predicate) = predicate: if let Some(predicate) =
Self::convert_named_node_or_var(&quad.predicate, variables, values, dataset)? Self::convert_named_node_or_var(&quad.predicate, variables, values, dataset)?
@ -525,10 +502,10 @@ impl SimpleUpdateEvaluator<'_> {
variables: &[Variable], variables: &[Variable],
values: &EncodedTuple, values: &EncodedTuple,
dataset: &DatasetView, dataset: &DatasetView,
) -> Result<Option<OxTerm>, EvaluationError> { ) -> Result<Option<Term>, EvaluationError> {
Ok(match term { Ok(match term {
GroundTermPattern::NamedNode(term) => Some(Self::convert_named_node(term).into()), GroundTermPattern::NamedNode(term) => Some(term.clone().into()),
GroundTermPattern::Literal(term) => Some(Self::convert_literal(term).into()), GroundTermPattern::Literal(term) => Some(term.clone().into()),
GroundTermPattern::Triple(triple) => { GroundTermPattern::Triple(triple) => {
Self::convert_ground_triple_pattern(triple, variables, values, dataset)? Self::convert_ground_triple_pattern(triple, variables, values, dataset)?
.map(|t| t.into()) .map(|t| t.into())
@ -544,18 +521,18 @@ impl SimpleUpdateEvaluator<'_> {
variables: &[Variable], variables: &[Variable],
values: &EncodedTuple, values: &EncodedTuple,
dataset: &DatasetView, dataset: &DatasetView,
) -> Result<Option<OxTriple>, EvaluationError> { ) -> Result<Option<Triple>, EvaluationError> {
Ok(Some(OxTriple { Ok(Some(Triple {
subject: match Self::convert_ground_term_or_var( subject: match Self::convert_ground_term_or_var(
&triple.subject, &triple.subject,
variables, variables,
values, values,
dataset, dataset,
)? { )? {
Some(OxTerm::NamedNode(node)) => node.into(), Some(Term::NamedNode(node)) => node.into(),
Some(OxTerm::BlankNode(node)) => node.into(), Some(Term::BlankNode(node)) => node.into(),
Some(OxTerm::Triple(triple)) => triple.into(), Some(Term::Triple(triple)) => triple.into(),
Some(OxTerm::Literal(_)) | None => return Ok(None), Some(Term::Literal(_)) | None => return Ok(None),
}, },
predicate: if let Some(predicate) = predicate: if let Some(predicate) =
Self::convert_named_node_or_var(&triple.predicate, variables, values, dataset)? Self::convert_named_node_or_var(&triple.predicate, variables, values, dataset)?

Loading…
Cancel
Save