Ejemplo n.º 1
0
 /// <summary>
 /// Creates a new Numeric Expression
 /// </summary>
 /// <param name="value">Float Value</param>
 public NumericExpressionTerm(float value)
 {
     this._type     = SparqlNumericType.Float;
     this._fltvalue = (float)value;
     this._dblvalue = (double)value;
     this._value    = new LiteralNode(null, this._dblvalue.ToString(), new Uri(XmlSpecsHelper.XmlSchemaDataTypeFloat));
 }
Ejemplo n.º 2
0
        /// <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 a = _leftExpr.Evaluate(context, bindingID);
            IValuedNode b = _rightExpr.Evaluate(context, bindingID);

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

            switch (type)
            {
            case SparqlNumericType.Integer:
                return(new LongNode(null, Math.Max(a.AsInteger(), b.AsInteger())));

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

            case SparqlNumericType.Float:
                return(new FloatNode(null, Math.Max(a.AsFloat(), b.AsFloat())));

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

            default:
                throw new RdfQueryException("Cannot evalute an Arithmetic Expression when the Numeric Type of the expression cannot be determined");
            }
        }
Ejemplo n.º 3
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._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");
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Compares two Nodes for Numeric Ordering
        /// </summary>
        /// <param name="x">Node</param>
        /// <param name="y">Node</param>
        /// <param name="type">Numeric Type</param>
        /// <returns></returns>
        protected virtual int NumericCompare(IValuedNode x, IValuedNode y, SparqlNumericType type)
        {
            if (x == null || y == null)
            {
                throw new RdfQueryException("Cannot evaluate numeric ordering when one or both arguments are Null");
            }
            if (type == SparqlNumericType.NaN)
            {
                throw new RdfQueryException("Cannot evaluate numeric ordering when the Numeric Type is NaN");
            }

            switch (type)
            {
            case SparqlNumericType.Decimal:
                return(x.AsDecimal().CompareTo(y.AsDecimal()));

            case SparqlNumericType.Double:
                return(x.AsDouble().CompareTo(y.AsDouble()));

            case SparqlNumericType.Float:
                return(x.AsFloat().CompareTo(y.AsFloat()));

            case SparqlNumericType.Integer:
                return(x.AsInteger().CompareTo(y.AsInteger()));

            default:
                throw new RdfQueryException("Cannot evaluate numeric equality since of the arguments is not numeric");
            }
        }
Ejemplo n.º 5
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 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");
            }
        }
Ejemplo n.º 6
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 object NumericValue(SparqlEvaluationContext context, int bindingID)
        {
            if (this._leftExpr is ISparqlNumericExpression && this._rightExpr is ISparqlNumericExpression)
            {
                ISparqlNumericExpression a = (ISparqlNumericExpression)this._leftExpr;
                ISparqlNumericExpression 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(this.IntegerValueInternal(a.IntegerValue(context, bindingID), b.IntegerValue(context, bindingID)));

                case SparqlNumericType.Decimal:
                    return(this.DecimalValueInternal(a.DecimalValue(context, bindingID), b.DecimalValue(context, bindingID)));

                case SparqlNumericType.Double:
                    return(this.DoubleValueInternal(a.DoubleValue(context, bindingID), b.DoubleValue(context, bindingID)));

                case SparqlNumericType.NaN:
                default:
                    throw new RdfQueryException("Unable to evaluate a Leviathan Numeric Expression since both arguments did not evaluate to a Numeric Value");
                }
            }
            else
            {
                throw new RdfQueryException("Unable to evaluate a Leviathan Numeric Expression since the one/both of the arguments are not Numeric Expressions");
            }
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Compares two Nodes for Numeric Ordering
        /// </summary>
        /// <param name="x">Node</param>
        /// <param name="y">Node</param>
        /// <param name="type">Numeric Type</param>
        /// <returns></returns>
        protected int NumericCompare(INode x, INode y, SparqlNumericType type)
        {
            if (x == null || y == null)
            {
                throw new RdfQueryException("Cannot evaluate numeric ordering when one or both arguments are Null");
            }
            if (type == SparqlNumericType.NaN)
            {
                throw new RdfQueryException("Cannot evaluate numeric ordering when the Numeric Type is NaN");
            }

            ILiteralNode a = (ILiteralNode)x;
            ILiteralNode b = (ILiteralNode)y;

            switch (type)
            {
            case SparqlNumericType.Decimal:
                return(SparqlSpecsHelper.ToDecimal(a).CompareTo(SparqlSpecsHelper.ToDecimal(b)));

            case SparqlNumericType.Double:
                return(SparqlSpecsHelper.ToDouble(a).CompareTo(SparqlSpecsHelper.ToDouble(b)));

            case SparqlNumericType.Float:
                return(SparqlSpecsHelper.ToFloat(a).CompareTo(SparqlSpecsHelper.ToFloat(b)));

            case SparqlNumericType.Integer:
                return(SparqlSpecsHelper.ToInteger(a).CompareTo(SparqlSpecsHelper.ToInteger(b)));

            default:
                throw new RdfQueryException("Cannot evaluate numeric equality since of the arguments is not numeric");
            }
        }
        /// <summary>
        /// Applies the operator
        /// </summary>
        /// <param name="ns">Arguments</param>
        /// <returns></returns>
        public override IValuedNode Apply(params IValuedNode[] ns)
        {
            if (ns == null)
            {
                throw new RdfQueryException("Cannot apply to null arguments");
            }
            if (ns.Any(n => n == null))
            {
                throw new RdfQueryException("Cannot apply multiplication when any arguments are null");
            }

            SparqlNumericType type = (SparqlNumericType)ns.Max(n => (int)n.NumericType);

            switch (type)
            {
            case SparqlNumericType.Integer:
                return(new LongNode(null, this.Multiply(ns.Select(n => n.AsInteger()))));

            case SparqlNumericType.Decimal:
                return(new DecimalNode(null, this.Multiply(ns.Select(n => n.AsDecimal()))));

            case SparqlNumericType.Float:
                return(new FloatNode(null, this.Multiply(ns.Select(n => n.AsFloat()))));

            case SparqlNumericType.Double:
                return(new DoubleNode(null, this.Multiply(ns.Select(n => n.AsDouble()))));

            default:
                throw new RdfQueryException("Cannot evalute an Arithmetic Expression when the Numeric Type of the expression cannot be determined");
            }
        }
Ejemplo n.º 9
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._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));

                try
                {
                    switch (type)
                    {
                    case SparqlNumericType.Integer:
                    case SparqlNumericType.Decimal:
                        //For Division Integers are treated as decimals
                        decimal d = a.DecimalValue(context, bindingID) / b.DecimalValue(context, bindingID);
                        if (Decimal.Floor(d).Equals(d) && d >= Int64.MinValue && d <= Int64.MaxValue)
                        {
                            return(Convert.ToInt64(d));
                        }
                        return(d);

                    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");
                    }
                }
                catch (DivideByZeroException)
                {
                    throw new RdfQueryException("Cannot evaluate a Division Expression where the divisor is Zero");
                }
            }
            else
            {
                throw new RdfQueryException("Cannot evalute an Arithmetic Expression where the two sub-expressions are not Numeric Expressions");
            }
        }
Ejemplo n.º 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._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");
            }
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Applies the operator
        /// </summary>
        /// <param name="ns">Arguments</param>
        /// <returns></returns>
        public override IValuedNode Apply(params IValuedNode[] ns)
        {
            if (ns.Any(n => n == null))
            {
                throw new RdfQueryException("Cannot apply division when any arguments are null");
            }

            SparqlNumericType type = (SparqlNumericType)ns.Max(n => (int)n.NumericType);

            try
            {
                switch (type)
                {
                case SparqlNumericType.Integer:
                case SparqlNumericType.Decimal:
                    // For Division Integers are treated as decimals
                    decimal d = this.Divide(ns.Select(n => n.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, this.Divide(ns.Select(n => n.AsFloat()))));

                case SparqlNumericType.Double:
                    return(new DoubleNode(null, this.Divide(ns.Select(n => n.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");
            }
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Applies the Average 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 INode Apply(SparqlEvaluationContext context, IEnumerable <int> bindingIDs)
        {
            if (this._varname != null)
            {
                //Ensured the AVGed 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 AVG Aggregate since the Variable does not occur in a Graph Pattern");
                }
            }

            //Prep Variables
            HashSet <INode> values = new HashSet <INode>();
            int             count  = 0;
            //long lngtotal = 0;
            decimal                  dectotal = 0.0m;
            float                    flttotal = 0.0f;
            double                   dbltotal = 0.0d;
            SparqlNumericType        maxtype  = SparqlNumericType.NaN;
            ISparqlNumericExpression numExpr;

            if (!(this._expr is ISparqlNumericExpression))
            {
                numExpr = new NumericWrapperExpression(this._expr);
                //throw new RdfQueryException("Cannot calculate an average aggregate over a non-numeric expression");
            }
            else
            {
                numExpr = (ISparqlNumericExpression)this._expr;
            }
            SparqlNumericType numtype;

            foreach (int id in bindingIDs)
            {
                try
                {
                    //Apply DISTINCT modifier if required
                    if (this._distinct)
                    {
                        INode temp = this._expr.Value(context, id);
                        if (temp == null)
                        {
                            return(null);
                        }
                        if (values.Contains(temp))
                        {
                            continue;
                        }
                        else
                        {
                            values.Add(temp);
                        }
                    }
                    numtype = numExpr.NumericType(context, id);
                }
                catch
                {
                    //SPARQL Working Group changed spec so this should now return no binding
                    return(null);
                }

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

                //Track the Numeric Type
                if ((int)numtype > (int)maxtype)
                {
                    maxtype = numtype;
                }

                //Increment the Totals based on the current Numeric Type
                switch (maxtype)
                {
                case SparqlNumericType.Integer:
                    //lngtotal += numExpr.IntegerValue(context, id);
                    dectotal += numExpr.DecimalValue(context, id);
                    flttotal += numExpr.FloatValue(context, id);
                    dbltotal += numExpr.DoubleValue(context, id);
                    break;

                case SparqlNumericType.Decimal:
                    dectotal += numExpr.DecimalValue(context, id);
                    flttotal += numExpr.FloatValue(context, id);
                    dbltotal += numExpr.DoubleValue(context, id);
                    break;

                case SparqlNumericType.Float:
                    flttotal += numExpr.FloatValue(context, id);
                    dbltotal += numExpr.DoubleValue(context, id);
                    break;

                case SparqlNumericType.Double:
                    dbltotal += numExpr.DoubleValue(context, id);
                    break;
                }

                count++;
            }

            //Calculate the Average
            if (count == 0)
            {
                return(new LiteralNode(null, "0", new Uri(XmlSpecsHelper.XmlSchemaDataTypeInteger)));
            }
            else
            {
                //long lngavg;
                decimal decavg;
                float   fltavg;
                double  dblavg;

                switch (maxtype)
                {
                case SparqlNumericType.NaN:
                    //No Numeric Values
                    return(new LiteralNode(null, "0", new Uri(XmlSpecsHelper.XmlSchemaDataTypeInteger)));

                case SparqlNumericType.Integer:
                ////Integer Values
                //lngavg = lngtotal / (long)count;
                //return new LiteralNode(null, lngavg.ToString(), new Uri(XmlSpecsHelper.XmlSchemaDataTypeInteger));

                case SparqlNumericType.Decimal:
                    //Decimal Values
                    decavg = dectotal / (decimal)count;
                    return(new LiteralNode(null, decavg.ToString(), new Uri(XmlSpecsHelper.XmlSchemaDataTypeDecimal)));

                case SparqlNumericType.Float:
                    //Float values
                    fltavg = flttotal / (float)count;
                    return(new LiteralNode(null, fltavg.ToString(), new Uri(XmlSpecsHelper.XmlSchemaDataTypeFloat)));

                case SparqlNumericType.Double:
                    //Double Values
                    dblavg = dbltotal / (double)count;
                    return(new LiteralNode(null, dblavg.ToString(), new Uri(XmlSpecsHelper.XmlSchemaDataTypeDouble)));

                default:
                    throw new RdfQueryException("Failed to calculate a valid Average");
                }
            }
        }
Ejemplo n.º 13
0
 /// <summary>
 /// Creates a new numeric valued node.
 /// </summary>
 /// <param name="g">Graph the node belongs to.</param>
 /// <param name="value">Lexical Value.</param>
 /// <param name="datatype">Datatype URI.</param>
 /// <param name="numType">SPARQL Numeric Type.</param>
 protected NumericNode(IGraph g, String value, Uri datatype, SparqlNumericType numType)
     : base(g, value, datatype)
 {
     _numType = numType;
 }
Ejemplo n.º 14
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 = _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");
            }
        }
Ejemplo n.º 15
0
        /// <summary>
        /// Implements Numeric Equality with SPARQL Semantics
        /// </summary>
        /// <param name="x">Node</param>
        /// <param name="y">Node</param>
        /// <param name="type">SPARQL Numeric Tyoe</param>
        /// <returns></returns>
        public static bool NumericEquality(INode x, INode y, SparqlNumericType type)
        {
            if (x == null || y == null) throw new RdfQueryException("Cannot evaluate numeric equality when one or both arguments are Null");
            if (type == SparqlNumericType.NaN) throw new RdfQueryException("Cannot evaluate numeric equality when the Numeric Type is NaN");

            try
            {
                ILiteralNode a = (ILiteralNode)x;
                ILiteralNode b = (ILiteralNode)y;

                switch (type)
                {
                    case SparqlNumericType.Decimal:
                        return ToDecimal(a).Equals(ToDecimal(b));
                    case SparqlNumericType.Double:
                        return ToDouble(a).Equals(ToDouble(b));
                    case SparqlNumericType.Float:
                        return ToFloat(a).Equals(ToFloat(b));
                    case SparqlNumericType.Integer:
                        return ToInteger(a).Equals(ToInteger(b));
                    default:
                        throw new RdfQueryException("Cannot evaluate numeric equality since of the arguments is not numeric");
                }
            }
            catch (FormatException)
            {
                throw;// new RdfQueryException("Cannot evaluate numeric equality since one of the arguments does not have a valid lexical value for the given type");
            }
        }
Ejemplo n.º 16
0
        /// <summary>
        /// Determines the Effective Boolean Value of the expression 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)
        {
            try
            {
                //While we could use NumericType or NumericValue for Numeric Expressions we can't guarantee that
                //this would work properly

                INode temp = this._expr.Value(context, bindingID);
                if (temp.NodeType == NodeType.Literal)
                {
                    ILiteralNode lit = (ILiteralNode)temp;

                    //No DatatType means not numeric
                    if (lit.DataType == null)
                    {
                        return(false);
                    }

                    //Get the Numeric Type from the DataType URI
                    SparqlNumericType type = SparqlSpecsHelper.GetNumericTypeFromDataTypeUri(lit.DataType);

                    //Now check the lexical value
                    switch (type)
                    {
                    case SparqlNumericType.Decimal:
                        //Decimal - just regex on lexical form
                        return(SparqlSpecsHelper.IsDecimal(lit.Value));

                    case SparqlNumericType.Double:
                    case SparqlNumericType.Float:
                        //Double/Float just regex on lexical form
                        return(SparqlSpecsHelper.IsDouble(lit.Value));

                    case SparqlNumericType.Integer:
                        //Integer Type so could be any of the supported types
                        switch (lit.DataType.ToString())
                        {
                        case XmlSpecsHelper.XmlSchemaDataTypeByte:
                            //Byte - have to try parsing it
                            SByte sb;
                            return(SByte.TryParse(lit.Value, out sb));

                        case XmlSpecsHelper.XmlSchemaDataTypeUnsignedByte:
                            //Unsigned Byte - have to try parsing it
                            Byte b;
                            return(Byte.TryParse(lit.Value, out b) && b >= 0);

                        case XmlSpecsHelper.XmlSchemaDataTypeInt:
                        case XmlSpecsHelper.XmlSchemaDataTypeInteger:
                        case XmlSpecsHelper.XmlSchemaDataTypeLong:
                        case XmlSpecsHelper.XmlSchemaDataTypeShort:
                            //Standard Integer - can just regex on its lexical form
                            return(SparqlSpecsHelper.IsInteger(lit.Value));

                        case XmlSpecsHelper.XmlSchemaDataTypeNegativeInteger:
                        case XmlSpecsHelper.XmlSchemaDataTypeNonPositiveInteger:
                            //Negative Integer - can just regex on its lexical form
                            //plus ensure that the value starts with a -
                            return(lit.Value.StartsWith("-") && SparqlSpecsHelper.IsInteger(lit.Value));

                        case XmlSpecsHelper.XmlSchemaDataTypeNonNegativeInteger:
                        case XmlSpecsHelper.XmlSchemaDataTypePositiveInteger:
                        case XmlSpecsHelper.XmlSchemaDataTypeUnsignedInt:
                        case XmlSpecsHelper.XmlSchemaDataTypeUnsignedLong:
                        case XmlSpecsHelper.XmlSchemaDataTypeUnsignedShort:
                            //Positive Integer - can just regex on its lexical form
                            //plus ensure that the value doesn't start with a -
                            return(!lit.Value.StartsWith("-") && SparqlSpecsHelper.IsInteger(lit.Value));

                        default:
                            //Otherwise not numeric
                            return(false);
                        }

                    default:
                        return(false);
                    }
                }
                else
                {
                    return(false);
                }
            }
            catch (RdfQueryException)
            {
                return(false);
            }
        }
Ejemplo n.º 17
0
        /// <summary>
        /// Compares two Nodes
        /// </summary>
        /// <param name="x">Node</param>
        /// <param name="y">Node</param>
        /// <returns></returns>
        public override int Compare(IValuedNode x, IValuedNode y)
        {
            // Nulls are less than everything
            if (x == null && y == null)
            {
                return(0);
            }
            if (x == null)
            {
                return(-1);
            }
            if (y == null)
            {
                return(1);
            }

            // If the Node Types are different use Node ordering
            if (x.NodeType != y.NodeType)
            {
                return(x.CompareTo(y));
            }

            if (x.NodeType == NodeType.Literal)
            {
                try
                {
                    // Do they have supported Data Types?
                    String xtype, ytype;
                    try
                    {
                        xtype = XmlSpecsHelper.GetSupportedDataType(x);
                        ytype = XmlSpecsHelper.GetSupportedDataType(y);
                    }
                    catch (RdfException)
                    {
                        // Can't determine a Data Type for one/both of the Nodes so use Node ordering
                        return(x.CompareTo(y));
                    }

                    if (xtype.Equals(String.Empty) || ytype.Equals(String.Empty))
                    {
                        // One/both has an unknown type
                        if (x.Equals(y))
                        {
                            // If RDF Term equality returns true then we return that they are equal
                            return(0);
                        }
                        else
                        {
                            // If RDF Term equality returns false then we fall back to Node Ordering
                            return(x.CompareTo(y));
                        }
                    }
                    else
                    {
                        // Both have known types
                        SparqlNumericType xnumtype = x.NumericType;
                        SparqlNumericType ynumtype = y.NumericType;
                        SparqlNumericType numtype  = (SparqlNumericType)Math.Max((int)xnumtype, (int)ynumtype);
                        if (numtype != SparqlNumericType.NaN)
                        {
                            if (xnumtype == SparqlNumericType.NaN)
                            {
                                return(1);
                            }
                            else if (ynumtype == SparqlNumericType.NaN)
                            {
                                return(-1);
                            }

                            // Both are Numeric so use Numeric ordering
                            try
                            {
                                return(this.NumericCompare(x, y, numtype));
                            }
                            catch (FormatException)
                            {
                                if (x.Equals(y))
                                {
                                    return(0);
                                }
                                // Otherwise fall back to Node Ordering
                                return(x.CompareTo(y));
                            }
                            catch (RdfQueryException)
                            {
                                // If this errors try RDF Term equality since that might still give equality
                                if (x.Equals(y))
                                {
                                    return(0);
                                }
                                // Otherwise fall back to Node Ordering
                                return(x.CompareTo(y));
                            }
                        }
                        else if (xtype.Equals(ytype))
                        {
                            switch (xtype)
                            {
                            case XmlSpecsHelper.XmlSchemaDataTypeDate:
                                return(DateCompare(x, y));

                            case XmlSpecsHelper.XmlSchemaDataTypeDateTime:
                                return(DateTimeCompare(x, y));

                            case XmlSpecsHelper.XmlSchemaDataTypeString:
                                // Both Strings so use Lexical string ordering
                                return(((ILiteralNode)x).Value.CompareTo(((ILiteralNode)y).Value));

                            default:
                                // Use node ordering
                                return(x.CompareTo(y));
                            }
                        }
                        else
                        {
                            String commontype = XmlSpecsHelper.GetCompatibleSupportedDataType(xtype, ytype, true);
                            if (commontype.Equals(String.Empty))
                            {
                                // Use Node ordering
                                return(x.CompareTo(y));
                            }
                            else
                            {
                                switch (commontype)
                                {
                                case XmlSpecsHelper.XmlSchemaDataTypeDate:
                                    return(DateCompare(x, y));

                                case XmlSpecsHelper.XmlSchemaDataTypeDateTime:
                                    return(DateTimeCompare(x, y));

                                default:
                                    // Use Node ordering
                                    return(x.CompareTo(y));
                                }
                            }
                        }
                    }
                }
                catch
                {
                    // If error then can't determine ordering so fall back to node ordering
                    return(x.CompareTo(y));
                }
            }
            else
            {
                // If not Literals use Node ordering
                return(x.CompareTo(y));
            }
        }
Ejemplo n.º 18
0
        /// <summary>
        /// Compares two Nodes
        /// </summary>
        /// <param name="x">Node</param>
        /// <param name="y">Node</param>
        /// <returns></returns>
        public virtual int Compare(INode x, INode y)
        {
            // Nulls are less than everything
            if (x == null && y == null)
            {
                return(0);
            }
            if (x == null)
            {
                return(-1);
            }
            if (y == null)
            {
                return(1);
            }

            // If the Node Types are different use Node ordering
            if (x.NodeType != y.NodeType)
            {
                return(x.CompareTo(y));
            }

            if (x.NodeType == NodeType.Literal)
            {
                // Do they have supported Data Types?
                String xtype, ytype;
                try
                {
                    xtype = XmlSpecsHelper.GetSupportedDataType(x);
                    ytype = XmlSpecsHelper.GetSupportedDataType(y);
                }
                catch (RdfException)
                {
                    // Can't determine a Data Type for one/both of the Nodes so use Node ordering
                    return(x.CompareTo(y));
                }

                if (xtype.Equals(String.Empty) || ytype.Equals(String.Empty))
                {
                    // One/both has an unknown type
                    if (x.Equals(y))
                    {
                        // If RDF Term equality returns true then we return that they are equal
                        return(0);
                    }
                    else
                    {
                        // If RDF Term equality returns false then we error
                        // UNLESS they have the same Datatype
                        throw new RdfQueryException("Unable to determine ordering since one/both arguments has an Unknown Type");
                    }
                }
                else
                {
                    // Both have known types
                    SparqlNumericType xnumtype = SparqlSpecsHelper.GetNumericTypeFromDataTypeUri(xtype);
                    SparqlNumericType ynumtype = SparqlSpecsHelper.GetNumericTypeFromDataTypeUri(ytype);
                    SparqlNumericType numtype  = (SparqlNumericType)Math.Max((int)xnumtype, (int)ynumtype);
                    if (numtype != SparqlNumericType.NaN)
                    {
                        if (xnumtype == SparqlNumericType.NaN || ynumtype == SparqlNumericType.NaN)
                        {
                            // If one is non-numeric then we can't assume non-equality
                            throw new RdfQueryException("Unable to determine ordering since one/both arguments does not return a Number");
                        }

                        // Both are Numeric so use Numeric ordering
                        try
                        {
                            return(this.NumericCompare(x, y, numtype));
                        }
                        catch (FormatException)
                        {
                            if (x.Equals(y))
                            {
                                return(0);
                            }
                            throw new RdfQueryException("Unable to determine ordering since one/both arguments does not contain a valid value for it's type");
                        }
                        catch (RdfQueryException)
                        {
                            // If this errors try RDF Term equality since
                            if (x.Equals(y))
                            {
                                return(0);
                            }
                            throw new RdfQueryException("Unable to determine ordering since one/both arguments was not a valid numeric");
                        }
                    }
                    else if (xtype.Equals(ytype))
                    {
                        switch (xtype)
                        {
                        case XmlSpecsHelper.XmlSchemaDataTypeDate:
                            return(DateCompare(x, y));

                        case XmlSpecsHelper.XmlSchemaDataTypeDateTime:
                            return(DateTimeCompare(x, y));

                        case XmlSpecsHelper.XmlSchemaDataTypeString:
                            // Both Strings so use Lexical string ordering
#if NETCORE
                            return(Options.DefaultCulture.CompareInfo.Compare(((ILiteralNode)x).Value,
                                                                              ((ILiteralNode)y).Value, Options.DefaultComparisonOptions));
#else
                            return(String.Compare(((ILiteralNode)x).Value, ((ILiteralNode)y).Value, Options.DefaultCulture, Options.DefaultComparisonOptions));
#endif
                        default:
                            // Use node ordering
                            return(x.CompareTo(y));
                        }
                    }
                    else
                    {
                        String commontype = XmlSpecsHelper.GetCompatibleSupportedDataType(xtype, ytype, true);
                        if (commontype.Equals(String.Empty))
                        {
                            // Use Node ordering
                            return(x.CompareTo(y));
                        }
                        else
                        {
                            switch (commontype)
                            {
                            case XmlSpecsHelper.XmlSchemaDataTypeDate:
                                return(DateCompare(x, y));

                            case XmlSpecsHelper.XmlSchemaDataTypeDateTime:
                                return(DateTimeCompare(x, y));

                            default:
                                // Use Node ordering
                                return(x.CompareTo(y));
                            }
                        }
                    }
                }
            }
            else
            {
                // If not Literals use Node ordering
                return(x.CompareTo(y));
            }
        }
Ejemplo n.º 19
0
 /// <summary>
 ///   Creates a new Numeric Expression
 /// </summary>
 /// <param name = "value">Integer Value</param>
 public NumericExpressionTerm(long value)
 {
     _type = SparqlNumericType.Integer;
     _intvalue = value;
     _decvalue = value;
     _fltvalue = value;
     _dblvalue = value;
     _value = new LiteralNode(null, _intvalue.ToString(), new Uri(XmlSpecsHelper.XmlSchemaDataTypeInteger));
 }
Ejemplo n.º 20
0
 /// <summary>
 /// Creates a new Numeric Expression
 /// </summary>
 /// <param name="value">Float Value</param>
 public NumericExpressionTerm(float value)
 {
     this._type = SparqlNumericType.Float;
     this._fltvalue = (float)value;
     this._dblvalue = (double)value;
     this._value = new LiteralNode(null, this._dblvalue.ToString(), new Uri(XmlSpecsHelper.XmlSchemaDataTypeFloat));
 }
Ejemplo n.º 21
0
 /// <summary>
 ///   Creates a new Numeric Expression
 /// </summary>
 /// <param name = "value">Decimal Value</param>
 public NumericExpressionTerm(decimal value)
 {
     _type = SparqlNumericType.Decimal;
     _decvalue = value;
     _fltvalue = (float) value;
     _dblvalue = (double) value;
     _value = new LiteralNode(null, _decvalue.ToString(), new Uri(XmlSpecsHelper.XmlSchemaDataTypeDecimal));
 }
Ejemplo n.º 22
0
 /// <summary>
 ///   Creates a new Numeric Expression
 /// </summary>
 /// <param name = "value">Float Value</param>
 public NumericExpressionTerm(float value)
 {
     _type = SparqlNumericType.Float;
     _fltvalue = value;
     _dblvalue = value;
     _value = new LiteralNode(null, _dblvalue.ToString(), new Uri(XmlSpecsHelper.XmlSchemaDataTypeFloat));
 }
Ejemplo n.º 23
0
        /// <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 INode 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;

            if (!(this._expr is ISparqlNumericExpression))
            {
                throw new RdfQueryException("Cannot evaluate a NMIN aggregate over a non-numeric expression");
            }
            ISparqlNumericExpression numExpr = (ISparqlNumericExpression)this._expr;
            SparqlNumericType        numtype;

            foreach (int id in bindingIDs)
            {
                try
                {
                    numtype = numExpr.NumericType(context, id);
                }
                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 = numExpr.IntegerValue(context, id);
                            decmin = numExpr.DecimalValue(context, id);
                            fltmin = numExpr.FloatValue(context, id);
                            dblmin = numExpr.DoubleValue(context, id);
                            break;

                        case SparqlNumericType.Decimal:
                            decmin = numExpr.DecimalValue(context, id);
                            fltmin = numExpr.FloatValue(context, id);
                            dblmin = numExpr.DoubleValue(context, id);
                            break;

                        case SparqlNumericType.Float:
                            fltmin = numExpr.FloatValue(context, id);
                            dblmin = numExpr.DoubleValue(context, id);
                            break;

                        case SparqlNumericType.Double:
                            dblmin = numExpr.DoubleValue(context, id);
                            break;
                        }
                        mintype = numtype;
                        continue;
                    }
                    else
                    {
                        mintype = numtype;
                    }
                }

                long    lngval;
                decimal decval;
                float   fltval;
                double  dblval;
                switch (mintype)
                {
                case SparqlNumericType.Integer:
                    lngval = numExpr.IntegerValue(context, id);

                    if (lngval < lngmin)
                    {
                        lngmin = lngval;
                        decmin = numExpr.DecimalValue(context, id);
                        fltmin = numExpr.FloatValue(context, id);
                        dblmin = numExpr.DoubleValue(context, id);
                    }
                    break;

                case SparqlNumericType.Decimal:
                    decval = numExpr.DecimalValue(context, id);

                    if (decval < decmin)
                    {
                        decmin = decval;
                        fltmin = numExpr.FloatValue(context, id);
                        dblmin = numExpr.DoubleValue(context, id);
                    }
                    break;

                case SparqlNumericType.Float:
                    fltval = numExpr.FloatValue(context, id);

                    if (fltval < fltmin)
                    {
                        fltmin = fltval;
                        dblmin = numExpr.DoubleValue(context, id);
                    }
                    break;

                case SparqlNumericType.Double:
                    dblval = numExpr.DoubleValue(context, id);

                    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 LiteralNode(null, lngmin.ToString(), new Uri(XmlSpecsHelper.XmlSchemaDataTypeInteger)));

            case SparqlNumericType.Decimal:
                //Decimal Values
                return(new LiteralNode(null, decmin.ToString(), new Uri(XmlSpecsHelper.XmlSchemaDataTypeDecimal)));

            case SparqlNumericType.Double:
                //Double Values
                return(new LiteralNode(null, dblmin.ToString(), new Uri(XmlSpecsHelper.XmlSchemaDataTypeDouble)));

            default:
                throw new RdfQueryException("Failed to calculate a valid Minimum");
            }
        }
Ejemplo n.º 24
0
        /// <summary>
        /// Applies the Sum 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 INode Apply(SparqlEvaluationContext context, IEnumerable <int> bindingIDs)
        {
            if (this._varname != null)
            {
                //Ensured the SUMmed 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 SUM Aggregate since the Variable does not occur in a Graph Pattern");
                }
            }

            //Prep Variables
            long              lngtotal = 0;
            decimal           dectotal = 0.0m;
            float             flttotal = 0.0f;
            double            dbltotal = 0.0d;
            SparqlNumericType maxtype  = SparqlNumericType.NaN;

            if (!(this._expr is ISparqlNumericExpression))
            {
                throw new RdfQueryException("Cannot calculate an sum aggregate over a non-numeric expression");
            }
            ISparqlNumericExpression numExpr = (ISparqlNumericExpression)this._expr;
            SparqlNumericType        numtype;
            HashSet <INode>          values = new HashSet <INode>();

            foreach (int id in bindingIDs)
            {
                try
                {
                    if (this._distinct)
                    {
                        INode temp = this._expr.Value(context, id);
                        if (temp == null)
                        {
                            continue;
                        }
                        if (values.Contains(temp))
                        {
                            continue;
                        }
                        else
                        {
                            values.Add(temp);
                        }
                    }
                    numtype = numExpr.NumericType(context, id);
                }
                catch
                {
                    continue;
                }

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

                //Track the Numeric Type
                if ((int)numtype > (int)maxtype)
                {
                    maxtype = numtype;
                }

                //Increment the Totals based on the current Numeric Type
                switch (maxtype)
                {
                case SparqlNumericType.Integer:
                    lngtotal += numExpr.IntegerValue(context, id);
                    dectotal += numExpr.DecimalValue(context, id);
                    flttotal += numExpr.FloatValue(context, id);
                    dbltotal += numExpr.DoubleValue(context, id);
                    break;

                case SparqlNumericType.Decimal:
                    dectotal += numExpr.DecimalValue(context, id);
                    flttotal += numExpr.FloatValue(context, id);
                    dbltotal += numExpr.DoubleValue(context, id);
                    break;

                case SparqlNumericType.Float:
                    flttotal += numExpr.FloatValue(context, id);
                    dbltotal += numExpr.DoubleValue(context, id);
                    break;

                case SparqlNumericType.Double:
                    dbltotal += numExpr.DoubleValue(context, id);
                    break;
                }
            }

            //Return the Sum
            switch (maxtype)
            {
            case SparqlNumericType.NaN:
                //No Numeric Values
                return(new LiteralNode(null, "0", new Uri(XmlSpecsHelper.XmlSchemaDataTypeInteger)));

            case SparqlNumericType.Integer:
                //Integer Values
                return(new LiteralNode(null, lngtotal.ToString(), new Uri(XmlSpecsHelper.XmlSchemaDataTypeInteger)));

            case SparqlNumericType.Decimal:
                //Decimal Values
                return(new LiteralNode(null, dectotal.ToString(), new Uri(XmlSpecsHelper.XmlSchemaDataTypeDecimal)));

            case SparqlNumericType.Float:
                //Float Values
                return(new LiteralNode(null, flttotal.ToString(), new Uri(XmlSpecsHelper.XmlSchemaDataTypeFloat)));

            case SparqlNumericType.Double:
                //Double Values
                return(new LiteralNode(null, dbltotal.ToString(), new Uri(XmlSpecsHelper.XmlSchemaDataTypeDouble)));

            default:
                throw new RdfQueryException("Failed to calculate a valid Sum");
            }
        }
Ejemplo n.º 25
0
 /// <summary>
 ///   Creates a new Numeric Expression
 /// </summary>
 /// <param name = "value">Double Value</param>
 public NumericExpressionTerm(double value)
 {
     _type = SparqlNumericType.Double;
     _dblvalue = value;
     _value = new LiteralNode(null, _dblvalue.ToString(), new Uri(XmlSpecsHelper.XmlSchemaDataTypeDouble));
 }
Ejemplo n.º 26
0
        /// <summary>
        /// Applies the Sum 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)
        {
            // Prep Variables
            long                  lngtotal = 0;
            decimal               dectotal = 0.0m;
            float                 flttotal = 0.0f;
            double                dbltotal = 0.0d;
            SparqlNumericType     maxtype  = SparqlNumericType.NaN;
            SparqlNumericType     numtype;
            HashSet <IValuedNode> values = new HashSet <IValuedNode>();

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

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

                // Track the Numeric Type
                if ((int)numtype > (int)maxtype)
                {
                    maxtype = numtype;
                }

                // Increment the Totals based on the current Numeric Type
                switch (maxtype)
                {
                case SparqlNumericType.Integer:
                    lngtotal += temp.AsInteger();
                    dectotal += temp.AsDecimal();
                    flttotal += temp.AsFloat();
                    dbltotal += temp.AsDouble();
                    break;

                case SparqlNumericType.Decimal:
                    dectotal += temp.AsDecimal();
                    flttotal += temp.AsFloat();
                    dbltotal += temp.AsDouble();
                    break;

                case SparqlNumericType.Float:
                    flttotal += temp.AsFloat();
                    dbltotal += temp.AsDouble();
                    break;

                case SparqlNumericType.Double:
                    dbltotal += temp.AsDouble();
                    break;
                }
            }

            // Return the Sum
            switch (maxtype)
            {
            case SparqlNumericType.NaN:
                // No Numeric Values
                return(new LongNode(null, 0));

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

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

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

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

            default:
                throw new RdfQueryException("Failed to calculate a valid Sum");
            }
        }
Ejemplo n.º 27
0
        /// <summary>
        /// Applies the Average 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)
        {
            //Prep Variables
            HashSet <IValuedNode> values = new HashSet <IValuedNode>();
            int count = 0;
            //long lngtotal = 0;
            decimal           dectotal = 0.0m;
            float             flttotal = 0.0f;
            double            dbltotal = 0.0d;
            SparqlNumericType maxtype  = SparqlNumericType.NaN;
            SparqlNumericType numtype;

            foreach (int id in bindingIDs)
            {
                IValuedNode temp;
                try
                {
                    temp = this._expr.Evaluate(context, id);
                    if (temp == null)
                    {
                        return(null);
                    }
                    //Apply DISTINCT modifier if required
                    if (this._distinct)
                    {
                        if (values.Contains(temp))
                        {
                            continue;
                        }
                        else
                        {
                            values.Add(temp);
                        }
                    }
                    numtype = temp.NumericType;
                }
                catch
                {
                    //SPARQL Working Group changed spec so this should now return no binding
                    return(null);
                }

                //No result if anything resolves to non-numeric
                if (numtype == SparqlNumericType.NaN)
                {
                    return(null);
                }

                //Track the Numeric Type
                if ((int)numtype > (int)maxtype)
                {
                    maxtype = numtype;
                }

                //Increment the Totals based on the current Numeric Type
                switch (maxtype)
                {
                case SparqlNumericType.Integer:
                    //lngtotal += numExpr.IntegerValue(context, id);
                    dectotal += temp.AsDecimal();
                    flttotal += temp.AsFloat();
                    dbltotal += temp.AsDouble();
                    break;

                case SparqlNumericType.Decimal:
                    dectotal += temp.AsDecimal();
                    flttotal += temp.AsFloat();
                    dbltotal += temp.AsDouble();
                    break;

                case SparqlNumericType.Float:
                    flttotal += temp.AsFloat();
                    dbltotal += temp.AsDouble();
                    break;

                case SparqlNumericType.Double:
                    dbltotal += temp.AsDouble();
                    break;
                }

                count++;
            }

            //Calculate the Average
            if (count == 0)
            {
                return(new LongNode(null, 0));
            }
            else
            {
                //long lngavg;
                decimal decavg;
                float   fltavg;
                double  dblavg;

                switch (maxtype)
                {
                case SparqlNumericType.Integer:
                ////Integer Values
                //lngavg = lngtotal / (long)count;
                //return new LiteralNode(null, lngavg.ToString(), new Uri(XmlSpecsHelper.XmlSchemaDataTypeInteger));

                case SparqlNumericType.Decimal:
                    //Decimal Values
                    decavg = dectotal / (decimal)count;
                    return(new DecimalNode(null, decavg));

                case SparqlNumericType.Float:
                    //Float values
                    fltavg = flttotal / (float)count;
                    return(new FloatNode(null, fltavg));

                case SparqlNumericType.Double:
                    //Double Values
                    dblavg = dbltotal / (double)count;
                    return(new DoubleNode(null, dblavg));

                default:
                    throw new RdfQueryException("Failed to calculate a valid Average");
                }
            }
        }
Ejemplo n.º 28
0
 /// <summary>
 /// Creates a new numeric valued node
 /// </summary>
 /// <param name="g">Graph the node belongs to</param>
 /// <param name="value">Lexical Value</param>
 /// <param name="datatype">Datatype URI</param>
 /// <param name="numType">SPARQL Numeric Type</param>
 public NumericNode(IGraph g, String value, Uri datatype, SparqlNumericType numType)
     : base(g, value, datatype)
 {
     this._numType = numType;
 }
Ejemplo n.º 29
0
 /// <summary>
 /// Creates a new numeric valued node
 /// </summary>
 /// <param name="g">Graph the node belongs to</param>
 /// <param name="value">Lexical Value</param>
 /// <param name="datatype">Datatype URI</param>
 /// <param name="numType">SPARQL Numeric Type</param>
 public NumericNode(IGraph g, String value, Uri datatype, SparqlNumericType numType)
     : base(g, value, datatype)
 {
     this._numType = numType;
 }
Ejemplo n.º 30
0
        /// <summary>
        /// Applies the Numeric Max 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 (_varname != null)
            {
                // Ensured the MAXed variable is in the Variables of the Results
                if (!context.Binder.Variables.Contains(_varname))
                {
                    throw new RdfQueryException("Cannot use the Variable " + _expr.ToString() + " in a NMAX Aggregate since the Variable does not occur in a Graph Pattern");
                }
            }

            // Prep Variables
            long              lngmax  = 0;
            decimal           decmax  = 0.0m;
            float             fltmax  = 0.0f;
            double            dblmax  = 0.0d;
            SparqlNumericType maxtype = SparqlNumericType.NaN;
            SparqlNumericType numtype;

            foreach (int id in bindingIDs)
            {
                IValuedNode temp;
                try
                {
                    temp = _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)maxtype)
                {
                    if (maxtype == SparqlNumericType.NaN)
                    {
                        // Initialise Maximums
                        switch (numtype)
                        {
                        case SparqlNumericType.Integer:
                            lngmax = temp.AsInteger();
                            decmax = temp.AsDecimal();
                            fltmax = temp.AsFloat();
                            dblmax = temp.AsDouble();
                            break;

                        case SparqlNumericType.Decimal:
                            decmax = temp.AsDecimal();
                            fltmax = temp.AsFloat();
                            dblmax = temp.AsDouble();
                            break;

                        case SparqlNumericType.Float:
                            fltmax = temp.AsFloat();
                            dblmax = temp.AsDouble();
                            break;

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

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

                    if (lngval > lngmax)
                    {
                        lngmax = lngval;
                        decmax = temp.AsDecimal();
                        fltmax = temp.AsFloat();
                        dblmax = temp.AsDouble();
                    }
                    break;

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

                    if (decval > decmax)
                    {
                        decmax = decval;
                        fltmax = temp.AsFloat();
                        dblmax = temp.AsDouble();
                    }
                    break;

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

                    if (fltval > fltmax)
                    {
                        fltmax = fltval;
                        dblmax = temp.AsDouble();
                    }
                    break;

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

                    if (dblval > dblmax)
                    {
                        dblmax = dblval;
                    }
                    break;
                }
            }

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

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

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

            case SparqlNumericType.Float:
                // Float values
                return(new FloatNode(null, fltmax));

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

            default:
                throw new RdfQueryException("Failed to calculate a valid Maximum");
            }
        }
Ejemplo n.º 31
0
 /// <summary>
 /// Compares two Nodes for Numeric Ordering
 /// </summary>
 /// <param name="x">Node</param>
 /// <param name="y">Node</param>
 /// <param name="type">Numeric Type</param>
 /// <returns></returns>
 protected virtual int NumericCompare(INode x, INode y, SparqlNumericType type)
 {
     return(NumericCompare(x.AsValuedNode(), y.AsValuedNode(), type));
 }
Ejemplo n.º 32
0
 /// <summary>
 /// Creates a new Numeric Expression
 /// </summary>
 /// <param name="value">Double Value</param>
 public NumericExpressionTerm(double value)
 {
     this._type     = SparqlNumericType.Double;
     this._dblvalue = value;
     this._value    = new LiteralNode(null, this._dblvalue.ToString(), new Uri(XmlSpecsHelper.XmlSchemaDataTypeDouble));
 }
Ejemplo n.º 33
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 INode Value(SparqlEvaluationContext context, int bindingID)
        {
            INode n = this._expr.Value(context, bindingID);

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

            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
                ILiteralNode lit = (ILiteralNode)n;
                if (lit.DataType != null)
                {
                    String dt = lit.DataType.ToString();

                    if (dt.Equals(XmlSpecsHelper.XmlSchemaDataTypeBoolean))
                    {
                        //Already a Boolean
                        return(lit);
                    }

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

                    switch (type)
                    {
                    case SparqlNumericType.Decimal:
                        Decimal dec;
                        if (Decimal.TryParse(lit.Value, out dec))
                        {
                            if (dec.Equals(Decimal.Zero))
                            {
                                return(new LiteralNode(lit.Graph, "false", new Uri(XmlSpecsHelper.XmlSchemaDataTypeBoolean)));
                            }
                            else
                            {
                                return(new LiteralNode(lit.Graph, "true", new Uri(XmlSpecsHelper.XmlSchemaDataTypeBoolean)));
                            }
                        }
                        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, out dbl))
                        {
                            if (Double.IsNaN(dbl) || dbl == 0.0d)
                            {
                                return(new LiteralNode(lit.Graph, "false", new Uri(XmlSpecsHelper.XmlSchemaDataTypeBoolean)));
                            }
                            else
                            {
                                return(new LiteralNode(lit.Graph, "true", new Uri(XmlSpecsHelper.XmlSchemaDataTypeBoolean)));
                            }
                        }
                        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 LiteralNode(lit.Graph, "false", new Uri(XmlSpecsHelper.XmlSchemaDataTypeBoolean)));
                            }
                            else
                            {
                                return(new LiteralNode(lit.Graph, "true", new Uri(XmlSpecsHelper.XmlSchemaDataTypeBoolean)));
                            }
                        }
                        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 LiteralNode(lit.Graph, b.ToString(), new Uri(XmlSpecsHelper.XmlSchemaDataTypeBoolean)));
                            }
                            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 LiteralNode(lit.Graph, b.ToString(), new Uri(XmlSpecsHelper.XmlSchemaDataTypeBoolean)));
                    }
                    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");
            }
        }