Ejemplo n.º 1
0
        /// <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");
            }
        }
Ejemplo n.º 2
0
        /// <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");
            }
        }