Example #1
0
 /// <summary>
 /// Gets the value of the function in the given Evaluation Context for the given Binding ID
 /// </summary>
 /// <param name="context">Evaluation Context</param>
 /// <param name="bindingID">Binding ID</param>
 /// <returns></returns>
 public override IValuedNode Evaluate(SparqlEvaluationContext context, int bindingID)
 {
     INode temp = this._expr.Evaluate(context, bindingID);
     if (temp != null)
     {
         if (temp.NodeType == NodeType.Uri)
         {
             IUriNode u = (IUriNode)temp;
             if (!u.Uri.Fragment.Equals(String.Empty))
             {
                 return new StringNode(null, u.Uri.Fragment.Substring(1));
             }
             else
             {
     #if SILVERLIGHT
                 return new StringNode(null, u.Uri.Segments().Last());
     #else
                 return new StringNode(null, u.Uri.Segments.Last());
     #endif
             }
         }
         else
         {
             throw new RdfQueryException("Cannot find the Local Name for a non-URI Node");
         }
     }
     else
     {
         throw new RdfQueryException("Cannot find the Local Name for a null");
     }
 }
Example #2
0
        /// <summary>
        /// Evaluates an ExistsJoin
        /// </summary>
        /// <param name="context">Evaluation Context</param>
        /// <returns></returns>
        public BaseMultiset Evaluate(SparqlEvaluationContext context)
        {
            BaseMultiset initialInput = context.InputMultiset;
            BaseMultiset lhsResult = context.Evaluate(this._lhs);//this._lhs.Evaluate(context);
            context.CheckTimeout();

            if (lhsResult is NullMultiset)
            {
                context.OutputMultiset = lhsResult;
            }
            else if (lhsResult.IsEmpty)
            {
                context.OutputMultiset = new NullMultiset();
            }
            else
            {
                //Only execute the RHS if the LHS had results
                context.InputMultiset = lhsResult;
                BaseMultiset rhsResult = context.Evaluate(this._rhs);//this._rhs.Evaluate(context);
                context.CheckTimeout();

                context.OutputMultiset = lhsResult.ExistsJoin(rhsResult, this._mustExist);
                context.CheckTimeout();
            }

            context.InputMultiset = context.OutputMultiset;
            return context.OutputMultiset;
        }
 /// <summary>
 ///   Gets the numeric value of the function in the given Evaluation Context for the given Binding ID
 /// </summary>
 /// <param name = "context">Evaluation Context</param>
 /// <param name = "bindingID">Binding ID</param>
 /// <returns></returns>
 public override object NumericValue(SparqlEvaluationContext context, int bindingID)
 {
     INode temp = _expr.Value(context, bindingID);
     if (temp != null)
     {
         if (temp.NodeType == NodeType.Literal)
         {
             ILiteralNode lit = (ILiteralNode) temp;
             if (lit.DataType != null)
             {
                 if (lit.DataType.ToString().Equals(XmlSpecsHelper.XmlSchemaDataTypeDateTime) ||
                     lit.DataType.ToString().Equals(XmlSpecsHelper.XmlSchemaDataTypeDate))
                 {
                     DateTimeOffset dt;
                     if (DateTimeOffset.TryParse(lit.Value, out dt))
                     {
                         return NumericValueInternal(dt);
                     }
                     throw new RdfQueryException(
                         "Unable to evaluate an XPath Date Time function as the value of the Date Time typed literal couldn't be parsed as a Date Time");
                 }
                 throw new RdfQueryException(
                     "Unable to evaluate an XPath Date Time function on a typed literal which is not a Date Time");
             }
             throw new RdfQueryException(
                 "Unable to evaluate an XPath Date Time function on an untyped literal argument");
         }
         throw new RdfQueryException(
             "Unable to evaluate an XPath Date Time function on a non-literal argument");
     }
     throw new RdfQueryException("Unable to evaluate an XPath Date Time function on a null argument");
 }
Example #4
0
        /// <summary>
        /// Returns the value of the Expression as evaluated for a given Binding as a Literal Node
        /// </summary>
        /// <param name="context">Evaluation Context</param>
        /// <param name="bindingID">Binding ID</param>
        /// <returns></returns>
        public override IValuedNode Evaluate(SparqlEvaluationContext context, int bindingID)
        {
            INode result = this._expr.Evaluate(context, bindingID);
            if (result == null)
            {
                throw new RdfQueryException("Cannot return the Data Type URI of a NULL");
            }
            else
            {
                switch (result.NodeType)
                {
                    case NodeType.Literal:
                        ILiteralNode lit = (ILiteralNode)result;
                        if (lit.DataType == null)
                        {
                            if (!lit.Language.Equals(string.Empty))
                            {
                                return new UriNode(null, UriFactory.Create(RdfSpecsHelper.RdfLangString));
                            }
                            else
                            {
                                return new UriNode(null, UriFactory.Create(XmlSpecsHelper.XmlSchemaDataTypeString));
                            }
                        }
                        else
                        {
                            return new UriNode(null, lit.DataType);
                        }

                    default:
                        throw new RdfQueryException("Cannot return the Data Type URI of Nodes which are not Literal Nodes");
                }
            }
        }
        /// <summary>
        /// Evaluates the Select Distinct Graphs optimisation
        /// </summary>
        /// <param name="context">Evaluation Context</param>
        /// <returns></returns>
        public BaseMultiset Evaluate(SparqlEvaluationContext context)
        {
            context.OutputMultiset = new Multiset();
            String var;
            if (context.Query != null)
            {
                var = context.Query.Variables.First(v => v.IsResultVariable).Name;
            }
            else
            {
                var = this._graphVar;
            }

            foreach (Uri graphUri in context.Data.GraphUris)
            {
                Set s = new Set();
                if (graphUri == null)
                {
                    s.Add(var, null);
                }
                else
                {
                    s.Add(var, new UriNode(null, graphUri));
                }
                context.OutputMultiset.Add(s);
            }

            return context.OutputMultiset;
        }
Example #6
0
        /// <summary>
        /// Generates the Description for each of the Nodes to be described
        /// </summary>
        /// <param name="handler">RDF Handler</param>
        /// <param name="context">SPARQL Evaluation Context</param>
        /// <param name="nodes">Nodes to be described</param>
        protected override void DescribeInternal(IRdfHandler handler, SparqlEvaluationContext context, IEnumerable<INode> nodes)
        {
            //Rewrite Blank Node IDs for DESCRIBE Results
            Dictionary<String, INode> bnodeMapping = new Dictionary<string, INode>();

            //Get Triples for this Subject
            Queue<INode> bnodes = new Queue<INode>();
            HashSet<INode> expandedBNodes = new HashSet<INode>();
            INode rdfsLabel = handler.CreateUriNode(UriFactory.Create(NamespaceMapper.RDFS + "label"));
            foreach (INode n in nodes)
            {
                //Get Triples where the Node is the Subject
                foreach (Triple t in context.Data.GetTriplesWithSubject(n))
                {
                    if (t.Object.NodeType == NodeType.Blank)
                    {
                        if (!expandedBNodes.Contains(t.Object)) bnodes.Enqueue(t.Object);
                    }
                    if (!handler.HandleTriple((this.RewriteDescribeBNodes(t, bnodeMapping, handler)))) ParserHelper.Stop();
                }

                //Compute the Blank Node Closure for this Subject
                while (bnodes.Count > 0)
                {
                    INode bsubj = bnodes.Dequeue();
                    if (expandedBNodes.Contains(bsubj)) continue;
                    expandedBNodes.Add(bsubj);

                    foreach (Triple t2 in context.Data.GetTriplesWithSubjectPredicate(bsubj, rdfsLabel))
                    {
                        if (!handler.HandleTriple((this.RewriteDescribeBNodes(t2, bnodeMapping, handler)))) ParserHelper.Stop();
                    }
                }
            }
        }
 /// <summary>
 /// Computes the Effective Boolean Value of this Expression as evaluated for a given Binding
 /// </summary>
 /// <param name="context">Evaluation Context</param>
 /// <param name="bindingID">Binding ID</param>
 /// <returns></returns>
 public override bool EffectiveBooleanValue(SparqlEvaluationContext context, int bindingID)
 {
     //Lazy Evaluation for efficiency
     try
     {
         bool leftResult = this._leftExpr.EffectiveBooleanValue(context, bindingID);
         if (leftResult)
         {
             //If the LHS is true it doesn't matter about any subsequenct results
             return true;
         }
         else
         {
             //If the LHS is false then we have to evaluate the RHS
             return this._rightExpr.EffectiveBooleanValue(context, bindingID);
         }
     }
     catch
     {
         //If there's an Error on the LHS we return true only if the RHS evaluates to true
         //Otherwise we throw the Error
         bool rightResult = this._rightExpr.EffectiveBooleanValue(context, bindingID);
         if (rightResult)
         {
             return true;
         }
         else
         {
             throw;
         }
     }
 }
Example #8
0
        /// <summary>
        /// Evaluates a Filter in the given Evaluation Context
        /// </summary>
        /// <param name="context">Evaluation Context</param>
        public override void Evaluate(SparqlEvaluationContext context)
        {
            if (context.InputMultiset is NullMultiset)
            {
                //If we get a NullMultiset then the FILTER has no effect since there are already no results
            }
            else if (context.InputMultiset is IdentityMultiset)
            {
                if (!this._filter.Variables.Any())
                {
                    //If we get an IdentityMultiset then the FILTER only has an effect if there are no
                    //variables - otherwise it is not in scope and is ignored

                    try
                    {
                        if (!this._filter.Expression.EffectiveBooleanValue(context, 0))
                        {
                            context.OutputMultiset = new NullMultiset();
                            return;
                        }
                    }
                    catch
                    {
                        context.OutputMultiset = new NullMultiset();
                        return;
                    }
                }
            }
            else
            {
                this._filter.Evaluate(context);
            }
            context.OutputMultiset = new IdentityMultiset();
        }
Example #9
0
        /// <summary>
        /// Gets the Numeric Value of the function as evaluated in the given Context for the given Binding ID
        /// </summary>
        /// <param name="context">Evaluation Context</param>
        /// <param name="bindingID">Binding ID</param>
        /// <returns></returns>
        public override IValuedNode Evaluate(SparqlEvaluationContext context, int bindingID)
        {
            IValuedNode a = this._expr.Evaluate(context, bindingID);
            if (a == null) throw new RdfQueryException("Cannot calculate an arithmetic expression on a null");

            switch (a.NumericType)
            {
                case SparqlNumericType.Integer:
                    return new LongNode(null, Math.Abs(a.AsInteger()));

                case SparqlNumericType.Decimal:
                    return new DecimalNode(null, Math.Abs(a.AsDecimal()));

                case SparqlNumericType.Float:
                    try
                    {
                        return new FloatNode(null, Convert.ToSingle(Math.Abs(a.AsDouble())));
                    }
                    catch (RdfQueryException)
                    {
                        throw;
                    }
                    catch (Exception ex)
                    {
                        throw new RdfQueryException("Unable to cast absolute value of float to a float", ex);
                    }

                case SparqlNumericType.Double:
                    return new DoubleNode(null, Math.Abs(a.AsDouble()));

                default:
                    throw new RdfQueryException("Cannot evalute an Arithmetic Expression when the Numeric Type of the expression cannot be determined");
            }
        }
Example #10
0
        /// <summary>
        /// Calculates the Numeric Value of this Expression as evaluated for a given Binding
        /// </summary>
        /// <param name="context">Evaluation Context</param>
        /// <param name="bindingID">Binding ID</param>
        /// <returns></returns>
        public override IValuedNode Evaluate(SparqlEvaluationContext context, int bindingID)
        {
            IValuedNode a = this._expr.Evaluate(context, bindingID);
            if (a == null) throw new RdfQueryException("Cannot apply unary minus to a null");

            switch (a.NumericType)
            {
                case SparqlNumericType.Integer:
                    return new LongNode(null, -1 * a.AsInteger());

                case SparqlNumericType.Decimal:
                    decimal decvalue = a.AsDecimal();
                    if (decvalue == Decimal.Zero)
                    {
                        return new DecimalNode(null, Decimal.Zero);
                    }
                    else
                    {
                        return new DecimalNode(null, -1 * decvalue);
                    }
                case SparqlNumericType.Float:
                    float fltvalue = a.AsFloat();
                    if (Single.IsNaN(fltvalue))
                    {
                        return new FloatNode(null, Single.NaN);
                    }
                    else if (Single.IsPositiveInfinity(fltvalue))
                    {
                        return new FloatNode(null, Single.NegativeInfinity);
                    }
                    else if (Single.IsNegativeInfinity(fltvalue))
                    {
                        return new FloatNode(null, Single.PositiveInfinity);
                    }
                    else
                    {
                        return new FloatNode(null, -1.0f * fltvalue);
                    }
                case SparqlNumericType.Double:
                    double dblvalue = a.AsDouble();
                    if (Double.IsNaN(dblvalue))
                    {
                        return new DoubleNode(null, Double.NaN);
                    }
                    else if (Double.IsPositiveInfinity(dblvalue))
                    {
                        return new DoubleNode(null, Double.NegativeInfinity);
                    }
                    else if (Double.IsNegativeInfinity(dblvalue))
                    {
                        return new DoubleNode(null, Double.PositiveInfinity);
                    }
                    else
                    {
                        return new DoubleNode(null, -1.0 * dblvalue);
                    }
                default:
                    throw new RdfQueryException("Cannot evalute an Arithmetic Expression when the Numeric Type of the expression cannot be determined");
            }
        }
        /// <summary>
        /// Gets the Numeric Value of the Function as evaluated in the given Context for the given Binding ID
        /// </summary>
        /// <param name="context">Evaluation Context</param>
        /// <param name="bindingID">Binding ID</param>
        /// <returns></returns>
        public override object NumericValue(SparqlEvaluationContext context, int bindingID)
        {
            if (this._expr is ISparqlNumericExpression)
            {
                ISparqlNumericExpression a = (ISparqlNumericExpression)this._expr;

                SparqlNumericType type = a.NumericType(context, bindingID);
                switch (type)
                {
                    case SparqlNumericType.Integer:
                        return this.IntegerValueInternal(a.IntegerValue(context, bindingID));
                    case SparqlNumericType.Decimal:
                        return this.DecimalValueInternal(a.DecimalValue(context, bindingID));
                    case SparqlNumericType.Double:
                        return this.DoubleValueInternal(a.DoubleValue(context, bindingID));
                    case SparqlNumericType.NaN:
                    default:
                        throw new RdfQueryException("Unable to evaluate a Leviathan Numeric Expression since the inner expression did not evaluate to a Numeric Value");
                }
            }
            else
            {
                throw new RdfQueryException("Unable to evaluate a Leviathan Numeric Expression since the inner expression is not a Numeric Expression");
            }
        }
Example #12
0
        /// <summary>
        /// Calculates the Numeric Value of this Expression as evaluated for a given Binding
        /// </summary>
        /// <param name="context">Evaluation Context</param>
        /// <param name="bindingID">Binding ID</param>
        /// <returns></returns>
        public override IValuedNode Evaluate(SparqlEvaluationContext context, int bindingID)
        {
            IValuedNode a = this._leftExpr.Evaluate(context, bindingID);
            IValuedNode b = this._rightExpr.Evaluate(context, bindingID);
            if (a == null || b == null) throw new RdfQueryException("Cannot apply division when one/both arguments are null");

            SparqlNumericType type = (SparqlNumericType)Math.Max((int)a.NumericType, (int)b.NumericType);

            try
            {
                switch (type)
                {
                    case SparqlNumericType.Integer:
                    case SparqlNumericType.Decimal:
                        //For Division Integers are treated as decimals
                        decimal d = a.AsDecimal() / b.AsDecimal();
                        if (Decimal.Floor(d).Equals(d) && d >= Int64.MinValue && d <= Int64.MaxValue)
                        {
                            return new LongNode(null, Convert.ToInt64(d));
                        }
                        return new DecimalNode(null, d);
                    case SparqlNumericType.Float:
                        return new FloatNode(null, a.AsFloat() / b.AsFloat());
                    case SparqlNumericType.Double:
                        return new DoubleNode(null, a.AsDouble() / b.AsDouble());
                    default:
                        throw new RdfQueryException("Cannot evalute an Arithmetic Expression when the Numeric Type of the expression cannot be determined");
                }
            }
            catch (DivideByZeroException)
            {
                throw new RdfQueryException("Cannot evaluate a Division Expression where the divisor is Zero");
            }
        }
Example #13
0
        /// <summary>
        /// Gets the Timezone of the Argument Expression as evaluated for the given Binding in the given Context
        /// </summary>
        /// <param name="context">Evaluation Context</param>
        /// <param name="bindingID">Binding ID</param>
        /// <returns></returns>
        public override IValuedNode Evaluate(SparqlEvaluationContext context, int bindingID)
        {
            IValuedNode temp = this._expr.Evaluate(context, bindingID);
            if (temp != null)
            {
                DateTimeOffset dt = temp.AsDateTime();
                //Regex based check to see if the value has a Timezone component
                //If not then the result is a null
                if (!Regex.IsMatch(temp.AsString(), "(Z|[+-]\\d{2}:\\d{2})$")) return new StringNode(null, string.Empty);

                //Now we have a DateTime we can try and return the Timezone
                if (dt.Offset.Equals(TimeSpan.Zero))
                {
                    //If Zero it was specified as Z (which means UTC so zero offset)
                    return new StringNode(null, "Z");
                }
                else
                {
                    //If the Offset is outside the range -14 to 14 this is considered invalid
                    if (dt.Offset.Hours < -14 || dt.Offset.Hours > 14) return null;

                    //Otherwise it has an offset which is a given number of hours (and minutes)
                    return new StringNode(null, dt.Offset.Hours.ToString("00") + ":" + dt.Offset.Minutes.ToString("00"));
                }
            }
            else
            {
                throw new RdfQueryException("Unable to evaluate a Date Time function on a null argument");
            }
        }
        /// <summary>
        /// Calculates the Numeric Value of this Expression as evaluated for a given Binding
        /// </summary>
        /// <param name="context">Evaluation Context</param>
        /// <param name="bindingID">Binding ID</param>
        /// <returns></returns>
        public override object NumericValue(SparqlEvaluationContext context, int bindingID)
        {
            if (this._leftExpr is ISparqlNumericExpression && this._rightExpr is ISparqlNumericExpression)
            {
                ISparqlNumericExpression a, b;
                a = (ISparqlNumericExpression)this._leftExpr;
                b = (ISparqlNumericExpression)this._rightExpr;

                SparqlNumericType type = (SparqlNumericType)Math.Max((int)a.NumericType(context, bindingID), (int)b.NumericType(context, bindingID));

                switch (type)
                {
                    case SparqlNumericType.Integer:
                        return a.IntegerValue(context, bindingID) + b.IntegerValue(context, bindingID);
                    case SparqlNumericType.Decimal:
                        return a.DecimalValue(context, bindingID) + b.DecimalValue(context, bindingID);
                    case SparqlNumericType.Float:
                        return a.FloatValue(context, bindingID) + b.FloatValue(context, bindingID);
                    case SparqlNumericType.Double:
                        return a.DoubleValue(context, bindingID) + b.DoubleValue(context, bindingID);
                    default:
                        throw new RdfQueryException("Cannot evalute an Arithmetic Expression when the Numeric Type of the expression cannot be determined");
                }
            }
            else
            {
                throw new RdfQueryException("Cannot evalute an Arithmetic Expression where the two sub-expressions are not Numeric Expressions");
            }
        }
Example #15
0
 /// <summary>
 /// Gets the Value of the function as evaluated in the given Context for the given Binding ID
 /// </summary>
 /// <param name="context">Context</param>
 /// <param name="bindingID">Binding ID</param>
 /// <returns></returns>
 public INode Value(SparqlEvaluationContext context, int bindingID)
 {
     INode temp = this._expr.Value(context, bindingID);
     if (temp != null)
     {
         if (temp.NodeType == NodeType.Literal)
         {
             ILiteralNode lit = (ILiteralNode)temp;
             if (lit.DataType != null)
             {
                 if (lit.DataType.ToString().Equals(XmlSpecsHelper.XmlSchemaDataTypeString))
                 {
                     return this.ValueInternal(lit);
                 }
                 else
                 {
                     throw new RdfQueryException("Unable to evalaute an XPath String function on a non-string typed Literal");
                 }
             }
             else
             {
                 return this.ValueInternal(lit);
             }
         }
         else
         {
             throw new RdfQueryException("Unable to evaluate an XPath String function on a non-Literal input");
         }
     }
     else
     {
         throw new RdfQueryException("Unable to evaluate an XPath String function on a null input");
     }
 }
        /// <summary>
        /// Gets the Numeric Value of the function as evaluated in the given Context for the given Binding ID
        /// </summary>
        /// <param name="context">Evaluation Context</param>
        /// <param name="bindingID">Binding ID</param>
        /// <returns></returns>
        public override object NumericValue(SparqlEvaluationContext context, int bindingID)
        {
            if (this._expr is ISparqlNumericExpression)
            {
                ISparqlNumericExpression a = (ISparqlNumericExpression)this._expr;

                switch (a.NumericType(context, bindingID))
                {
                    case SparqlNumericType.Integer:
                        return Math.Abs(a.IntegerValue(context, bindingID));

                    case SparqlNumericType.Decimal:
                        return Math.Abs(a.DecimalValue(context, bindingID));

                    case SparqlNumericType.Float:
                        return (float)Math.Abs(a.DoubleValue(context, bindingID));

                    case SparqlNumericType.Double:
                        return Math.Abs(a.DoubleValue(context, bindingID));
                        
                    default:
                        throw new RdfQueryException("Cannot evalute an Arithmetic Expression when the Numeric Type of the expression cannot be determined");
                }
            }
            else
            {
                throw new RdfQueryException("Cannot evalute an Arithmetic Expression where the sub-expression is not a Numeric Expressions");
            }
        }
 /// <summary>
 /// Creates a new Path Evaluation Context
 /// </summary>
 /// <param name="context">SPARQL Evaluation Context</param>
 /// <param name="end">Start point of the Path</param>
 /// <param name="start">End point of the Path</param>
 public PathEvaluationContext(SparqlEvaluationContext context, PatternItem start, PatternItem end)
 {
     this._context = context;
     this._start = start;
     this._end = end;
     if (this._start.VariableName == null && this._end.VariableName == null) this._earlyAbort = true;
 }
        /// <summary>
        /// Returns the Graph which is the Result of the Describe Query by computing the Concise Bounded Description for all Results
        /// </summary>
        /// <param name="context">SPARQL Evaluation Context</param>
        /// <returns></returns>
        public override IGraph Describe(SparqlEvaluationContext context)
        {
            //Get a new empty Graph and import the Base Uri and Namespace Map of the Query
            Graph g = new Graph();
            g.BaseUri = context.Query.BaseUri;
            g.NamespaceMap.Import(context.Query.NamespaceMap);

            //Build a list of INodes to describe
            List<INode> nodes = new List<INode>();
            foreach (IToken t in context.Query.DescribeVariables)
            {
                switch (t.TokenType)
                {
                    case Token.QNAME:
                    case Token.URI:
                        //Resolve Uri/QName
                        nodes.Add(new UriNode(g, new Uri(Tools.ResolveUriOrQName(t, g.NamespaceMap, g.BaseUri))));
                        break;

                    case Token.VARIABLE:
                        //Get Variable Values
                        String var = t.Value.Substring(1);
                        if (context.OutputMultiset.ContainsVariable(var))
                        {
                            foreach (Set s in context.OutputMultiset.Sets)
                            {
                                INode temp = s[var];
                                if (temp != null) nodes.Add(temp);
                            }
                        }
                        break;

                    default:
                        throw new RdfQueryException("Unexpected Token '" + t.GetType().ToString() + "' in DESCRIBE Variables list");
                }
            }

            //Rewrite Blank Node IDs for DESCRIBE Results
            Dictionary<String, INode> bnodeMapping = new Dictionary<string, INode>();

            //Get Triples for this Subject
            foreach (INode n in nodes)
            {
                //Get Triples where the Node is the Subject
                foreach (Triple t in context.Data.GetTriplesWithSubject(n))
                {
                    g.Assert(this.RewriteDescribeBNodes(t, bnodeMapping, g));
                }
                //Get Triples where the Node is the Object
                foreach (Triple t in context.Data.GetTriplesWithObject(n))
                {
                    g.Assert(this.RewriteDescribeBNodes(t, bnodeMapping, g));
                }
            }

            //Return the Graph
            g.BaseUri = null;
            return g;
        }
        /// <summary>
        /// Evaluates the expression
        /// </summary>
        /// <param name="context">Evaluation Context</param>
        /// <param name="bindingID">Binding ID</param>
        /// <returns></returns>
        public override IValuedNode Evaluate(SparqlEvaluationContext context, int bindingID)
        {
            IValuedNode temp = this._expr.Evaluate(context, bindingID);
            if (temp == null) throw new RdfQueryException("Cannot apply a trigonometric function to a null");

            if (temp.NumericType == SparqlNumericType.NaN) throw new RdfQueryException("Cannot apply a trigonometric function to a non-numeric argument");

            return new DoubleNode(null, this._func(temp.AsDouble()));
        }
Example #20
0
        /// <summary>
        /// Evaluates the subquery in the given context
        /// </summary>
        /// <param name="context">Evaluation Context</param>
        /// <returns></returns>
        public BaseMultiset Evaluate(SparqlEvaluationContext context)
        {
            //Use the same algebra optimisers as the parent query (if any)
            if (context.Query != null)
            {
                this._subquery.AlgebraOptimisers = context.Query.AlgebraOptimisers;
            }

            if (context.InputMultiset is NullMultiset)
            {
                context.OutputMultiset = context.InputMultiset;
            }
            else if (context.InputMultiset.IsEmpty)
            {
                context.OutputMultiset = new NullMultiset();
            }
            else
            {
                SparqlEvaluationContext subcontext = new SparqlEvaluationContext(this._subquery, context.Data, context.Processor);
                subcontext.InputMultiset = context.InputMultiset;

                //Add any Named Graphs to the subquery
                if (context.Query != null)
                {
                    foreach (Uri u in context.Query.NamedGraphs)
                    {
                        this._subquery.AddNamedGraph(u);
                    }
                }

                ISparqlAlgebra query = this._subquery.ToAlgebra();
                try
                {
                    //Evaluate the Subquery
                    context.OutputMultiset = subcontext.Evaluate(query);

                    //If the Subquery contains a GROUP BY it may return a Group Multiset in which case we must flatten this to a Multiset
                    if (context.OutputMultiset is GroupMultiset)
                    {
                        context.OutputMultiset = new Multiset((GroupMultiset)context.OutputMultiset);
                    }

                    //Strip out any Named Graphs from the subquery
                    if (this._subquery.NamedGraphs.Any())
                    {
                        this._subquery.ClearNamedGraphs();
                    }
                }
                catch (RdfQueryException queryEx)
                {
                    throw new RdfQueryException("Query failed due to a failure in Subquery Execution:\n" + queryEx.Message, queryEx);
                }
            }

            return context.OutputMultiset;
        }
        /// <summary>
        ///   Gets the value of the function in the given Evaluation Context for the given Binding ID
        /// </summary>
        /// <param name = "context">Evaluation Context</param>
        /// <param name = "bindingID">Binding ID</param>
        /// <returns></returns>
        public INode Value(SparqlEvaluationContext context, int bindingID)
        {
            ILiteralNode input = CheckArgument(_expr, context, bindingID);
            ILiteralNode start = CheckArgument(_start, context, bindingID, XPathFunctionFactory.AcceptNumericArguments);

            if (_end != null)
            {
                ILiteralNode end = CheckArgument(_end, context, bindingID, XPathFunctionFactory.AcceptNumericArguments);

                if (input.Value.Equals(String.Empty))
                    return new LiteralNode(null, String.Empty, new Uri(XmlSpecsHelper.XmlSchemaDataTypeString));

                try
                {
                    int s = Convert.ToInt32(start.Value);
                    int e = Convert.ToInt32(end.Value);

                    if (s < 0) s = 0;
                    if (e < s)
                    {
                        //If no/negative characters are being selected the empty string is returned
                        return new LiteralNode(null, String.Empty, new Uri(XmlSpecsHelper.XmlSchemaDataTypeString));
                    }
                    if (s > input.Value.Length)
                    {
                        //If the start is after the end of the string the empty string is returned
                        return new LiteralNode(null, String.Empty, new Uri(XmlSpecsHelper.XmlSchemaDataTypeString));
                    }
                    return e > input.Value.Length
                               ? new LiteralNode(null, input.Value.Substring(s),
                                                 new Uri(XmlSpecsHelper.XmlSchemaDataTypeString))
                               : new LiteralNode(null, input.Value.Substring(s, e - s),
                                                 new Uri(XmlSpecsHelper.XmlSchemaDataTypeString));
                }
                catch
                {
                    throw new RdfQueryException("Unable to convert the Start/End argument to an Integer");
                }
            }
            if (input.Value.Equals(String.Empty))
                return new LiteralNode(null, String.Empty, new Uri(XmlSpecsHelper.XmlSchemaDataTypeString));

            try
            {
                int s = Convert.ToInt32(start.Value);
                if (s < 0) s = 0;

                return new LiteralNode(null, input.Value.Substring(s),
                                       new Uri(XmlSpecsHelper.XmlSchemaDataTypeString));
            }
            catch
            {
                throw new RdfQueryException("Unable to convert the Start argument to an Integer");
            }
        }
 /// <summary>
 /// Checks whether the pattern accepts the given Node
 /// </summary>
 /// <param name="context">SPARQL Evaluation Context</param>
 /// <param name="obj">Node to test</param>
 /// <returns></returns>
 protected internal override bool Accepts(SparqlEvaluationContext context, INode obj)
 {
     if (obj.NodeType == NodeType.Blank)
     {
         return ((IBlankNode)obj).InternalID.Equals(this._id);
     }
     else
     {
         return false;
     }
 }
 /// <summary>
 /// Checks whether the given Node matches the Node this pattern was instantiated with
 /// </summary>
 /// <param name="context">Evaluation Context</param>
 /// <param name="obj">Node to test</param>
 /// <returns></returns>
 protected internal override bool Accepts(SparqlEvaluationContext context, INode obj)
 {
     //if (context.RigorousEvaluation)
     //{
         return this._node.Equals(obj);
     //}
     //else
     //{
     //    return true;
     //}
 }
Example #24
0
        /// <summary>
        /// Casts the results of the inner expression to a Literal Node typed xsd:string
        /// </summary>
        /// <param name="context">Evaluation Context</param>
        /// <param name="bindingID">Binding ID</param>
        /// <returns></returns>
        public override IValuedNode Evaluate(SparqlEvaluationContext context, int bindingID)
        {
            IValuedNode n = this._expr.Evaluate(context, bindingID);

            if (n == null)
            {
                throw new RdfQueryException("Cannot cast a Null to a xsd:string");
            }

            return new StringNode(null, n.AsString(), UriFactory.Create(XmlSpecsHelper.XmlSchemaDataTypeString));
        }
 /// <summary>
 /// Gets the numeric value of the function in the given Evaluation Context for the given Binding ID
 /// </summary>
 /// <param name="context">Evaluation Context</param>
 /// <param name="bindingID">Binding ID</param>
 /// <returns></returns>
 public override IValuedNode Evaluate(SparqlEvaluationContext context, int bindingID)
 {
     IValuedNode temp = this._expr.Evaluate(context, bindingID);
     if (temp != null)
     {
         return this.ValueInternal(temp.AsDateTime());
     }
     else
     {
         throw new RdfQueryException("Unable to evaluate an XPath Date Time function on a null argument");
     }
 }
Example #26
0
 /// <summary>
 /// Computes the Effective Boolean Value of this Expression as evaluated for a given Binding
 /// </summary>
 /// <param name="context">Evaluation Context</param>
 /// <param name="bindingID">Binding ID</param>
 /// <returns></returns>
 public override IValuedNode Evaluate(SparqlEvaluationContext context, int bindingID)
 {
     INode result = this._expr.Evaluate(context, bindingID);
     if (result == null)
     {
         return new BooleanNode(null, false);
     }
     else
     {
         return new BooleanNode(null, result.NodeType == NodeType.Uri);
     }
 }
Example #27
0
        public BaseMultiset Evaluate(SparqlEvaluationContext context)
        {
            //First evaluate the inner algebra
            BaseMultiset results = context.Evaluate(this._inner);
            context.OutputMultiset = new Multiset();

            if (results is NullMultiset)
            {
                context.OutputMultiset = results;
            }
            else if (results is IdentityMultiset)
            {
                context.OutputMultiset.AddVariable(this._var);
                Set s = new Set();
                try
                {
                    INode temp = this._expr.Value(context, 0);
                    s.Add(this._var, temp);
                }
                catch
                {
                    //No assignment if there's an error
                    s.Add(this._var, null);
                }
                context.OutputMultiset.Add(s);
            }
            else
            {
                if (results.ContainsVariable(this._var))
                {
                    throw new RdfQueryException("Cannot use a BIND assigment to BIND to a variable that has previously been used in the Query");
                }

                context.OutputMultiset.AddVariable(this._var);
                foreach (int id in results.SetIDs.ToList())
                {
                    Set s = new Set(results[id]);
                    try
                    {
                        //Make a new assignment
                        INode temp = this._expr.Value(context, id);
                        s.Add(this._var, temp);
                    }
                    catch
                    {
                        //No assignment if there's an error but the solution is preserved
                    }
                    context.OutputMultiset.Add(s);
                }
            }

            return context.OutputMultiset;
        }
        /// <summary>
        /// Evaluates the Union
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public BaseMultiset Evaluate(SparqlEvaluationContext context)
        {
            //Create a copy of the evaluation context for the RHS
            SparqlEvaluationContext context2 = new SparqlEvaluationContext(context.Query, context.Data, context.Processor);
            if (!(context.InputMultiset is IdentityMultiset))
            {
                context2.InputMultiset = new Multiset();
                foreach (ISet s in context.InputMultiset.Sets)
                {
                    context2.InputMultiset.Add(s.Copy());
                }
            }

            IGraph activeGraph = context.Data.ActiveGraph;
            IGraph defaultGraph = context.Data.DefaultGraph;

            ParallelEvaluateDelegate d = new ParallelEvaluateDelegate(this.ParallelEvaluate);
            IAsyncResult lhs = d.BeginInvoke(this._lhs, context, activeGraph, defaultGraph, null, null);
            IAsyncResult rhs = d.BeginInvoke(this._rhs, context2, activeGraph, defaultGraph, null, null);

            WaitHandle.WaitAll(new WaitHandle[] { lhs.AsyncWaitHandle, rhs.AsyncWaitHandle });

            bool rhsOk = false;
            try 
            {
                BaseMultiset lhsResult = d.EndInvoke(lhs);
                rhsOk = true;
                BaseMultiset rhsResult = d.EndInvoke(rhs);
                context.CheckTimeout();

                context.OutputMultiset = lhsResult.Union(rhsResult);
                context.CheckTimeout();

                context.InputMultiset = context.OutputMultiset;
                return context.OutputMultiset;
            }
            catch 
            {
                if (!rhsOk)
                {
                    //Clean up the RHS evaluation call if the LHS has errored
                    try
                    {
                        d.EndInvoke(rhs);
                    }
                    catch
                    {
                        //Ignore this error as we're already going to throw the other error
                    }
                }
                throw;
            }
        }
 public override object NumericValue(SparqlEvaluationContext context, int bindingID)
 {
     INode value = this._expr.Value(context, bindingID);
     if (value != null)
     {
         if (value.NodeType == NodeType.Literal)
         {
             ILiteralNode lit = (ILiteralNode)value;
             if (!lit.Language.Equals(String.Empty))
             {
                 //If there's a Language Tag implied type is string so no numeric value
                 throw new RdfQueryException("Cannot calculate the Numeric Value of literal with a language specifier");
             }
             else if (lit.DataType == null)
             {
                 throw new RdfQueryException("Cannot calculate the Numeric Value of an untyped Literal");
             }
             else
             {
                 try
                 {
                     switch (SparqlSpecsHelper.GetNumericTypeFromDataTypeUri(lit.DataType))
                     {
                         case SparqlNumericType.Decimal:
                             return Decimal.Parse(lit.Value);
                         case SparqlNumericType.Double:
                             return Double.Parse(lit.Value);
                         case SparqlNumericType.Float:
                             return Single.Parse(lit.Value);
                         case SparqlNumericType.Integer:
                             return Int64.Parse(lit.Value);
                         case SparqlNumericType.NaN:
                         default:
                             throw new RdfQueryException("Cannot calculate the Numeric Value of a literal since its Data Type URI does not correspond to a Data Type URI recognised as a Numeric Type in the SPARQL Specification");
                     }
                 }
                 catch (FormatException fEx)
                 {
                     throw new RdfQueryException("Cannot calculate the Numeric Value of a Literal since the Value contained is not a valid value in it's given Data Type", fEx);
                 }
             }
         }
         else
         {
             throw new RdfQueryException("Cannot evaluate a numeric expression when the inner expression evaluates to a non-literal node");
         }
     }
     else
     {
         throw new RdfQueryException("Cannot evaluate a numeric expression when the inner expression evaluates to null");
     }
 }
Example #30
0
        /// <summary>
        /// Returns the value of the Expression as evaluated for a given Binding as a Literal Node
        /// </summary>
        /// <param name="context">Evaluation Context</param>
        /// <param name="bindingID">Binding ID</param>
        /// <returns></returns>
        public override IValuedNode Evaluate(SparqlEvaluationContext context, int bindingID)
        {
            INode s = this._leftExpr.Evaluate(context, bindingID);
            INode dt = this._rightExpr.Evaluate(context, bindingID);

            if (s != null)
            {
                if (dt != null)
                {
                    Uri dtUri;
                    if (dt.NodeType == NodeType.Uri)
                    {
                        dtUri = ((IUriNode)dt).Uri;
                    }
                    else
                    {
                        throw new RdfQueryException("Cannot create a datatyped literal when the datatype is a non-URI Node");
                    }
                    if (s.NodeType == NodeType.Literal)
                    {
                        ILiteralNode lit = (ILiteralNode)s;
                        if (lit.DataType == null)
                        {
                            if (lit.Language.Equals(string.Empty))
                            {
                                return new StringNode(null, lit.Value, dtUri);
                            }
                            else
                            {
                                throw new RdfQueryException("Cannot create a datatyped literal from a language specified literal");
                            }
                        }
                        else
                        {
                            throw new RdfQueryException("Cannot create a datatyped literal from a typed literal");
                        }
                    }
                    else
                    {
                        throw new RdfQueryException("Cannot create a datatyped literal from a non-literal Node");
                    }
                }
                else
                {
                    throw new RdfQueryException("Cannot create a datatyped literal from a null string");
                }
            }
            else
            {
                throw new RdfQueryException("Cannot create a datatyped literal from a null string");
            }
        }
Example #31
0
 /// <summary>
 /// Evaluates the function
 /// </summary>
 /// <param name="context">Context</param>
 /// <param name="bindingID">Binding ID</param>
 /// <returns></returns>
 public IValuedNode Evaluate(SparqlEvaluationContext context, int bindingID)
 {
     return(this._node);
 }
Example #32
0
        /// <summary>
        /// Evaluates the BGP against the Evaluation Context.
        /// </summary>
        /// <param name="context">Evaluation Context.</param>
        /// <returns></returns>
        public override BaseMultiset Evaluate(SparqlEvaluationContext context)
        {
            bool         halt;
            BaseMultiset results      = null;
            int          origRequired = _requiredResults;

            // May need to detect the actual amount of required results if not specified at instantation
            if (_requiredResults < 0)
            {
                if (context.Query != null)
                {
                    if (context.Query.HasDistinctModifier || (context.Query.OrderBy != null && !context.Query.IsOptimisableOrderBy) || context.Query.GroupBy != null || context.Query.Having != null || context.Query.Bindings != null)
                    {
                        // If there's an DISTINCT/ORDER BY/GROUP BY/HAVING/BINDINGS present then can't do Lazy evaluation
                        _requiredResults = -1;
                    }
                    else
                    {
                        int limit  = context.Query.Limit;
                        int offset = context.Query.Offset;
                        if (limit >= 0 && offset >= 0)
                        {
                            // If there is a Limit and Offset specified then the required results is the LIMIT+OFFSET
                            _requiredResults = limit + offset;
                        }
                        else if (limit >= 0)
                        {
                            // If there is just a Limit specified then the required results is the LIMIT
                            _requiredResults = limit;
                        }
                        else
                        {
                            // In any other case required results is everything i.e. -1
                            _requiredResults = -1;
                        }
                    }
                    Debug.WriteLine("Lazy Evaluation - Number of required results is " + _requiredResults);
                }
            }

            switch (_requiredResults)
            {
            case -1:
                // If required results is everything just use normal evaluation as otherwise
                // lazy evaluation will significantly impact performance and lead to an apparent infinite loop
                return(base.Evaluate(context));

            case 0:
                // Don't need any results
                results = new NullMultiset();
                break;

            default:
                // Do streaming evaluation
                if (_requiredResults != 0)
                {
                    results = StreamingEvaluate(context, 0, out halt);
                    if (results is Multiset && results.IsEmpty)
                    {
                        results = new NullMultiset();
                    }
                }
                break;
            }
            _requiredResults = origRequired;

            context.OutputMultiset = results;
            context.OutputMultiset.Trim();
            return(context.OutputMultiset);
        }
Example #33
0
        /// <summary>
        /// Evaluates a Zero Length Path
        /// </summary>
        /// <param name="context">Evaluation Context</param>
        /// <returns></returns>
        public override BaseMultiset Evaluate(SparqlEvaluationContext context)
        {
            if (this.AreBothTerms())
            {
                if (this.AreSameTerms())
                {
                    return(new IdentityMultiset());
                }
                else
                {
                    return(new NullMultiset());
                }
            }

            String subjVar = this.PathStart.VariableName;
            String objVar  = this.PathEnd.VariableName;

            context.OutputMultiset = new Multiset();

            //Determine the Triples to which this applies
            IEnumerable <Triple> ts = null;

            if (subjVar != null)
            {
                //Subject is a Variable
                if (context.InputMultiset.ContainsVariable(subjVar))
                {
                    //Subject is Bound
                    if (objVar != null)
                    {
                        //Object is a Variable
                        if (context.InputMultiset.ContainsVariable(objVar))
                        {
                            //Object is Bound
                            ts = (from s in context.InputMultiset.Sets
                                  where s[subjVar] != null && s[objVar] != null
                                  from t in context.Data.GetTriplesWithSubjectObject(s[subjVar], s[objVar])
                                  select t);
                        }
                        else
                        {
                            //Object is Unbound
                            ts = (from s in context.InputMultiset.Sets
                                  where s[subjVar] != null
                                  from t in context.Data.GetTriplesWithSubject(s[subjVar])
                                  select t);
                        }
                    }
                    else
                    {
                        //Object is a Term
                        //Preseve sets where the Object Term is equal to the currently bound Subject
                        INode objTerm = ((NodeMatchPattern)this.PathEnd).Node;
                        foreach (ISet s in context.InputMultiset.Sets)
                        {
                            INode temp = s[subjVar];
                            if (temp != null && temp.Equals(objTerm))
                            {
                                context.OutputMultiset.Add(s.Copy());
                            }
                        }
                    }
                }
                else
                {
                    //Subject is Unbound
                    if (objVar != null)
                    {
                        //Object is a Variable
                        if (context.InputMultiset.ContainsVariable(objVar))
                        {
                            //Object is Bound
                            ts = (from s in context.InputMultiset.Sets
                                  where s[objVar] != null
                                  from t in context.Data.GetTriplesWithObject(s[objVar])
                                  select t);
                        }
                        else
                        {
                            //Object is Unbound
                            HashSet <INode> nodes = new HashSet <INode>();
                            foreach (Triple t in context.Data.Triples)
                            {
                                nodes.Add(t.Subject);
                                nodes.Add(t.Object);
                            }
                            foreach (INode n in nodes)
                            {
                                Set s = new Set();
                                s.Add(subjVar, n);
                                s.Add(objVar, n);
                                context.OutputMultiset.Add(s);
                            }
                        }
                    }
                    else
                    {
                        //Object is a Term
                        //Create a single set with the Variable bound to the Object Term
                        Set s = new Set();
                        s.Add(subjVar, ((NodeMatchPattern)this.PathEnd).Node);
                        context.OutputMultiset.Add(s);
                    }
                }
            }
            else if (objVar != null)
            {
                //Subject is a Term but Object is a Variable
                if (context.InputMultiset.ContainsVariable(objVar))
                {
                    //Object is Bound
                    //Preseve sets where the Subject Term is equal to the currently bound Object
                    INode subjTerm = ((NodeMatchPattern)this.PathStart).Node;
                    foreach (ISet s in context.InputMultiset.Sets)
                    {
                        INode temp = s[objVar];
                        if (temp != null && temp.Equals(subjTerm))
                        {
                            context.OutputMultiset.Add(s.Copy());
                        }
                    }
                }
                else
                {
                    //Object is Unbound
                    //Create a single set with the Variable bound to the Suject Term
                    Set s = new Set();
                    s.Add(objVar, ((NodeMatchPattern)this.PathStart).Node);
                    context.OutputMultiset.Add(s);
                }
            }
            else
            {
                //Should already have dealt with this earlier (the AreBothTerms() and AreSameTerms() branch)
                throw new RdfQueryException("Reached unexpected point of ZeroLengthPath evaluation");
            }

            //Get the Matches only if we haven't already generated the output
            if (ts != null)
            {
                HashSet <KeyValuePair <INode, INode> > matches = new HashSet <KeyValuePair <INode, INode> >();
                foreach (Triple t in ts)
                {
                    if (this.PathStart.Accepts(context, t.Subject) && this.PathEnd.Accepts(context, t.Object))
                    {
                        matches.Add(new KeyValuePair <INode, INode>(t.Subject, t.Object));
                    }
                }

                //Generate the Output based on the mathces
                if (matches.Count == 0)
                {
                    context.OutputMultiset = new NullMultiset();
                }
                else
                {
                    if (this.PathStart.VariableName == null && this.PathEnd.VariableName == null)
                    {
                        context.OutputMultiset = new IdentityMultiset();
                    }
                    else
                    {
                        context.OutputMultiset = new Multiset();
                        foreach (KeyValuePair <INode, INode> m in matches)
                        {
                            Set s = new Set();
                            if (subjVar != null)
                            {
                                s.Add(subjVar, m.Key);
                            }
                            if (objVar != null)
                            {
                                s.Add(objVar, m.Value);
                            }
                            context.OutputMultiset.Add(s);
                        }
                    }
                }
            }
            return(context.OutputMultiset);
        }
Example #34
0
        /// <summary>
        /// Gets the Timezone of the Argument Expression as evaluated for the given Binding in the given Context
        /// </summary>
        /// <param name="context">Evaluation Context</param>
        /// <param name="bindingID">Binding ID</param>
        /// <returns></returns>
        public override INode Value(SparqlEvaluationContext context, int bindingID)
        {
            INode temp = this._expr.Value(context, bindingID);

            if (temp != null)
            {
                if (temp.NodeType == NodeType.Literal)
                {
                    ILiteralNode lit = (ILiteralNode)temp;
                    if (lit.DataType != null)
                    {
                        if (lit.DataType.ToString().Equals(XmlSpecsHelper.XmlSchemaDataTypeDateTime))
                        {
                            DateTimeOffset dt;
                            if (DateTimeOffset.TryParse(lit.Value, out dt))
                            {
                                //Regex based check to see if the value has a Timezone component
                                //If not then the result is a null
                                if (!Regex.IsMatch(lit.Value, "(Z|[+-]\\d{2}:\\d{2})$"))
                                {
                                    return(new LiteralNode(null, String.Empty));
                                }

                                //Now we have a DateTime we can try and return the Timezone
                                if (dt.Offset.Equals(TimeSpan.Zero))
                                {
                                    //If Zero it was specified as Z (which means UTC so zero offset)
                                    return(new LiteralNode(null, "Z"));
                                }
                                else
                                {
                                    //If the Offset is outside the range -14 to 14 this is considered invalid
                                    if (dt.Offset.Hours < -14 || dt.Offset.Hours > 14)
                                    {
                                        return(null);
                                    }

                                    //Otherwise it has an offset which is a given number of hours (and minutes)
                                    return(new LiteralNode(null, dt.Offset.Hours.ToString("00") + ":" + dt.Offset.Minutes.ToString("00")));
                                }
                            }
                            else
                            {
                                throw new RdfQueryException("Unable to evaluate a Date Time function as the value of the Date Time typed literal couldn't be parsed as a Date Time");
                            }
                        }
                        else
                        {
                            throw new RdfQueryException("Unable to evaluate a Date Time function on a typed literal which is not a Date Time");
                        }
                    }
                    else
                    {
                        throw new RdfQueryException("Unable to evaluate a Date Time function on an untyped literal argument");
                    }
                }
                else
                {
                    throw new RdfQueryException("Unable to evaluate a Date Time function on a non-literal argument");
                }
            }
            else
            {
                throw new RdfQueryException("Unable to evaluate a Date Time function on a null argument");
            }
        }
Example #35
0
        /// <summary>
        /// Calculates the Numeric Value of this Expression as evaluated for a given Binding
        /// </summary>
        /// <param name="context">Evaluation Context</param>
        /// <param name="bindingID">Binding ID</param>
        /// <returns></returns>
        public override Object NumericValue(SparqlEvaluationContext context, int bindingID)
        {
            if (this._expr is ISparqlNumericExpression)
            {
                ISparqlNumericExpression a = (ISparqlNumericExpression)this._expr;

                switch (a.NumericType(context, bindingID))
                {
                case SparqlNumericType.Integer:
                    return(-1 * a.IntegerValue(context, bindingID));

                case SparqlNumericType.Decimal:
                    decimal decvalue = a.DecimalValue(context, bindingID);
                    if (decvalue == 0)
                    {
                        return(0.0m);
                    }
                    else
                    {
                        return(-1 * decvalue);
                    }

                case SparqlNumericType.Float:
                    float fltvalue = a.FloatValue(context, bindingID);
                    if (Single.IsNaN(fltvalue))
                    {
                        return(Single.NaN);
                    }
                    else if (Single.IsPositiveInfinity(fltvalue))
                    {
                        return(Single.NegativeInfinity);
                    }
                    else if (Single.IsNegativeInfinity(fltvalue))
                    {
                        return(Single.PositiveInfinity);
                    }
                    else
                    {
                        return(-1.0 * fltvalue);
                    }

                case SparqlNumericType.Double:
                    double dblvalue = a.DoubleValue(context, bindingID);
                    if (Double.IsNaN(dblvalue))
                    {
                        return(Double.NaN);
                    }
                    else if (Double.IsPositiveInfinity(dblvalue))
                    {
                        return(Double.NegativeInfinity);
                    }
                    else if (Double.IsNegativeInfinity(dblvalue))
                    {
                        return(Double.PositiveInfinity);
                    }
                    else
                    {
                        return(-1.0 * dblvalue);
                    }

                default:
                    throw new RdfQueryException("Cannot evalute an Arithmetic Expression when the Numeric Type of the expression cannot be determined");
                }
            }
            else
            {
                throw new RdfQueryException("Cannot evalute an Arithmetic Expression where the sub-expression is not a Numeric Expressions");
            }
        }
Example #36
0
        /// <summary>
        /// Casts the value of the inner Expression to a Boolean
        /// </summary>
        /// <param name="context">Evaluation Context</param>
        /// <param name="bindingID">Binding ID</param>
        /// <returns></returns>
        public override IValuedNode Evaluate(SparqlEvaluationContext context, int bindingID)
        {
            IValuedNode n = this._expr.Evaluate(context, bindingID);//.CoerceToBoolean();

            //if (n == null)
            //{
            //    throw new RdfQueryException("Cannot cast a Null to a xsd:boolean");
            //}

            ////New method should be much faster
            //if (n is BooleanNode) return n;
            //return new BooleanNode(null, n.AsBoolean());

            switch (n.NodeType)
            {
            case NodeType.Blank:
            case NodeType.GraphLiteral:
            case NodeType.Uri:
                throw new RdfQueryException("Cannot cast a Blank/URI/Graph Literal Node to a xsd:boolean");

            case NodeType.Literal:
                //See if the value can be cast
                if (n is BooleanNode)
                {
                    return(n);
                }
                ILiteralNode lit = (ILiteralNode)n;
                if (lit.DataType != null)
                {
                    string dt = lit.DataType.ToString();

                    if (dt.Equals(XmlSpecsHelper.XmlSchemaDataTypeBoolean))
                    {
                        //Already a Boolean
                        bool b;
                        if (Boolean.TryParse(lit.Value, out b))
                        {
                            return(new BooleanNode(lit.Graph, b));
                        }
                        else
                        {
                            throw new RdfQueryException("Invalid Lexical Form for xsd:boolean");
                        }
                    }

                    //Cast based on Numeric Type
                    SparqlNumericType type = SparqlSpecsHelper.GetNumericTypeFromDataTypeUri(dt);

                    switch (type)
                    {
                    case SparqlNumericType.Decimal:
                        Decimal dec;
                        if (Decimal.TryParse(lit.Value, NumberStyles.Any, CultureInfo.InvariantCulture, out dec))
                        {
                            if (dec.Equals(Decimal.Zero))
                            {
                                return(new BooleanNode(lit.Graph, false));
                            }
                            else
                            {
                                return(new BooleanNode(lit.Graph, true));
                            }
                        }
                        else
                        {
                            throw new RdfQueryException("Cannot cast the value '" + lit.Value + "' to a xsd:decimal as an intermediate stage in casting to a xsd:boolean");
                        }

                    case SparqlNumericType.Double:
                        Double dbl;
                        if (Double.TryParse(lit.Value, NumberStyles.Any, CultureInfo.InvariantCulture, out dbl))
                        {
                            if (Double.IsNaN(dbl) || dbl == 0.0d)
                            {
                                return(new BooleanNode(lit.Graph, false));
                            }
                            else
                            {
                                return(new BooleanNode(lit.Graph, true));
                            }
                        }
                        else
                        {
                            throw new RdfQueryException("Cannot cast the value '" + lit.Value + "' to a xsd:double as an intermediate stage in casting to a xsd:boolean");
                        }

                    case SparqlNumericType.Integer:
                        Int64 i;
                        if (Int64.TryParse(lit.Value, out i))
                        {
                            if (i == 0)
                            {
                                return(new BooleanNode(lit.Graph, false));
                            }
                            else
                            {
                                return(new BooleanNode(lit.Graph, true));
                            }
                        }
                        else
                        {
                            throw new RdfQueryException("Cannot cast the value '" + lit.Value + "' to a xsd:integer as an intermediate stage in casting to a xsd:boolean");
                        }

                    case SparqlNumericType.NaN:
                        if (dt.Equals(XmlSpecsHelper.XmlSchemaDataTypeDateTime))
                        {
                            //DateTime cast forbidden
                            throw new RdfQueryException("Cannot cast a xsd:dateTime to a xsd:boolean");
                        }
                        else
                        {
                            Boolean b;
                            if (Boolean.TryParse(lit.Value, out b))
                            {
                                return(new BooleanNode(lit.Graph, b));
                            }
                            else
                            {
                                throw new RdfQueryException("Cannot cast the value '" + lit.Value + "' to a xsd:boolean");
                            }
                        }

                    default:
                        throw new RdfQueryException("Cannot cast the value '" + lit.Value + "' to a xsd:boolean");
                    }
                }
                else
                {
                    Boolean b;
                    if (Boolean.TryParse(lit.Value, out b))
                    {
                        return(new BooleanNode(lit.Graph, b));
                    }
                    else
                    {
                        throw new RdfQueryException("Cannot cast the value '" + lit.Value + "' to a xsd:boolean");
                    }
                }

            default:
                throw new RdfQueryException("Cannot cast an Unknown Node to a xsd:decimal");
            }
        }
        /// <summary>
        /// Applies the Numeric Min Aggregate function to the results
        /// </summary>
        /// <param name="context">Evaluation Context</param>
        /// <param name="bindingIDs">Binding IDs over which the Aggregate applies</param>
        /// <returns></returns>
        public override IValuedNode Apply(SparqlEvaluationContext context, IEnumerable <int> bindingIDs)
        {
            if (this._varname != null)
            {
                // Ensured the MINed variable is in the Variables of the Results
                if (!context.Binder.Variables.Contains(this._varname))
                {
                    throw new RdfQueryException("Cannot use the Variable " + this._expr.ToString() + " in a NMIN Aggregate since the Variable does not occur in a Graph Pattern");
                }
            }

            // Prep Variables
            long              lngmin  = 0;
            decimal           decmin  = 0.0m;
            float             fltmin  = 0.0f;
            double            dblmin  = 0.0d;
            SparqlNumericType mintype = SparqlNumericType.NaN;
            SparqlNumericType numtype;

            foreach (int id in bindingIDs)
            {
                IValuedNode temp;
                try
                {
                    temp = this._expr.Evaluate(context, id);
                    if (temp == null)
                    {
                        continue;
                    }
                    numtype = temp.NumericType;
                }
                catch
                {
                    continue;
                }

                // Skip if Not a Number
                if (numtype == SparqlNumericType.NaN)
                {
                    continue;
                }

                // Track the Numeric Type
                if ((int)numtype > (int)mintype)
                {
                    if (mintype == SparqlNumericType.NaN)
                    {
                        // Initialise Minimums
                        switch (numtype)
                        {
                        case SparqlNumericType.Integer:
                            lngmin = temp.AsInteger();
                            decmin = temp.AsDecimal();
                            fltmin = temp.AsFloat();
                            dblmin = temp.AsDouble();
                            break;

                        case SparqlNumericType.Decimal:
                            decmin = temp.AsDecimal();
                            fltmin = temp.AsFloat();
                            dblmin = temp.AsDouble();
                            break;

                        case SparqlNumericType.Float:
                            fltmin = temp.AsFloat();
                            dblmin = temp.AsDouble();
                            break;

                        case SparqlNumericType.Double:
                            dblmin = temp.AsDouble();
                            break;
                        }
                        mintype = numtype;
                        continue;
                    }
                    else
                    {
                        mintype = numtype;
                    }
                }

                long    lngval;
                decimal decval;
                float   fltval;
                double  dblval;
                switch (mintype)
                {
                case SparqlNumericType.Integer:
                    lngval = temp.AsInteger();

                    if (lngval < lngmin)
                    {
                        lngmin = lngval;
                        decmin = temp.AsDecimal();
                        fltmin = temp.AsFloat();
                        dblmin = temp.AsDouble();
                    }
                    break;

                case SparqlNumericType.Decimal:
                    decval = temp.AsDecimal();

                    if (decval < decmin)
                    {
                        decmin = decval;
                        fltmin = temp.AsFloat();
                        dblmin = temp.AsDouble();
                    }
                    break;

                case SparqlNumericType.Float:
                    fltval = temp.AsFloat();

                    if (fltval < fltmin)
                    {
                        fltmin = fltval;
                        dblmin = temp.AsDouble();
                    }
                    break;

                case SparqlNumericType.Double:
                    dblval = temp.AsDouble();

                    if (dblval < dblmin)
                    {
                        dblmin = dblval;
                    }
                    break;
                }
            }

            // Return the Min
            switch (mintype)
            {
            case SparqlNumericType.NaN:
                // No Numeric Values
                return(null);

            case SparqlNumericType.Integer:
                // Integer Values
                return(new LongNode(null, lngmin));

            case SparqlNumericType.Decimal:
                // Decimal Values
                return(new DecimalNode(null, decmin));

            case SparqlNumericType.Float:
                // Float Values
                return(new FloatNode(null, fltmin));

            case SparqlNumericType.Double:
                // Double Values
                return(new DoubleNode(null, dblmin));

            default:
                throw new RdfQueryException("Failed to calculate a valid Minimum");
            }
        }
Example #38
0
        /// <summary>
        /// Trims the Results of evaluating the inner pattern to remove Variables which are not Result Variables.
        /// </summary>
        /// <param name="context">Evaluation Context.</param>
        /// <returns></returns>
        public BaseMultiset Evaluate(SparqlEvaluationContext context)
        {
            try
            {
                context.InputMultiset = context.Evaluate(_pattern);
            }
            catch (RdfQueryTimeoutException)
            {
                // If not partial results throw the error
                if (context.Query == null || !context.Query.PartialResultsOnTimeout)
                {
                    throw;
                }
            }

            // Ensure expected variables are present
            HashSet <SparqlVariable> vars = new HashSet <SparqlVariable>(_variables);

            if (context.InputMultiset is NullMultiset)
            {
                context.InputMultiset = new Multiset(vars.Select(v => v.Name));
            }
            else if (context.InputMultiset is IdentityMultiset)
            {
                context.InputMultiset = new Multiset(vars.Select(v => v.Name));
                context.InputMultiset.Add(new Set());
            }
            else if (context.InputMultiset.IsEmpty)
            {
                foreach (SparqlVariable var in vars)
                {
                    context.InputMultiset.AddVariable(var.Name);
                }
            }

            // Trim Variables that aren't being SELECTed
            if (!IsSelectAll)
            {
                foreach (String var in context.InputMultiset.Variables.ToList())
                {
                    if (!vars.Any(v => v.Name.Equals(var) && v.IsResultVariable))
                    {
                        // If not a Result variable then trim from results
                        context.InputMultiset.Trim(var);
                    }
                }
            }

            // Ensure all SELECTed variables are present
            foreach (SparqlVariable var in vars)
            {
                if (!context.InputMultiset.ContainsVariable(var.Name))
                {
                    context.InputMultiset.AddVariable(var.Name);
                }
            }

            context.OutputMultiset = context.InputMultiset;

            // Apply variable ordering if applicable
            if (!IsSelectAll && (context.Query == null || SparqlSpecsHelper.IsSelectQuery(context.Query.QueryType)))
            {
                context.OutputMultiset.SetVariableOrder(context.Query.Variables.Where(v => v.IsResultVariable).Select(v => v.Name));
            }
            return(context.OutputMultiset);
        }
        /// <summary>
        /// Generates the Description for each of the Nodes to be described
        /// </summary>
        /// <param name="handler">RDF Handler</param>
        /// <param name="context">SPARQL Evaluation Context</param>
        /// <param name="nodes">Nodes to be described</param>
        protected override void DescribeInternal(IRdfHandler handler, SparqlEvaluationContext context, IEnumerable <INode> nodes)
        {
            // Rewrite Blank Node IDs for DESCRIBE Results
            Dictionary <String, INode> bnodeMapping = new Dictionary <string, INode>();

            // Get Triples for this Subject
            Queue <INode>   bnodes         = new Queue <INode>();
            HashSet <INode> expandedBNodes = new HashSet <INode>();

            foreach (INode n in nodes)
            {
                // Get Triples where the Node is the Subject
                foreach (Triple t in context.Data.GetTriplesWithSubject(n).ToList())
                {
                    if (t.Object.NodeType == NodeType.Blank)
                    {
                        if (!expandedBNodes.Contains(t.Object))
                        {
                            bnodes.Enqueue(t.Object);
                        }
                    }
                    if (!handler.HandleTriple(RewriteDescribeBNodes(t, bnodeMapping, handler)))
                    {
                        ParserHelper.Stop();
                    }
                }
                // Get Triples where the Node is the Object
                foreach (Triple t in context.Data.GetTriplesWithObject(n).ToList())
                {
                    if (t.Subject.NodeType == NodeType.Blank)
                    {
                        if (!expandedBNodes.Contains(t.Subject))
                        {
                            bnodes.Enqueue(t.Subject);
                        }
                    }
                    if (!handler.HandleTriple(RewriteDescribeBNodes(t, bnodeMapping, handler)))
                    {
                        ParserHelper.Stop();
                    }
                }

                // Compute the Blank Node Closure for this Subject
                while (bnodes.Count > 0)
                {
                    INode bsubj = bnodes.Dequeue();
                    if (expandedBNodes.Contains(bsubj))
                    {
                        continue;
                    }
                    expandedBNodes.Add(bsubj);

                    foreach (Triple t2 in context.Data.GetTriplesWithSubject(bsubj).ToList())
                    {
                        if (t2.Object.NodeType == NodeType.Blank)
                        {
                            if (!expandedBNodes.Contains(t2.Object))
                            {
                                bnodes.Enqueue(t2.Object);
                            }
                        }
                        if (!handler.HandleTriple(RewriteDescribeBNodes(t2, bnodeMapping, handler)))
                        {
                            ParserHelper.Stop();
                        }
                    }
                    foreach (Triple t2 in context.Data.GetTriplesWithObject(bsubj).ToList())
                    {
                        if (t2.Subject.NodeType == NodeType.Blank)
                        {
                            if (!expandedBNodes.Contains(t2.Subject))
                            {
                                bnodes.Enqueue(t2.Subject);
                            }
                        }
                        if (!handler.HandleTriple(RewriteDescribeBNodes(t2, bnodeMapping, handler)))
                        {
                            ParserHelper.Stop();
                        }
                    }
                }
            }
        }
Example #40
0
 /// <summary>
 /// Evaluates the expression.
 /// </summary>
 /// <param name="context">Evaluation Context.</param>
 /// <param name="bindingID">Binding ID.</param>
 /// <returns></returns>
 public override IValuedNode Evaluate(SparqlEvaluationContext context, int bindingID)
 {
     return(new BooleanNode(null, _expr.Evaluate(context, bindingID).AsSafeBoolean()));
 }
 /// <summary>
 /// Evaluates a filter in the given Evaluation Context.
 /// </summary>
 /// <param name="context">Evaluation Context.</param>
 public abstract void Evaluate(SparqlEvaluationContext context);
Example #42
0
        /// <summary>
        /// Casts the Value of the inner Expression to a Decimal
        /// </summary>
        /// <param name="context">Evaluation Context</param>
        /// <param name="bindingID">Binding ID</param>
        /// <returns></returns>
        public override IValuedNode Evaluate(SparqlEvaluationContext context, int bindingID)
        {
            IValuedNode n = _expr.Evaluate(context, bindingID);//.CoerceToDecimal();

            if (n == null)
            {
                throw new RdfQueryException("Cannot cast a Null to a xsd:decimal");
            }

            // New method should be much faster
            // if (n is DecimalNode) return n;
            // return new DecimalNode(null, n.AsDecimal());

            switch (n.NodeType)
            {
            case NodeType.Blank:
            case NodeType.GraphLiteral:
            case NodeType.Uri:
                throw new RdfQueryException("Cannot cast a Blank/URI/Graph Literal Node to a xsd:decimal");

            case NodeType.Literal:
                if (n is DecimalNode)
                {
                    return(n);
                }
                // See if the value can be cast
                ILiteralNode lit = (ILiteralNode)n;
                if (lit.DataType != null)
                {
                    string dt = lit.DataType.ToString();
                    if (SparqlSpecsHelper.IntegerDataTypes.Contains(dt))
                    {
                        // Already an integer type so valid as a xsd:decimal
                        decimal d;
                        if (Decimal.TryParse(lit.Value, NumberStyles.Any ^ NumberStyles.AllowExponent, CultureInfo.InvariantCulture, out d))
                        {
                            // Parsed OK
                            return(new DecimalNode(lit.Graph, d));
                        }
                        else
                        {
                            throw new RdfQueryException("Invalid lexical form for xsd:decimal");
                        }
                    }
                    else if (dt.Equals(XmlSpecsHelper.XmlSchemaDataTypeDateTime))
                    {
                        // DateTime cast forbidden
                        throw new RdfQueryException("Cannot cast a xsd:dateTime to a xsd:decimal");
                    }
                    else
                    {
                        decimal d;
                        if (Decimal.TryParse(lit.Value, NumberStyles.Any ^ NumberStyles.AllowExponent, CultureInfo.InvariantCulture, out d))
                        {
                            // Parsed OK
                            return(new DecimalNode(lit.Graph, d));
                        }
                        else
                        {
                            throw new RdfQueryException("Cannot cast the value '" + lit.Value + "' to a xsd:decimal");
                        }
                    }
                }
                else
                {
                    decimal d;
                    if (Decimal.TryParse(lit.Value, NumberStyles.Any ^ NumberStyles.AllowExponent, CultureInfo.InvariantCulture, out d))
                    {
                        // Parsed OK
                        return(new DecimalNode(lit.Graph, d));
                    }
                    else
                    {
                        throw new RdfQueryException("Cannot cast the value '" + lit.Value + "' to a xsd:decimal");
                    }
                }

            default:
                throw new RdfQueryException("Cannot cast an Unknown Node to a xsd:decimal");
            }
        }
Example #43
0
        /// <summary>
        /// Gets the value of the expression as evaluated in a given Context for a given Binding
        /// </summary>
        /// <param name="context">Evaluation Context</param>
        /// <param name="bindingID">Binding ID</param>
        /// <returns></returns>
        public override IValuedNode Evaluate(SparqlEvaluationContext context, int bindingID)
        {
            this._funcContext = context[SparqlSpecsHelper.SparqlKeywordBNode] as BNodeFunctionContext;

            if (this._funcContext == null)
            {
                this._funcContext = new BNodeFunctionContext(context.InputMultiset.GetHashCode());
                context[SparqlSpecsHelper.SparqlKeywordBNode] = this._funcContext;
            }
            else if (this._funcContext.CurrentInput != context.InputMultiset.GetHashCode())
            {
                //Clear the Context
                this._funcContext.BlankNodes.Clear();
                context[SparqlSpecsHelper.SparqlKeywordBNode] = this._funcContext;
            }

            if (this._expr == null)
            {
                //If no argument then always a fresh BNode
                return(this._funcContext.Graph.CreateBlankNode().AsValuedNode());
            }
            else
            {
                INode temp = this._expr.Evaluate(context, bindingID);
                if (temp != null)
                {
                    if (temp.NodeType == NodeType.Literal)
                    {
                        ILiteralNode lit = (ILiteralNode)temp;

                        if (lit.DataType == null)
                        {
                            if (lit.Language.Equals(string.Empty))
                            {
                                if (!this._funcContext.BlankNodes.ContainsKey(bindingID))
                                {
                                    this._funcContext.BlankNodes.Add(bindingID, new Dictionary <string, INode>());
                                }

                                if (!this._funcContext.BlankNodes[bindingID].ContainsKey(lit.Value))
                                {
                                    this._funcContext.BlankNodes[bindingID].Add(lit.Value, this._funcContext.Graph.CreateBlankNode());
                                }
                                return(this._funcContext.BlankNodes[bindingID][lit.Value].AsValuedNode());
                            }
                            else
                            {
                                throw new RdfQueryException("Cannot create a Blank Node when the argument Expression evaluates to a lanuage specified literal");
                            }
                        }
                        else
                        {
                            throw new RdfQueryException("Cannot create a Blank Node when the argument Expression evaluates to a typed literal node");
                        }
                    }
                    else
                    {
                        throw new RdfQueryException("Cannot create a Blank Node when the argument Expression evaluates to a non-literal node");
                    }
                }
                else
                {
                    throw new RdfQueryException("Cannot create a Blank Node when the argument Expression evaluates to null");
                }
            }
        }
Example #44
0
        /// <summary>
        /// Casts the value of the inner Expression to a Date Time
        /// </summary>
        /// <param name="context">Evaluation Context</param>
        /// <param name="bindingID">Binding ID</param>
        /// <returns></returns>
        public override IValuedNode Evaluate(SparqlEvaluationContext context, int bindingID)
        {
            IValuedNode n = this._expr.Evaluate(context, bindingID);//.CoerceToDateTime();

            if (n == null)
            {
                throw new RdfQueryException("Cannot cast a Null to a xsd:dateTime");
            }

            // New method should be much faster
            // if (n is DateTimeNode) return n;
            // if (n is DateNode) return new DateTimeNode(n.Graph, n.AsDateTime());
            // return new DateTimeNode(null, n.AsDateTime());

            switch (n.NodeType)
            {
            case NodeType.Blank:
            case NodeType.GraphLiteral:
            case NodeType.Uri:
                throw new RdfQueryException("Cannot cast a Blank/URI/Graph Literal Node to a xsd:dateTime");

            case NodeType.Literal:
                if (n is DateTimeNode)
                {
                    return(n);
                }
                if (n is DateNode)
                {
                    return(new DateTimeNode(n.Graph, n.AsDateTime()));
                }
                // See if the value can be cast
                ILiteralNode lit = (ILiteralNode)n;
                if (lit.DataType != null)
                {
                    string dt = lit.DataType.ToString();
                    if (dt.Equals(XmlSpecsHelper.XmlSchemaDataTypeDateTime))
                    {
                        // Already a xsd:dateTime
                        DateTimeOffset d;
                        if (DateTimeOffset.TryParse(lit.Value, out d))
                        {
                            // Parsed OK
                            return(new DateTimeNode(lit.Graph, d));
                        }
                        else
                        {
                            throw new RdfQueryException("Invalid lexical form for xsd:dateTime");
                        }
                    }
                    else if (dt.Equals(XmlSpecsHelper.XmlSchemaDataTypeString))
                    {
                        DateTimeOffset d;
                        if (DateTimeOffset.TryParse(lit.Value, out d))
                        {
                            // Parsed OK
                            return(new DateTimeNode(lit.Graph, d));
                        }
                        else
                        {
                            throw new RdfQueryException("Cannot cast the value '" + lit.Value + "' to a xsd:double");
                        }
                    }
                    else
                    {
                        throw new RdfQueryException("Cannot cast a Literal typed <" + dt + "> to a xsd:dateTime");
                    }
                }
                else
                {
                    DateTimeOffset d;
                    if (DateTimeOffset.TryParse(lit.Value, out d))
                    {
                        // Parsed OK
                        return(new DateTimeNode(lit.Graph, d));
                    }
                    else
                    {
                        throw new RdfQueryException("Cannot cast the value '" + lit.Value + "' to a xsd:dateTime");
                    }
                }

            default:
                throw new RdfQueryException("Cannot cast an Unknown Node to a xsd:string");
            }
        }
Example #45
0
        /// <summary>
        /// Returns the value of the Expression as evaluated for a given Binding as a Literal Node
        /// </summary>
        /// <param name="context">Evaluation Context</param>
        /// <param name="bindingID">Binding ID</param>
        /// <returns></returns>
        public IValuedNode Evaluate(SparqlEvaluationContext context, int bindingID)
        {
            //Configure Options
            if (this._optionExpr != null)
            {
                this.ConfigureOptions(this._optionExpr.Evaluate(context, bindingID), true);
            }

            //Compile the Regex if necessary
            if (!this._fixedPattern)
            {
                //Regex is not pre-compiled
                if (this._findExpr != null)
                {
                    IValuedNode p = this._findExpr.Evaluate(context, bindingID);
                    if (p != null)
                    {
                        if (p.NodeType == NodeType.Literal)
                        {
                            this._find = p.AsString();
                        }
                        else
                        {
                            throw new RdfQueryException("Cannot parse a Pattern String from a non-Literal Node");
                        }
                    }
                    else
                    {
                        throw new RdfQueryException("Not a valid Pattern Expression");
                    }
                }
                else
                {
                    throw new RdfQueryException("Not a valid Pattern Expression or the fixed Pattern String was invalid");
                }
            }
            //Compute the Replace if necessary
            if (!this._fixedReplace)
            {
                if (this._replaceExpr != null)
                {
                    IValuedNode r = this._replaceExpr.Evaluate(context, bindingID);
                    if (r != null)
                    {
                        if (r.NodeType == NodeType.Literal)
                        {
                            this._replace = r.AsString();
                        }
                        else
                        {
                            throw new RdfQueryException("Cannot parse a Replace String from a non-Literal Node");
                        }
                    }
                    else
                    {
                        throw new RdfQueryException("Not a valid Replace Expression");
                    }
                }
                else
                {
                    throw new RdfQueryException("Not a valid Replace Expression");
                }
            }

            //Execute the Regular Expression
            IValuedNode textNode = this._textExpr.Evaluate(context, bindingID);

            if (textNode == null)
            {
                throw new RdfQueryException("Cannot evaluate a Regular Expression against a NULL");
            }
            if (textNode.NodeType == NodeType.Literal)
            {
                //Execute
                ILiteralNode lit = (ILiteralNode)textNode;
                if (lit.DataType != null && !lit.DataType.ToString().Equals(XmlSpecsHelper.XmlSchemaDataTypeString))
                {
                    throw new RdfQueryException("Text Argument to Replace must be of type xsd:string if a datatype is specified");
                }
                string text   = lit.Value;
                string output = Regex.Replace(text, this._find, this._replace, this._options);

                if (lit.DataType != null)
                {
                    return(new StringNode(null, output, lit.DataType));
                }
                else if (!lit.Language.Equals(string.Empty))
                {
                    return(new StringNode(null, output, lit.Language));
                }
                else
                {
                    return(new StringNode(null, output));
                }
            }
            else
            {
                throw new RdfQueryException("Cannot evaluate a Regular Expression against a non-Literal Node");
            }
        }
Example #46
0
        /// <summary>
        /// Evaluates the BGP against the Evaluation Context
        /// </summary>
        /// <param name="context">Evaluation Context</param>
        /// <returns></returns>
        public BaseMultiset Evaluate(SparqlEvaluationContext context)
        {
            if (this._triplePatterns.Count > 0)
            {
                for (int i = 0; i < this._triplePatterns.Count; i++)
                {
                    if (i == 0)
                    {
                        //If the 1st thing in a BGP is a BIND/LET/FILTER the Input becomes the Identity Multiset
                        if (this._triplePatterns[i].PatternType == TriplePatternType.Filter || this._triplePatterns[i].PatternType == TriplePatternType.BindAssignment || this._triplePatterns[i].PatternType == TriplePatternType.LetAssignment)
                        {
                            if (this._triplePatterns[i].PatternType == TriplePatternType.BindAssignment)
                            {
                                if (context.InputMultiset.ContainsVariable(((IAssignmentPattern)this._triplePatterns[i]).VariableName))
                                {
                                    throw new RdfQueryException("Cannot use a BIND assigment to BIND to a variable that has previously been declared");
                                }
                            }
                            else
                            {
                                context.InputMultiset = new IdentityMultiset();
                            }
                        }
                    }

                    //Create a new Output Multiset
                    context.OutputMultiset = new Multiset();

                    this._triplePatterns[i].Evaluate(context);

                    //If at any point we've got an Empty Multiset as our Output then we terminate BGP execution
                    if (context.OutputMultiset.IsEmpty)
                    {
                        break;
                    }

                    //Check for Timeout before attempting the Join
                    context.CheckTimeout();

                    //If this isn't the first Pattern we do Join/Product the Output to the Input
                    if (i > 0)
                    {
                        if (context.InputMultiset.IsDisjointWith(context.OutputMultiset))
                        {
                            //Disjoint so do a Product
                            context.OutputMultiset = context.InputMultiset.ProductWithTimeout(context.OutputMultiset, context.RemainingTimeout);
                        }
                        else
                        {
                            //Normal Join
                            context.OutputMultiset = context.InputMultiset.Join(context.OutputMultiset);
                        }
                    }

                    //Then the Input for the next Pattern is the Output from the previous Pattern
                    context.InputMultiset = context.OutputMultiset;
                }

                if (context.TrimTemporaryVariables)
                {
                    //Trim the Multiset - this eliminates any temporary variables
                    context.OutputMultiset.Trim();
                }
            }
            else
            {
                //For an Empty BGP we just return the Identity Multiset
                context.OutputMultiset = new IdentityMultiset();
            }

            //If we've ended with an Empty Multiset then we turn it into the Null Multiset
            //to indicate that this BGP did not match anything
            if (context.OutputMultiset is Multiset && context.OutputMultiset.IsEmpty)
            {
                context.OutputMultiset = new NullMultiset();
            }

            //Return the Output Multiset
            return(context.OutputMultiset);
        }
 /// <summary>
 /// Evaluates the algebra in the given context
 /// </summary>
 /// <param name="context">Evaluation Context</param>
 /// <returns></returns>
 public BaseMultiset Evaluate(SparqlEvaluationContext context)
 {
     context.InputMultiset = context.Evaluate(this._algebra);
     return(this._function.Evaluate(context));
 }
 /// <summary>
 /// Counts the results
 /// </summary>
 /// <param name="context">Evaluation Context</param>
 /// <param name="bindingIDs">Binding IDs over which the Aggregate applies</param>
 /// <returns></returns>
 public override IValuedNode Apply(SparqlEvaluationContext context, IEnumerable <int> bindingIDs)
 {
     //Just Count the number of results
     return(new LongNode(null, bindingIDs.Count()));
 }
Example #49
0
 private ILiteralNode CheckArgument(ISparqlExpression expr, SparqlEvaluationContext context, int bindingID)
 {
     return(this.CheckArgument(expr, context, bindingID, XPathFunctionFactory.AcceptStringArguments));
 }
Example #50
0
 /// <summary>
 /// Returns the fixed set of solutions.
 /// </summary>
 /// <param name="context">Evaluation Context.</param>
 /// <returns></returns>
 public BaseMultiset Evaluate(SparqlEvaluationContext context)
 {
     context.OutputMultiset = _table;
     return(context.OutputMultiset);
 }
Example #51
0
 /// <summary>
 /// Evaluates the property function
 /// </summary>
 /// <param name="context">Evaluation Context</param>
 public override void Evaluate(SparqlEvaluationContext context)
 {
     context.OutputMultiset = this._function.Evaluate(context);
 }
Example #52
0
 /// <summary>
 /// Evalutes the algebra for the given evaluation context
 /// </summary>
 /// <param name="context">Evaluation Context</param>
 /// <returns></returns>
 public abstract BaseMultiset Evaluate(SparqlEvaluationContext context);
Example #53
0
 /// <summary>
 /// Gets the Effective Boolean Value of the Expression as evaluated for the given Binding in the given Context
 /// </summary>
 /// <param name="context">Evaluation Context</param>
 /// <param name="bindingID">Binding ID</param>
 /// <returns></returns>
 public override bool EffectiveBooleanValue(SparqlEvaluationContext context, int bindingID)
 {
     return(SparqlSpecsHelper.EffectiveBooleanValue(this.Value(context, bindingID)));
 }
Example #54
0
        /// <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 = this._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(this.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(this.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(this.RestrictionVariable))
                            {
                                //If does exist check it has appropriate value and if not remove it
                                if (!term.Equals(x[this.RestrictionVariable]))
                                {
                                    context.InputMultiset.Remove(id);
                                }
                            }
                            else
                            {
                                //If doesn't exist for this set then bind it to the term
                                x.Add(this.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(this.RestrictionVariable, term);
                    }
                }
            }

            //Then evaluate the inner algebra
            BaseMultiset results = context.Evaluate(this.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[this.RestrictionVariable]))
                    {
                        results.Remove(id);
                    }
                }
                catch (RdfQueryException)
                {
                    results.Remove(id);
                }
            }

            if (results.Count > 0)
            {
                context.OutputMultiset = results;
            }
            else
            {
                context.OutputMultiset = new NullMultiset();
            }
            return(context.OutputMultiset);
        }
        /// <summary>
        /// Evaluates the expression
        /// </summary>
        /// <param name="context">Evaluation Context</param>
        /// <param name="bindingID">Binding ID</param>
        /// <returns></returns>
        public virtual IValuedNode Evaluate(SparqlEvaluationContext context, int bindingID)
        {
            Guid uuid = Guid.NewGuid();

            return(EvaluateInternal(uuid));
        }
        /// <summary>
        /// Evaluates the property function.
        /// </summary>
        /// <param name="context">Evaluation Context.</param>
        /// <returns></returns>
        public BaseMultiset Evaluate(SparqlEvaluationContext context)
        {
            //The very first thing we must do is check the incoming input
            if (context.InputMultiset is NullMultiset)
            {
                return(context.InputMultiset);                                       //Can abort evaluation if input is null
            }
            if (context.InputMultiset.IsEmpty)
            {
                return(context.InputMultiset);                               //Can abort evaluation if input is null
            }
            //Then we need to retrieve the full text search provider
            IFullTextSearchProvider provider = context[FullTextHelper.ContextKey] as IFullTextSearchProvider;

            if (provider == null)
            {
                throw new FullTextQueryException("No Full Text Search Provider is available, please ensure you attach a FullTextQueryOptimiser to your query");
            }

            //First determine whether we can apply the limit when talking to the provider
            //Essentially as long as the Match Variable (the one we'll bind results to) is not already
            //bound AND we are actually using a limit
            bool applyLimitDirect = this._limit.HasValue && this._limit.Value > -1 && this._matchVar.VariableName != null && !context.InputMultiset.ContainsVariable(this._matchVar.VariableName);

            //Is there a constant for the Match Item?  If so extract it now
            //Otherwise are we needing to check against existing bindings
            INode           matchConstant = null;
            bool            checkExisting = false;
            HashSet <INode> existing      = null;

            if (this._matchVar.VariableName == null)
            {
                matchConstant = ((NodeMatchPattern)this._matchVar).Node;
            }
            else if (this._matchVar.VariableName != null && context.InputMultiset.ContainsVariable(this._matchVar.VariableName))
            {
                checkExisting = true;
                existing      = new HashSet <INode>();
                foreach (INode n in context.InputMultiset.Sets.Select(s => s[this._matchVar.VariableName]).Where(s => s != null))
                {
                    existing.Add(n);
                }
            }

            //Then check that the score variable is not already bound, if so error
            //If a Score Variable is provided and it is OK then we'll bind scores at a later stage
            if (this._scoreVar != null)
            {
                if (this._scoreVar.VariableName == null)
                {
                    throw new FullTextQueryException("Queries using full text search that wish to return result scores must provide a variable");
                }
                if (this._scoreVar.VariableName != null && context.InputMultiset.ContainsVariable(this._scoreVar.VariableName))
                {
                    throw new FullTextQueryException("Queries using full text search that wish to return result scores must use an unbound variable to do so");
                }
            }

            //Next ensure that the search text is a node and not a variable
            if (this._searchVar.VariableName != null)
            {
                throw new FullTextQueryException("Queries using full text search must provide a constant value for the search term");
            }
            INode searchNode = ((NodeMatchPattern)this._searchVar).Node;

            if (searchNode.NodeType != NodeType.Literal)
            {
                throw new FullTextQueryException("Queries using full text search must use a literal value for the search term");
            }
            String search = ((ILiteralNode)searchNode).Value;

            //Determine which graphs we are operating over
            IEnumerable <Uri> graphUris = context.Data.ActiveGraphUris;

            //Now we can use the full text search provider to start getting results
            context.OutputMultiset = new Multiset();
            IEnumerable <IFullTextSearchResult> results = applyLimitDirect ? this.GetResults(graphUris, provider, search, this._limit.Value) : this.GetResults(graphUris, provider, search);
            int    r        = 0;
            String matchVar = this._matchVar.VariableName;
            String scoreVar = this._scoreVar != null ? this._scoreVar.VariableName : null;

            foreach (IFullTextSearchResult result in results)
            {
                if (matchConstant != null)
                {
                    //Check against constant if present
                    if (result.Node.Equals(matchConstant))
                    {
                        r++;
                        context.OutputMultiset.Add(result.ToSet(matchVar, scoreVar));
                    }
                }
                else if (checkExisting)
                {
                    //Check against existing bindings if present
                    if (existing.Contains(result.Node))
                    {
                        r++;
                        context.OutputMultiset.Add(result.ToSet(matchVar, scoreVar));
                    }
                }
                else
                {
                    //Otherwise all results are acceptable
                    r++;
                    context.OutputMultiset.Add(result.ToSet(matchVar, scoreVar));
                }

                //Apply the limit locally if necessary
                if (!applyLimitDirect && this._limit > -1 && r >= this._limit)
                {
                    break;
                }
            }

            return(context.OutputMultiset);
        }
Example #57
0
        private BaseMultiset StreamingEvaluate(SparqlEvaluationContext context, int pattern, out bool halt)
        {
            // Remember to check for Timeouts during Lazy Evaluation
            context.CheckTimeout();

            halt = false;

            // Handle Empty BGPs
            if (pattern == 0 && _triplePatterns.Count == 0)
            {
                context.OutputMultiset = new IdentityMultiset();
                return(context.OutputMultiset);
            }

            BaseMultiset initialInput, localOutput, results = null;

            // Determine whether the Pattern modifies the existing Input rather than joining to it
            bool modifies = (_triplePatterns[pattern].PatternType == TriplePatternType.Filter);
            bool extended = (pattern > 0 && _triplePatterns[pattern - 1].PatternType == TriplePatternType.BindAssignment);
            bool modified = (pattern > 0 && _triplePatterns[pattern - 1].PatternType == TriplePatternType.Filter);

            // Set up the Input and Output Multiset appropriately
            switch (pattern)
            {
            case 0:
                // Input is as given and Output is new empty multiset
                if (!modifies)
                {
                    initialInput = context.InputMultiset;
                }
                else
                {
                    // If the Pattern will modify the Input and is the first thing in the BGP then it actually modifies a new empty input
                    // This takes care of FILTERs being out of scope
                    initialInput = new Multiset();
                }
                localOutput = new Multiset();
                break;

            case 1:
                // Input becomes current Output and Output is new empty multiset
                initialInput = context.OutputMultiset;
                localOutput  = new Multiset();
                break;

            default:
                if (!extended && !modified)
                {
                    // Input is join of previous input and output and Output is new empty multiset
                    if (context.InputMultiset.IsDisjointWith(context.OutputMultiset))
                    {
                        // Disjoint so do a Product
                        initialInput = context.InputMultiset.ProductWithTimeout(context.OutputMultiset, context.RemainingTimeout);
                    }
                    else
                    {
                        // Normal Join
                        initialInput = context.InputMultiset.Join(context.OutputMultiset);
                    }
                }
                else
                {
                    initialInput = context.OutputMultiset;
                }
                localOutput = new Multiset();
                break;
            }
            context.InputMultiset  = initialInput;
            context.OutputMultiset = localOutput;

            // Get the Triple Pattern we're evaluating
            ITriplePattern temp         = _triplePatterns[pattern];
            int            resultsFound = 0;
            int            prevResults  = -1;

            if (temp.PatternType == TriplePatternType.Match)
            {
                // Find the first Triple which matches the Pattern
                IMatchTriplePattern  tp = (IMatchTriplePattern)temp;
                IEnumerable <Triple> ts = tp.GetTriples(context);

                // In the case that we're lazily evaluating an optimisable ORDER BY then
                // we need to apply OrderBy()'s to our enumeration
                // This only applies to the 1st pattern
                if (pattern == 0)
                {
                    if (context.Query != null)
                    {
                        if (context.Query.OrderBy != null && context.Query.IsOptimisableOrderBy)
                        {
                            IComparer <Triple> comparer = context.Query.OrderBy.GetComparer(tp);
                            if (comparer != null)
                            {
                                ts = ts.OrderBy(t => t, comparer);
                            }
                            else
                            {
                                // Can't get a comparer so can't optimise
                                // Thus required results is everything so just use normal evaluation as otherwise
                                // lazy evaluation will significantly impact performance and lead to an apparent infinite loop
                                return(base.Evaluate(context));
                            }
                        }
                    }
                }

                foreach (Triple t in ts)
                {
                    if (tp.Accepts(context, t))
                    {
                        resultsFound++;
                        if (tp.IndexType == TripleIndexType.NoVariables)
                        {
                            localOutput            = new IdentityMultiset();
                            context.OutputMultiset = localOutput;
                        }
                        else
                        {
                            context.OutputMultiset.Add(tp.CreateResult(t));
                        }
                    }
                }
                // Recurse unless we're the last pattern
                if (pattern < _triplePatterns.Count - 1)
                {
                    results = StreamingEvaluate(context, pattern + 1, out halt);

                    // If recursion leads to a halt then we halt and return immediately
                    if (halt && results.Count >= _requiredResults && _requiredResults != -1)
                    {
                        return(results);
                    }
                    else if (halt)
                    {
                        if (results.Count == 0)
                        {
                            // If recursing leads to no results then eliminate all outputs
                            // Also reset to prevResults to -1
                            resultsFound = 0;
                            localOutput  = new Multiset();
                            prevResults  = -1;
                        }
                        else if (prevResults > -1)
                        {
                            if (results.Count == prevResults)
                            {
                                // If the amount of results found hasn't increased then this match does not
                                // generate any further solutions further down the recursion so we can eliminate
                                // this from the results
                                localOutput.Remove(localOutput.SetIDs.Max());
                            }
                        }
                        prevResults = results.Count;

                        // If we're supposed to halt but not reached the number of required results then continue
                        context.InputMultiset  = initialInput;
                        context.OutputMultiset = localOutput;
                    }
                    else
                    {
                        // Otherwise we need to keep going here
                        // So must reset our input and outputs before continuing
                        context.InputMultiset  = initialInput;
                        context.OutputMultiset = new Multiset();
                        resultsFound--;
                    }
                }
                else
                {
                    // If we're at the last pattern and we've found a match then we can halt
                    halt = true;

                    // Generate the final output and return it
                    if (context.InputMultiset.IsDisjointWith(context.OutputMultiset))
                    {
                        // Disjoint so do a Product
                        results = context.InputMultiset.ProductWithTimeout(context.OutputMultiset,
                                                                           context.RemainingTimeout);
                    }
                    else
                    {
                        // Normal Join
                        results = context.InputMultiset.Join(context.OutputMultiset);
                    }

                    // If not reached required number of results continue
                    if (results.Count >= _requiredResults && _requiredResults != -1)
                    {
                        context.OutputMultiset = results;
                        return(context.OutputMultiset);
                    }
                }
                context.InputMultiset = results;
            }
            else if (temp.PatternType == TriplePatternType.Filter)
            {
                IFilterPattern    filter     = (IFilterPattern)temp;
                ISparqlExpression filterExpr = filter.Filter.Expression;

                if (filter.Variables.IsDisjoint(context.InputMultiset.Variables))
                {
                    // Filter is Disjoint so determine whether it has any affect or not
                    if (filter.Variables.Any())
                    {
                        // Has Variables but disjoint from input => not in scope so gets ignored

                        // Do we recurse or not?
                        if (pattern < _triplePatterns.Count - 1)
                        {
                            // Recurse and return
                            results = StreamingEvaluate(context, pattern + 1, out halt);
                            return(results);
                        }
                        else
                        {
                            // We don't affect the input in any way so just return it
                            return(context.InputMultiset);
                        }
                    }
                    else
                    {
                        // No Variables so have to evaluate it to see if it gives true otherwise
                        try
                        {
                            if (filterExpr.Evaluate(context, 0).AsSafeBoolean())
                            {
                                if (pattern < _triplePatterns.Count - 1)
                                {
                                    // Recurse and return
                                    results = StreamingEvaluate(context, pattern + 1, out halt);
                                    return(results);
                                }
                                else
                                {
                                    // Last Pattern and we evaluate to true so can return the input as-is
                                    halt = true;
                                    return(context.InputMultiset);
                                }
                            }
                        }
                        catch (RdfQueryException)
                        {
                            // Evaluates to false so eliminates all solutions (use an empty Multiset)
                            return(new Multiset());
                        }
                    }
                }
                else
                {
                    // Test each solution found so far against the Filter and eliminate those that evalute to false/error
                    foreach (int id in context.InputMultiset.SetIDs.ToList())
                    {
                        try
                        {
                            if (filterExpr.Evaluate(context, id).AsSafeBoolean())
                            {
                                // If evaluates to true then add to output
                                context.OutputMultiset.Add(context.InputMultiset[id].Copy());
                            }
                        }
                        catch (RdfQueryException)
                        {
                            // Error means we ignore the solution
                        }
                    }

                    // Remember to check for Timeouts during Lazy Evaluation
                    context.CheckTimeout();

                    // Decide whether to recurse or not
                    resultsFound = context.OutputMultiset.Count;
                    if (pattern < _triplePatterns.Count - 1)
                    {
                        // Recurse then return
                        // We can never decide whether to recurse again at this point as we are not capable of deciding
                        // which solutions should be dumped (that is the job of an earlier pattern in the BGP)
                        results = StreamingEvaluate(context, pattern + 1, out halt);

                        return(results);
                    }
                    else
                    {
                        halt = true;

                        // However many results we need we'll halt - previous patterns can call us again if they find more potential solutions
                        // for us to filter
                        return(context.OutputMultiset);
                    }
                }
            }
            else if (temp is BindPattern)
            {
                BindPattern       bind     = (BindPattern)temp;
                ISparqlExpression bindExpr = bind.AssignExpression;
                String            bindVar  = bind.VariableName;

                if (context.InputMultiset.ContainsVariable(bindVar))
                {
                    throw new RdfQueryException(
                              "Cannot use a BIND assigment to BIND to a variable that has previously been used in the Query");
                }
                else
                {
                    // Compute the Binding for every value
                    context.OutputMultiset.AddVariable(bindVar);
                    foreach (ISet s in context.InputMultiset.Sets)
                    {
                        ISet x = s.Copy();
                        try
                        {
                            INode val = bindExpr.Evaluate(context, s.ID);
                            x.Add(bindVar, val);
                        }
                        catch (RdfQueryException)
                        {
                            // Equivalent to no assignment but the solution is preserved
                        }
                        context.OutputMultiset.Add(x.Copy());
                    }

                    // Remember to check for Timeouts during Lazy Evaluation
                    context.CheckTimeout();

                    // Decide whether to recurse or not
                    resultsFound = context.OutputMultiset.Count;
                    if (pattern < _triplePatterns.Count - 1)
                    {
                        // Recurse then return
                        results = StreamingEvaluate(context, pattern + 1, out halt);
                        return(results);
                    }
                    else
                    {
                        halt = true;

                        // However many results we need we'll halt - previous patterns can call us again if they find more potential solutions
                        // for us to extend
                        return(context.OutputMultiset);
                    }
                }
            }
            else
            {
                throw new RdfQueryException("Encountered a " + temp.GetType().FullName +
                                            " which is not a lazily evaluable Pattern");
            }

            // If we found no possibles we return the null multiset
            if (resultsFound == 0)
            {
                return(new NullMultiset());
            }
            else
            {
                // Remember to check for Timeouts during Lazy Evaluation
                context.CheckTimeout();

                // Generate the final output and return it
                if (!modifies)
                {
                    if (context.InputMultiset.IsDisjointWith(context.OutputMultiset))
                    {
                        // Disjoint so do a Product
                        results = context.InputMultiset.ProductWithTimeout(context.OutputMultiset, context.RemainingTimeout);
                    }
                    else
                    {
                        // Normal Join
                        results = context.InputMultiset.Join(context.OutputMultiset);
                    }
                    context.OutputMultiset = results;
                }
                return(context.OutputMultiset);
            }
        }
        /// <summary>
        /// Calculates the Numeric Value of this Expression as evaluated for a given Binding.
        /// </summary>
        /// <param name="context">Evaluation Context.</param>
        /// <param name="bindingID">Binding ID.</param>
        /// <returns></returns>
        public override IValuedNode Evaluate(SparqlEvaluationContext context, int bindingID)
        {
            IValuedNode a = _expr.Evaluate(context, bindingID);

            if (a == null)
            {
                throw new RdfQueryException("Cannot apply unary minus to a null");
            }

            switch (a.NumericType)
            {
            case SparqlNumericType.Integer:
                return(new LongNode(null, -1 * a.AsInteger()));

            case SparqlNumericType.Decimal:
                decimal decvalue = a.AsDecimal();
                if (decvalue == Decimal.Zero)
                {
                    return(new DecimalNode(null, Decimal.Zero));
                }
                else
                {
                    return(new DecimalNode(null, -1 * decvalue));
                }

            case SparqlNumericType.Float:
                float fltvalue = a.AsFloat();
                if (Single.IsNaN(fltvalue))
                {
                    return(new FloatNode(null, Single.NaN));
                }
                else if (Single.IsPositiveInfinity(fltvalue))
                {
                    return(new FloatNode(null, Single.NegativeInfinity));
                }
                else if (Single.IsNegativeInfinity(fltvalue))
                {
                    return(new FloatNode(null, Single.PositiveInfinity));
                }
                else
                {
                    return(new FloatNode(null, -1.0f * fltvalue));
                }

            case SparqlNumericType.Double:
                double dblvalue = a.AsDouble();
                if (Double.IsNaN(dblvalue))
                {
                    return(new DoubleNode(null, Double.NaN));
                }
                else if (Double.IsPositiveInfinity(dblvalue))
                {
                    return(new DoubleNode(null, Double.NegativeInfinity));
                }
                else if (Double.IsNegativeInfinity(dblvalue))
                {
                    return(new DoubleNode(null, Double.PositiveInfinity));
                }
                else
                {
                    return(new DoubleNode(null, -1.0 * dblvalue));
                }

            default:
                throw new RdfQueryException("Cannot evalute an Arithmetic Expression when the Numeric Type of the expression cannot be determined");
            }
        }
Example #59
0
 /// <summary>
 /// Gets the value of casting the result of the inner expression
 /// </summary>
 /// <param name="context">Evaluation Context</param>
 /// <param name="bindingID">Binding ID</param>
 /// <returns></returns>
 public abstract IValuedNode Evaluate(SparqlEvaluationContext context, int bindingID);
        /// <summary>
        /// Casts the value of the inner Expression to an Integer.
        /// </summary>
        /// <param name="context">Evaluation Context.</param>
        /// <param name="bindingID">Binding ID.</param>
        /// <returns></returns>
        public override IValuedNode Evaluate(SparqlEvaluationContext context, int bindingID)
        {
            IValuedNode n = _expr.Evaluate(context, bindingID);//.CoerceToInteger();

            if (n == null)
            {
                throw new RdfQueryException("Cannot cast a Null to a xsd:integer");
            }

            ////New method should be much faster
            // if (n is LongNode) return n;
            // return new LongNode(null, n.AsInteger());

            switch (n.NodeType)
            {
            case NodeType.Blank:
            case NodeType.GraphLiteral:
            case NodeType.Uri:
                throw new RdfQueryException("Cannot cast a Blank/URI/Graph Literal Node to a xsd:integer");

            case NodeType.Literal:
                // See if the value can be cast
                if (n is LongNode)
                {
                    return(n);
                }
                ILiteralNode lit = (ILiteralNode)n;
                if (lit.DataType != null)
                {
                    string dt = lit.DataType.AbsoluteUri;
                    if (SparqlSpecsHelper.IntegerDataTypes.Contains(dt))
                    {
                        // Already a integer type so valid as a xsd:integer
                        long i;
                        if (Int64.TryParse(lit.Value, out i))
                        {
                            return(new LongNode(lit.Graph, i));
                        }
                        else
                        {
                            throw new RdfQueryException("Invalid lexical form for xsd:integer");
                        }
                    }
                    else if (dt.Equals(XmlSpecsHelper.XmlSchemaDataTypeDateTime))
                    {
                        // DateTime cast forbidden
                        throw new RdfQueryException("Cannot cast a xsd:dateTime to a xsd:integer");
                    }
                    else
                    {
                        Int64 i;
                        if (Int64.TryParse(lit.Value, out i))
                        {
                            // Parsed OK
                            return(new LongNode(lit.Graph, i));
                        }
                        else
                        {
                            throw new RdfQueryException("Cannot cast the value '" + lit.Value + "' to a xsd:integer");
                        }
                    }
                }
                else
                {
                    Int64 i;
                    if (Int64.TryParse(lit.Value, out i))
                    {
                        // Parsed OK
                        return(new LongNode(lit.Graph, i));
                    }
                    else
                    {
                        throw new RdfQueryException("Cannot cast the value '" + lit.Value + "' to a xsd:integer");
                    }
                }

            default:
                throw new RdfQueryException("Cannot cast an Unknown Node to a xsd:integer");
            }
        }