예제 #1
0
        /// <summary>
        /// Gets the Algebra representation of the Graph Pattern
        /// </summary>
        /// <returns></returns>
        public ISparqlAlgebra ToAlgebra()
        {
            if (_isUnion)
            {
                // If this Graph Pattern represents a UNION of Graph Patterns turn into a series of UNIONs
                ISparqlAlgebra union = new Union(_graphPatterns[0].ToAlgebra(), _graphPatterns[1].ToAlgebra());
                if (_graphPatterns.Count > 2)
                {
                    for (int i = 2; i < _graphPatterns.Count; i++)
                    {
                        union = new Union(union, _graphPatterns[i].ToAlgebra());
                    }
                }
                // Apply Inline Data
                if (HasInlineData)
                {
                    union = Join.CreateJoin(union, new Bindings(_data));
                }
                // If there's a FILTER apply it over the Union
                if (_isFiltered && (_filter != null || _unplacedFilters.Count > 0))
                {
                    return(new Filter(union, Filter));
                }
                return(union);
            }

            // Terminal graph pattern
            if (_graphPatterns.Count == 0)
            {
                // If there are no Child Graph Patterns then this is a BGP
                ISparqlAlgebra bgp = new Bgp(_triplePatterns);
                if (_unplacedAssignments.Count > 0)
                {
                    // If we have any unplaced LETs these get Extended onto the BGP
                    foreach (IAssignmentPattern p in _unplacedAssignments)
                    {
                        bgp = new Extend(bgp, p.AssignExpression, p.VariableName);
                    }
                }
                if (IsGraph)
                {
                    bgp = Algebra.Graph.ApplyGraph(bgp, GraphSpecifier);
                }
                else if (IsService)
                {
                    bgp = new Service(GraphSpecifier, this, IsSilent);
                }

                // Apply Inline Data
                if (HasInlineData)
                {
                    bgp = Join.CreateJoin(bgp, new Bindings(_data));
                }
                if (_isFiltered && (_filter != null || _unplacedFilters.Count > 0))
                {
                    if (_isOptional && !(_isExists || _isNotExists))
                    {
                        // If we contain an unplaced FILTER and we're an OPTIONAL then the FILTER
                        // applies over the LEFT JOIN and will have been added elsewhere in the Algebra transform
                        return(bgp);
                    }

                    // If we contain an unplaced FILTER and we're not an OPTIONAL the FILTER
                    // applies here
                    return(new Filter(bgp, Filter));
                }
                // We're not filtered (or all FILTERs were placed in the BGP) so we're just a BGP
                return(bgp);
            }

            // Create a basic BGP to start with
            ISparqlAlgebra complex = new Bgp();

            if (_triplePatterns.Count > 0)
            {
                complex = new Bgp(_triplePatterns);
            }

            // Apply Inline Data
            // If this Graph Pattern had child patterns before this Graph Pattern then we would
            // have broken the BGP and not added the Inline Data here so it's always safe to apply this here
            if (HasInlineData)
            {
                complex = Join.CreateJoin(complex, new Bindings(_data));
            }

            // Then Join each of the Graph Patterns as appropriate
            foreach (GraphPattern gp in _graphPatterns)
            {
                if (gp.IsGraph)
                {
                    // A GRAPH clause means a Join of the current pattern to a Graph clause
                    ISparqlAlgebra gpAlgebra = gp.ToAlgebra();
                    complex = Join.CreateJoin(complex, Algebra.Graph.ApplyGraph(gpAlgebra, gp.GraphSpecifier));
                }
                else if (gp.IsOptional)
                {
                    if (gp.IsExists || gp.IsNotExists)
                    {
                        // An EXISTS/NOT EXISTS means an Exists Join of the current pattern to the EXISTS/NOT EXISTS clause
                        complex = new ExistsJoin(complex, gp.ToAlgebra(), gp.IsExists);
                    }
                    else
                    {
                        // An OPTIONAL means a Left Join of the current pattern to the OPTIONAL clause
                        // with a possible FILTER applied over the LeftJoin
                        if (gp.IsFiltered && gp.Filter != null)
                        {
                            // If the OPTIONAL clause has an unplaced FILTER it applies over the Left Join
                            complex = new LeftJoin(complex, gp.ToAlgebra(), gp.Filter);
                        }
                        else
                        {
                            complex = new LeftJoin(complex, gp.ToAlgebra());
                        }
                    }
                }
                else if (gp.IsMinus)
                {
                    // Always introduce a Minus here even if the Minus is disjoint since during evaluation we'll choose
                    // not to execute it if it's disjoint
                    complex = new Minus(complex, gp.ToAlgebra());
                }
                else if (gp.IsService)
                {
                    complex = Join.CreateJoin(complex, new Service(gp.GraphSpecifier, gp, gp.IsSilent));
                }
                else
                {
                    // Otherwise we just join the pattern to the existing pattern
                    complex = Join.CreateJoin(complex, gp.ToAlgebra());
                }
            }
            if (_unplacedAssignments.Count > 0)
            {
                // Unplaced assignments get Extended over the algebra so far here
                // complex = Join.CreateJoin(complex, new Bgp(this._unplacedAssignments.OfType<ITriplePattern>()));
                foreach (IAssignmentPattern p in _unplacedAssignments)
                {
                    complex = new Extend(complex, p.AssignExpression, p.VariableName);
                }
            }
            if (IsGraph)
            {
                complex = Algebra.Graph.ApplyGraph(complex, GraphSpecifier);
            }
            if (_isFiltered && (_filter != null || _unplacedFilters.Count > 0))
            {
                if (_isOptional && !(_isExists || _isNotExists))
                {
                    // If there's an unplaced FILTER and we're an OPTIONAL then the FILTER will
                    // apply over the LeftJoin and is applied elsewhere in the Algebra transform
                    return(complex);
                }
                else
                {
                    if (_filter != null || _unplacedFilters.Count > 0)
                    {
                        // If there's an unplaced FILTER and we're not an OPTIONAL pattern we apply
                        // the FILTER here
                        return(new Filter(complex, Filter));
                    }
                    else
                    {
                        return(complex);
                    }
                }
            }
            else
            {
                // If no FILTER just return the transform
                return(complex);
            }
        }
예제 #2
0
        /// <summary>
        /// Gets the Algebra representation of the Graph Pattern
        /// </summary>
        /// <returns></returns>
        public ISparqlAlgebra ToAlgebra()
        {
            if (this._isUnion)
            {
                //If this Graph Pattern represents a UNION of Graph Patterns turn into a series of UNIONs
                ISparqlAlgebra union = new Union(this._graphPatterns[0].ToAlgebra(), this._graphPatterns[1].ToAlgebra());
                if (this._graphPatterns.Count > 2)
                {
                    for (int i = 2; i < this._graphPatterns.Count; i++)
                    {
                        union = new Union(union, this._graphPatterns[i].ToAlgebra());
                    }
                }
                //If there's a FILTER apply it over the Union
                if (this._isFiltered && (this._filter != null || this._unplacedFilters.Count > 0))
                {
                    return(new Filter(union, this.Filter));
                }
                else
                {
                    return(union);
                }
            }
            else if (this._graphPatterns.Count == 0)
            {
                //If there are no Child Graph Patterns then this is a BGP
                ISparqlAlgebra bgp = new Bgp(this._triplePatterns);
                if (this._unplacedAssignments.Count > 0)
                {
                    //If we have any unplaced LETs these get Joined onto the BGP
                    bgp = Join.CreateJoin(bgp, new Bgp(this._unplacedAssignments));
                }
                if (this._isFiltered && (this._filter != null || this._unplacedFilters.Count > 0))
                {
                    if (this._isOptional && !(this._isExists || this._isNotExists))
                    {
                        //If we contain an unplaced FILTER and we're an OPTIONAL then the FILTER
                        //applies over the LEFT JOIN and will have been added elsewhere in the Algebra transform
                        return(bgp);
                    }
                    else
                    {
                        ISparqlAlgebra complex = bgp;

                        //If we contain an unplaced FILTER and we're not an OPTIONAL the FILTER
                        //applies here
                        return(new Filter(bgp, this.Filter));
                    }
                }
                else
                {
                    //We're not filtered (or all FILTERs were placed in the BGP) so we're just a BGP
                    return(bgp);
                }
            }
            else
            {
                //Create a basic BGP to start with
                ISparqlAlgebra complex = new Bgp();
                if (this._triplePatterns.Count > 0)
                {
                    complex = new Bgp(this._triplePatterns);
                }

                //Then Join each of the Graph Patterns as appropriate
                foreach (GraphPattern gp in this._graphPatterns)
                {
                    if (gp.IsGraph)
                    {
                        //A GRAPH clause means a Join of the current pattern to a Graph clause
                        complex = Join.CreateJoin(complex, new Algebra.Graph(gp.ToAlgebra(), gp.GraphSpecifier));
                    }
                    else if (gp.IsOptional)
                    {
                        if (gp.IsExists || gp.IsNotExists)
                        {
                            //An EXISTS/NOT EXISTS means an Exists Join of the current pattern to the EXISTS/NOT EXISTS clause
                            complex = new ExistsJoin(complex, gp.ToAlgebra(), gp.IsExists);
                        }
                        else
                        {
                            //An OPTIONAL means a Left Join of the current pattern to the OPTIONAL clause
                            //with a possible FILTER applied over the LeftJoin
                            if (gp.IsFiltered && gp.Filter != null)
                            {
                                //If the OPTIONAL clause has an unplaced FILTER it applies over the Left Join
                                complex = new LeftJoin(complex, gp.ToAlgebra(), gp.Filter);
                            }
                            else
                            {
                                complex = new LeftJoin(complex, gp.ToAlgebra());
                            }
                        }
                    }
                    else if (gp.IsMinus)
                    {
                        //Always introduce a Minus here even if the Minus is disjoint since during evaluation we'll choose
                        //not to execute it if it's disjoint
                        complex = new Minus(complex, gp.ToAlgebra());
                    }
                    else if (gp.IsService)
                    {
                        complex = Join.CreateJoin(complex, new Service(gp.GraphSpecifier, gp, gp.IsSilent));
                    }
                    else
                    {
                        //Otherwise we just join the pattern to the existing pattern
                        complex = Join.CreateJoin(complex, gp.ToAlgebra());
                    }
                }
                if (this._unplacedAssignments.Count > 0)
                {
                    //Unplaced assignments get Joined as a BGP here
                    complex = Join.CreateJoin(complex, new Bgp(this._unplacedAssignments));
                }
                if (this._isFiltered && (this._filter != null || this._unplacedFilters.Count > 0))
                {
                    if (this._isOptional && !(this._isExists || this._isNotExists))
                    {
                        //If there's an unplaced FILTER and we're an OPTIONAL then the FILTER will
                        //apply over the LeftJoin and is applied elsewhere in the Algebra transform
                        return(complex);
                    }
                    else
                    {
                        if (this._filter != null || this._unplacedFilters.Count > 0)
                        {
                            //If there's an unplaced FILTER and we're not an OPTIONAL pattern we apply
                            //the FILTER here
                            return(new Filter(complex, this.Filter));
                        }
                        else
                        {
                            return(complex);
                        }
                    }
                }
                else
                {
                    //If no FILTER just return the transform
                    return(complex);
                }
            }
        }