/// <summary> /// Creates a new Bound Filter /// </summary> /// <param name="varTerm">Variable Expression</param> public BoundFilter(VariableExpressionTerm varTerm) : base(varTerm) { }
private ISparqlExpression TryParseBuiltInCall(Queue<IToken> tokens) { IToken next = tokens.Dequeue(); bool comma = false, first = true; List<ISparqlExpression> args; ISparqlExpression strExpr; switch (next.TokenType) { case Token.ABS: return new AbsFunction(this.TryParseBrackettedExpression(tokens)); case Token.BNODE: return new BNodeFunction(this.TryParseBrackettedExpression(tokens)); case Token.BOUND: //Expect a Left Bracket, Variable and then a Right Bracket next = tokens.Dequeue(); if (next.TokenType == Token.LEFTBRACKET) { next = tokens.Dequeue(); if (next.TokenType == Token.VARIABLE) { VariableExpressionTerm varExpr = new VariableExpressionTerm(next.Value); next = tokens.Dequeue(); if (next.TokenType == Token.RIGHTBRACKET) { return new BoundFunction(varExpr); } else { throw Error("Unexpected Token '" + next.GetType().ToString() + "' encountered, a Right Bracket to end a BOUND function call was expected",next); } } else { throw Error("Unexpected Token '" + next.GetType().ToString() + "' encountered, a Variable Token for a BOUND function call was expected", next); } } else { throw Error("Unexpected Token '" + next.GetType().ToString() + "' encountered, a Left Bracket to start a BOUND function call was expected", next); } case Token.CEIL: return new CeilFunction(this.TryParseBrackettedExpression(tokens)); case Token.COALESCE: //Get as many argument expressions as we can args = new List<ISparqlExpression>(); do { args.Add(this.TryParseBrackettedExpression(tokens, first, out comma)); first = false; } while (comma); return new CoalesceFunction(args); case Token.CONCAT: //Get as many argument expressions as we can args = new List<ISparqlExpression>(); do { args.Add(this.TryParseBrackettedExpression(tokens, first, out comma)); first = false; } while (comma); return new ConcatFunction(args); case Token.CONTAINS: return new ContainsFunction(this.TryParseBrackettedExpression(tokens), this.TryParseBrackettedExpression(tokens, false)); case Token.DATATYPEFUNC: return new DataTypeFunction(this.TryParseBrackettedExpression(tokens)); case Token.DAY: return new DayFunction(this.TryParseBrackettedExpression(tokens)); case Token.ENCODEFORURI: return new EncodeForUriFunction(this.TryParseBrackettedExpression(tokens)); case Token.FLOOR: return new FloorFunction(this.TryParseBrackettedExpression(tokens)); case Token.HOURS: return new HoursFunction(this.TryParseBrackettedExpression(tokens)); case Token.IF: return new IfElseFunction(this.TryParseBrackettedExpression(tokens, true, out comma), this.TryParseBrackettedExpression(tokens, false, out comma), this.TryParseBrackettedExpression(tokens, false, out comma)); case Token.IRI: case Token.URIFUNC: return new IriFunction(this.TryParseBrackettedExpression(tokens)); case Token.ISBLANK: return new IsBlankFunction(this.TryParseBrackettedExpression(tokens)); case Token.ISIRI: return new IsIriFunction(this.TryParseBrackettedExpression(tokens)); case Token.ISLITERAL: return new IsLiteralFunction(this.TryParseBrackettedExpression(tokens)); case Token.ISNUMERIC: return new IsNumericFunction(this.TryParseBrackettedExpression(tokens)); case Token.ISURI: return new IsUriFunction(this.TryParseBrackettedExpression(tokens)); case Token.LANG: return new LangFunction(this.TryParseBrackettedExpression(tokens)); case Token.LANGMATCHES: return new LangMatchesFunction(this.TryParseBrackettedExpression(tokens), this.TryParseBrackettedExpression(tokens, false)); case Token.LCASE: return new LCaseFunction(this.TryParseBrackettedExpression(tokens)); case Token.MD5: return new MD5HashFunction(this.TryParseBrackettedExpression(tokens)); case Token.MINUTES: return new MinutesFunction(this.TryParseBrackettedExpression(tokens)); case Token.MONTH: return new MonthFunction(this.TryParseBrackettedExpression(tokens)); case Token.NOW: //Expect a () after the Keyword Token next = tokens.Dequeue(); if (next.TokenType != Token.LEFTBRACKET) throw Error("Expected a Left Bracket after a NOW keyword to call the NOW() function", next); next = tokens.Dequeue(); if (next.TokenType != Token.RIGHTBRACKET) throw Error("Expected a Right Bracket after NOW( since the NOW() function does not take any arguments", next); return new NowFunction(); case Token.RAND: //Expect a () after the Keyword Token next = tokens.Dequeue(); if (next.TokenType != Token.LEFTBRACKET) throw Error("Expected a Left Bracket after a RAND keyword to call the RAND() function", next); next = tokens.Dequeue(); if (next.TokenType != Token.RIGHTBRACKET) throw Error("Expected a Right Bracket after RAND( since the RAND() function does not take any arguments", next); return new RandFunction(); case Token.REGEX: return this.TryParseRegexExpression(tokens); case Token.REPLACE: //REPLACE may have 3/4 arguments strExpr = this.TryParseBrackettedExpression(tokens); ISparqlExpression patternExpr = this.TryParseBrackettedExpression(tokens, false); ISparqlExpression replaceExpr = this.TryParseBrackettedExpression(tokens, false, out comma); if (comma) { ISparqlExpression opsExpr = this.TryParseBrackettedExpression(tokens, false); return new ReplaceFunction(strExpr, patternExpr, replaceExpr, opsExpr); } else { return new ReplaceFunction(strExpr, patternExpr, replaceExpr); } case Token.ROUND: return new RoundFunction(this.TryParseBrackettedExpression(tokens)); case Token.SAMETERM: return new SameTermFunction(this.TryParseBrackettedExpression(tokens), this.TryParseBrackettedExpression(tokens, false)); case Token.SECONDS: return new SecondsFunction(this.TryParseBrackettedExpression(tokens)); case Token.SHA1: return new Sha1HashFunction(this.TryParseBrackettedExpression(tokens)); case Token.SHA224: return new Sha224HashFunction(this.TryParseBrackettedExpression(tokens)); case Token.SHA256: return new Sha256HashFunction(this.TryParseBrackettedExpression(tokens)); case Token.SHA384: return new Sha384HashFunction(this.TryParseBrackettedExpression(tokens)); case Token.SHA512: return new Sha512HashFunction(this.TryParseBrackettedExpression(tokens)); case Token.STR: return new StrFunction(this.TryParseBrackettedExpression(tokens)); case Token.STRAFTER: return new StrAfterFunction(this.TryParseBrackettedExpression(tokens), this.TryParseBrackettedExpression(tokens, false)); case Token.STRBEFORE: return new StrBeforeFunction(this.TryParseBrackettedExpression(tokens), this.TryParseBrackettedExpression(tokens, false)); case Token.STRDT: return new StrDtFunction(this.TryParseBrackettedExpression(tokens), this.TryParseBrackettedExpression(tokens, false)); case Token.STRENDS: return new StrEndsFunction(this.TryParseBrackettedExpression(tokens), this.TryParseBrackettedExpression(tokens, false)); case Token.STRLANG: return new StrLangFunction(this.TryParseBrackettedExpression(tokens), this.TryParseBrackettedExpression(tokens, false)); case Token.STRLEN: return new StrLenFunction(this.TryParseBrackettedExpression(tokens)); case Token.STRSTARTS: return new StrStartsFunction(this.TryParseBrackettedExpression(tokens), this.TryParseBrackettedExpression(tokens, false)); case Token.SUBSTR: //SUBSTR may have 2/3 arguments strExpr = this.TryParseBrackettedExpression(tokens); ISparqlExpression startExpr = this.TryParseBrackettedExpression(tokens, false, out comma); if (comma) { ISparqlExpression lengthExpr = this.TryParseBrackettedExpression(tokens, false); return new SubStrFunction(strExpr, startExpr, lengthExpr); } else { return new SubStrFunction(strExpr, startExpr); } case Token.TIMEZONE: return new TimezoneFunction(this.TryParseBrackettedExpression(tokens)); case Token.TZ: return new TZFunction(this.TryParseBrackettedExpression(tokens)); case Token.UCASE: return new UCaseFunction(this.TryParseBrackettedExpression(tokens)); case Token.YEAR: return new YearFunction(this.TryParseBrackettedExpression(tokens)); case Token.EXISTS: case Token.NOTEXISTS: if (this._syntax == SparqlQuerySyntax.Sparql_1_0) throw new RdfParseException("EXISTS/NOT EXISTS clauses are not supported in SPARQL 1.0"); if (this._parser == null) throw new RdfParseException("Unable to parse an EXISTS/NOT EXISTS as there is no Query Parser to call into"); //Gather Tokens for the Pattern NonTokenisedTokenQueue temptokens = new NonTokenisedTokenQueue(); int openbrackets = 0; bool mustExist = (next.TokenType == Token.EXISTS); do { if (tokens.Count == 0) throw new RdfParseException("Unexpected end of Tokens while trying to parse an EXISTS/NOT EXISTS function"); next = tokens.Dequeue(); if (next.TokenType == Token.LEFTCURLYBRACKET) { openbrackets++; } else if (next.TokenType == Token.RIGHTCURLYBRACKET) { openbrackets--; } temptokens.Enqueue(next); } while (openbrackets > 0); //Call back into the Query Parser to try and Parse the Graph Pattern for the Function SparqlQueryParserContext tempcontext = new SparqlQueryParserContext(temptokens); tempcontext.Query.NamespaceMap.Import(this._nsmapper); tempcontext.Query.BaseUri = this._baseUri; return new ExistsFunction(this._parser.TryParseGraphPattern(tempcontext, true), mustExist); default: throw Error("Unexpected Token '" + next.GetType().ToString() + "' encountered while trying to parse a Built-in Function call", next); } }
/// <summary> /// Creates a new MEDIAN Aggregate /// </summary> /// <param name="expr">Variable Expression</param> public MedianAggregate(VariableExpressionTerm expr) : this(expr, false) { }
/// <summary> /// Creates a new MEDIAN Aggregate /// </summary> /// <param name="expr">Variable Expression</param> /// <param name="distinct">Whether a DISTINCT modifier applies</param> public MedianAggregate(VariableExpressionTerm expr, bool distinct) : base(expr, distinct) { this._varname = expr.ToString().Substring(1); }
/// <summary> /// Creates a new NMIN Aggregate /// </summary> /// <param name="expr">Variable Expression</param> public NumericMinAggregate(VariableExpressionTerm expr) : this(expr, false) { }
/// <summary> /// Creates a new MODE Aggregate /// </summary> /// <param name="expr">Variable Expression</param> public ModeAggregate(VariableExpressionTerm expr) : base(expr, false) { }
/// <summary> /// Creates a new AVG Aggregate /// </summary> /// <param name="expr">Variable Expression</param> public AverageAggregate(VariableExpressionTerm expr) : this(expr, false) { }
/// <summary> /// Creates a new COUNT(DISTINCT ?x) Aggregate /// </summary> /// <param name="expr">Variable Expression</param> public CountDistinctAggregate(VariableExpressionTerm expr) : base(expr) { this._varname = expr.ToString().Substring(1); }
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); } }