diff --git a/maplib/src/mapping.rs b/maplib/src/mapping.rs index 249ba81..3b28a4b 100644 --- a/maplib/src/mapping.rs +++ b/maplib/src/mapping.rs @@ -30,9 +30,9 @@ use std::collections::{HashMap, HashSet}; use std::io::Write; use std::path::Path; use std::time::Instant; +use triplestore::constants::{OBJECT_COL_NAME, SUBJECT_COL_NAME, VERB_COL_NAME}; use triplestore::{TriplesToAdd, Triplestore}; use uuid::Uuid; -use triplestore::constants::{OBJECT_COL_NAME, SUBJECT_COL_NAME, VERB_COL_NAME}; pub struct Mapping { pub template_dataset: TemplateDataset, @@ -185,8 +185,7 @@ impl Mapping { let target_template = self.resolve_template(template)?.clone(); let target_template_name = target_template.signature.template_name.as_str().to_string(); - let columns = - self.validate_infer_dataframe_columns(&target_template.signature, &df)?; + let columns = self.validate_infer_dataframe_columns(&target_template.signature, &df)?; let ExpandOptions { unique_subsets: unique_subsets_opt, } = options; @@ -368,14 +367,7 @@ impl Mapping { ok_triples.push(t?); } let mut all_triples_to_add = vec![]; - for ( - mut df, - subj_rdf_node_type, - obj_rdf_node_type, - verb, - has_unique_subset, - ) in ok_triples - { + for (mut df, subj_rdf_node_type, obj_rdf_node_type, verb, has_unique_subset) in ok_triples { let mut coltypes_names = vec![ (&subj_rdf_node_type, SUBJECT_COL_NAME), (&obj_rdf_node_type, OBJECT_COL_NAME), @@ -448,16 +440,7 @@ fn get_term_names<'a>(out_vars: &mut Vec<&'a String>, term: &'a StottrTerm) { fn create_triples( i: OTTRTripleInstance, -) -> Result< - ( - DataFrame, - RDFNodeType, - RDFNodeType, - Option, - bool, - ), - MappingError, -> { +) -> Result<(DataFrame, RDFNodeType, RDFNodeType, Option, bool), MappingError> { let OTTRTripleInstance { mut df, mut dynamic_columns, @@ -524,9 +507,7 @@ fn create_dynamic_expression_from_static( ptype: &Option, ) -> Result<(Expr, PrimitiveColumn), MappingError> { let (mut expr, _, rdf_node_type) = constant_to_expr(constant_term, ptype)?; - let mapped_column = PrimitiveColumn { - rdf_node_type, - }; + let mapped_column = PrimitiveColumn { rdf_node_type }; expr = expr.alias(column_name); Ok((expr, mapped_column)) } @@ -547,9 +528,7 @@ fn create_series_from_blank_node_constant( n_rows, )?; series.rename(column_name); - let mapped_column = PrimitiveColumn { - rdf_node_type, - }; + let mapped_column = PrimitiveColumn { rdf_node_type }; Ok((series, mapped_column)) } diff --git a/maplib/tests/test_stottr.rs b/maplib/tests/test_stottr.rs index 1e0ecfa..8a19f02 100644 --- a/maplib/tests/test_stottr.rs +++ b/maplib/tests/test_stottr.rs @@ -12,7 +12,7 @@ use polars::series::Series; use polars_core::prelude::{AnyValue, TimeUnit}; use rstest::*; use serial_test::serial; -use std::collections::{HashSet}; +use std::collections::HashSet; use std::fs::File; use std::path::PathBuf; @@ -151,16 +151,12 @@ fn test_string_language_tag_cases() { Triple { subject: Subject::NamedNode(NamedNode::new_unchecked("http://example.net/ns#anObject")), predicate: NamedNode::new_unchecked("http://example.net/ns#hasString"), - object: Term::Literal(Literal::new_simple_literal( - "one", - )), + object: Term::Literal(Literal::new_simple_literal("one")), }, Triple { subject: Subject::NamedNode(NamedNode::new_unchecked("http://example.net/ns#anObject")), predicate: NamedNode::new_unchecked("http://example.net/ns#hasString"), - object: Term::Literal(Literal::new_simple_literal( - "two" - )), + object: Term::Literal(Literal::new_simple_literal("two")), }, Triple { subject: Subject::NamedNode(NamedNode::new_unchecked( diff --git a/py_maplib/python/maplib/_maplib.pyi b/py_maplib/python/maplib/_maplib.pyi index 88c359f..42187d9 100644 --- a/py_maplib/python/maplib/_maplib.pyi +++ b/py_maplib/python/maplib/_maplib.pyi @@ -1,5 +1,5 @@ from pathlib import Path -from typing import Union, List +from typing import Union, List, Dict from polars import DataFrame from .semantic_dataframe import SemanticDataFrame @@ -82,7 +82,8 @@ class Mapping: :return: The generated template """ - def query(self, query: str) -> Union[SemanticDataFrame, List[SemanticDataFrame], None]: + def query(self, query: str, parameters: Dict[str, DataFrame] = None) -> Union[ + SemanticDataFrame, List[SemanticDataFrame], None]: """ Query the contained knowledge graph using SPARQL Currently, SELECT, CONSTRUCT and INSERT are supported. @@ -97,10 +98,11 @@ class Mapping: ... print(res.types) :param query: The SPARQL query string + :param parameters: PVALUES Parameters, a DataFrame containing the value bindings in the custom PVALUES construction. :return: DataFrame (Select), list of DataFrames (Construct) containing results, or None for Insert-queries """ - def insert(self, query: str): + def insert(self, query: str, parameters: Dict[str, DataFrame] = None, transient: bool = False): """ Insert the results of a Construct query in the graph. Useful for being able to use the same query for inspecting what will be inserted and actually inserting. @@ -119,10 +121,12 @@ class Mapping: ... m.insert(hpizzas) :param query: The SPARQL Insert query string + :param parameters: PVALUES Parameters, a DataFrame containing the value bindings in the custom PVALUES construction. + :param transient: Should the inserted triples be included in exports? :return: None """ - def insert_sprout(self, query: str): + def insert_sprout(self, query: str, parameters: Dict[str, DataFrame] = None, transient: bool = False): """ Insert the results of a Construct query in the sprouted graph. Useful for being able to use the same query for inspecting what will be inserted and actually inserting. @@ -142,6 +146,8 @@ class Mapping: ... m.insert_sprout(hpizzas) :param query: The SPARQL Insert query string + :param parameters: PVALUES Parameters, a DataFrame containing the value bindings in the custom PVALUES construction. + :param transient: Should the inserted triples be included in exports? :return: None """ diff --git a/py_maplib/src/lib.rs b/py_maplib/src/lib.rs index 28e843d..8f40083 100644 --- a/py_maplib/src/lib.rs +++ b/py_maplib/src/lib.rs @@ -43,10 +43,13 @@ use triplestore::sparql::{QueryResult as SparqlQueryResult, QueryResult}; // SOFTWARE. #[cfg(target_os = "linux")] use jemallocator::Jemalloc; +use oxrdf::vocab::xsd; use polars_core::frame::DataFrame; use polars_lazy::frame::IntoLazy; use pyo3::types::PyList; use representation::multitype::multi_col_to_string_col; +use representation::polars_to_sparql::primitive_polars_type_to_literal_type; +use representation::solution_mapping::EagerSolutionMappings; use representation::RDFNodeType; #[cfg(not(target_os = "linux"))] @@ -219,11 +222,17 @@ impl Mapping { return Ok(format!("{}", tmpl)); } - fn query(&mut self, py: Python<'_>, query: String) -> PyResult { + fn query( + &mut self, + py: Python<'_>, + query: String, + parameters: Option>, + ) -> PyResult { + let mapped_parameters = map_parameters(parameters)?; let res = self .inner .triplestore - .query(&query) + .query(&query, &mapped_parameters) .map_err(PyMaplibError::from)?; query_to_result(res, py) } @@ -241,10 +250,11 @@ impl Mapping { Ok(ValidationReport { conforms, report }) } - fn insert(&mut self, query: String, transient: Option) -> PyResult<()> { + fn insert(&mut self, query: String, parameters: Option>, transient: Option) -> PyResult<()> { + let mapped_parameters = map_parameters(parameters)?; self.inner .triplestore - .insert(&query, transient.unwrap_or(false)) + .insert(&query, &mapped_parameters, transient.unwrap_or(false)) .map_err(PyMaplibError::from)?; if self.sprout.is_some() { self.sprout.as_mut().unwrap().blank_node_counter = self.inner.blank_node_counter; @@ -252,14 +262,15 @@ impl Mapping { Ok(()) } - fn insert_sprout(&mut self, query: String, transient: Option) -> PyResult<()> { + fn insert_sprout(&mut self, query: String, parameters: Option>, transient: Option) -> PyResult<()> { + let mapped_parameters = map_parameters(parameters)?; if self.sprout.is_none() { self.create_sprout()?; } let res = self .inner .triplestore - .query(&query) + .query(&query, &mapped_parameters) .map_err(PyMaplibError::from)?; if let QueryResult::Construct(dfs_and_dts) = res { self.sprout @@ -352,3 +363,45 @@ fn query_to_result(res: SparqlQueryResult, py: Python<'_>) -> PyResult fn dtypes_map(map: HashMap) -> HashMap { map.into_iter().map(|(x, y)| (x, y.to_string())).collect() } + +fn map_parameters( + parameters: Option>, +) -> PyResult>> { + if let Some(parameters) = parameters { + let mut mapped_parameters = HashMap::new(); + for (k, pydf) in parameters { + let mut rdf_node_types = HashMap::new(); + let df = polars_df_to_rust_df(pydf)?; + let names = df.get_column_names(); + for c in df.columns(names).unwrap() { + let dt = primitive_polars_type_to_literal_type(c.dtype()).unwrap(); + + let mut rdf_node_type = None; + + if dt == xsd::STRING { + let ch = c.utf8().unwrap(); + if let Some(s) = ch.first_non_null() { + let f = ch.get(s).unwrap(); + if f.starts_with("<") { + rdf_node_type = Some(RDFNodeType::IRI); + } + } + } + + if rdf_node_type.is_none() { + rdf_node_type = Some(RDFNodeType::Literal(dt.into_owned())) + } + rdf_node_types.insert(c.name().to_string(), rdf_node_type.unwrap()); + } + let m = EagerSolutionMappings { + mappings: df, + rdf_node_types, + }; + mapped_parameters.insert(k, m); + } + + Ok(Some(mapped_parameters)) + } else { + Ok(None) + } +} diff --git a/triplestore/src/constants.rs b/triplestore/src/constants.rs index b438640..c4ea952 100644 --- a/triplestore/src/constants.rs +++ b/triplestore/src/constants.rs @@ -4,4 +4,4 @@ pub const XSD_DATE_WITHOUT_TZ_FORMAT: &str = "%Y-%m-%d"; pub const VERB_COL_NAME: &str = "verb"; pub const OBJECT_COL_NAME: &str = "object"; -pub const SUBJECT_COL_NAME: &str = "subject"; \ No newline at end of file +pub const SUBJECT_COL_NAME: &str = "subject"; diff --git a/triplestore/src/export_triples.rs b/triplestore/src/export_triples.rs index 930036e..c3509a3 100644 --- a/triplestore/src/export_triples.rs +++ b/triplestore/src/export_triples.rs @@ -1,5 +1,6 @@ use super::Triplestore; +use crate::constants::{OBJECT_COL_NAME, SUBJECT_COL_NAME}; use crate::conversion::convert_to_string; use crate::errors::TriplestoreError; use oxrdf::{Literal, NamedNode, Subject, Term, Triple}; @@ -9,7 +10,6 @@ use representation::{ literal_iri_to_namednode, RDFNodeType, TripleType, LANG_STRING_LANG_FIELD, LANG_STRING_VALUE_FIELD, }; -use crate::constants::{OBJECT_COL_NAME, SUBJECT_COL_NAME}; impl Triplestore { pub fn object_property_triples( @@ -135,7 +135,8 @@ impl Triplestore { return Ok(()); } let mut subject_iterator = df.column(SUBJECT_COL_NAME).unwrap().iter(); - let data_as_strings = convert_to_string(df.column(OBJECT_COL_NAME).unwrap()); + let data_as_strings = + convert_to_string(df.column(OBJECT_COL_NAME).unwrap()); if let Some(s) = data_as_strings { let mut data_iterator = s.iter(); for _ in 0..df.height() { diff --git a/triplestore/src/lib.rs b/triplestore/src/lib.rs index 32a3f1f..b1cf4a6 100644 --- a/triplestore/src/lib.rs +++ b/triplestore/src/lib.rs @@ -11,6 +11,7 @@ pub mod rdfs_inferencing; pub mod sparql; pub mod triples_read; +use crate::constants::{OBJECT_COL_NAME, SUBJECT_COL_NAME, VERB_COL_NAME}; use crate::errors::TriplestoreError; use crate::io_funcs::{create_folder_if_not_exists, delete_tmp_parquets_in_caching_folder}; use crate::sparql::lazy_graph_patterns::load_tt::multiple_tt_to_lf; @@ -26,16 +27,13 @@ use polars_core::frame::{DataFrame, UniqueKeepStrategy}; use polars_core::utils::concat_df; use rayon::iter::ParallelIterator; use rayon::iter::{IntoParallelRefIterator, ParallelDrainRange}; -use representation::{ - literal_iri_to_namednode, RDFNodeType, -}; +use representation::{literal_iri_to_namednode, RDFNodeType}; use std::collections::HashMap; use std::fs::remove_file; use std::io; use std::path::Path; use std::time::Instant; use uuid::Uuid; -use crate::constants::{OBJECT_COL_NAME, SUBJECT_COL_NAME, VERB_COL_NAME}; pub struct Triplestore { deduplicated: bool, diff --git a/triplestore/src/ntriples_write.rs b/triplestore/src/ntriples_write.rs index 857ec38..29e91ae 100644 --- a/triplestore/src/ntriples_write.rs +++ b/triplestore/src/ntriples_write.rs @@ -20,6 +20,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. use super::Triplestore; +use crate::constants::OBJECT_COL_NAME; use crate::conversion::convert_to_string; use crate::errors::TriplestoreError; use oxrdf::NamedNode; @@ -32,7 +33,6 @@ use polars_core::POOL; use polars_utils::contention_pool::LowContentionPool; use representation::{RDFNodeType, TripleType}; use std::io::Write; -use crate::constants::OBJECT_COL_NAME; /// Utility to write to `&mut Vec` buffer struct StringWrap<'a>(pub &'a mut Vec); diff --git a/triplestore/src/rdfs_inferencing.rs b/triplestore/src/rdfs_inferencing.rs index b85c564..824859e 100644 --- a/triplestore/src/rdfs_inferencing.rs +++ b/triplestore/src/rdfs_inferencing.rs @@ -12,7 +12,7 @@ WHERE { impl Triplestore { pub fn rdfs_class_inheritance(&mut self) -> Result<(), TriplestoreError> { - self.insert(SUBCLASS_INFERENCING, true) + self.insert(SUBCLASS_INFERENCING, &None, true) .map_err(|x| TriplestoreError::RDFSClassInheritanceError(x.to_string()))?; Ok(()) } diff --git a/triplestore/src/sparql.rs b/triplestore/src/sparql.rs index eb843c2..830451a 100644 --- a/triplestore/src/sparql.rs +++ b/triplestore/src/sparql.rs @@ -19,7 +19,7 @@ use polars_core::enable_string_cache; use polars_core::prelude::{DataType, Series, UniqueKeepStrategy}; use representation::literals::sparql_literal_to_any_value; use representation::multitype::split_df_multicols; -use representation::solution_mapping::SolutionMappings; +use representation::solution_mapping::{EagerSolutionMappings, SolutionMappings}; use representation::RDFNodeType; use spargebra::term::{NamedNodePattern, TermPattern, TriplePattern}; use spargebra::Query; @@ -31,25 +31,41 @@ pub enum QueryResult { } impl Triplestore { - pub fn query_deduplicated(&self, query: &str) -> Result { + pub fn query_deduplicated( + &self, + query: &str, + parameters: &Option>, + ) -> Result { let query = Query::parse(query, None).map_err(SparqlError::ParseError)?; - self.query_deduplicated_impl(&query) + self.query_deduplicated_impl(&query, parameters) } - pub fn query(&mut self, query: &str) -> Result { + pub fn query( + &mut self, + query: &str, + parameters: &Option>, + ) -> Result { let query = Query::parse(query, None).map_err(SparqlError::ParseError)?; - self.query_impl(&query) + self.query_impl(&query, parameters) } - fn query_impl(&mut self, query: &Query) -> Result { + fn query_impl( + &mut self, + query: &Query, + parameters: &Option>, + ) -> Result { if !self.deduplicated { self.deduplicate() .map_err(SparqlError::DeduplicationError)?; } - self.query_deduplicated_impl(query) + self.query_deduplicated_impl(query, parameters) } - fn query_deduplicated_impl(&self, query: &Query) -> Result { + fn query_deduplicated_impl( + &self, + query: &Query, + parameters: &Option>, + ) -> Result { enable_string_cache(); let context = Context::new(); match query { @@ -61,7 +77,7 @@ impl Triplestore { let SolutionMappings { mappings, rdf_node_types: types, - } = self.lazy_graph_pattern(pattern, None, &context)?; + } = self.lazy_graph_pattern(pattern, None, &context, parameters)?; let mut df = mappings.collect().unwrap(); df = cats_to_strings(df); @@ -76,7 +92,7 @@ impl Triplestore { let SolutionMappings { mappings, rdf_node_types, - } = self.lazy_graph_pattern(pattern, None, &context)?; + } = self.lazy_graph_pattern(pattern, None, &context, parameters)?; let mut df = mappings.collect().unwrap(); df = cats_to_strings(df); let mut dfs = vec![]; @@ -91,10 +107,15 @@ impl Triplestore { } } - pub fn insert(&mut self, query: &str, transient: bool) -> Result<(), SparqlError> { + pub fn insert( + &mut self, + query: &str, + parameters: &Option>, + transient: bool, + ) -> Result<(), SparqlError> { let query = Query::parse(query, None).map_err(SparqlError::ParseError)?; if let Query::Construct { .. } = &query { - let res = self.query_impl(&query)?; + let res = self.query_impl(&query, parameters)?; match res { QueryResult::Select(_, _) => { panic!("Should never happen") diff --git a/triplestore/src/sparql/errors.rs b/triplestore/src/sparql/errors.rs index 8450207..96ab398 100644 --- a/triplestore/src/sparql/errors.rs +++ b/triplestore/src/sparql/errors.rs @@ -1,5 +1,5 @@ -use query_processing::errors::QueryProcessingError; use crate::errors::TriplestoreError; +use query_processing::errors::QueryProcessingError; use representation::RDFNodeType; use spargebra::ParseError; use thiserror::Error; diff --git a/triplestore/src/sparql/lazy_aggregate.rs b/triplestore/src/sparql/lazy_aggregate.rs index dd06a8d..5e8a6c5 100644 --- a/triplestore/src/sparql/lazy_aggregate.rs +++ b/triplestore/src/sparql/lazy_aggregate.rs @@ -1,10 +1,15 @@ use super::Triplestore; use crate::sparql::errors::SparqlError; -use representation::query_context::{Context, PathEntry}; -use representation::solution_mapping::SolutionMappings; use oxrdf::Variable; -use query_processing::aggregates::{AggregateReturn, avg, count_with_expression, count_without_expression, group_concat, max, min, sample, sum}; +use polars_core::frame::DataFrame; +use query_processing::aggregates::{ + avg, count_with_expression, count_without_expression, group_concat, max, min, sample, sum, + AggregateReturn, +}; +use representation::query_context::{Context, PathEntry}; +use representation::solution_mapping::{EagerSolutionMappings, SolutionMappings}; use spargebra::algebra::AggregateExpression; +use std::collections::HashMap; impl Triplestore { pub fn sparql_aggregate_expression_as_lazy_column_and_expression( @@ -13,6 +18,7 @@ impl Triplestore { aggregate_expression: &AggregateExpression, solution_mappings: SolutionMappings, context: &Context, + parameters: &Option>, ) -> Result { let output_solution_mappings; let mut out_expr; @@ -26,12 +32,15 @@ impl Triplestore { some_expr, solution_mappings, column_context.as_ref().unwrap(), + parameters, )?; - (out_expr, out_rdf_node_type) = count_with_expression(column_context.as_ref().unwrap(), *distinct); + (out_expr, out_rdf_node_type) = + count_with_expression(column_context.as_ref().unwrap(), *distinct); } else { output_solution_mappings = solution_mappings; column_context = None; - (out_expr, out_rdf_node_type) = count_without_expression(&output_solution_mappings, *distinct); + (out_expr, out_rdf_node_type) = + count_without_expression(&output_solution_mappings, *distinct); } } AggregateExpression::Sum { expr, distinct } => { @@ -41,8 +50,13 @@ impl Triplestore { expr, solution_mappings, column_context.as_ref().unwrap(), + parameters, )?; - (out_expr, out_rdf_node_type) = sum(&output_solution_mappings, column_context.as_ref().unwrap(), *distinct); + (out_expr, out_rdf_node_type) = sum( + &output_solution_mappings, + column_context.as_ref().unwrap(), + *distinct, + ); } AggregateExpression::Avg { expr, distinct } => { column_context = Some(context.extension_with(PathEntry::AggregationOperation)); @@ -50,8 +64,13 @@ impl Triplestore { expr, solution_mappings, column_context.as_ref().unwrap(), + parameters, )?; - (out_expr, out_rdf_node_type) = avg(&output_solution_mappings, column_context.as_ref().unwrap(), *distinct); + (out_expr, out_rdf_node_type) = avg( + &output_solution_mappings, + column_context.as_ref().unwrap(), + *distinct, + ); } AggregateExpression::Min { expr, distinct: _ } => { column_context = Some(context.extension_with(PathEntry::AggregationOperation)); @@ -59,8 +78,10 @@ impl Triplestore { expr, solution_mappings, column_context.as_ref().unwrap(), + parameters, )?; - (out_expr, out_rdf_node_type) = min(&output_solution_mappings, column_context.as_ref().unwrap()); + (out_expr, out_rdf_node_type) = + min(&output_solution_mappings, column_context.as_ref().unwrap()); } AggregateExpression::Max { expr, distinct: _ } => { column_context = Some(context.extension_with(PathEntry::AggregationOperation)); @@ -69,8 +90,10 @@ impl Triplestore { expr, solution_mappings, column_context.as_ref().unwrap(), + parameters, )?; - (out_expr, out_rdf_node_type) = max(&output_solution_mappings, column_context.as_ref().unwrap()); + (out_expr, out_rdf_node_type) = + max(&output_solution_mappings, column_context.as_ref().unwrap()); } AggregateExpression::GroupConcat { expr, @@ -83,17 +106,21 @@ impl Triplestore { expr, solution_mappings, column_context.as_ref().unwrap(), + parameters, )?; - (out_expr, out_rdf_node_type) = group_concat(column_context.as_ref().unwrap(), separator, *distinct); + (out_expr, out_rdf_node_type) = + group_concat(column_context.as_ref().unwrap(), separator, *distinct); } - AggregateExpression::Sample { expr, distinct:_ } => { + AggregateExpression::Sample { expr, distinct: _ } => { column_context = Some(context.extension_with(PathEntry::AggregationOperation)); output_solution_mappings = self.lazy_expression( expr, solution_mappings, column_context.as_ref().unwrap(), + parameters, )?; - (out_expr, out_rdf_node_type) = sample(&output_solution_mappings, column_context.as_ref().unwrap()); + (out_expr, out_rdf_node_type) = + sample(&output_solution_mappings, column_context.as_ref().unwrap()); } AggregateExpression::Custom { name, @@ -112,4 +139,3 @@ impl Triplestore { }) } } - diff --git a/triplestore/src/sparql/lazy_expressions.rs b/triplestore/src/sparql/lazy_expressions.rs index 3a7441b..f6eb50f 100644 --- a/triplestore/src/sparql/lazy_expressions.rs +++ b/triplestore/src/sparql/lazy_expressions.rs @@ -3,15 +3,17 @@ use std::collections::HashMap; use crate::sparql::errors::SparqlError; use oxrdf::vocab::xsd; -use polars::prelude::{ - col, Expr, LiteralValue, Operator, -}; +use polars::prelude::{col, Expr, LiteralValue, Operator}; +use polars_core::frame::DataFrame; use query_processing::exists_helper::rewrite_exists_graph_pattern; -use query_processing::expressions::{binary_expression, bound, coalesce_expression, exists, func_expression, if_expression, in_expression, literal, named_node, not_expression, unary_minus, unary_plus, variable}; +use query_processing::expressions::{ + binary_expression, bound, coalesce_expression, exists, func_expression, if_expression, + in_expression, literal, named_node, not_expression, unary_minus, unary_plus, variable, +}; use representation::query_context::{Context, PathEntry}; -use representation::solution_mapping::SolutionMappings; +use representation::solution_mapping::{EagerSolutionMappings, SolutionMappings}; use representation::RDFNodeType; -use spargebra::algebra::{Expression}; +use spargebra::algebra::Expression; impl Triplestore { pub fn lazy_expression( @@ -19,6 +21,7 @@ impl Triplestore { expr: &Expression, solution_mappings: SolutionMappings, context: &Context, + parameters: &Option>, ) -> Result { let output_solution_mappings = match expr { Expression::NamedNode(nn) => named_node(solution_mappings, nn, context)?, @@ -27,10 +30,14 @@ impl Triplestore { Expression::Or(left, right) => { let left_context = context.extension_with(PathEntry::OrLeft); let mut output_solution_mappings = - self.lazy_expression(left, solution_mappings, &left_context)?; + self.lazy_expression(left, solution_mappings, &left_context, parameters)?; let right_context = context.extension_with(PathEntry::OrRight); - output_solution_mappings = - self.lazy_expression(right, output_solution_mappings, &right_context)?; + output_solution_mappings = self.lazy_expression( + right, + output_solution_mappings, + &right_context, + parameters, + )?; binary_expression( output_solution_mappings, Operator::Or, @@ -42,10 +49,14 @@ impl Triplestore { Expression::And(left, right) => { let left_context = context.extension_with(PathEntry::AndLeft); let mut output_solution_mappings = - self.lazy_expression(left, solution_mappings, &left_context)?; + self.lazy_expression(left, solution_mappings, &left_context, parameters)?; let right_context = context.extension_with(PathEntry::AndRight); - output_solution_mappings = - self.lazy_expression(right, output_solution_mappings, &right_context)?; + output_solution_mappings = self.lazy_expression( + right, + output_solution_mappings, + &right_context, + parameters, + )?; binary_expression( output_solution_mappings, Operator::And, @@ -57,10 +68,14 @@ impl Triplestore { Expression::Equal(left, right) => { let left_context = context.extension_with(PathEntry::EqualLeft); let mut output_solution_mappings = - self.lazy_expression(left, solution_mappings, &left_context)?; + self.lazy_expression(left, solution_mappings, &left_context, parameters)?; let right_context = context.extension_with(PathEntry::EqualRight); - output_solution_mappings = - self.lazy_expression(right, output_solution_mappings, &right_context)?; + output_solution_mappings = self.lazy_expression( + right, + output_solution_mappings, + &right_context, + parameters, + )?; binary_expression( output_solution_mappings, Operator::Eq, @@ -75,10 +90,14 @@ impl Triplestore { Expression::Greater(left, right) => { let left_context = context.extension_with(PathEntry::GreaterLeft); let mut output_solution_mappings = - self.lazy_expression(left, solution_mappings, &left_context)?; + self.lazy_expression(left, solution_mappings, &left_context, parameters)?; let right_context = context.extension_with(PathEntry::GreaterRight); - output_solution_mappings = - self.lazy_expression(right, output_solution_mappings, &right_context)?; + output_solution_mappings = self.lazy_expression( + right, + output_solution_mappings, + &right_context, + parameters, + )?; binary_expression( output_solution_mappings, Operator::Gt, @@ -90,10 +109,14 @@ impl Triplestore { Expression::GreaterOrEqual(left, right) => { let left_context = context.extension_with(PathEntry::GreaterOrEqualLeft); let mut output_solution_mappings = - self.lazy_expression(left, solution_mappings, &left_context)?; + self.lazy_expression(left, solution_mappings, &left_context, parameters)?; let right_context = context.extension_with(PathEntry::GreaterOrEqualRight); - output_solution_mappings = - self.lazy_expression(right, output_solution_mappings, &right_context)?; + output_solution_mappings = self.lazy_expression( + right, + output_solution_mappings, + &right_context, + parameters, + )?; binary_expression( output_solution_mappings, @@ -106,10 +129,14 @@ impl Triplestore { Expression::Less(left, right) => { let left_context = context.extension_with(PathEntry::LessLeft); let mut output_solution_mappings = - self.lazy_expression(left, solution_mappings, &left_context)?; + self.lazy_expression(left, solution_mappings, &left_context, parameters)?; let right_context = context.extension_with(PathEntry::LessRight); - output_solution_mappings = - self.lazy_expression(right, output_solution_mappings, &right_context)?; + output_solution_mappings = self.lazy_expression( + right, + output_solution_mappings, + &right_context, + parameters, + )?; binary_expression( output_solution_mappings, Operator::Lt, @@ -121,10 +148,14 @@ impl Triplestore { Expression::LessOrEqual(left, right) => { let left_context = context.extension_with(PathEntry::LessOrEqualLeft); let mut output_solution_mappings = - self.lazy_expression(left, solution_mappings, &left_context)?; + self.lazy_expression(left, solution_mappings, &left_context, parameters)?; let right_context = context.extension_with(PathEntry::LessOrEqualRight); - output_solution_mappings = - self.lazy_expression(right, output_solution_mappings, &right_context)?; + output_solution_mappings = self.lazy_expression( + right, + output_solution_mappings, + &right_context, + parameters, + )?; binary_expression( output_solution_mappings, Operator::LtEq, @@ -139,22 +170,35 @@ impl Triplestore { .map(|i| context.extension_with(PathEntry::InRight(i as u16))) .collect(); let mut output_solution_mappings = - self.lazy_expression(left, solution_mappings, &left_context)?; + self.lazy_expression(left, solution_mappings, &left_context, parameters)?; for i in 0..right.len() { let expr = right.get(i).unwrap(); let expr_context = right_contexts.get(i).unwrap(); - output_solution_mappings = - self.lazy_expression(expr, output_solution_mappings, expr_context)?; + output_solution_mappings = self.lazy_expression( + expr, + output_solution_mappings, + expr_context, + parameters, + )?; } - in_expression(output_solution_mappings, &left_context, &right_contexts, &context)? + in_expression( + output_solution_mappings, + &left_context, + &right_contexts, + &context, + )? } Expression::Add(left, right) => { let left_context = context.extension_with(PathEntry::AddLeft); let mut output_solution_mappings = - self.lazy_expression(left, solution_mappings, &left_context)?; + self.lazy_expression(left, solution_mappings, &left_context, parameters)?; let right_context = context.extension_with(PathEntry::AddRight); - output_solution_mappings = - self.lazy_expression(right, output_solution_mappings, &right_context)?; + output_solution_mappings = self.lazy_expression( + right, + output_solution_mappings, + &right_context, + parameters, + )?; binary_expression( output_solution_mappings, Operator::Plus, @@ -166,10 +210,14 @@ impl Triplestore { Expression::Subtract(left, right) => { let left_context = context.extension_with(PathEntry::SubtractLeft); let mut output_solution_mappings = - self.lazy_expression(left, solution_mappings, &left_context)?; + self.lazy_expression(left, solution_mappings, &left_context, parameters)?; let right_context = context.extension_with(PathEntry::SubtractRight); - output_solution_mappings = - self.lazy_expression(right, output_solution_mappings, &right_context)?; + output_solution_mappings = self.lazy_expression( + right, + output_solution_mappings, + &right_context, + parameters, + )?; binary_expression( output_solution_mappings, Operator::Minus, @@ -181,10 +229,14 @@ impl Triplestore { Expression::Multiply(left, right) => { let left_context = context.extension_with(PathEntry::MultiplyLeft); let mut output_solution_mappings = - self.lazy_expression(left, solution_mappings, &left_context)?; + self.lazy_expression(left, solution_mappings, &left_context, parameters)?; let right_context = context.extension_with(PathEntry::MultiplyRight); - output_solution_mappings = - self.lazy_expression(right, output_solution_mappings, &right_context)?; + output_solution_mappings = self.lazy_expression( + right, + output_solution_mappings, + &right_context, + parameters, + )?; binary_expression( output_solution_mappings, Operator::Multiply, @@ -196,10 +248,14 @@ impl Triplestore { Expression::Divide(left, right) => { let left_context = context.extension_with(PathEntry::DivideLeft); let mut output_solution_mappings = - self.lazy_expression(left, solution_mappings, &left_context)?; + self.lazy_expression(left, solution_mappings, &left_context, parameters)?; let right_context = context.extension_with(PathEntry::DivideRight); - output_solution_mappings = - self.lazy_expression(right, output_solution_mappings, &right_context)?; + output_solution_mappings = self.lazy_expression( + right, + output_solution_mappings, + &right_context, + parameters, + )?; binary_expression( output_solution_mappings, @@ -213,19 +269,19 @@ impl Triplestore { let plus_context = context.extension_with(PathEntry::UnaryPlus); let output_solution_mappings = - self.lazy_expression(inner, solution_mappings, &plus_context)?; + self.lazy_expression(inner, solution_mappings, &plus_context, parameters)?; unary_plus(output_solution_mappings, &plus_context, context)? } Expression::UnaryMinus(inner) => { let minus_context = context.extension_with(PathEntry::UnaryMinus); let output_solution_mappings = - self.lazy_expression(inner, solution_mappings, &minus_context)?; + self.lazy_expression(inner, solution_mappings, &minus_context, parameters)?; unary_minus(output_solution_mappings, &minus_context, &context)? } Expression::Not(inner) => { let not_context = context.extension_with(PathEntry::Not); let output_solution_mappings = - self.lazy_expression(inner, solution_mappings, ¬_context)?; + self.lazy_expression(inner, solution_mappings, ¬_context, parameters)?; not_expression(output_solution_mappings, ¬_context, &context)? } Expression::Exists(inner) => { @@ -249,6 +305,7 @@ impl Triplestore { &new_inner, Some(output_solution_mappings.clone()), &exists_context, + parameters, )?; exists( output_solution_mappings, @@ -257,20 +314,32 @@ impl Triplestore { &context, )? } - Expression::Bound(v) => { - bound(solution_mappings, v, &context)? - } + Expression::Bound(v) => bound(solution_mappings, v, &context)?, Expression::If(left, middle, right) => { let left_context = context.extension_with(PathEntry::IfLeft); let mut output_solution_mappings = - self.lazy_expression(left, solution_mappings, &left_context)?; + self.lazy_expression(left, solution_mappings, &left_context, parameters)?; let middle_context = context.extension_with(PathEntry::IfMiddle); - output_solution_mappings = - self.lazy_expression(middle, output_solution_mappings, &middle_context)?; + output_solution_mappings = self.lazy_expression( + middle, + output_solution_mappings, + &middle_context, + parameters, + )?; let right_context = context.extension_with(PathEntry::IfRight); - output_solution_mappings = - self.lazy_expression(right, output_solution_mappings, &right_context)?; - if_expression(output_solution_mappings, &left_context, &middle_context, &right_context, &context)? + output_solution_mappings = self.lazy_expression( + right, + output_solution_mappings, + &right_context, + parameters, + )?; + if_expression( + output_solution_mappings, + &left_context, + &middle_context, + &right_context, + &context, + )? } Expression::Coalesce(inner) => { let inner_contexts: Vec = (0..inner.len()) @@ -283,6 +352,7 @@ impl Triplestore { inner.get(i).unwrap(), output_solution_mappings, inner_context, + parameters, )?; } @@ -297,10 +367,17 @@ impl Triplestore { args.get(i).unwrap(), output_solution_mappings, &arg_context, + parameters, )?; args_contexts.insert(i, arg_context); } - func_expression(output_solution_mappings, func, args, args_contexts, &context)? + func_expression( + output_solution_mappings, + func, + args, + args_contexts, + &context, + )? } }; Ok(output_solution_mappings) diff --git a/triplestore/src/sparql/lazy_graph_patterns.rs b/triplestore/src/sparql/lazy_graph_patterns.rs index 67de6f1..ab3ab84 100644 --- a/triplestore/src/sparql/lazy_graph_patterns.rs +++ b/triplestore/src/sparql/lazy_graph_patterns.rs @@ -9,16 +9,19 @@ mod minus; mod order_by; mod path; mod project; +mod pvalues; mod triple; mod union; mod values; use super::Triplestore; use crate::sparql::errors::SparqlError; -use representation::query_context::{Context, PathEntry}; -use representation::solution_mapping::SolutionMappings; use log::{debug, info}; +use polars_core::frame::DataFrame; +use representation::query_context::{Context, PathEntry}; +use representation::solution_mapping::{EagerSolutionMappings, SolutionMappings}; use spargebra::algebra::GraphPattern; +use std::collections::HashMap; impl Triplestore { pub fn lazy_graph_pattern( @@ -26,6 +29,7 @@ impl Triplestore { graph_pattern: &GraphPattern, solution_mappings: Option, context: &Context, + parameters: &Option>, ) -> Result { debug!("Processing graph pattern at context: {}", context.as_str()); @@ -48,18 +52,25 @@ impl Triplestore { object, } => self.lazy_path(subject, path, object, solution_mappings, context), GraphPattern::Join { left, right } => { - self.lazy_join(left, right, solution_mappings, context) + self.lazy_join(left, right, solution_mappings, context, parameters) } GraphPattern::LeftJoin { left, right, expression, - } => self.lazy_left_join(left, right, expression, solution_mappings, context), + } => self.lazy_left_join( + left, + right, + expression, + solution_mappings, + context, + parameters, + ), GraphPattern::Filter { expr, inner } => { - self.lazy_filter(inner, expr, solution_mappings, context) + self.lazy_filter(inner, expr, solution_mappings, context, parameters) } GraphPattern::Union { left, right } => { - self.lazy_union(left, right, solution_mappings, context) + self.lazy_union(left, right, solution_mappings, context, parameters) } GraphPattern::Graph { name: _, inner: _ } => { unimplemented!("Graphs not supported") @@ -68,22 +79,29 @@ impl Triplestore { inner, variable, expression, - } => self.lazy_extend(inner, variable, expression, solution_mappings, context), + } => self.lazy_extend( + inner, + variable, + expression, + solution_mappings, + context, + parameters, + ), GraphPattern::Minus { left, right } => { - self.lazy_minus(left, right, solution_mappings, context) + self.lazy_minus(left, right, solution_mappings, context, parameters) } GraphPattern::Values { variables, bindings, } => self.lazy_values(solution_mappings, variables, bindings, context), GraphPattern::OrderBy { inner, expression } => { - self.lazy_order_by(inner, expression, solution_mappings, context) + self.lazy_order_by(inner, expression, solution_mappings, context, parameters) } GraphPattern::Project { inner, variables } => { - self.lazy_project(inner, variables, solution_mappings, context) + self.lazy_project(inner, variables, solution_mappings, context, parameters) } GraphPattern::Distinct { inner } => { - self.lazy_distinct(inner, solution_mappings, context) + self.lazy_distinct(inner, solution_mappings, context, parameters) } GraphPattern::Reduced { inner } => { info!("Reduced has no practical effect in this implementation"); @@ -91,6 +109,7 @@ impl Triplestore { inner, solution_mappings, &context.extension_with(PathEntry::ReducedInner), + parameters, ) } GraphPattern::Slice { @@ -102,6 +121,7 @@ impl Triplestore { inner, solution_mappings, &context.extension_with(PathEntry::ReducedInner), + parameters, )?; if let Some(length) = length { newsols.mappings = newsols.mappings.slice(*start as i64, *length as u32); @@ -114,11 +134,30 @@ impl Triplestore { inner, variables, aggregates, - } => self.lazy_group(inner, variables, aggregates, solution_mappings, context), + } => self.lazy_group( + inner, + variables, + aggregates, + solution_mappings, + context, + parameters, + ), GraphPattern::Service { .. } => { unimplemented!("Services are not implemented") } - GraphPattern::DT { .. } => {panic!()} + GraphPattern::DT { .. } => { + panic!() + } + GraphPattern::PValues { + variables, + bindings_parameter, + } => self.lazy_pvalues( + solution_mappings, + variables, + bindings_parameter, + context, + parameters, + ), } } } diff --git a/triplestore/src/sparql/lazy_graph_patterns/distinct.rs b/triplestore/src/sparql/lazy_graph_patterns/distinct.rs index d197b48..b765e95 100644 --- a/triplestore/src/sparql/lazy_graph_patterns/distinct.rs +++ b/triplestore/src/sparql/lazy_graph_patterns/distinct.rs @@ -1,10 +1,11 @@ use super::Triplestore; use crate::sparql::errors::SparqlError; -use representation::query_context::{Context, PathEntry}; -use representation::solution_mapping::SolutionMappings; use log::debug; use query_processing::graph_patterns::distinct; +use representation::query_context::{Context, PathEntry}; +use representation::solution_mapping::{EagerSolutionMappings, SolutionMappings}; use spargebra::algebra::GraphPattern; +use std::collections::HashMap; impl Triplestore { pub(crate) fn lazy_distinct( @@ -12,12 +13,14 @@ impl Triplestore { inner: &GraphPattern, solution_mappings: Option, context: &Context, + parameters: &Option>, ) -> Result { debug!("Processing distinct graph pattern"); let solution_mappings = self.lazy_graph_pattern( inner, solution_mappings, &context.extension_with(PathEntry::DistinctInner), + parameters, )?; Ok(distinct(solution_mappings)?) } diff --git a/triplestore/src/sparql/lazy_graph_patterns/extend.rs b/triplestore/src/sparql/lazy_graph_patterns/extend.rs index 19b6c20..79e1f26 100644 --- a/triplestore/src/sparql/lazy_graph_patterns/extend.rs +++ b/triplestore/src/sparql/lazy_graph_patterns/extend.rs @@ -1,11 +1,13 @@ use super::Triplestore; use crate::sparql::errors::SparqlError; -use representation::query_context::{Context, PathEntry}; -use representation::solution_mapping::SolutionMappings; use log::debug; use oxrdf::Variable; +use polars_core::frame::DataFrame; use query_processing::graph_patterns::extend; +use representation::query_context::{Context, PathEntry}; +use representation::solution_mapping::{EagerSolutionMappings, SolutionMappings}; use spargebra::algebra::{Expression, GraphPattern}; +use std::collections::HashMap; impl Triplestore { pub(crate) fn lazy_extend( @@ -15,16 +17,25 @@ impl Triplestore { expression: &Expression, input_solution_mappings: Option, context: &Context, + parameters: &Option>, ) -> Result { debug!("Processing extend graph pattern"); let inner_context = context.extension_with(PathEntry::ExtendInner); let expression_context = context.extension_with(PathEntry::ExtendExpression); let mut output_solution_mappings = - self.lazy_graph_pattern(inner, input_solution_mappings, &inner_context)?; + self.lazy_graph_pattern(inner, input_solution_mappings, &inner_context, parameters)?; - output_solution_mappings = - self.lazy_expression(expression, output_solution_mappings, &expression_context)?; - Ok(extend(output_solution_mappings, &expression_context, variable)?) + output_solution_mappings = self.lazy_expression( + expression, + output_solution_mappings, + &expression_context, + parameters, + )?; + Ok(extend( + output_solution_mappings, + &expression_context, + variable, + )?) } } diff --git a/triplestore/src/sparql/lazy_graph_patterns/filter.rs b/triplestore/src/sparql/lazy_graph_patterns/filter.rs index 8f56c86..a364919 100644 --- a/triplestore/src/sparql/lazy_graph_patterns/filter.rs +++ b/triplestore/src/sparql/lazy_graph_patterns/filter.rs @@ -1,10 +1,12 @@ use super::Triplestore; use crate::sparql::errors::SparqlError; -use representation::query_context::{Context, PathEntry}; -use representation::solution_mapping::SolutionMappings; use log::debug; +use polars_core::frame::DataFrame; use query_processing::graph_patterns::filter; +use representation::query_context::{Context, PathEntry}; +use representation::solution_mapping::{EagerSolutionMappings, SolutionMappings}; use spargebra::algebra::{Expression, GraphPattern}; +use std::collections::HashMap; impl Triplestore { pub(crate) fn lazy_filter( @@ -13,14 +15,20 @@ impl Triplestore { expression: &Expression, input_solution_mappings: Option, context: &Context, + parameters: &Option>, ) -> Result { debug!("Processing filter graph pattern"); let inner_context = context.extension_with(PathEntry::FilterInner); let expression_context = context.extension_with(PathEntry::FilterExpression); let mut output_solution_mappings = - self.lazy_graph_pattern(inner, input_solution_mappings, &inner_context)?; - output_solution_mappings = self.lazy_expression(expression, output_solution_mappings, &expression_context)?; + self.lazy_graph_pattern(inner, input_solution_mappings, &inner_context, parameters)?; + output_solution_mappings = self.lazy_expression( + expression, + output_solution_mappings, + &expression_context, + parameters, + )?; Ok(filter(output_solution_mappings, &expression_context)?) } } diff --git a/triplestore/src/sparql/lazy_graph_patterns/group.rs b/triplestore/src/sparql/lazy_graph_patterns/group.rs index 2fb529f..717d988 100644 --- a/triplestore/src/sparql/lazy_graph_patterns/group.rs +++ b/triplestore/src/sparql/lazy_graph_patterns/group.rs @@ -1,13 +1,14 @@ use super::Triplestore; use crate::sparql::errors::SparqlError; -use query_processing::aggregates::AggregateReturn; -use representation::query_context::{Context, PathEntry}; -use representation::solution_mapping::SolutionMappings; use log::debug; use oxrdf::Variable; +use polars_core::frame::DataFrame; +use query_processing::aggregates::AggregateReturn; +use query_processing::graph_patterns::{group_by, prepare_group_by}; +use representation::query_context::{Context, PathEntry}; +use representation::solution_mapping::{EagerSolutionMappings, SolutionMappings}; use spargebra::algebra::{AggregateExpression, GraphPattern}; use std::collections::HashMap; -use query_processing::graph_patterns::{group_by, prepare_group_by}; impl Triplestore { pub(crate) fn lazy_group( @@ -17,12 +18,14 @@ impl Triplestore { aggregates: &Vec<(Variable, AggregateExpression)>, solution_mapping: Option, context: &Context, + parameters: &Option>, ) -> Result { debug!("Processing group graph pattern"); let inner_context = context.extension_with(PathEntry::GroupInner); let output_solution_mappings = - self.lazy_graph_pattern(inner, solution_mapping, &inner_context)?; - let (mut output_solution_mappings, by, dummy_varname) = prepare_group_by(output_solution_mappings, variables); + self.lazy_graph_pattern(inner, solution_mapping, &inner_context, parameters)?; + let (mut output_solution_mappings, by, dummy_varname) = + prepare_group_by(output_solution_mappings, variables); let mut aggregate_expressions = vec![]; let mut new_rdf_node_types = HashMap::new(); @@ -40,11 +43,18 @@ impl Triplestore { a, output_solution_mappings, &aggregate_context, + parameters, )?; output_solution_mappings = aggregate_solution_mappings; new_rdf_node_types.insert(v.as_str().to_string(), rdf_node_type); aggregate_expressions.push(expr); } - Ok(group_by(output_solution_mappings, aggregate_expressions, by, dummy_varname, new_rdf_node_types)?) + Ok(group_by( + output_solution_mappings, + aggregate_expressions, + by, + dummy_varname, + new_rdf_node_types, + )?) } } diff --git a/triplestore/src/sparql/lazy_graph_patterns/join.rs b/triplestore/src/sparql/lazy_graph_patterns/join.rs index ce68409..3743124 100644 --- a/triplestore/src/sparql/lazy_graph_patterns/join.rs +++ b/triplestore/src/sparql/lazy_graph_patterns/join.rs @@ -1,8 +1,10 @@ use super::Triplestore; use crate::sparql::errors::SparqlError; -use representation::query_context::{Context, PathEntry}; -use representation::solution_mapping::{SolutionMappings}; use log::debug; +use polars_core::frame::DataFrame; +use representation::query_context::{Context, PathEntry}; +use representation::solution_mapping::{EagerSolutionMappings, SolutionMappings}; +use std::collections::HashMap; use spargebra::algebra::GraphPattern; @@ -13,17 +15,19 @@ impl Triplestore { right: &GraphPattern, solution_mappings: Option, context: &Context, + parameters: &Option>, ) -> Result { debug!("Processing join graph pattern"); let left_context = context.extension_with(PathEntry::JoinLeftSide); let right_context = context.extension_with(PathEntry::JoinRightSide); let mut output_solution_mappings = - self.lazy_graph_pattern(left, solution_mappings, &left_context)?; + self.lazy_graph_pattern(left, solution_mappings, &left_context, parameters)?; output_solution_mappings = self.lazy_graph_pattern( right, Some(output_solution_mappings), &right_context, + parameters, )?; Ok(output_solution_mappings) } diff --git a/triplestore/src/sparql/lazy_graph_patterns/left_join.rs b/triplestore/src/sparql/lazy_graph_patterns/left_join.rs index 6d34b4b..1587e34 100644 --- a/triplestore/src/sparql/lazy_graph_patterns/left_join.rs +++ b/triplestore/src/sparql/lazy_graph_patterns/left_join.rs @@ -1,10 +1,12 @@ use super::Triplestore; use crate::sparql::errors::SparqlError; -use representation::query_context::{Context, PathEntry}; -use representation::solution_mapping::{SolutionMappings}; use log::debug; +use polars_core::frame::DataFrame; use query_processing::graph_patterns::{filter, left_join}; +use representation::query_context::{Context, PathEntry}; +use representation::solution_mapping::{EagerSolutionMappings, SolutionMappings}; use spargebra::algebra::{Expression, GraphPattern}; +use std::collections::HashMap; impl Triplestore { pub fn lazy_left_join( @@ -14,6 +16,7 @@ impl Triplestore { expression: &Option, solution_mappings: Option, context: &Context, + parameters: &Option>, ) -> Result { debug!("Processing left join graph pattern"); let left_context = context.extension_with(PathEntry::LeftJoinLeftSide); @@ -21,14 +24,22 @@ impl Triplestore { let expression_context = context.extension_with(PathEntry::LeftJoinExpression); let left_solution_mappings = - self.lazy_graph_pattern(left, solution_mappings, &left_context)?; + self.lazy_graph_pattern(left, solution_mappings, &left_context, parameters)?; - let mut right_solution_mappings = - self.lazy_graph_pattern(right, Some(left_solution_mappings.clone()), &right_context)?; + let mut right_solution_mappings = self.lazy_graph_pattern( + right, + Some(left_solution_mappings.clone()), + &right_context, + parameters, + )?; if let Some(expr) = expression { - right_solution_mappings = - self.lazy_expression(expr, right_solution_mappings, &expression_context)?; + right_solution_mappings = self.lazy_expression( + expr, + right_solution_mappings, + &expression_context, + parameters, + )?; right_solution_mappings = filter(right_solution_mappings, &expression_context)?; } Ok(left_join(left_solution_mappings, right_solution_mappings)?) diff --git a/triplestore/src/sparql/lazy_graph_patterns/load_tt.rs b/triplestore/src/sparql/lazy_graph_patterns/load_tt.rs index 0a0797f..9d9ef91 100644 --- a/triplestore/src/sparql/lazy_graph_patterns/load_tt.rs +++ b/triplestore/src/sparql/lazy_graph_patterns/load_tt.rs @@ -1,10 +1,10 @@ +use crate::constants::{OBJECT_COL_NAME, SUBJECT_COL_NAME}; use crate::sparql::errors::SparqlError; -use representation::multitype::convert_lf_col_to_multitype; use crate::TripleTable; use polars::prelude::{col, concat, Expr, IntoLazy, LazyFrame, UnionArgs}; +use representation::multitype::convert_lf_col_to_multitype; use representation::RDFNodeType; use std::collections::{HashMap, HashSet}; -use crate::constants::{OBJECT_COL_NAME, SUBJECT_COL_NAME}; fn single_tt_to_lf(tt: &TripleTable) -> Result { assert!(tt.unique, "Should be deduplicated"); diff --git a/triplestore/src/sparql/lazy_graph_patterns/minus.rs b/triplestore/src/sparql/lazy_graph_patterns/minus.rs index dcf8654..c02bacf 100644 --- a/triplestore/src/sparql/lazy_graph_patterns/minus.rs +++ b/triplestore/src/sparql/lazy_graph_patterns/minus.rs @@ -1,10 +1,12 @@ use super::Triplestore; use crate::sparql::errors::SparqlError; use log::debug; +use polars_core::frame::DataFrame; use query_processing::graph_patterns::minus; use representation::query_context::{Context, PathEntry}; -use representation::solution_mapping::{SolutionMappings}; +use representation::solution_mapping::{EagerSolutionMappings, SolutionMappings}; use spargebra::algebra::GraphPattern; +use std::collections::HashMap; impl Triplestore { pub(crate) fn lazy_minus( @@ -13,15 +15,16 @@ impl Triplestore { right: &GraphPattern, solution_mappings: Option, context: &Context, + parameters: &Option>, ) -> Result { debug!("Processing minus graph pattern"); let left_context = context.extension_with(PathEntry::MinusLeftSide); let right_context = context.extension_with(PathEntry::MinusRightSide); let left_solution_mappings = - self.lazy_graph_pattern(left, solution_mappings.clone(), &left_context)?; + self.lazy_graph_pattern(left, solution_mappings.clone(), &left_context, parameters)?; let right_solution_mappings = - self.lazy_graph_pattern(right, solution_mappings, &right_context)?; + self.lazy_graph_pattern(right, solution_mappings, &right_context, parameters)?; Ok(minus(left_solution_mappings, right_solution_mappings)?) } diff --git a/triplestore/src/sparql/lazy_graph_patterns/order_by.rs b/triplestore/src/sparql/lazy_graph_patterns/order_by.rs index a2b6578..afea513 100644 --- a/triplestore/src/sparql/lazy_graph_patterns/order_by.rs +++ b/triplestore/src/sparql/lazy_graph_patterns/order_by.rs @@ -1,10 +1,12 @@ use super::Triplestore; use crate::sparql::errors::SparqlError; -use representation::query_context::{Context, PathEntry}; -use representation::solution_mapping::SolutionMappings; use log::debug; +use polars_core::frame::DataFrame; use query_processing::graph_patterns::order_by; +use representation::query_context::{Context, PathEntry}; +use representation::solution_mapping::{EagerSolutionMappings, SolutionMappings}; use spargebra::algebra::{GraphPattern, OrderExpression}; +use std::collections::HashMap; impl Triplestore { pub(crate) fn lazy_order_by( @@ -13,12 +15,14 @@ impl Triplestore { expression: &Vec, solution_mappings: Option, context: &Context, + parameters: &Option>, ) -> Result { debug!("Processing order by graph pattern"); let mut output_solution_mappings = self.lazy_graph_pattern( inner, solution_mappings, &context.extension_with(PathEntry::OrderByInner), + parameters, )?; let SolutionMappings { @@ -41,11 +45,16 @@ impl Triplestore { expression.get(i).unwrap(), output_solution_mappings, order_expression_contexts.get(i).unwrap(), + parameters, )?; output_solution_mappings = ordering_solution_mappings; inner_contexts.push(inner_context); asc_ordering.push(reverse); } - Ok(order_by(output_solution_mappings, &inner_contexts, asc_ordering)?) + Ok(order_by( + output_solution_mappings, + &inner_contexts, + asc_ordering, + )?) } } diff --git a/triplestore/src/sparql/lazy_graph_patterns/path.rs b/triplestore/src/sparql/lazy_graph_patterns/path.rs index bb68f71..1bd064d 100644 --- a/triplestore/src/sparql/lazy_graph_patterns/path.rs +++ b/triplestore/src/sparql/lazy_graph_patterns/path.rs @@ -1,12 +1,6 @@ use super::Triplestore; use crate::sparql::errors::SparqlError; use crate::sparql::lazy_graph_patterns::load_tt::multiple_tt_to_lf; -use representation::multitype::{convert_lf_col_to_multitype, multi_col_to_string_col}; -use representation::query_context::{Context, PathEntry}; -use representation::solution_mapping::SolutionMappings; -use representation::sparql_to_polars::{ - sparql_literal_to_polars_literal_value, sparql_named_node_to_polars_literal_value, -}; use oxrdf::{NamedNode, Variable}; use polars::prelude::{col, lit, DataFrameJoinOps, Expr, IntoLazy}; use polars::prelude::{ChunkAgg, JoinArgs, JoinType}; @@ -14,6 +8,12 @@ use polars_core::datatypes::{AnyValue, DataType}; use polars_core::frame::{DataFrame, UniqueKeepStrategy}; use polars_core::series::{IntoSeries, Series}; use polars_core::utils::concat_df; +use representation::multitype::{convert_lf_col_to_multitype, multi_col_to_string_col}; +use representation::query_context::{Context, PathEntry}; +use representation::solution_mapping::SolutionMappings; +use representation::sparql_to_polars::{ + sparql_literal_to_polars_literal_value, sparql_named_node_to_polars_literal_value, +}; use representation::RDFNodeType; use spargebra::algebra::{GraphPattern, PropertyPathExpression}; use spargebra::term::{NamedNodePattern, TermPattern, TriplePattern}; @@ -68,6 +68,7 @@ impl Triplestore { &gp, solution_mappings, &context.extension_with(PathEntry::PathRewrite), + &None, )?; let select: Vec<_> = var_cols.iter().map(|x| col(x)).collect(); sms.mappings = sms.mappings.select(select); @@ -815,4 +816,4 @@ fn sparse_path( todo!() } } -} \ No newline at end of file +} diff --git a/triplestore/src/sparql/lazy_graph_patterns/project.rs b/triplestore/src/sparql/lazy_graph_patterns/project.rs index d6b15b6..b582a5a 100644 --- a/triplestore/src/sparql/lazy_graph_patterns/project.rs +++ b/triplestore/src/sparql/lazy_graph_patterns/project.rs @@ -1,11 +1,13 @@ use super::Triplestore; use crate::sparql::errors::SparqlError; -use representation::query_context::{Context, PathEntry}; -use representation::solution_mapping::SolutionMappings; -use log::{debug}; +use log::debug; use oxrdf::Variable; -use spargebra::algebra::GraphPattern; +use polars_core::frame::DataFrame; use query_processing::graph_patterns::project; +use representation::query_context::{Context, PathEntry}; +use representation::solution_mapping::{EagerSolutionMappings, SolutionMappings}; +use spargebra::algebra::GraphPattern; +use std::collections::HashMap; impl Triplestore { pub(crate) fn lazy_project( @@ -14,12 +16,14 @@ impl Triplestore { variables: &Vec, solution_mappings: Option, context: &Context, + parameters: &Option>, ) -> Result { debug!("Processing project graph pattern"); let solution_mappings = self.lazy_graph_pattern( inner, solution_mappings, &context.extension_with(PathEntry::ProjectInner), + parameters, )?; Ok(project(solution_mappings, variables)?) } diff --git a/triplestore/src/sparql/lazy_graph_patterns/pvalues.rs b/triplestore/src/sparql/lazy_graph_patterns/pvalues.rs new file mode 100644 index 0000000..75a6993 --- /dev/null +++ b/triplestore/src/sparql/lazy_graph_patterns/pvalues.rs @@ -0,0 +1,50 @@ +use super::Triplestore; +use crate::sparql::errors::SparqlError; +use oxrdf::Variable; +use polars::prelude::IntoLazy; +use polars_core::frame::DataFrame; +use query_processing::graph_patterns::join; +use representation::query_context::Context; +use representation::solution_mapping::{EagerSolutionMappings, SolutionMappings}; +use representation::sparql_to_polars::{ + polars_literal_values_to_series, sparql_literal_to_polars_literal_value, + sparql_named_node_to_polars_literal_value, +}; +use representation::RDFNodeType; +use spargebra::term::GroundTerm; +use std::collections::HashMap; + +impl Triplestore { + pub(crate) fn lazy_pvalues( + &self, + solution_mappings: Option, + variables: &Vec, + bindings_name: &String, + _context: &Context, + parameters: &Option>, + ) -> Result { + let sm = if let Some(parameters) = parameters { + if let Some(EagerSolutionMappings { + mappings, + rdf_node_types, + }) = parameters.get(bindings_name) + { + //Todo! Check that variables are in df.. + SolutionMappings { + mappings: mappings.clone().lazy(), + rdf_node_types: rdf_node_types.clone(), + } + } else { + todo!("Handle this error.. ") + } + } else { + todo!("Handle this error") + }; + if let Some(mut mappings) = solution_mappings { + mappings = join(mappings, sm)?; + Ok(mappings) + } else { + Ok(sm) + } + } +} diff --git a/triplestore/src/sparql/lazy_graph_patterns/triple.rs b/triplestore/src/sparql/lazy_graph_patterns/triple.rs index 1d9f397..3d8257f 100644 --- a/triplestore/src/sparql/lazy_graph_patterns/triple.rs +++ b/triplestore/src/sparql/lazy_graph_patterns/triple.rs @@ -6,10 +6,8 @@ use representation::sparql_to_polars::{ sparql_literal_to_polars_literal_value, sparql_named_node_to_polars_literal_value, }; +use crate::constants::{OBJECT_COL_NAME, SUBJECT_COL_NAME}; use crate::sparql::lazy_graph_patterns::load_tt::multiple_tt_to_lf; -use representation::multitype::{ - convert_lf_col_to_multitype, create_join_compatible_solution_mappings, join_workaround, -}; use log::debug; use oxrdf::vocab::xsd; use oxrdf::NamedNode; @@ -18,10 +16,12 @@ use polars::prelude::{IntoLazy, UnionArgs}; use polars_core::datatypes::{AnyValue, DataType}; use polars_core::frame::DataFrame; use polars_core::series::Series; +use representation::multitype::{ + convert_lf_col_to_multitype, create_join_compatible_solution_mappings, join_workaround, +}; use representation::{literal_iri_to_namednode, RDFNodeType}; use spargebra::term::{NamedNodePattern, TermPattern, TriplePattern}; use std::collections::HashMap; -use crate::constants::{OBJECT_COL_NAME, SUBJECT_COL_NAME}; impl Triplestore { pub fn lazy_triple_pattern( @@ -206,7 +206,7 @@ impl Triplestore { let use_object_col_name = uuid::Uuid::new_v4().to_string(); lf = lf.rename( [SUBJECT_COL_NAME, OBJECT_COL_NAME], - [&use_subject_col_name, &use_object_col_name] + [&use_subject_col_name, &use_object_col_name], ); let mut drop = vec![]; diff --git a/triplestore/src/sparql/lazy_graph_patterns/union.rs b/triplestore/src/sparql/lazy_graph_patterns/union.rs index dd8854d..cbcf956 100644 --- a/triplestore/src/sparql/lazy_graph_patterns/union.rs +++ b/triplestore/src/sparql/lazy_graph_patterns/union.rs @@ -1,10 +1,12 @@ use super::Triplestore; use crate::sparql::errors::SparqlError; -use representation::query_context::{Context, PathEntry}; -use representation::solution_mapping::SolutionMappings; use log::debug; +use polars_core::frame::DataFrame; use query_processing::graph_patterns::union; +use representation::query_context::{Context, PathEntry}; +use representation::solution_mapping::{EagerSolutionMappings, SolutionMappings}; use spargebra::algebra::GraphPattern; +use std::collections::HashMap; impl Triplestore { pub(crate) fn lazy_union( @@ -13,13 +15,16 @@ impl Triplestore { right: &GraphPattern, solution_mappings: Option, context: &Context, + parameters: &Option>, ) -> Result { debug!("Processing union graph pattern"); let left_context = context.extension_with(PathEntry::UnionLeftSide); let right_context = context.extension_with(PathEntry::UnionRightSide); - let left_solution_mappings = self.lazy_graph_pattern(left, solution_mappings.clone(), &left_context)?; - let right_solution_mappings = self.lazy_graph_pattern(right, solution_mappings, &right_context)?; + let left_solution_mappings = + self.lazy_graph_pattern(left, solution_mappings.clone(), &left_context, parameters)?; + let right_solution_mappings = + self.lazy_graph_pattern(right, solution_mappings, &right_context, parameters)?; Ok(union(left_solution_mappings, right_solution_mappings)?) } } diff --git a/triplestore/src/sparql/lazy_graph_patterns/values.rs b/triplestore/src/sparql/lazy_graph_patterns/values.rs index d2b61f2..9e689d1 100644 --- a/triplestore/src/sparql/lazy_graph_patterns/values.rs +++ b/triplestore/src/sparql/lazy_graph_patterns/values.rs @@ -1,15 +1,18 @@ use super::Triplestore; use crate::sparql::errors::SparqlError; -use representation::query_context::Context; -use representation::solution_mapping::SolutionMappings; -use oxrdf::{Variable}; -use polars::prelude::{IntoLazy}; +use oxrdf::Variable; +use polars::prelude::IntoLazy; use polars_core::frame::DataFrame; +use query_processing::graph_patterns::join; +use representation::query_context::Context; +use representation::solution_mapping::{EagerSolutionMappings, SolutionMappings}; +use representation::sparql_to_polars::{ + polars_literal_values_to_series, sparql_literal_to_polars_literal_value, + sparql_named_node_to_polars_literal_value, +}; use representation::RDFNodeType; use spargebra::term::GroundTerm; use std::collections::HashMap; -use query_processing::graph_patterns::join; -use representation::sparql_to_polars::{polars_literal_values_to_series, sparql_literal_to_polars_literal_value, sparql_named_node_to_polars_literal_value}; impl Triplestore { pub(crate) fn lazy_values( @@ -55,7 +58,9 @@ impl Triplestore { } sparql_literal_to_polars_literal_value(l) } - _ => {todo!()} + _ => { + todo!() + } }; col_vecs.get_mut(&j).unwrap().push(t); if i + 1 == bindings.len() { @@ -76,7 +81,10 @@ impl Triplestore { let var = variables.get(k).unwrap(); rdf_node_types.insert(var.as_str().to_string(), v); } - let sm = SolutionMappings{ mappings:df.lazy(), rdf_node_types }; + let sm = SolutionMappings { + mappings: df.lazy(), + rdf_node_types, + }; if let Some(mut mappings) = solution_mappings { mappings = join(mappings, sm)?; diff --git a/triplestore/src/sparql/lazy_order.rs b/triplestore/src/sparql/lazy_order.rs index 09ed01a..82d2558 100644 --- a/triplestore/src/sparql/lazy_order.rs +++ b/triplestore/src/sparql/lazy_order.rs @@ -1,8 +1,10 @@ use super::Triplestore; use crate::sparql::errors::SparqlError; +use polars_core::frame::DataFrame; use representation::query_context::{Context, PathEntry}; -use representation::solution_mapping::SolutionMappings; +use representation::solution_mapping::{EagerSolutionMappings, SolutionMappings}; use spargebra::algebra::OrderExpression; +use std::collections::HashMap; impl Triplestore { pub fn lazy_order_expression( @@ -10,12 +12,13 @@ impl Triplestore { oexpr: &OrderExpression, solution_mappings: SolutionMappings, context: &Context, + parameters: &Option>, ) -> Result<(SolutionMappings, bool, Context), SparqlError> { match oexpr { OrderExpression::Asc(expr) => { let inner_context = context.extension_with(PathEntry::OrderingOperation); Ok(( - self.lazy_expression(expr, solution_mappings, &inner_context)?, + self.lazy_expression(expr, solution_mappings, &inner_context, parameters)?, true, inner_context, )) @@ -23,7 +26,7 @@ impl Triplestore { OrderExpression::Desc(expr) => { let inner_context = context.extension_with(PathEntry::OrderingOperation); Ok(( - self.lazy_expression(expr, solution_mappings, &inner_context)?, + self.lazy_expression(expr, solution_mappings, &inner_context, parameters)?, false, inner_context, )) diff --git a/triplestore/src/triples_read.rs b/triplestore/src/triples_read.rs index 417f694..7b72e1f 100644 --- a/triplestore/src/triples_read.rs +++ b/triplestore/src/triples_read.rs @@ -3,6 +3,7 @@ use crate::errors::TriplestoreError; use crate::TriplesToAdd; use oxiri::Iri; +use crate::constants::{OBJECT_COL_NAME, SUBJECT_COL_NAME}; use oxrdf::vocab::xsd; use oxrdf::NamedNode; use polars_core::frame::DataFrame; @@ -15,7 +16,6 @@ use std::collections::HashMap; use std::fs::File; use std::io::BufReader; use std::path::Path; -use crate::constants::{OBJECT_COL_NAME, SUBJECT_COL_NAME}; impl Triplestore { pub fn read_triples(