Esempio n. 1
0
        /// <summary>
        /// Converts the Minus() back to a MINUS Graph Pattern
        /// </summary>
        /// <returns></returns>
        public GraphPattern ToGraphPattern()
        {
            GraphPattern p   = _lhs.ToGraphPattern();
            GraphPattern opt = _rhs.ToGraphPattern();

            if (!opt.HasModifier)
            {
                opt.IsMinus = true;
                p.AddGraphPattern(opt);
            }
            else
            {
                GraphPattern parent = new GraphPattern();
                parent.AddGraphPattern(opt);
                parent.IsMinus = true;
                p.AddGraphPattern(parent);
            }
            return(p);
        }
Esempio n. 2
0
        /// <summary>
        /// Converts the Algebra into a Graph Pattern.
        /// </summary>
        /// <returns></returns>
        public GraphPattern ToGraphPattern()
        {
            GraphPattern p = new GraphPattern(_pattern);

            if (!p.HasModifier)
            {
                p.IsService      = true;
                p.GraphSpecifier = _endpointSpecifier;
                return(p);
            }
            else
            {
                GraphPattern parent = new GraphPattern();
                parent.IsService      = true;
                parent.GraphSpecifier = _endpointSpecifier;
                parent.AddGraphPattern(p);
                return(parent);
            }
        }
Esempio n. 3
0
        private GraphPattern TryParseModifyTemplate(SparqlUpdateParserContext context)
        {
            SparqlQueryParserContext subContext = new SparqlQueryParserContext(context.Tokens);

            subContext.Query.BaseUri                        = context.BaseUri;
            subContext.Query.NamespaceMap                   = context.NamespaceMap;
            subContext.ExpressionParser.NamespaceMap        = context.NamespaceMap;
            subContext.ExpressionParser.ExpressionFactories = context.ExpressionFactories;
            subContext.ExpressionFactories                  = context.ExpressionFactories;
            subContext.ExpressionParser.QueryParser         = context.QueryParser;
            GraphPattern gp = context.QueryParser.TryParseGraphPattern(subContext, context.Tokens.LastTokenType != Token.LEFTCURLYBRACKET);

            // Validate that the Graph Pattern is simple
            // Check it doesn't contain anything other than Triple Patterns or if it does it just contains a single GRAPH Pattern
            if (gp.IsFiltered)
            {
                throw new RdfParseException("A FILTER Clause cannot occur in a Modify Template");
            }
            else if (gp.IsOptional)
            {
                throw new RdfParseException("An OPTIONAL Clause cannot occur in a Modify Template");
            }
            else if (gp.IsUnion)
            {
                throw new RdfParseException("A UNION Clause cannot occur in a Modify Template");
            }
            else if (gp.HasChildGraphPatterns)
            {
                if (gp.ChildGraphPatterns.All(p => p.IsGraph && !p.IsFiltered && !p.IsOptional && !p.IsUnion && !p.HasChildGraphPatterns))
                {
                    return(gp);
                }
                else
                {
                    throw new RdfParseException("Nested Graph Patterns cannot occur in a Modify Template");
                }
            }
            else
            {
                return(gp);
            }
        }
 /// <summary>
 /// Determines whether a Graph Pattern is valid for use in an DELETE pattern.
 /// </summary>
 /// <param name="p">Graph Pattern.</param>
 /// <param name="top">Is this the top level pattern?.</param>
 /// <returns></returns>
 protected bool IsValidDeletePattern(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).HasNoBlankVariables));
     }
     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 blank 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).HasNoBlankVariables) && ((top && p.ChildGraphPatterns.All(gp => IsValidDeletePattern(gp, false))) || !p.HasChildGraphPatterns));
     }
 }
Esempio n. 5
0
        /// <summary>
        /// Converts the Algebra back to a SPARQL Query
        /// </summary>
        /// <returns></returns>
        public GraphPattern ToGraphPattern()
        {
            GraphPattern p   = this._lhs.ToGraphPattern();
            GraphPattern opt = this._rhs.ToGraphPattern();

            opt.IsOptional = true;
            if (this._filter.Expression is BooleanExpressionTerm)
            {
                if (!this._filter.Expression.EffectiveBooleanValue(null, 0))
                {
                    opt.Filter = this._filter;
                }
            }
            else
            {
                opt.Filter = this._filter;
            }
            p.AddGraphPattern(opt);
            return(p);
        }
Esempio n. 6
0
        private static void BindPath(GraphPattern pattern, ISparqlPath path)
        {
            for (var i = 0; i < pattern.TriplePatterns.Count(); i++)
            {
                if (pattern.TriplePatterns[i] is TriplePattern triplePattern && triplePattern.Predicate.VariableName == "PATH")
                {
                    pattern.TriplePatterns.RemoveAt(i);
                    pattern.TriplePatterns.Insert(i, new PropertyPathPattern(triplePattern.Subject, path, triplePattern.Object));
                }
            }

            foreach (var subPattern in pattern.ChildGraphPatterns)
            {
                BindPath(subPattern, path);
            }

            foreach (var subQueryPattern in pattern.TriplePatterns.OfType <SubQueryPattern>())
            {
                BindPath(subQueryPattern.SubQuery.RootGraphPattern, path);
            }
        }
Esempio n. 7
0
        public void SparqlGraphPatternToAlgebra5()
        {
            GraphPattern gp = new GraphPattern();

            gp.IsGraph        = true;
            gp.GraphSpecifier = new VariableToken("g", 0, 0, 1);
            gp.AddInlineData(new BindingsPattern());

            ISparqlAlgebra algebra = gp.ToAlgebra();

            Assert.IsInstanceOf(typeof(IJoin), algebra);

            IJoin join = (IJoin)algebra;

            Assert.IsInstanceOf(typeof(Graph), join.Lhs);
            Graph g = (Graph)join.Lhs;

            Assert.IsInstanceOf(typeof(IBgp), g.InnerAlgebra);

            Assert.IsInstanceOf(typeof(Bindings), join.Rhs);
        }
        private static void AddTriplePattern(GraphPattern graphPattern, ITriplePattern tp)
        {
            switch (tp.PatternType)
            {
            case TriplePatternType.Match:
            case TriplePatternType.Path:
            case TriplePatternType.PropertyFunction:
            case TriplePatternType.SubQuery:
                graphPattern.AddTriplePattern(tp);
                break;

            case TriplePatternType.LetAssignment:
            case TriplePatternType.BindAssignment:
                graphPattern.AddAssignment((IAssignmentPattern)tp);
                break;

            case TriplePatternType.Filter:
                graphPattern.AddFilter(((IFilterPattern)tp).Filter);
                break;
            }
        }
        public void SparqlGraphPatternToAlgebra5()
        {
            GraphPattern gp = new GraphPattern();

            gp.IsGraph        = true;
            gp.GraphSpecifier = new VariableToken("g", 0, 0, 1);
            gp.AddInlineData(new BindingsPattern());

            ISparqlAlgebra algebra = gp.ToAlgebra();

            Assert.IsAssignableFrom <IJoin>(algebra);

            IJoin join = (IJoin)algebra;

            Assert.IsType <Graph>(join.Lhs);
            Graph g = (Graph)join.Lhs;

            Assert.IsAssignableFrom <IBgp>(g.InnerAlgebra);

            Assert.IsAssignableFrom <Bindings>(join.Rhs);
        }
        public void SparqlGraphPatternToAlgebra9()
        {
            GraphPattern gp = new GraphPattern();

            gp.IsGraph        = true;
            gp.GraphSpecifier = new VariableToken("g", 0, 0, 1);

            ISparqlAlgebra algebra = gp.ToAlgebra();

            Assert.IsType <Graph>(algebra);

            Graph g = (Graph)algebra;

            Assert.IsAssignableFrom <IBgp>(g.InnerAlgebra);

            // Nest in another graph pattern with same specifier but also with another BGP
            GraphPattern parent = new GraphPattern();

            parent.IsGraph        = true;
            parent.GraphSpecifier = gp.GraphSpecifier;
            parent.AddGraphPattern(gp);
            ITriplePattern tp = new TriplePattern(new VariablePattern("s"), new VariablePattern("p"), new VariablePattern("o"));

            parent.AddTriplePattern(tp);

            // Resulting algebra will keep both graph clauses because of the join
            algebra = parent.ToAlgebra();

            Assert.IsType <Graph>(algebra);
            g = (Graph)algebra;

            Assert.IsType <Join>(g.InnerAlgebra);

            Join join = (Join)g.InnerAlgebra;

            Assert.IsType <Graph>(join.Lhs);

            g = (Graph)join.Lhs;
            Assert.IsAssignableFrom <IBgp>(g.InnerAlgebra);
        }
Esempio n. 11
0
        private void Validate(GraphPattern pattern)
        {
            if (pattern.IsMinus || pattern.InlineData != null || pattern.IsService)
            {
                throw new Exception("illegal clauses");
            }

            foreach (var subPattern in pattern.ChildGraphPatterns)
            {
                Validate(subPattern);
            }

            foreach (var subQueryPattern in pattern.TriplePatterns.OfType <SubQueryPattern>())
            {
                if (!subQueryPattern.Variables.Contains("this"))
                {
                    throw new Exception("missing projection");
                }

                Validate(subQueryPattern.SubQuery.RootGraphPattern);
            }
        }
        /// <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].PatternType == TriplePatternType.Match || gp.TriplePatterns[p].PatternType == TriplePatternType.BindAssignment || gp.TriplePatterns[p].PatternType == TriplePatternType.LetAssignment)
                {
                    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);
        }
        /// <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;
                }
            }
        }
Esempio n. 14
0
 /// <summary>
 /// Creates a new INSERT command which operates on the Default Graph
 /// </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>
 public InsertCommand(GraphPattern insertions, GraphPattern where)
     : this(insertions, where, null)
 {
 }
Esempio n. 15
0
        internal static INode ToSpinRdf(this GraphPattern pattern, IGraph g, SpinVariableTable varTable)
        {
            INode p  = g.CreateBlankNode();
            INode ps = p;

            if (pattern.IsExists)
            {
                g.Assert(p, RDF.PropertyType, SP.ClassExists);
                ps = g.CreateBlankNode();
                g.Assert(p, SP.PropertyElements, ps);
            }
            else if (pattern.IsGraph)
            {
                g.Assert(p, RDF.PropertyType, SP.ClassNamedGraph);
                INode gSpec = pattern.GraphSpecifier.ToSpinRdf(g, varTable);
                //g.Assert(p, SP.named, gSpec); // TODO check which is right
                g.Assert(p, SP.PropertyGraphNameNode, gSpec); // TODO check which is right
                if (gSpec is IBlankNode)
                {
                    g.Assert(gSpec, SP.PropertyVarName, pattern.GraphSpecifier.Value.Substring(1).ToLiteral(g));
                }
                ps = g.CreateBlankNode();
                g.Assert(p, SP.PropertyElements, ps);
            }
            else if (pattern.IsMinus)
            {
                g.Assert(p, RDF.PropertyType, SP.ClassMinus);
                ps = g.CreateBlankNode();
                g.Assert(p, SP.PropertyElements, ps);
            }
            else if (pattern.IsNotExists)
            {
                g.Assert(p, RDF.PropertyType, SP.ClassNotExists);
                ps = g.CreateBlankNode();
                g.Assert(p, SP.PropertyElements, ps);
            }
            else if (pattern.IsOptional)
            {
                g.Assert(p, RDF.PropertyType, SP.ClassOptional);
                ps = g.CreateBlankNode();
                g.Assert(p, SP.PropertyElements, ps);
            }
            else if (pattern.IsService)
            {
                g.Assert(p, RDF.PropertyType, SP.ClassService);
                g.Assert(p, SP.PropertyServiceURI, pattern.GraphSpecifier.ToSpinRdf(g, varTable));
                ps = g.CreateBlankNode();
                g.Assert(p, SP.PropertyElements, ps);
            }
            else if (pattern.IsSubQuery)
            {
                g.Assert(p, RDF.PropertyType, SP.ClassSubQuery);
                ps = g.CreateBlankNode();
                g.Assert(p, SP.PropertyQuery, ps);
            }
            else if (pattern.IsUnion)
            {
                g.Assert(p, RDF.PropertyType, SP.ClassUnion);
                ps = g.CreateBlankNode();
                g.Assert(p, SP.PropertyElements, ps);
            }

            if (!pattern.IsEmpty)
            {
                //First output Triple Patterns
                for (int i = 0; i < pattern.TriplePatterns.Count; i++)
                {
                    INode current = pattern.TriplePatterns[i].ToSpinRdf(g, varTable);
                    if (i == 0)
                    {
                        g.Assert(ps, RDF.PropertyFirst, current);
                    }
                    else
                    {
                        INode temp = g.CreateBlankNode();
                        g.Assert(ps, RDF.PropertyRest, temp);
                        g.Assert(temp, RDF.PropertyFirst, current);
                        ps = temp;
                    }
                }

                if (!pattern.HasChildGraphPatterns)
                {
                    g.Assert(ps, RDF.PropertyRest, RDF.Nil);
                }
            }

            //Then output Graph Patterns
            if (pattern.HasChildGraphPatterns)
            {
                for (int i = 0; i < pattern.ChildGraphPatterns.Count; i++)
                {
                    INode current = pattern.ChildGraphPatterns[i].ToSpinRdf(g, varTable);
                    if (pattern.TriplePatterns.Count == 0 && i == 0)
                    {
                        g.Assert(ps, RDF.PropertyFirst, current);
                    }
                    else
                    {
                        INode temp = g.CreateBlankNode();
                        g.Assert(ps, RDF.PropertyRest, temp);
                        g.Assert(temp, RDF.PropertyFirst, current);
                        ps = temp;
                    }
                }
                g.Assert(ps, RDF.PropertyRest, RDF.Nil);
            }

            return(p);
        }
Esempio n. 16
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)
 {
     _endpointSpecifier = endpointSpecifier;
     _pattern           = pattern;
     _silent            = silent;
 }
Esempio n. 17
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)
 {
 }
Esempio n. 18
0
        private SparqlUpdateCommand TryParseInsertCommand(SparqlUpdateParserContext context, bool allowData)
        {
            List <Uri> usings     = new List <Uri>();
            List <Uri> usingNamed = new List <Uri>();
            IToken     next       = context.Tokens.Dequeue();

            if (allowData)
            {
                //We are allowed to have an INSERT DATA command here so check for it
                if (next.TokenType == Token.DATA)
                {
                    return(this.TryParseInsertDataCommand(context));
                }
            }
            else
            {
                if (next.TokenType == Token.DATA)
                {
                    throw ParserHelper.Error("The DATA keyword is not permitted here as this INSERT command forms part of a modification command", next);
                }
            }

            //Get the Modification Template
            GraphPattern insertions = this.TryParseModifyTemplate(context);

            //Then we expect a WHERE keyword
            next = context.Tokens.Dequeue();
            if (next.TokenType == Token.USING)
            {
                foreach (KeyValuePair <Uri, bool> kvp in this.TryParseUsingStatements(context))
                {
                    if (kvp.Value)
                    {
                        usingNamed.Add(kvp.Key);
                    }
                    else
                    {
                        usings.Add(kvp.Key);
                    }
                }
                next = context.Tokens.Dequeue();
            }
            if (next.TokenType != Token.WHERE)
            {
                throw ParserHelper.Error("Unexpected Token '" + next.GetType().ToString() + "' encountered, expected a WHERE keyword as part of a INSERT command", next);
            }

            //Now parse the WHERE pattern
            SparqlQueryParserContext subContext = new SparqlQueryParserContext(context.Tokens);

            subContext.Query.BaseUri                        = context.BaseUri;
            subContext.Query.NamespaceMap                   = context.NamespaceMap;
            subContext.ExpressionParser.NamespaceMap        = context.NamespaceMap;
            subContext.ExpressionParser.ExpressionFactories = context.ExpressionFactories;
            subContext.ExpressionFactories                  = context.ExpressionFactories;
            GraphPattern where = context.QueryParser.TryParseGraphPattern(subContext, context.Tokens.LastTokenType != Token.LEFTCURLYBRACKET);

            //And finally return the command
            InsertCommand cmd = new InsertCommand(insertions, where);

            usings.ForEach(u => cmd.AddUsingUri(u));
            usingNamed.ForEach(u => cmd.AddUsingNamedUri(u));
            return(cmd);
        }
Esempio n. 19
0
        private SparqlUpdateCommand TryParseDeleteCommand(SparqlUpdateParserContext context, bool allowData)
        {
            IToken     next       = context.Tokens.Dequeue();
            List <Uri> usings     = new List <Uri>();
            List <Uri> usingNamed = new List <Uri>();

            if (allowData)
            {
                // We are allowed to have an DELETE DATA command here so check for it
                if (next.TokenType == Token.DATA)
                {
                    return(TryParseDeleteDataCommand(context));
                }
            }
            else
            {
                if (next.TokenType == Token.DATA)
                {
                    throw ParserHelper.Error("The DATA keyword is not permitted here as this INSERT command forms part of a modification command", next);
                }
            }

            if (next.TokenType == Token.WHERE)
            {
                // Parse the WHERE pattern which serves as both the selection and deletion pattern in this case
                context.Tokens.Dequeue();
                GraphPattern where = TryParseModifyTemplate(context);

                // Then return the command
                return(new DeleteCommand(where, where));
            }
            // Get the Modification Template
            GraphPattern deletions = TryParseModifyTemplate(context);

            // Then we expect a WHERE keyword
            next = context.Tokens.Dequeue();
            if (next.TokenType == Token.USING)
            {
                foreach (KeyValuePair <Uri, bool> kvp in TryParseUsingStatements(context))
                {
                    if (kvp.Value)
                    {
                        usingNamed.Add(kvp.Key);
                    }
                    else
                    {
                        usings.Add(kvp.Key);
                    }
                }
                next = context.Tokens.Dequeue();
            }
            if (next.TokenType == Token.WHERE)
            {
                // Now parse the WHERE pattern
                SparqlQueryParserContext subContext = new SparqlQueryParserContext(context.Tokens);
                subContext.Query.BaseUri                        = context.BaseUri;
                subContext.Query.NamespaceMap                   = context.NamespaceMap;
                subContext.ExpressionParser.NamespaceMap        = context.NamespaceMap;
                subContext.ExpressionParser.ExpressionFactories = context.ExpressionFactories;
                subContext.ExpressionFactories                  = context.ExpressionFactories;
                subContext.ExpressionParser.QueryParser         = context.QueryParser;
                GraphPattern where = context.QueryParser.TryParseGraphPattern(subContext, context.Tokens.LastTokenType != Token.LEFTCURLYBRACKET);

                // And finally return the command
                DeleteCommand cmd = new DeleteCommand(deletions, @where);
                usings.ForEach(u => cmd.AddUsingUri(u));
                usingNamed.ForEach(u => cmd.AddUsingNamedUri(u));
                return(cmd);
            }
            if (next.TokenType == Token.INSERT)
            {
                InsertCommand insertCmd = (InsertCommand)TryParseInsertCommand(context, false);
                ModifyCommand cmd       = new ModifyCommand(deletions, insertCmd.InsertPattern, insertCmd.WherePattern);
                insertCmd.UsingUris.ToList().ForEach(u => cmd.AddUsingUri(u));
                insertCmd.UsingNamedUris.ToList().ForEach(u => cmd.AddUsingNamedUri(u));
                return(cmd);
            }
            throw ParserHelper.Error("Unexpected Token '" + next.GetType().ToString() + "' encountered, expected a WHERE keyword as part of a DELETE command", next);
        }
Esempio n. 20
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;
 }
Esempio n. 21
0
 /// <summary>
 /// Creates a new Graph Pattern Term
 /// </summary>
 /// <param name="pattern">Graph Pattern</param>
 public GraphPatternTerm(GraphPattern pattern)
 {
     this._pattern = pattern;
 }
Esempio n. 22
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)
 {
 }
Esempio n. 23
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)
 {
 }
        /// <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(GetRankingComparer());

            // Apply reordering unless an optimiser has chosen to disable it
            if (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))
                                {
                                    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())
                        {
                            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
                            TryReorderPatterns(gp, gp.TriplePatterns[0].Variables, 2, 1);
                        }
                    }
                }
            }

            if (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 (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 (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
                    {
                        if (ShouldSplitFilters)
                        {
                            // See whether we can split any/all of the Unplaced Filters
                            List <ISparqlFilter> fs = gp.UnplacedFilters.ToList();
                            for (int i = 0; i < fs.Count; i++)
                            {
                                ISparqlFilter f = fs[i];
                                if (f.Expression is AndExpression)
                                {
                                    // Split the And
                                    // Note that multiple nested And's are handled by the fact that we will continue working through the list until it is finished
                                    UnaryExpressionFilter lhs = new UnaryExpressionFilter(f.Expression.Arguments.First());
                                    UnaryExpressionFilter rhs = new UnaryExpressionFilter(f.Expression.Arguments.Last());
                                    fs.RemoveAt(i);
                                    fs.Add(lhs);
                                    fs.Add(rhs);
                                }
                            }
                            // Finally we need to ensure the Unplaced Filters list is appropriately updated
                            gp.ResetFilters(fs);
                        }

                        foreach (ISparqlFilter f in gp.UnplacedFilters.ToList())
                        {
                            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
        }
Esempio n. 25
0
        private SparqlUpdateCommand TryParseInsertDataCommand(SparqlUpdateParserContext context)
        {
            InsertDataCommand cmd;

            SparqlQueryParserContext subContext = new SparqlQueryParserContext(context.Tokens);

            subContext.Query.BaseUri                        = context.BaseUri;
            subContext.Query.NamespaceMap                   = context.NamespaceMap;
            subContext.ExpressionParser.NamespaceMap        = context.NamespaceMap;
            subContext.ExpressionParser.ExpressionFactories = context.ExpressionFactories;
            subContext.ExpressionFactories                  = context.ExpressionFactories;
            subContext.CheckBlankNodeScope                  = false;
            GraphPattern gp = context.QueryParser.TryParseGraphPattern(subContext, context.Tokens.LastTokenType != Token.LEFTCURLYBRACKET);

            //Validate use of Blank Nodes in INSERT DATA, same BNode MAY be used within different graph patterns in a single command
            //though each represents a fresh blank node
            //The same BNode MAY NOT be used across separate commands
            if (context.DataBNodes.Count == 0)
            {
                //First INSERT DATA so simply register all the BNodes
                foreach (String var in gp.Variables.Where(v => v.StartsWith("_:")))
                {
                    context.DataBNodes.Add(var);
                }
            }
            else
            {
                //Some INSERT DATA commands have already occurred, validate that newly introduced variables are not already present
                foreach (String var in gp.Variables.Where(v => v.StartsWith("_:")).Distinct())
                {
                    if (context.DataBNodes.Contains(var))
                    {
                        throw new RdfParseException("An INSERT DATA command used the BNode " + var + " which has been used in previous INSERT DATA commands and is not permitted per Section 19.6 of the specification");
                    }
                    else
                    {
                        context.DataBNodes.Add(var);
                    }
                }
            }

            //Validate that the Graph Pattern is simple
            //Check it doesn't contain anything other than Triple Patterns or if it does it just contains a single GRAPH Pattern
            if (gp.IsFiltered)
            {
                throw new RdfParseException("A FILTER Clause cannot occur in a INSERT DATA Command");
            }
            else if (gp.IsOptional)
            {
                throw new RdfParseException("An OPTIONAL Clause cannot occur in a INSERT DATA Command");
            }
            else if (gp.IsUnion)
            {
                throw new RdfParseException("A UNION Clause cannot occur in a INSERT DATA Command");
            }
            else if (gp.HasChildGraphPatterns)
            {
                if (!gp.ChildGraphPatterns.All(p => (p.IsGraph && p.GraphSpecifier.TokenType != Token.VARIABLE) || (!p.IsExists && !p.IsMinus && !p.IsNotExists && !p.IsOptional && !p.IsOptional && !p.IsService && !p.IsSubQuery && !p.IsUnion && !p.IsGraph)))
                {
                    throw new RdfParseException("An INSERT DATA Command may only contain a combination of Triple Patterns and GRAPH clauses, GRAPH clauses must specify a Graph URI");
                }
                else if (gp.ChildGraphPatterns.Any(p => p.HasChildGraphPatterns))
                {
                    throw new RdfParseException("An INSERT DATA Command may not contain nested Graph Patterns");
                }
                else if (gp.ChildGraphPatterns.Count == 1 && gp.ChildGraphPatterns[0].IsGraph && gp.TriplePatterns.Count == 0)
                {
                    cmd = new InsertDataCommand(gp.ChildGraphPatterns[0]);
                }
                else if (gp.HasChildGraphPatterns)
                {
                    cmd = new InsertDataCommand(gp);
                }
                else
                {
                    throw new RdfParseException("Nested Graph Patterns cannot occur in a INSERT DATA Command");
                }
            }
            else
            {
                //OK
                cmd = new InsertDataCommand(gp);
            }

            return(cmd);
        }
Esempio n. 26
0
 /// <summary>
 /// Creates a new Graph Pattern Term.
 /// </summary>
 /// <param name="pattern">Graph Pattern.</param>
 public GraphPatternTerm(GraphPattern pattern)
 {
     _pattern = pattern;
 }
Esempio n. 27
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++)
                {
                    GraphPattern cgp = gp.ChildGraphPatterns[i];
                    if (cgp.HasModifier)
                    {
                        String formatted = this.Format(cgp);
                        formatted = formatted.TrimEnd(new char[] { '\n', '\r' });
                        if (formatted.Contains("\n"))
                        {
                            output.AppendLine("{");
                            output.AppendLineIndented(formatted, 2);
                            output.AppendLine("}");
                        }
                        else
                        {
                            output.AppendLine("{ " + formatted + "}");
                        }
                    }
                    else
                    {
                        output.AppendLine(this.Format(cgp));
                    }
                    if (i < gp.ChildGraphPatterns.Count - 1)
                    {
                        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(((ISubQueryPattern)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 || gp.HasInlineData)
            {
                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);
                }
                if (gp.HasInlineData)
                {
                    output.AppendLineIndented(this.FormatInlineData(gp.InlineData), 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)
                {
                    if (gp.HasInlineData)
                    {
                        output.AppendLineIndented("{", 2);
                        output.AppendLineIndented(this.FormatInlineData(gp.InlineData), 4);
                        output.AppendLineIndented("FILTER (" + this.FormatExpression(gp.Filter.Expression) + ")", 4);
                        output.AppendLineIndented("}", 2);
                    }
                    else
                    {
                        output.AppendIndented("{ FILTER(", 2);
                        output.Append(this.FormatExpression(gp.Filter.Expression));
                        output.AppendLine(") }");
                    }
                }
                else if (gp.HasInlineData)
                {
                    output.AppendLineIndented("{", 2);
                    output.AppendLineIndented(this.FormatInlineData(gp.InlineData), 4);
                    output.AppendLineIndented("}", 2);
                }
                else
                {
                    output.Append("{ }");
                }
            }
            else if (gp.HasInlineData)
            {
                output.AppendLineIndented("{", 2);
                output.AppendLineIndented(this.Format(gp.TriplePatterns[0]), 4);
                output.AppendLineIndented(this.FormatInlineData(gp.InlineData), 4);
                output.AppendLineIndented("}", 2);
            }
            else
            {
                output.Append("{ ");
                output.Append(this.Format(gp.TriplePatterns[0]));
                output.Append(" }");
            }

            return(output.ToString());
        }
Esempio n. 28
0
 public void AppendTo(GraphPattern graphPattern)
 {
     graphPattern.AddInlineData(_bindingsPattern);
 }
Esempio n. 29
0
 /// <summary>
 /// Creates a new Graph Pattern Expression
 /// </summary>
 /// <param name="pattern">Graph Pattern</param>
 public GraphPatternExpressionTerm(GraphPattern pattern)
 {
     this._pattern = pattern;
 }
Esempio n. 30
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)
 {
 }