/// <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(); } }
/// <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; } }
private void TryParseBindAssignment(SparqlQueryParserContext context, GraphPattern p) { if (context.SyntaxMode == SparqlQuerySyntax.Sparql_1_0) throw new RdfParseException("BIND assignment is not supported in SPARQL 1.0"); //First need to discard opening ( IToken next = context.Tokens.Dequeue(); if (next.TokenType != Token.LEFTBRACKET) throw ParserHelper.Error("Unexpected Token '" + next.GetType().ToString() + "' encountered, expected a ( to start a BIND assignment after a BIND keyword", next); //Expect a bracketted expression terminated by an AS ISparqlExpression expr = this.TryParseExpression(context, false, true); if (context.Tokens.LastTokenType != Token.AS) { throw ParserHelper.Error("A BIND assignment did not end with an AS ?var as expected, BIND assignment must be of the general form BIND(expr AS ?var)", next); } //Ensure there is a Variable after the AS next = context.Tokens.Dequeue(); if (next.TokenType == Token.VARIABLE) { BindPattern bind = new BindPattern(next.Value.Substring(1), expr); //Check that the Variable has not already been used if (context.Query.RootGraphPattern != null && context.Query.RootGraphPattern.Variables.Contains(bind.VariableName)) { throw ParserHelper.Error("A BIND assignment is attempting to bind to the variable ?" + bind.VariableName + " but this variable is already in use in the query", next); } else if (p.Variables.Contains(bind.VariableName)) { throw ParserHelper.Error("A BIND assignment is attempting to bind to the variable ?" + bind.VariableName + " but this variable is already in use earlier in the Graph pattern", next); } if (Options.QueryOptimisation) { p.AddAssignment(bind); } else { //When Optimisation is turned off we'll just stick the BIND in the Triples Pattern where it occurs //since we're not going to do any Triple Pattern ordering, Assignment or FILTER placement p.AddTriplePattern(bind); //In this case the BIND must break the BGP since using AddTriplePattern will not do it automatically p.BreakBGP(); } //Ensure the BIND assignment is terminated with a ) next = context.Tokens.Dequeue(); if (next.TokenType != Token.RIGHTBRACKET) throw ParserHelper.Error("Unexpected Token '" + next.GetType().ToString() + "' encountered, expected a ) to terminate a BIND assignment", next); } else { throw ParserHelper.Error("Unexpected Token '" + next.GetType().ToString() + "' encountered, expected a Variable after the AS in a BIND assignment", next); } }
private void TryParseLetAssignment(SparqlQueryParserContext context, GraphPattern p) { if (context.SyntaxMode == SparqlQuerySyntax.Sparql_1_0) throw new RdfParseException("LET assignment is not supported in SPARQL 1.0"); if (context.SyntaxMode == SparqlQuerySyntax.Sparql_1_1) throw new RdfParseException("LET assignment is not supported in SPARQL 1.1 - use BIND assignment instead"); IToken variable; ISparqlExpression expr; //Firstly we expect an opening bracket, a variable and then an assignment operator IToken next = context.Tokens.Dequeue(); if (next.TokenType == Token.LEFTBRACKET) { next = context.Tokens.Dequeue(); if (next.TokenType == Token.VARIABLE) { variable = next; context.Query.AddVariable(variable.Value, false); next = context.Tokens.Dequeue(); if (next.TokenType == Token.ASSIGNMENT) { //See if there is a valid expression for the right hand side of the assignment next = context.Tokens.Peek(); switch (next.TokenType) { case Token.ABS: case Token.BNODE: case Token.BOUND: case Token.CEIL: case Token.COALESCE: case Token.CONCAT: case Token.DATATYPEFUNC: case Token.DAY: case Token.ENCODEFORURI: case Token.EXISTS: case Token.FLOOR: case Token.HOURS: case Token.IF: case Token.IRI: case Token.ISBLANK: case Token.ISIRI: case Token.ISLITERAL: case Token.ISNUMERIC: case Token.ISURI: case Token.LANG: case Token.LANGMATCHES: case Token.LCASE: case Token.MINUTES: case Token.MONTH: case Token.NOTEXISTS: case Token.NOW: case Token.RAND: case Token.REGEX: case Token.ROUND: case Token.SAMETERM: case Token.SECONDS: case Token.SHA1: case Token.SHA224: case Token.SHA256: case Token.SHA384: case Token.SHA512: case Token.STR: case Token.CONTAINS: case Token.STRDT: case Token.STRENDS: case Token.STRLANG: case Token.STRLEN: case Token.STRSTARTS: case Token.SUBSTR: case Token.TIMEZONE: case Token.TZ: case Token.UCASE: case Token.URIFUNC: case Token.YEAR: case Token.URI: case Token.QNAME: expr = this.TryParseFunctionExpression(context); break; case Token.LEFTBRACKET: context.Tokens.Dequeue(); expr = this.TryParseExpression(context, false); break; case Token.VARIABLE: context.Tokens.Dequeue(); expr = new VariableExpressionTerm(next.Value); break; default: throw ParserHelper.Error("Unexpected Token '" + next.GetType().ToString() + "' encountered, expected a Token which was valid as the start of an expression for the right hand side of a LET assignment", next); } //Finally expect a Right Bracket to terminate the LET next = context.Tokens.Dequeue(); if (next.TokenType != Token.RIGHTBRACKET) { throw ParserHelper.Error("Unexpected Token '" + next.GetType().ToString() + "' encountered, expected a Right Bracket to terminate the LET assignment", next); } //Create a Let Pattern and add to the Query appropriately LetPattern let = new LetPattern(variable.Value.Substring(1), expr); if (Options.QueryOptimisation) { p.AddAssignment(let); } else { //When Optimisation is turned off we'll just stick the Let in the Triples Pattern where it occurs //since we're not going to do any Triple Pattern ordering, Assignment or FILTER placement p.AddTriplePattern(let); } } else { throw ParserHelper.Error("Unexpected Token '" + next.GetType().ToString() + "' encountered, expected an Assignment operator as part of a LET assignment", next); } } else { throw ParserHelper.Error("Unexpected Token '" + next.GetType().ToString() + "' encountered, expected a Variable as the first item in a LET assignment", next); } } else { throw ParserHelper.Error("Unexpected Token '" + next.GetType().ToString() + "' encountered, expected a Left Bracket to start a LET assignment after a LET Keyword", next); } }