/// <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);
     }
 }
Beispiel #2
0
        /// <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);
        }