Пример #1
0
        /// <summary>
        /// Creates a new DELETE command which operates on the Default Graph
        /// </summary>
        /// <param name="deletions">Pattern to construct Triples to delete</param>
        /// <param name="where">Pattern to select data which is then used in evaluating the deletions pattern</param>
        public DeleteCommand(GraphPattern deletions, GraphPattern where)
            : base(SparqlUpdateCommandType.Delete)
        {
            if (!this.IsValidDeletePattern(deletions, true)) throw new SparqlUpdateException("Cannot create a DELETE command where any of the Triple Patterns are not constructable triple patterns (Blank Node Variables are not permitted) or a GRAPH clause has nested Graph Patterns");

            this._deletePattern = deletions;
            this._wherePattern = where;
        }
Пример #2
0
        /// <summary>
        /// Creates a new INSERT command
        /// </summary>
        /// <param name="insertions">Pattern to construct Triples to insert</param>
        /// <param name="where">Pattern to select data which is then used in evaluating the insertions</param>
        /// <param name="graphUri">URI of the affected Graph</param>
        public InsertCommand(GraphPattern insertions, GraphPattern where, Uri graphUri)
            : base(SparqlUpdateCommandType.Insert) 
        {
            this._insertPattern = insertions;
            this._wherePattern = where;
            this._graphUri = graphUri;

            //Optimise the WHERE
            this._wherePattern.Optimise();
        }
Пример #3
0
        /// <summary>
        /// Creates a new INSERT/DELETE command
        /// </summary>
        /// <param name="deletions">Pattern to construct Triples to delete</param>
        /// <param name="insertions">Pattern to construct Triples to insert</param>
        /// <param name="where">Pattern to select data which is then used in evaluating the insertions and deletions</param>
        /// <param name="graphUri">URI of the affected Graph</param>
        public ModifyCommand(GraphPattern deletions, GraphPattern insertions, GraphPattern where, Uri graphUri)
            : base(SparqlUpdateCommandType.Modify)
        {
            if (!this.IsValidDeletePattern(deletions, true)) throw new SparqlUpdateException("Cannot create a DELETE command where any of the Triple Patterns are not constructable triple patterns (Blank Node Variables are not permitted) or a GRAPH clause has nested Graph Patterns");

            this._deletePattern = deletions;
            this._insertPattern = insertions;
            this._wherePattern = where;
            this._graphUri = graphUri;

            //Optimise the WHERE
            this._wherePattern.Optimise();
        }
Пример #4
0
 /// <summary>
 /// Adds a Triple Pattern to the Graph Pattern respecting any BGP breaks
 /// </summary>
 /// <param name="p">Triple Pattern</param>
 internal void AddTriplePattern(ITriplePattern p)
 {
     if (_break)
     {
         if (_broken)
         {
             _graphPatterns.Last().AddTriplePattern(p);
         }
         else
         {
             GraphPattern breakPattern = new GraphPattern();
             breakPattern.AddTriplePattern(p);
             _graphPatterns.Add(breakPattern);
         }
     }
     else
     {
         _triplePatterns.Add(p);
     }
 }
Пример #5
0
 /// <summary>
 /// Determines whether a Graph Pattern is valid for use in an DELETE DATA command
 /// </summary>
 /// <param name="p">Graph Pattern</param>
 /// <param name="top">Is this the top level pattern?</param>
 /// <returns></returns>
 private bool IsValidDataPattern(GraphPattern p, bool top)
 {
     if (p.IsGraph)
     {
         //If a GRAPH clause then all triple patterns must be constructable and have no Child Graph Patterns
         return !p.HasChildGraphPatterns && p.TriplePatterns.All(tp => tp is IConstructTriplePattern && ((IConstructTriplePattern)tp).HasNoVariables);
     }
     else if (p.IsExists || p.IsMinus || p.IsNotExists || p.IsOptional || p.IsService || p.IsSubQuery || p.IsUnion)
     {
         //EXISTS/MINUS/NOT EXISTS/OPTIONAL/SERVICE/Sub queries/UNIONs are not permitted
         return false;
     }
     else
     {
         //For other patterns all Triple patterns must be constructable with no explicit variables
         //If top level then any Child Graph Patterns must be valid
         //Otherwise must have no Child Graph Patterns
         return p.TriplePatterns.All(tp => tp is IConstructTriplePattern && ((IConstructTriplePattern)tp).HasNoVariables) && ((top && p.ChildGraphPatterns.All(gp => IsValidDataPattern(gp, false))) || !p.HasChildGraphPatterns);
     }
 }
Пример #6
0
 internal GraphPattern(GraphPattern gp)
 {
     this._break  = gp._break;
     this._broken = gp._broken;
     this._filter = gp._filter;
     this._graphPatterns.AddRange(gp._graphPatterns);
     this._graphSpecifier = gp._graphSpecifier;
     this._isExists       = gp._isExists;
     this._isFiltered     = gp._isFiltered;
     this._isGraph        = gp._isGraph;
     this._isMinus        = gp._isMinus;
     this._isNotExists    = gp._isExists;
     this._isOptimised    = gp._isOptimised;
     this._isOptional     = gp._isOptional;
     this._isService      = gp._isService;
     this._isSilent       = gp._isSilent;
     this._isUnion        = gp._isUnion;
     this._triplePatterns.AddRange(gp._triplePatterns);
     this._unplacedAssignments.AddRange(gp._unplacedAssignments);
     this._unplacedFilters.AddRange(gp._unplacedFilters);
 }
Пример #7
0
 /// <summary>
 /// Adds an Assignment to the Graph Pattern respecting any BGP breaks
 /// </summary>
 /// <param name="p">Assignment Pattern</param>
 internal void AddAssignment(IAssignmentPattern p)
 {
     if (this._break)
     {
         if (this._broken)
         {
             this._graphPatterns.Last().AddAssignment(p);
         }
         else
         {
             GraphPattern breakPattern = new GraphPattern();
             breakPattern.AddAssignment(p);
             this._graphPatterns.Add(breakPattern);
         }
     }
     else
     {
         this._unplacedAssignments.Add(p);
         this.BreakBGP();
     }
 }
Пример #8
0
 internal GraphPattern(GraphPattern gp)
 {
     this._break = gp._break;
     this._broken = gp._broken;
     this._filter = gp._filter;
     this._graphPatterns.AddRange(gp._graphPatterns);
     this._graphSpecifier = gp._graphSpecifier;
     this._isExists = gp._isExists;
     this._isFiltered = gp._isFiltered;
     this._isGraph = gp._isGraph;
     this._isMinus = gp._isMinus;
     this._isNotExists = gp._isExists;
     this._isOptimised = gp._isOptimised;
     this._isOptional = gp._isOptional;
     this._isService = gp._isService;
     this._isSilent = gp._isSilent;
     this._isUnion = gp._isUnion;
     this._triplePatterns.AddRange(gp._triplePatterns);
     this._unplacedAssignments.AddRange(gp._unplacedAssignments);
     this._unplacedFilters.AddRange(gp._unplacedFilters);
 }
Пример #9
0
 /// <summary>
 /// Adds a child Graph Pattern to the Graph Pattern respecting any BGP breaks
 /// </summary>
 /// <param name="p">Graph Pattern</param>
 internal void AddGraphPattern(GraphPattern p)
 {
     if (_break)
     {
         if (_broken)
         {
             _graphPatterns.Last().AddGraphPattern(p);
         }
         else
         {
             _graphPatterns.Add(p);
         }
     }
     else
     {
         _graphPatterns.Add(p);
         if (!_isUnion && !p.IsSubQuery)
         {
             BreakBGP();
         }
     }
 }
Пример #10
0
 /// <summary>
 /// Converts the Algebra to a Graph Pattern
 /// </summary>
 /// <returns></returns>
 public GraphPattern ToGraphPattern()
 {
     GraphPattern gp = this._inner.ToGraphPattern();
     if (gp.HasModifier)
     {
         GraphPattern p = new GraphPattern();
         p.AddGraphPattern(gp);
         p.AddAssignment(new BindPattern(this._var, this._expr));
         return p;
     }
     else
     {
         gp.AddAssignment(new BindPattern(this._var, this._expr));
         return gp;
     }
 }
Пример #11
0
 /// <summary>
 /// Converts the BGP to a Graph Pattern
 /// </summary>
 /// <returns></returns>
 public GraphPattern ToGraphPattern()
 {
     GraphPattern p = new GraphPattern();
     foreach (ITriplePattern tp in this._triplePatterns)
     {
         p.AddTriplePattern(tp);
     }
     return p;
 }
Пример #12
0
 /// <summary>
 /// Transforms the Algebra back into a Graph Pattern
 /// </summary>
 /// <returns></returns>
 public override GraphPattern ToGraphPattern()
 {
     GraphPattern gp = new GraphPattern();
     PropertyPathPattern pp = new PropertyPathPattern(this.PathStart, new FixedCardinality(this.Path, 0), this.PathEnd);
     gp.AddTriplePattern(pp);
     return gp;
 }
Пример #13
0
 /// <summary>
 /// Creates a new Service clause with the given Endpoint Specifier and Graph Pattern
 /// </summary>
 /// <param name="endpointSpecifier">Endpoint Specifier</param>
 /// <param name="pattern">Graph Pattern</param>
 /// <param name="silent">Whether Evaluation Errors are suppressed</param>
 public Service(IToken endpointSpecifier, GraphPattern pattern, bool silent)
 {
     this._endpointSpecifier = endpointSpecifier;
     this._pattern = pattern;
     this._silent = silent;
 }
Пример #14
0
 /// <summary>
 /// Creates a new Service clause with the given Endpoint Specifier and Graph Pattern
 /// </summary>
 /// <param name="endpointSpecifier">Endpoint Specifier</param>
 /// <param name="pattern">Graph Pattern</param>
 public Service(IToken endpointSpecifier, GraphPattern pattern)
     : this(endpointSpecifier, pattern, false)
 {
 }
Пример #15
0
        /// <summary>
        /// Tries to place assignments at the earliest point possible i.e. the first point after which all required variables have occurred
        /// </summary>
        /// <param name="gp">Graph Pattern</param>
        /// <param name="assignment">Assignment (LET/BIND)</param>
        /// <returns></returns>
        private bool TryPlaceAssignment(GraphPattern gp, IAssignmentPattern assignment)
        {
            //Firstly we need to find out what variables are needed in the Assignment
            //The Variables property will include the variable that the Assignment assigns to so we can safely remove this
            List<String> variablesNeeded = assignment.Variables.Distinct().ToList();
            variablesNeeded.Remove(assignment.VariableName);

            //If there are no Variables Needed we can just place the assignment at the start
            //This implies that the assignment sets something to a fixed value
            if (variablesNeeded.Count == 0)
            {
                gp.InsertAssignment(assignment, 0);
                return true;
            }

            //Then we need to move through the Triple Patterns and find the first place at which all the
            //Variables used in the Assignment have been used in ordinary Triple Patterns
            List<String> variablesUsed = new List<string>();
            for (int p = 0; p < gp.TriplePatterns.Count; p++)
            {
                if (gp.TriplePatterns[p] is TriplePattern || gp.TriplePatterns[p] is IAssignmentPattern)
                {
                    foreach (String var in gp.TriplePatterns[p].Variables)
                    {
                        if (!variablesUsed.Contains(var)) variablesUsed.Add(var);
                    }

                    //Have all the Variables we need now been used in a Pattern?
                    if (variablesNeeded.All(v => variablesUsed.Contains(v)))
                    {
                        //We can place this Assignment after the Pattern we were just looking at
                        gp.InsertAssignment(assignment, p + 1);
                        return true;
                    }
                }
            }

            //If we reach here then this means that all the Variables used in the Assignment did not occur
            //in the Triple Patterns which means they likely occur in child graph patterns (or the query
            //is malformed).  In this case we cannot place the Assignment and it has to be applied post-commit
            //rather than during Triple Pattern execution
            return false;
        }
Пример #16
0
 /// <summary>
 /// Adds an Assignment to the Graph Pattern respecting any BGP breaks
 /// </summary>
 /// <param name="p">Assignment Pattern</param>
 internal void AddAssignment(IAssignmentPattern p)
 {
     if (this._break)
     {
         if (this._broken)
         {
             this._graphPatterns.Last().AddAssignment(p);
         }
         else
         {
             GraphPattern breakPattern = new GraphPattern();
             breakPattern.AddAssignment(p);
             this._graphPatterns.Add(breakPattern);
         }
     }
     else
     {
         this._unplacedAssignments.Add(p);
         this.BreakBGP();
     }
 }
Пример #17
0
 /// <summary>
 /// Converts the Algebra back to a SPARQL Query
 /// </summary>
 /// <returns></returns>
 public GraphPattern ToGraphPattern()
 {
     GraphPattern p = new GraphPattern();
     p.IsUnion = true;
     p.AddGraphPattern(this._lhs.ToGraphPattern());
     p.AddGraphPattern(this._rhs.ToGraphPattern());
     return p;
 }
Пример #18
0
 /// <summary>
 /// Adds a Triple Pattern to the Graph Pattern respecting any BGP breaks
 /// </summary>
 /// <param name="p">Triple Pattern</param>
 internal void AddTriplePattern(ITriplePattern p)
 {
     if (this._break)
     {
         if (this._broken)
         {
             this._graphPatterns.Last().AddTriplePattern(p);
         }
         else
         {
             GraphPattern breakPattern = new GraphPattern();
             breakPattern.AddTriplePattern(p);
             this._graphPatterns.Add(breakPattern);
         }
     }
     else
     {
         this._triplePatterns.Add(p);
     }
 }
Пример #19
0
 /// <summary>
 /// Creates a new INSERT DATA command
 /// </summary>
 /// <param name="pattern">Pattern containing concrete Triples to insert</param>
 public InsertDataCommand(GraphPattern pattern)
     : base(SparqlUpdateCommandType.InsertData)
 {
     if (!this.IsValidDataPattern(pattern, true)) throw new SparqlUpdateException("Cannot create a INSERT DATA command where any of the Triple Patterns are not concrete triples (variables are not permitted) or a GRAPH clause has nested Graph Patterns");
     this._pattern = pattern;
 }
Пример #20
0
 /// <summary>
 /// Transforms the Algebra back into a Graph Pattern
 /// </summary>
 /// <returns></returns>
 public GraphPattern ToGraphPattern()
 {
     GraphPattern gp = new GraphPattern();
     PropertyPathPattern pp;
     if (this._inverse)
     {
         pp = new PropertyPathPattern(this.PathStart, new NegatedSet(Enumerable.Empty<Property>(), this._properties.Select(p => new Property(p))), this.PathEnd);
     }
     else
     {
         pp = new PropertyPathPattern(this.PathStart, new NegatedSet(this._properties.Select(p => new Property(p)), Enumerable.Empty<Property>()), this.PathEnd);
     }
     gp.AddTriplePattern(pp);
     return gp;
 }
Пример #21
0
 /// <summary>
 /// Creates a new INSERT/DELETE command which operates on the Default Graph
 /// </summary>
 /// <param name="deletions">Pattern to construct Triples to delete</param>
 /// <param name="insertions">Pattern to construct Triples to insert</param>
 /// <param name="where">Pattern to select data which is then used in evaluating the insertions and deletions</param>
 public ModifyCommand(GraphPattern deletions, GraphPattern insertions, GraphPattern where)
     : this(deletions, insertions, where, null)
 {
 }
Пример #22
0
 /// <summary>
 /// Adds a child Graph Pattern to the Graph Pattern respecting any BGP breaks
 /// </summary>
 /// <param name="p">Graph Pattern</param>
 internal void AddGraphPattern(GraphPattern p)
 {
     if (this._break)
     {
         if (this._broken)
         {
             this._graphPatterns.Last().AddGraphPattern(p);
         }
         else
         {
             this._graphPatterns.Add(p);
         }
     }
     else
     {
         this._graphPatterns.Add(p);
         if (!this._isUnion && !p.IsSubQuery) this.BreakBGP();
     }
 }
Пример #23
0
 /// <summary>
 /// Creates a new EXISTS/NOT EXISTS function
 /// </summary>
 /// <param name="pattern">Graph Pattern</param>
 /// <param name="mustExist">Whether this is an EXIST</param>
 public ExistsFunction(GraphPattern pattern, bool mustExist)
 {
     this._pattern = pattern;
     this._mustExist = mustExist;
 }
Пример #24
0
 /// <summary>
 /// Transforms the Algebra into a Graph Pattern
 /// </summary>
 /// <returns></returns>
 public override GraphPattern ToGraphPattern()
 {
     GraphPattern gp = new GraphPattern();
     PropertyPathPattern pp = new PropertyPathPattern(this.PathStart, new ZeroOrMore(this.Path), this.PathEnd);
     gp.AddTriplePattern(pp);
     return gp;
 }
Пример #25
0
        /// <summary>
        /// Tries to reorder patterns when the initial ordering is considered poor
        /// </summary>
        /// <param name="gp">Graph Pattern</param>
        /// <param name="desiredVariables">Variables that are desired</param>
        /// <param name="start">Point at which to start looking for better matches</param>
        /// <param name="end">Point at which to move the better match to</param>
        private void TryReorderPatterns(GraphPattern gp, List<String> desiredVariables, int start, int end)
        {
            if (end > start) return;

            //Find the first pattern which does contain a pre-existing variable
            for (int i = start; i < gp.TriplePatterns.Count; i++)
            {
                if (gp.TriplePatterns[i].Variables.Any(v => desiredVariables.Contains(v)))
                {
                    int newEnd = i;
                    desiredVariables.AddRange(gp.TriplePatterns[i].Variables.Where(v => desiredVariables.Contains(v)));
                    while (i > end)
                    {
                        //Swap Patterns around
                        gp.SwapTriplePatterns(i - 1, i);
                        i--;
                    }
                    end = newEnd;
                }
            }
        }
Пример #26
0
 /// <summary>
 /// Creates a new Graph Pattern Term
 /// </summary>
 /// <param name="pattern">Graph Pattern</param>
 public GraphPatternTerm(GraphPattern pattern)
 {
     this._pattern = pattern;
 }
Пример #27
0
 /// <summary>
 /// Converts the algebra back into a Subquery
 /// </summary>
 /// <returns></returns>
 public VDS.RDF.Query.Patterns.GraphPattern ToGraphPattern()
 {
     GraphPattern gp = new GraphPattern();
     gp.TriplePatterns.Add(new SubQueryPattern(this._subquery));
     return gp;
 }
Пример #28
0
        /// <summary>
        /// Gets the String representation of the Graph Pattern
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            StringBuilder output = new StringBuilder();
            String        indent = String.Empty;

            if (_isUnion)
            {
                indent = new String(' ', 2);
                for (int i = 0; i < _graphPatterns.Count; i++)
                {
                    GraphPattern gp = _graphPatterns[i];

                    if (i > 0)
                    {
                        output.Append(indent);
                    }
                    String temp = gp.ToString();
                    if (!temp.Contains('\n'))
                    {
                        if (gp.HasModifier)
                        {
                            temp = "{ " + temp + " }";
                        }
                        output.Append(temp + " ");
                    }
                    else
                    {
                        if (gp.HasModifier)
                        {
                            temp = "{\n" + temp + "\n}";
                        }
                        output.AppendLineIndented(temp, 2);
                    }
                    if (i < _graphPatterns.Count - 1)
                    {
                        output.AppendLine();
                        output.Append(indent);
                        output.AppendLine("UNION");
                    }
                }
                return(output.ToString());
            }
            if (_isGraph || _isService)
            {
                if (_isGraph)
                {
                    output.Append("GRAPH ");
                }
                else
                {
                    output.Append("SERVICE ");
                    if (_isSilent)
                    {
                        output.Append("SILENT ");
                    }
                }
                switch (_graphSpecifier.TokenType)
                {
                case Token.QNAME:
                    output.Append(_graphSpecifier.Value);
                    break;

                case Token.URI:
                    output.Append('<');
                    output.Append(_graphSpecifier.Value);
                    output.Append('>');
                    break;

                case Token.VARIABLE:
                default:
                    output.Append(_graphSpecifier.Value);
                    break;
                }
                output.Append(" ");
            }
            else if (_isOptional)
            {
                if (_isExists)
                {
                    output.Append("EXISTS ");
                }
                else if (_isNotExists)
                {
                    output.Append("NOT EXISTS ");
                }
                else
                {
                    output.Append("OPTIONAL ");
                }
            }
            else if (_isMinus)
            {
                output.Append("MINUS ");
            }

            output.Append("{ ");
            bool linebreaks = ((_triplePatterns.Count + _graphPatterns.Count + _unplacedAssignments.Count) > 1) || _isFiltered;

            if (linebreaks)
            {
                output.AppendLine();
                indent = new String(' ', 2);
            }
            // Triple Patterns
            foreach (ITriplePattern tp in _triplePatterns)
            {
                String temp = tp.ToString();
                output.Append(indent);
                if (temp.Contains('\n'))
                {
                    String[] lines = temp.Split('\n');
                    for (int i = 0; i < lines.Length; i++)
                    {
                        if (i > 0)
                        {
                            output.Append(indent);
                        }
                        if (i > 0 && i < lines.Length - 1)
                        {
                            output.Append(' ');
                        }
                        output.Append(lines[i]);
                        if (i < lines.Length - 1)
                        {
                            output.AppendLine();
                        }
                    }
                    if (tp.PatternType != TriplePatternType.SubQuery)
                    {
                        output.Append(" . ");
                    }
                    if (linebreaks)
                    {
                        output.AppendLine();
                    }
                }
                else
                {
                    output.Append(temp + " . ");
                    if (linebreaks)
                    {
                        output.AppendLine();
                    }
                }
            }
            // Unplaced Assignments
            foreach (IAssignmentPattern ap in _unplacedAssignments)
            {
                output.Append(ap.ToString());
                if (linebreaks)
                {
                    output.AppendLine();
                }
            }
            // Inline Data
            if (HasInlineData)
            {
                output.Append(indent);
                String temp = _data.ToString();
                if (!temp.Contains('\n'))
                {
                    output.Append(temp + " ");
                }
                else
                {
                    String[] lines = temp.Split('\n');
                    for (int i = 0; i < lines.Length; i++)
                    {
                        if (i > 0)
                        {
                            output.Append(indent);
                        }
                        output.Append(lines[i]);
                        if (i < lines.Length - 1)
                        {
                            output.AppendLine();
                        }
                    }
                }
                if (linebreaks)
                {
                    output.AppendLine();
                }
            }
            // Graph Patterns
            foreach (GraphPattern gp in _graphPatterns)
            {
                output.Append(indent);
                String temp = gp.ToString();
                if (!temp.Contains('\n'))
                {
                    output.Append(temp + " ");
                }
                else
                {
                    String[] lines = temp.Split('\n');
                    for (int i = 0; i < lines.Length; i++)
                    {
                        if (i > 0)
                        {
                            output.Append(indent);
                        }
                        output.Append(lines[i]);
                        if (i < lines.Length - 1)
                        {
                            output.AppendLine();
                        }
                    }
                }
                if (linebreaks)
                {
                    output.AppendLine();
                }
            }
            // Filters
            if (_filter != null)
            {
                output.Append(indent);
                output.Append(_filter.ToString());
                if (linebreaks)
                {
                    output.AppendLine();
                }
            }
            foreach (ISparqlFilter filter in _unplacedFilters)
            {
                output.Append(indent);
                output.Append(filter.ToString());
                if (linebreaks)
                {
                    output.AppendLine();
                }
            }
            output.Append("}");

            return(output.ToString());
        }
Пример #29
0
 /// <summary>
 /// Creates a new DELETE command 
 /// </summary>
 /// <param name="where">Pattern to construct Triples to delete</param>
 /// <param name="graphUri">URI of the affected Graph</param>
 public DeleteCommand(GraphPattern where, Uri graphUri)
     : this(where, where, graphUri)
 {
 }
Пример #30
0
 /// <summary>
 /// Converts the Algebra back to a Graph Pattern
 /// </summary>
 /// <returns></returns>
 public GraphPattern ToGraphPattern()
 {
     GraphPattern p = this._pattern.ToGraphPattern();
     GraphPattern f = new GraphPattern();
     f.AddFilter(this._filter);
     p.AddGraphPattern(f);
     return p;
 }
Пример #31
0
 /// <summary>
 /// Createa a new DELETE command which operates on the Default Graph
 /// </summary>
 /// <param name="where">Pattern to construct Triples to delete</param>
 public DeleteCommand(GraphPattern where)
     : this(where, where, null)
 {
 }
Пример #32
0
        /// <summary>
        /// Tries to place filters at the earliest point possible i.e. the first point after which all required variables have occurred
        /// </summary>
        /// <param name="gp">Graph Pattern</param>
        /// <param name="filter">Filter to place</param>
        /// <returns></returns>
        private bool TryPlaceFilter(GraphPattern gp, ISparqlFilter filter)
        {
            //Firstly we need to find out what variables are needed in the Filter
            List<String> variablesNeeded = filter.Variables.Distinct().ToList();

            //Then we need to move through the Triple Patterns and find the first place at which all the
            //Variables used in the Filter have been used in ordinary Triple Patterns
            List<String> variablesUsed = new List<string>();
            for (int p = 0; p < gp.TriplePatterns.Count; p++)
            {
                if (gp.TriplePatterns[p] is TriplePattern || gp.TriplePatterns[p] is IAssignmentPattern)
                {
                    foreach (String var in gp.TriplePatterns[p].Variables)
                    {
                        if (!variablesUsed.Contains(var)) variablesUsed.Add(var);
                    }

                    //Have all the Variables we need now been used in a Pattern?
                    if (variablesNeeded.All(v => variablesUsed.Contains(v)))
                    {
                        //We can place this Filter after the Pattern we were just looking at
                        gp.InsertFilter(filter, p + 1);
                        return true;
                    }
                }
            }

            //If we reach here then this means that all the Variables used in the Filter did not occur
            //in the Triple Patterns which means they likely occur in child graph patterns (or the query
            //is malformed).  In this case we cannot place the Filter and it has to be applied post-commit
            //rather than during Triple Pattern execution
            return false;
        }
Пример #33
0
        /// <summary>
        /// Formats a Graph Pattern in nicely formatted SPARQL syntax
        /// </summary>
        /// <param name="gp">Graph Pattern</param>
        /// <returns></returns>
        public virtual String Format(GraphPattern gp)
        {
            if (gp == null) throw new RdfOutputException("Cannot format a null Graph Pattern as a String");

            StringBuilder output = new StringBuilder();

            if (gp.IsUnion)
            {
                for (int i = 0; i < gp.ChildGraphPatterns.Count; i++)
                {
                    output.Append(this.Format(gp.ChildGraphPatterns[i]));
                    if (i < gp.ChildGraphPatterns.Count - 1)
                    {
                        output.AppendLine();
                        output.AppendLine("UNION");
                    }
                }
                return output.ToString();
            }
            else if (gp.IsGraph || gp.IsService)
            {
                if (gp.IsGraph)
                {
                    output.Append("GRAPH ");
                }
                else
                {
                    output.Append("SERVICE ");
                    if (gp.IsSilent) output.Append("SILENT ");
                }

                switch (gp.GraphSpecifier.TokenType)
                {
                    case Token.QNAME:
                        try
                        {
                            String uri = Tools.ResolveQName(gp.GraphSpecifier.Value, this._qnameMapper, this._tempBaseUri);
                            //If the QName resolves OK in the context of the Namespace Map we're using to format this then we
                            //can print the QName as-is
                            output.Append(gp.GraphSpecifier.Value);
                        }
                        catch
                        {
                            //If the QName fails to resolve then can't format in the context
                            throw new RdfOutputException("Cannot format the Graph/Service Specifier QName " + gp.GraphSpecifier.Value + " as the Namespace Mapper in use for this Formatter cannot resolve the QName");
                        }
                        break;

                    case Token.URI:
                        output.Append('<');
                        output.Append(this.FormatUri(gp.GraphSpecifier.Value));
                        output.Append('>');
                        break;

                    case Token.VARIABLE:
                    default:
                        output.Append(gp.GraphSpecifier.Value);
                        break;
                }
                output.Append(' ');
            }
            else if (gp.IsSubQuery)
            {
                output.AppendLine("{");
                output.AppendLineIndented(this.Format(((SubQueryPattern)gp.TriplePatterns[0]).SubQuery), 2);
                output.AppendLine("}");
                return output.ToString();
            }
            else if (gp.IsOptional)
            {
                output.Append("OPTIONAL ");
            }
            else if (gp.IsExists)
            {
                output.Append("EXISTS ");
            }
            else if (gp.IsNotExists)
            {
                output.Append("NOT EXISTS ");
            }
            else if (gp.IsMinus)
            {
                output.Append("MINUS ");
            }

            if (gp.TriplePatterns.Count > 1 || gp.HasChildGraphPatterns || (gp.TriplePatterns.Count <= 1 && gp.Filter != null) || gp.UnplacedAssignments.Count() > 0 || gp.UnplacedFilters.Count() > 0)
            {
                output.AppendLine("{");
                foreach (ITriplePattern tp in gp.TriplePatterns)
                {
                    output.AppendLineIndented(this.Format(tp), 2);
                }
                foreach (IAssignmentPattern ap in gp.UnplacedAssignments)
                {
                    output.AppendLineIndented(this.Format(ap), 2);
                }
                foreach (GraphPattern child in gp.ChildGraphPatterns)
                {
                    output.AppendLineIndented(this.Format(child), 2);
                }
                foreach (ISparqlFilter fp in gp.UnplacedFilters)
                {
                    output.AppendIndented("FILTER(", 2);
                    output.Append(this.FormatExpression(fp.Expression));
                    output.AppendLine(")");
                }
                output.Append("}");
            }
            else if (gp.TriplePatterns.Count == 0)
            {
                if (gp.Filter != null)
                {
                    output.AppendIndented("{ FILTER(", 2);
                    output.Append(this.FormatExpression(gp.Filter.Expression));
                    output.AppendLine(") }");
                }
                else
                {
                    output.Append("{ }");
                }
            }
            else
            {
                output.Append("{ ");
                output.Append(this.Format(gp.TriplePatterns[0]));
                output.Append(" }");
            }

            return output.ToString();
        }
Пример #34
0
        /// <summary>
        /// Causes the Graph Pattern to be optimised if it isn't already
        /// </summary>
        /// <param name="gp">Graph Pattern</param>
        /// <param name="variables">Variables that have occurred prior to this Pattern</param>
        public void Optimise(GraphPattern gp, IEnumerable<String> variables)
        {
            //Our Variables is initially only those in our Triple Patterns since
            //anything else is considered to be out of scope
            List<String> ourVariables = (from tp in gp.TriplePatterns
                                         from v in tp.Variables
                                         select v).Distinct().ToList();

            //Start by sorting the Triple Patterns in the list according to the ranking function
            gp.TriplePatterns.Sort(this.GetRankingComparer());

            //Apply reordering unless an optimiser has chosen to disable it
            if (this.ShouldReorder)
            {
                if (gp.TriplePatterns.Count > 0)
                {
                    //After we sort which gives us a rough optimisation we then may want to reorder
                    //based on the Variables that occurred previous to us OR if we're the Root Graph Pattern

                    if (!variables.Any())
                    {
                        //Optimise this Graph Pattern
                        //No previously occurring variables so must be the first Graph Pattern
                        if (gp.TriplePatterns.Count > 1)
                        {
                            HashSet<String> currVariables = new HashSet<String>();
                            gp.TriplePatterns[0].Variables.ForEach(v => currVariables.Add(v));
                            for (int i = 1; i < gp.TriplePatterns.Count - 1; i++)
                            {
                                if (currVariables.Count == 0)
                                {
                                    gp.TriplePatterns[i].Variables.ForEach(v => currVariables.Add(v));
                                    continue;
                                }
                                else if (currVariables.IsDisjoint(gp.TriplePatterns[i].Variables))
                                {
                                    this.TryReorderPatterns(gp, currVariables.ToList(), i + 1, i);
                                    gp.TriplePatterns[i].Variables.ForEach(v => currVariables.Add(v));
                                }
                                else
                                {
                                    gp.TriplePatterns[i].Variables.ForEach(v => currVariables.Add(v));
                                }
                            }
                        }
                    }
                    else
                    {
                        //Optimise this Graph Pattern based on previously occurring variables
                        if (gp.TriplePatterns.Count > 1 && !gp.TriplePatterns[0].Variables.Any(v => variables.Contains(v)) && variables.Intersect(ourVariables).Any())
                        {
                            this.TryReorderPatterns(gp, variables.ToList(), 1, 0);
                        }
                        else if (gp.TriplePatterns.Count > 2)
                        {
                            //In the case where there are more than 2 patterns then we can try and reorder these
                            //in order to further optimise the pattern
                            this.TryReorderPatterns(gp, gp.TriplePatterns[0].Variables, 2, 1);
                        }
                    }
                }
            }

            if (this.ShouldPlaceAssignments)
            {
                //First we need to place Assignments (LETs) in appropriate places within the Pattern
                //This happens before Filter placement since Filters may use variables assigned to in LETs
                if (gp.UnplacedAssignments.Any())
                {
                    //Need to ensure that we sort Assignments
                    //This way those that use fewer variables get placed first
                    List<IAssignmentPattern> ps = gp.UnplacedAssignments.OrderBy(x => x).ToList();

                    //This next bit goes in a do loop as we want to keep attempting to place assignments while
                    //we are able to do so.  If the count of unplaced assignments has decreased but is not
                    //zero it may be that we were unable to place some patterns as they relied on variables
                    //assigned in other LETs which weren't placed when we attempted to place them
                    //When we reach the point where no further placements have occurred or all assignments
                    //are placed we stop trying to place assignments
                    int c;
                    do
                    {
                        c = ps.Count;

                        int i = 0;
                        while (i < ps.Count)
                        {
                            if (this.TryPlaceAssignment(gp, ps[i]))
                            {
                                //Remove from Unplaced Assignments since it's been successfully placed in the Triple Patterns
                                //Don't increment the counter since the next Assignment is now at the index we're already at
                                ps.RemoveAt(i);
                            }
                            else
                            {
                                //Unable to place so increment counter
                                i++;
                            }
                        }
                    } while (c > ps.Count && ps.Count > 0);
                }
            }

            //Regardless of what we've placed already we now place all remaining assignments
            foreach (IAssignmentPattern assignment in gp.UnplacedAssignments.ToList())
            {
                gp.InsertAssignment(assignment, gp.TriplePatterns.Count);
            }

            if (this.ShouldPlaceFilters)
            {
                //Then we need to place the Filters in appropriate places within the Pattern
                if (gp.UnplacedFilters.Any())
                {
                    if (gp.TriplePatterns.Count == 0)
                    {
                        //Where there are no Triple Patterns the Graph Pattern just contains this Filter and possibly some
                        //child Graph Patterns.  In such a case then we shouldn't place the Filters
                    }
                    else
                    {
                        foreach (ISparqlFilter f in gp.UnplacedFilters.ToList())
                        {
                            this.TryPlaceFilter(gp, f);
                        }
                    }
                }
            }

            //Finally optimise the Child Graph Patterns
            foreach (GraphPattern cgp in gp.ChildGraphPatterns)
            {
                //At each point the variables that have occurred are those in the Triple Patterns and
                //those in previous Graph Patterns
                cgp.Optimise(this, ourVariables);
                ourVariables.AddRange(cgp.Variables);
            }

            //Note: Any remaining Unplaced Filters/Assignments are OK since the ToAlgebra() method of a GraphPattern
            //will take care of placing these appropriately
        }
Пример #35
0
 /// <summary>
 /// Converts the Algebra into a Graph Pattern
 /// </summary>
 /// <returns></returns>
 public GraphPattern ToGraphPattern()
 {
     GraphPattern p = new GraphPattern(this._pattern);
     if (!p.HasModifier)
     {
         p.IsService = true;
         p.GraphSpecifier = this._endpointSpecifier;
         return p;
     }
     else
     {
         GraphPattern parent = new GraphPattern();
         parent.IsService = true;
         parent.GraphSpecifier = this._endpointSpecifier;
         parent.AddGraphPattern(p);
         return parent;
     }
 }