/// <summary> /// Substitutes a primary expression which is a Node term for a virtual Node term. /// </summary> /// <param name="expr">Expression.</param> /// <returns></returns> protected ISparqlExpression SubstitutePrimaryExpression(ISparqlExpression expr) { if (expr.GetType().Equals(_exprType)) { ConstantTerm term = (ConstantTerm)expr; INode curr = term.Evaluate(null, 0); TNodeID id = _provider.GetID(curr); if (id == null || id.Equals(_provider.NullID)) { throw new RdfQueryException("Cannot transform the Expression to use Virtual Nodes"); } INode virt = CreateVirtualNode(id, curr); return(new ConstantTerm(virt)); } else { return(expr); } }
/// <summary> /// Formats a SPARQL Expression /// </summary> /// <param name="expr">SPARQL Expression</param> /// <returns></returns> protected virtual String FormatExpression(ISparqlExpression expr) { StringBuilder output = new StringBuilder(); try { switch (expr.Type) { case SparqlExpressionType.Aggregate: if (expr is AggregateTerm) { AggregateTerm agg = (AggregateTerm)expr; output.Append(this.FormatAggregate(agg.Aggregate)); } else { output.Append(expr.ToString()); } break; case SparqlExpressionType.BinaryOperator: ISparqlExpression lhs = expr.Arguments.First(); ISparqlExpression rhs = expr.Arguments.Skip(1).First(); //Format the Expression wrapping the LHS and/or RHS in brackets if required //to ensure that ordering of operators is preserved if (lhs.Type == SparqlExpressionType.BinaryOperator) { output.Append('('); output.Append(this.FormatExpression(lhs)); output.Append(')'); } else { output.Append(this.FormatExpression(lhs)); } output.Append(' '); output.Append(expr.Functor); output.Append(' '); if (rhs.Type == SparqlExpressionType.BinaryOperator) { output.Append('('); output.Append(this.FormatExpression(rhs)); output.Append(')'); } else { output.Append(this.FormatExpression(rhs)); } break; case SparqlExpressionType.Function: //Show either a Keyword/URI/QName as appropriate if (SparqlSpecsHelper.IsFunctionKeyword(expr.Functor)) { output.Append(expr.Functor); } else { String funcQname; if (this._qnameMapper.ReduceToQName(expr.Functor, out funcQname)) { output.Append(funcQname); } else { output.Append('<'); output.Append(this.FormatUri(expr.Functor)); output.Append('>'); } } //Add Arguments list output.Append('('); List <ISparqlExpression> args = expr.Arguments.ToList(); for (int i = 0; i < args.Count; i++) { output.Append(this.FormatExpression(args[i])); if (i < args.Count - 1) { output.Append(", "); } } output.Append(')'); break; case SparqlExpressionType.GraphOperator: output.Append(expr.Functor); output.Append(' '); List <ISparqlExpression> gArgs = expr.Arguments.ToList(); if (gArgs.Count > 1) { throw new RdfOutputException("Error Formatting SPARQL Expression - Expressions of type GraphOperator are only allowed a single argument"); } for (int i = 0; i < gArgs.Count; i++) { output.Append(this.FormatExpression(gArgs[i])); if (i < gArgs.Count - 1) { output.Append(", "); } } break; case SparqlExpressionType.Primary: //If Node/Numeric Term then use Node Formatting otherwise use ToString() on the expression if (expr is ConstantTerm) { ConstantTerm nodeTerm = (ConstantTerm)expr; output.Append(this.Format(nodeTerm.Evaluate(null, 0))); } else if (expr is GraphPatternTerm) { GraphPatternTerm gp = (GraphPatternTerm)expr; output.Append(this.Format(gp.Pattern)); } else { output.Append(expr.ToString()); } break; case SparqlExpressionType.SetOperator: //Add First Argument and Set Operator output.Append(this.FormatExpression(expr.Arguments.First())); output.Append(' '); output.Append(expr.Functor); //Add Set output.Append(" ("); List <ISparqlExpression> set = expr.Arguments.Skip(1).ToList(); for (int i = 0; i < set.Count; i++) { output.Append(this.FormatExpression(set[i])); if (i < set.Count - 1) { output.Append(", "); } } output.Append(')'); break; case SparqlExpressionType.UnaryOperator: //Just Functor then Expression output.Append(expr.Functor); output.Append(this.FormatExpression(expr.Arguments.First())); break; } } catch (RdfOutputException) { throw; } catch (Exception ex) { throw new RdfOutputException("Error formatting a SPARQL Expression - the Expression may have the wrong number of arguments for the reported expression type", ex); } return(output.ToString()); }
/// <summary> /// Applies the Filter over the results of evaluating the inner pattern. /// </summary> /// <param name="context">Evaluation Context.</param> /// <returns></returns> public sealed override BaseMultiset Evaluate(SparqlEvaluationContext context) { INode term = _term.Evaluate(null, 0); // First take appropriate pre-filtering actions if (context.InputMultiset is IdentityMultiset) { // If the Input is Identity switch the input to be a Multiset containing a single Set // where the variable is bound to the term context.InputMultiset = new Multiset(); Set s = new Set(); s.Add(RestrictionVariable, term); context.InputMultiset.Add(s); } else if (context.InputMultiset is NullMultiset) { // If Input is Null then output is Null context.OutputMultiset = context.InputMultiset; return(context.OutputMultiset); } else { if (context.InputMultiset.ContainsVariable(RestrictionVariable)) { // If the Input Multiset contains the variable then pre-filter foreach (int id in context.InputMultiset.SetIDs.ToList()) { ISet x = context.InputMultiset[id]; try { if (x.ContainsVariable(RestrictionVariable)) { // If does exist check it has appropriate value and if not remove it if (!term.Equals(x[RestrictionVariable])) { context.InputMultiset.Remove(id); } } else { // If doesn't exist for this set then bind it to the term x.Add(RestrictionVariable, term); } } catch (RdfQueryException) { context.InputMultiset.Remove(id); } } } else { // If it doesn't contain the variable then bind for each existing set foreach (ISet x in context.InputMultiset.Sets) { x.Add(RestrictionVariable, term); } } } // Then evaluate the inner algebra BaseMultiset results = context.Evaluate(InnerAlgebra); if (results is NullMultiset || results is IdentityMultiset) { return(results); } // Filter the results to ensure that the variable is indeed bound to the term foreach (int id in results.SetIDs.ToList()) { ISet x = results[id]; try { if (!term.Equals(x[RestrictionVariable])) { results.Remove(id); } } catch (RdfQueryException) { results.Remove(id); } } if (results.Count > 0) { context.OutputMultiset = results; } else { context.OutputMultiset = new NullMultiset(); } return(context.OutputMultiset); }