/// <summary> /// Processes a Select Distinct Graphs /// </summary> /// <param name="selDistGraphs">Select Distinct Graphs</param> /// <param name="context">SPARQL Evaluation Context</param> public virtual BaseMultiset ProcessSelectDistinctGraphs(SelectDistinctGraphs selDistGraphs, SparqlEvaluationContext context) { if (context == null) { context = this.GetContext(); } return(selDistGraphs.Evaluate(context)); }
/// <summary> /// Processes a Select Distinct Graphs. /// </summary> /// <param name="selDistGraphs">Select Distinct Graphs.</param> /// <param name="context">SPARQL Evaluation Context.</param> public override BaseMultiset ProcessSelectDistinctGraphs(SelectDistinctGraphs selDistGraphs, SparqlEvaluationContext context) { return(ExplainAndEvaluate <SelectDistinctGraphs>(selDistGraphs, context, base.ProcessSelectDistinctGraphs)); }
/// <summary> /// Converts the Query into it's SPARQL Algebra representation (as represented in the Leviathan API) /// </summary> /// <returns></returns> public ISparqlAlgebra ToAlgebra() { //Firstly Transform the Root Graph Pattern to SPARQL Algebra ISparqlAlgebra pattern; if (this._rootGraphPattern != null) { if (Options.AlgebraOptimisation) { //If using Algebra Optimisation may use a special algebra in some cases switch (this.SpecialType) { case SparqlSpecialQueryType.DistinctGraphs: pattern = new SelectDistinctGraphs(this.Variables.First(v => v.IsResultVariable).Name); break; case SparqlSpecialQueryType.AskAnyTriples: pattern = new AskAnyTriples(); break; case SparqlSpecialQueryType.NotApplicable: default: //If not just use the standard transform pattern = this._rootGraphPattern.ToAlgebra(); break; } } else { //If not using Algebra Optimisation just use the standard transform pattern = this._rootGraphPattern.ToAlgebra(); } } else { pattern = new Bgp(); } //If we have a BINDINGS clause then we'll add it into the algebra here if (this._bindings != null) { pattern = new Bindings(this._bindings, pattern); } //Then we apply any optimisers followed by relevant solution modifiers switch (this._type) { case SparqlQueryType.Ask: //Apply Algebra Optimisation is enabled if (Options.AlgebraOptimisation) { pattern = this.ApplyAlgebraOptimisations(pattern); } return(new Ask(pattern)); case SparqlQueryType.Construct: case SparqlQueryType.Describe: case SparqlQueryType.DescribeAll: case SparqlQueryType.Select: case SparqlQueryType.SelectAll: case SparqlQueryType.SelectAllDistinct: case SparqlQueryType.SelectAllReduced: case SparqlQueryType.SelectDistinct: case SparqlQueryType.SelectReduced: //Apply Algebra Optimisation if enabled if (Options.AlgebraOptimisation) { pattern = this.ApplyAlgebraOptimisations(pattern); } //GROUP BY is the first thing applied if (this._groupBy != null) { pattern = new GroupBy(pattern, this._groupBy); } //After grouping we do projection //This will generate the values for any Project Expressions and Aggregates pattern = new Project(pattern, this.Variables); //Add HAVING clause after the projection if (this._having != null) { pattern = new Having(pattern, this._having); } //We can then Order our results //We do ordering before we do Select but after Project so we can order by any of //the project expressions/aggregates and any variable in the results even if //it won't be output as a result variable if (this._orderBy != null) { pattern = new OrderBy(pattern, this._orderBy); } //After Ordering we apply Select //Select effectively trims the results so only result variables are left //This doesn't apply to CONSTRUCT since any variable may be used in the Construct Template //so we don't want to eliminate anything if (this._type != SparqlQueryType.Construct) { pattern = new Select(pattern, this.Variables); } //If we have a Distinct/Reduced then we'll apply those after Selection if (this._type == SparqlQueryType.SelectAllDistinct || this._type == SparqlQueryType.SelectDistinct) { pattern = new Distinct(pattern); } else if (this._type == SparqlQueryType.SelectAllReduced || this._type == SparqlQueryType.SelectReduced) { pattern = new Reduced(pattern); } //Finally we can apply any limit and/or offset if (this._limit >= 0 || this._offset > 0) { pattern = new Slice(pattern, this._limit, this._offset); } return(pattern); default: throw new RdfQueryException("Unable to convert unknown Query Types to SPARQL Algebra"); } }
/// <summary> /// Converts the Query into it's SPARQL Algebra representation (as represented in the Leviathan API) /// </summary> /// <returns></returns> public ISparqlAlgebra ToAlgebra() { //Depending on how the query gets built we may not have had graph pattern optimization applied //which we should do here if query optimization is enabled if (!this.IsOptimised && Options.QueryOptimisation) { this.Optimise(); } //Firstly Transform the Root Graph Pattern to SPARQL Algebra ISparqlAlgebra algebra; if (this._rootGraphPattern != null) { if (Options.AlgebraOptimisation) { //If using Algebra Optimisation may use a special algebra in some cases switch (this.SpecialType) { case SparqlSpecialQueryType.DistinctGraphs: algebra = new SelectDistinctGraphs(this.Variables.First(v => v.IsResultVariable).Name); break; case SparqlSpecialQueryType.AskAnyTriples: algebra = new AskAnyTriples(); break; case SparqlSpecialQueryType.NotApplicable: default: //If not just use the standard transform algebra = this._rootGraphPattern.ToAlgebra(); break; } } else { //If not using Algebra Optimisation just use the standard transform algebra = this._rootGraphPattern.ToAlgebra(); } } else { //No root graph pattern means empty BGP algebra = new Bgp(); } //If we have a top level VALUES clause then we'll add it into the algebra here if (this._bindings != null) { algebra = Join.CreateJoin(algebra, new Bindings(this._bindings)); } //Then we apply any optimisers followed by relevant solution modifiers switch (this._type) { case SparqlQueryType.Ask: //Apply Algebra Optimisation is enabled if (Options.AlgebraOptimisation) { algebra = this.ApplyAlgebraOptimisations(algebra); } return(new Ask(algebra)); case SparqlQueryType.Construct: case SparqlQueryType.Describe: case SparqlQueryType.DescribeAll: case SparqlQueryType.Select: case SparqlQueryType.SelectAll: case SparqlQueryType.SelectAllDistinct: case SparqlQueryType.SelectAllReduced: case SparqlQueryType.SelectDistinct: case SparqlQueryType.SelectReduced: //Apply Algebra Optimisation if enabled if (Options.AlgebraOptimisation) { algebra = this.ApplyAlgebraOptimisations(algebra); } //GROUP BY is the first thing applied //This applies if there is a GROUP BY or if there are aggregates //With no GROUP BY it produces a single group of all results if (this._groupBy != null || this._vars.Any(v => v.IsAggregate)) { algebra = new GroupBy(algebra, this._groupBy, this._vars.Where(v => v.IsAggregate)); } //After grouping we do projection //We introduce an Extend for each Project Expression foreach (SparqlVariable var in this._vars) { if (var.IsProjection) { algebra = new Extend(algebra, var.Projection, var.Name); } } //Add HAVING clause after the projection if (this._having != null) { algebra = new Having(algebra, this._having); } //We can then Order our results //We do ordering before we do Select but after Project so we can order by any of //the project expressions/aggregates and any variable in the results even if //it won't be output as a result variable if (this._orderBy != null) { algebra = new OrderBy(algebra, this._orderBy); } //After Ordering we apply Select //Select effectively trims the results so only result variables are left //This doesn't apply to CONSTRUCT since any variable may be used in the Construct Template //so we don't want to eliminate anything if (this._type != SparqlQueryType.Construct) { algebra = new Select(algebra, this.Variables); } //If we have a Distinct/Reduced then we'll apply those after Selection if (this._type == SparqlQueryType.SelectAllDistinct || this._type == SparqlQueryType.SelectDistinct) { algebra = new Distinct(algebra); } else if (this._type == SparqlQueryType.SelectAllReduced || this._type == SparqlQueryType.SelectReduced) { algebra = new Reduced(algebra); } //Finally we can apply any limit and/or offset if (this._limit >= 0 || this._offset > 0) { algebra = new Slice(algebra, this._limit, this._offset); } return(algebra); default: throw new RdfQueryException("Unable to convert unknown Query Types to SPARQL Algebra"); } }