Ejemplo n.º 1
0
        /// <summary>
        /// Applies the result set to a Results Handler.
        /// </summary>
        /// <param name="handler">Results Handler.</param>
        /// <param name="results">Result Set.</param>
        public static void Apply(this ISparqlResultsHandler handler, SparqlResultSet results)
        {
            try
            {
                handler.StartResults();

                switch (results.ResultsType)
                {
                case SparqlResultsType.Boolean:
                    handler.HandleBooleanResult(results.Result);
                    break;

                case SparqlResultsType.VariableBindings:
                    foreach (String var in results.Variables)
                    {
                        if (!handler.HandleVariable(var))
                        {
                            ParserHelper.Stop();
                        }
                    }
                    foreach (SparqlResult r in results)
                    {
                        if (!handler.HandleResult(r))
                        {
                            ParserHelper.Stop();
                        }
                    }
                    break;

                default:
                    // Does nothing
                    break;
                }

                handler.EndResults(true);
            }
            catch (RdfParsingTerminatedException)
            {
                handler.EndResults(true);
            }
            catch
            {
                handler.EndResults(false);
                throw;
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Makes a Query where the expected Result is a SparqlResultSet ie. SELECT and ASK Queries
        /// </summary>
        /// <param name="handler">Results Handler to process the results</param>
        /// <param name="sparqlQuery">SPARQL Query String</param>
        /// <exception cref="RdfQueryException">Thrown if any of the requests to the endpoints fail</exception>
        /// <exception cref="RdfQueryTimeoutException">Thrown if not all the requests complete within the set timeout</exception>
        public override void QueryWithResultSet(ISparqlResultsHandler handler, string sparqlQuery)
        {
            //If no endpoints do nothing
            if (this._endpoints.Count == 0)
            {
                return;
            }

            //Fire off all the Asychronous Requests
            List <AsyncQueryWithResultSet> asyncCalls   = new List <AsyncQueryWithResultSet>();
            List <IAsyncResult>            asyncResults = new List <IAsyncResult>();
            int count = 0;

            foreach (SparqlRemoteEndpoint endpoint in this._endpoints)
            {
                //Limit the number of simultaneous requests we make to the user defined level (default 4)
                //We do this limiting check before trying to issue a request so that when the last request
                //is issued we'll always drop out of the loop and move onto our WaitAll()
                while (count >= this._maxSimultaneousRequests)
                {
                    //First check that the count of active requests is accurate
                    int active = asyncResults.Count(r => !r.IsCompleted);
                    if (active < count)
                    {
                        //Some of the requests have already completed so we don't need to wait
                        count = active;
                        break;
                    }
                    else if (active > count)
                    {
                        //There are more active requests then we thought
                        count = active;
                    }

                    //While the number of requests is at/above the maximum we'll wait for any of the requests to finish
                    //Then we can decrement the count and if this drops back below our maximum then we'll go back into the
                    //main loop and fire off our next request
                    WaitHandle.WaitAny(asyncResults.Select(r => r.AsyncWaitHandle).ToArray());
                    count--;
                }

                //Make an asynchronous query to the next endpoint
                AsyncQueryWithResultSet d = new AsyncQueryWithResultSet(endpoint.QueryWithResultSet);
                asyncCalls.Add(d);
                IAsyncResult asyncResult = d.BeginInvoke(sparqlQuery, null, null);
                asyncResults.Add(asyncResult);
                count++;
            }

            //Wait for all our requests to finish
            int waitTimeout = (base.Timeout > 0) ? base.Timeout : System.Threading.Timeout.Infinite;

            WaitHandle.WaitAll(asyncResults.Select(r => r.AsyncWaitHandle).ToArray(), waitTimeout);

            //Check for and handle timeouts
            if (!this._ignoreFailedRequests && !asyncResults.All(r => r.IsCompleted))
            {
                for (int i = 0; i < asyncCalls.Count; i++)
                {
                    try
                    {
                        asyncCalls[i].EndInvoke(asyncResults[i]);
                    }
                    catch
                    {
                        //Exceptions don't matter as we're just ensuring all the EndInvoke() calls are made
                    }
                }
                throw new RdfQueryTimeoutException("Federated Querying failed due to one/more endpoints failing to return results within the Timeout specified which is currently " + (base.Timeout / 1000) + " seconds");
            }

            //Now merge all the results together
            HashSet <String> varsSeen = new HashSet <string>();
            bool             cont     = true;

            for (int i = 0; i < asyncCalls.Count; i++)
            {
                //Retrieve the result for this call
                AsyncQueryWithResultSet call = asyncCalls[i];
                SparqlResultSet         partialResult;
                try
                {
                    partialResult = call.EndInvoke(asyncResults[i]);
                }
                catch (Exception ex)
                {
                    if (!this._ignoreFailedRequests)
                    {
                        //Clean up in the event of an error
                        for (int j = i + 1; j < asyncCalls.Count; j++)
                        {
                            try
                            {
                                asyncCalls[j].EndInvoke(asyncResults[j]);
                            }
                            catch
                            {
                                //Exceptions don't matter as we're just ensuring all the EndInvoke() calls are made
                            }
                        }

                        //If a single request fails then the entire query fails
                        throw new RdfQueryException("Federated Querying failed due to the query against the endpoint '" + this._endpoints[i].Uri.ToString() + "' failing", ex);
                    }
                    else
                    {
                        //If we're ignoring failed requests we continue here
                        continue;
                    }
                }

                //Merge the result into the final results
                //If the handler has previously told us to stop we skip this step
                if (cont)
                {
                    foreach (String variable in partialResult.Variables)
                    {
                        cont = handler.HandleVariable(variable);
                        //Stop if handler tells us to
                        if (!cont)
                        {
                            break;
                        }
                    }

                    if (cont)
                    {
                        foreach (SparqlResult result in partialResult.Results)
                        {
                            cont = handler.HandleResult(result);
                            //Stop if handler tells us to
                            if (!cont)
                            {
                                break;
                            }
                        }
                    }
                }
            }
        }
Ejemplo n.º 3
0
        internal static void Apply(this ISparqlResultsHandler handler, SparqlEvaluationContext context)
        {
            try
            {
                handler.StartResults();

                SparqlQuery     q = context.Query;
                SparqlQueryType type;
                if (q == null)
                {
                    type = (context.OutputMultiset.Variables.Any() || context.OutputMultiset.Sets.Any() ? SparqlQueryType.Select : SparqlQueryType.Ask);
                }
                else
                {
                    type = q.QueryType;
                }

                if (type == SparqlQueryType.Ask)
                {
                    //ASK Query so get the handler to handle an appropriate boolean result
                    if (context.OutputMultiset is IdentityMultiset)
                    {
                        handler.HandleBooleanResult(true);
                    }
                    else if (context.OutputMultiset is NullMultiset)
                    {
                        handler.HandleBooleanResult(false);
                    }
                    else
                    {
                        handler.HandleBooleanResult(!context.OutputMultiset.IsEmpty);
                    }
                }
                else
                {
                    //SELECT Query so get the handler to handle variables and then handle results
                    foreach (String var in context.OutputMultiset.Variables)
                    {
                        if (!handler.HandleVariable(var))
                        {
                            ParserHelper.Stop();
                        }
                    }
                    foreach (ISet s in context.OutputMultiset.Sets)
                    {
                        if (!handler.HandleResult(new SparqlResult(s)))
                        {
                            ParserHelper.Stop();
                        }
                    }
                    q.VirtualCount = context.OutputMultiset.VirtualCount;
                }

                handler.EndResults(true);
            }
            catch (RdfParsingTerminatedException)
            {
                handler.EndResults(true);
            }
            catch
            {
                handler.EndResults(false);
                throw;
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Makes a Query where the expected Result is a SparqlResultSet ie. SELECT and ASK Queries.
        /// </summary>
        /// <param name="handler">Results Handler to process the results.</param>
        /// <param name="sparqlQuery">SPARQL Query String.</param>
        /// <exception cref="RdfQueryException">Thrown if any of the requests to the endpoints fail.</exception>
        /// <exception cref="RdfQueryTimeoutException">Thrown if not all the requests complete within the set timeout.</exception>
        public override void QueryWithResultSet(ISparqlResultsHandler handler, string sparqlQuery)
        {
            // If no endpoints do nothing
            if (_endpoints.Count == 0)
            {
                return;
            }

            // Fire off all the asynchronous Requests
            var asyncCalls = new List <Task <SparqlResultSet> >();
            var cts        = new CancellationTokenSource();
            int count      = 0;

            foreach (SparqlRemoteEndpoint endpoint in _endpoints)
            {
                // Limit the number of simultaneous requests we make to the user defined level (default 4)
                // We do this limiting check before trying to issue a request so that when the last request
                // is issued we'll always drop out of the loop and move onto our WaitAll()
                while (count >= _maxSimultaneousRequests)
                {
                    // First check that the count of active requests is accurate
                    int active = asyncCalls.Count(r => !r.IsCompleted);
                    if (active < count)
                    {
                        // Some of the requests have already completed so we don't need to wait
                        count = active;
                        break;
                    }
                    if (active > count)
                    {
                        // There are more active requests then we thought
                        count = active;
                    }

                    // While the number of requests is at/above the maximum we'll wait for any of the requests to finish
                    // Then we can decrement the count and if this drops back below our maximum then we'll go back into the
                    // main loop and fire off our next request
                    Task.WaitAny(asyncCalls.ToArray(), cts.Token);
                    count--;
                }

                // Make an asynchronous query to the next endpoint
                asyncCalls.Add(Task.Factory.StartNew(() => endpoint.QueryWithResultSet(sparqlQuery), cts.Token));
                count++;
            }

            // Wait for all our requests to finish
            int waitTimeout = (Timeout > 0) ? Timeout : System.Threading.Timeout.Infinite;

            try
            {
                if (!Task.WaitAll(asyncCalls.ToArray(), waitTimeout, cts.Token))
                {
                    // Handle timeouts - cancel overrunning tasks and optionally throw an exception
                    cts.Cancel(false);
                    if (!_ignoreFailedRequests)
                    {
                        throw new RdfQueryTimeoutException(
                                  "Federated Querying failed due to one/more endpoints failing to return results within the Timeout specified which is currently " +
                                  (Timeout / 1000) + " seconds");
                    }
                }
            }
            catch (AggregateException ex)
            {
                if (!_ignoreFailedRequests)
                {
                    // Try to determine which endpoint faulted
                    var faultedTaskIndex   = asyncCalls.FindIndex(t => t.IsFaulted);
                    var faultedEndpointUri = _endpoints[faultedTaskIndex].Uri.AbsoluteUri;
                    throw new RdfQueryException(
                              "Federated querying failed due to the query against the endpoint '" + faultedEndpointUri +
                              "' failing.", ex.InnerException);
                }
            }

            // Now merge all the results together
            var cont = true;

            for (var i = 0; i < asyncCalls.Count; i++)
            {
                if (!asyncCalls[i].IsCompleted)
                {
                    // This is a timed out task that has not transitioned to cancelled state yet
                    // We will only get here if _ignoreFailedRequests is true
                    continue;
                }

                // Retrieve the result for this call
                SparqlResultSet partialResult;
                try
                {
                    partialResult = asyncCalls[i].Result;
                }
                catch (Exception ex)
                {
                    if (!_ignoreFailedRequests)
                    {
                        // If a single request fails then the entire query fails
                        throw new RdfQueryException(
                                  "Federated querying failed due to the query against the endpoint '" +
                                  _endpoints[i].Uri.AbsoluteUri + "' failing", ex);
                    }

                    // If we're ignoring failed requests we continue here
                    continue;
                }

                // Merge the result into the final results
                // If the handler has previously told us to stop we skip this step
                if (cont)
                {
                    handler.StartResults();
                    foreach (var variable in partialResult.Variables)
                    {
                        cont = handler.HandleVariable(variable);
                        // Stop if handler tells us to
                        if (!cont)
                        {
                            break;
                        }
                    }

                    if (cont)
                    {
                        foreach (var result in partialResult.Results)
                        {
                            cont = handler.HandleResult(result);
                            // Stop if handler tells us to
                            if (!cont)
                            {
                                break;
                            }
                        }
                    }
                    handler.EndResults(cont);
                }
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Makes a Query where the expected Result is a SparqlResultSet ie. SELECT and ASK Queries
        /// </summary>
        /// <param name="handler">Results Handler to process the results</param>
        /// <param name="sparqlQuery">SPARQL Query String</param>
        /// <exception cref="RdfQueryException">Thrown if any of the requests to the endpoints fail</exception>
        /// <exception cref="RdfQueryTimeoutException">Thrown if not all the requests complete within the set timeout</exception>
        public override void QueryWithResultSet(ISparqlResultsHandler handler, string sparqlQuery)
        {
            //If no endpoints do nothing
            if (this._endpoints.Count == 0) return;

            //Fire off all the Asychronous Requests
            List<AsyncQueryWithResultSet> asyncCalls = new List<AsyncQueryWithResultSet>();
            List<IAsyncResult> asyncResults = new List<IAsyncResult>();
            int count = 0;
            foreach (SparqlRemoteEndpoint endpoint in this._endpoints)
            {
                //Limit the number of simultaneous requests we make to the user defined level (default 4)
                //We do this limiting check before trying to issue a request so that when the last request
                //is issued we'll always drop out of the loop and move onto our WaitAll()
                while (count >= this._maxSimultaneousRequests)
                {
                    //First check that the count of active requests is accurate
                    int active = asyncResults.Count(r => !r.IsCompleted);
                    if (active < count)
                    {
                        //Some of the requests have already completed so we don't need to wait
                        count = active;
                        break;
                    }
                    else if (active > count)
                    {
                        //There are more active requests then we thought
                        count = active;
                    }

                    //While the number of requests is at/above the maximum we'll wait for any of the requests to finish
                    //Then we can decrement the count and if this drops back below our maximum then we'll go back into the
                    //main loop and fire off our next request
                    WaitHandle.WaitAny(asyncResults.Select(r => r.AsyncWaitHandle).ToArray());
                    count--;
                }

                //Make an asynchronous query to the next endpoint
                AsyncQueryWithResultSet d = new AsyncQueryWithResultSet(endpoint.QueryWithResultSet);
                asyncCalls.Add(d);
                IAsyncResult asyncResult = d.BeginInvoke(sparqlQuery, null, null);
                asyncResults.Add(asyncResult);
                count++;
            }

            //Wait for all our requests to finish
            int waitTimeout = (base.Timeout > 0) ? base.Timeout : System.Threading.Timeout.Infinite;
            WaitHandle.WaitAll(asyncResults.Select(r => r.AsyncWaitHandle).ToArray(), waitTimeout);

            //Check for and handle timeouts
            if (!this._ignoreFailedRequests && !asyncResults.All(r => r.IsCompleted))
            {
                for (int i = 0; i < asyncCalls.Count; i++)
                {
                    try
                    {
                        asyncCalls[i].EndInvoke(asyncResults[i]);
                    }
                    catch
                    {
                        //Exceptions don't matter as we're just ensuring all the EndInvoke() calls are made
                    }
                }
                throw new RdfQueryTimeoutException("Federated Querying failed due to one/more endpoints failing to return results within the Timeout specified which is currently " + (base.Timeout / 1000) + " seconds");
            }

            //Now merge all the results together
            HashSet<String> varsSeen = new HashSet<string>();
            bool cont = true;
            for (int i = 0; i < asyncCalls.Count; i++)
            {
                //Retrieve the result for this call
                AsyncQueryWithResultSet call = asyncCalls[i];
                SparqlResultSet partialResult;
                try
                {
                    partialResult = call.EndInvoke(asyncResults[i]);
                }
                catch (Exception ex)
                {
                    if (!this._ignoreFailedRequests)
                    {
                        //Clean up in the event of an error
                        for (int j = i + 1; j < asyncCalls.Count; j++)
                        {
                            try
                            {
                                asyncCalls[j].EndInvoke(asyncResults[j]);
                            }
                            catch
                            {
                                //Exceptions don't matter as we're just ensuring all the EndInvoke() calls are made
                            }
                        }

                        //If a single request fails then the entire query fails
                        throw new RdfQueryException("Federated Querying failed due to the query against the endpoint '" + this._endpoints[i].Uri.ToString() + "' failing", ex);
                    }
                    else
                    {
                        //If we're ignoring failed requests we continue here
                        continue;
                    }
                }

                //Merge the result into the final results
                //If the handler has previously told us to stop we skip this step
                if (cont)
                {
                    foreach (String variable in partialResult.Variables)
                    {
                        cont = handler.HandleVariable(variable);
                        //Stop if handler tells us to
                        if (!cont) break;
                    }

                    if (cont)
                    {
                        foreach (SparqlResult result in partialResult.Results)
                        {
                            cont = handler.HandleResult(result);
                            //Stop if handler tells us to
                            if (!cont) break;
                        }
                    }
                }
            }
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Executes a SPARQL Query on the native Quad Store processing the results with an appropriate handler from those provided
        /// </summary>
        /// <param name="rdfHandler">RDF Handler</param>
        /// <param name="resultsHandler">Results Handler</param>
        /// <param name="sparqlQuery">SPARQL Query to execute</param>
        /// <remarks>
        /// <para>
        /// This method will first attempt to parse the query into a <see cref="SparqlQuery">SparqlQuery</see> object.  If this succeeds then the Query Type can be used to determine how to handle the response.
        /// </para>
        /// <para>
        /// If the parsing fails then the query will be executed anyway using Virtuoso's SPASQL (SPARQL + SQL) syntax.  Parsing can fail because Virtuoso supports various SPARQL non-standardised extensions which the library does not support.  These include things like aggregate functions but also SPARUL updates (the non-standard precusor to SPARQL 1.1 Update).
        /// </para>
        /// <para>
        /// If you use an aggregate query which has an Integer, Decimal or Double type result then you will receive a <see cref="SparqlResultSet">SparqlResultSet</see> containing a single <see cref="SparqlResult">SparqlResult</see> which has contains a binding for a variable named <strong>Result</strong> which contains a <see cref="LiteralNode">LiteralNode</see> typed to the appropriate datatype.
        /// </para>
        /// </remarks>
        /// <exception cref="RdfQueryException">Thrown if an error occurs in making the query</exception>
        public void Query(IRdfHandler rdfHandler, ISparqlResultsHandler resultsHandler, String sparqlQuery)
        {
            try
            {
                if (resultsHandler != null) resultsHandler.StartResults();

                DataTable results = new DataTable();
                results.Columns.CollectionChanged += new System.ComponentModel.CollectionChangeEventHandler(Columns_CollectionChanged);

                //See if the query can be parsed into a SparqlQuery object
                //It might not since the user might use Virtuoso's extensions to Sparql in their query
                try
                {
                    //We'll set the Parser to SPARQL 1.1 mode even though Virtuoso's SPARQL implementation has
                    //various perculiarties in their SPARQL 1.1 implementation and we'll try and 
                    //handle the potential results in the catch branch if a valid SPARQL 1.0 query
                    //cannot be parsed
                    //Change made in response to a bug report by Aleksandr A. Zaripov [[email protected]]
                    SparqlQueryParser parser = new SparqlQueryParser();
                    parser.SyntaxMode = SparqlQuerySyntax.Sparql_1_1;
                    SparqlQuery query = parser.ParseFromString(sparqlQuery);

                    switch (query.QueryType)
                    {
                        case SparqlQueryType.Select:
                        case SparqlQueryType.SelectAll:
                        case SparqlQueryType.SelectAllDistinct:
                        case SparqlQueryType.SelectAllReduced:
                        case SparqlQueryType.SelectDistinct:
                        case SparqlQueryType.SelectReduced:
                            //Type the Tables columns as System.Object
                            foreach (SparqlVariable var in query.Variables)
                            {
                                if (var.IsResultVariable)
                                {
                                    results.Columns.Add(var.Name, typeof(System.Object));
                                }
                            }
                            break;
                    }

                    try
                    {
                        this.Open(false);

                        //Make the Query against Virtuoso
                        VirtuosoCommand cmd = this._db.CreateCommand();
                        cmd.CommandText = "SPARQL " + sparqlQuery;
                        VirtuosoDataAdapter adapter = new VirtuosoDataAdapter(cmd);
                        adapter.Fill(results);

                        //Decide how to process the results based on the return type
                        switch (query.QueryType)
                        {
                            case SparqlQueryType.Ask:
                                //Expect a DataTable containing a single row and column which contains a boolean

                                //Ensure Results Handler is not null
                                if (resultsHandler == null) throw new ArgumentNullException("Cannot handle a Boolean Result with a null SPARQL Results Handler");

                                if (results.Rows.Count == 1 && results.Columns.Count == 1)
                                {
                                    //Try and parse the result
                                    bool result;
                                    int r;
                                    if (Boolean.TryParse(results.Rows[0][0].ToString(), out result))
                                    {
                                        resultsHandler.HandleBooleanResult(result);
                                    }
                                    else if (Int32.TryParse(results.Rows[0][0].ToString(), out r))
                                    {
                                        if (r == 1)
                                        {
                                            resultsHandler.HandleBooleanResult(true);
                                        }
                                        else
                                        {
                                            resultsHandler.HandleBooleanResult(false);
                                        }
                                    }
                                    else
                                    {
                                        throw new RdfQueryException("Expected a Boolean as the result of an ASK query but the non-boolean value '" + results.Rows[0][0].ToString() + "' was received");
                                    }
                                }
                                else
                                {
                                    //If we get anything else then we'll return that the result was False
                                    resultsHandler.HandleBooleanResult(false);
                                }
                                break;

                            case SparqlQueryType.Construct:
                            case SparqlQueryType.Describe:
                            case SparqlQueryType.DescribeAll:
                                //Expect a DataTable containing a single row and column which contains a String
                                //That string will be a Turtle serialization of the Graph

                                //Ensure that RDF Handler is not null
                                if (rdfHandler == null) throw new ArgumentNullException("Cannot handle a Graph result with a null RDF Handler");

                                if (results.Rows.Count == 1 && results.Columns.Count == 1)
                                {
                                    try
                                    {
                                        //Use StringParser to parse
                                        String data = results.Rows[0][0].ToString();
                                        TurtleParser ttlparser = new TurtleParser();
                                        ttlparser.Load(rdfHandler, new StringReader(data));
                                    }
                                    catch (RdfParseException parseEx)
                                    {
                                        throw new RdfQueryException("Expected a valid Turtle serialization of the Graph resulting from a CONSTRUCT/DESCRIBE query but the result failed to parse", parseEx);
                                    }
                                }
                                else
                                {
                                    throw new RdfQueryException("Expected a single string value representing the serialization of the Graph resulting from a CONSTRUCT/DESCRIBE query but this was not received");
                                }
                                break;

                            case SparqlQueryType.Select:
                            case SparqlQueryType.SelectAll:
                            case SparqlQueryType.SelectAllDistinct:
                            case SparqlQueryType.SelectAllReduced:
                            case SparqlQueryType.SelectDistinct:
                            case SparqlQueryType.SelectReduced:
                                //Ensure Results Handler is not null
                                if (resultsHandler == null) throw new ArgumentNullException("Cannot handle SPARQL Results with a null Results Handler");

                                //Get Result Variables
                                List<SparqlVariable> resultVars = query.Variables.Where(v => v.IsResultVariable).ToList();
                                foreach (SparqlVariable var in resultVars)
                                {
                                    if (!resultsHandler.HandleVariable(var.Name)) ParserHelper.Stop();
                                }
                                Graph temp = new Graph();

                                //Convert each solution into a SPARQLResult
                                foreach (DataRow r in results.Rows)
                                {
                                    Set s = new Set();
                                    foreach (SparqlVariable var in resultVars)
                                    {
                                        if (r[var.Name] != null)
                                        {
                                            s.Add(var.Name, this.LoadNode(temp, r[var.Name]));
                                        }
                                    }
                                    if (!resultsHandler.HandleResult(new SparqlResult(s))) ParserHelper.Stop();
                                }
                                break;

                            default:
                                throw new RdfQueryException("Unable to process the Results of an Unknown query type");
                        }

                        this.Close(false);
                    }
                    catch
                    {
                        this.Close(true, true);
                        throw;
                    }
                }
                catch (RdfParseException)
                {
                    //Unable to parse a SPARQL 1.0 query
                    //Have to attempt to detect the return type based on the DataTable that
                    //the SPASQL (Sparql+SQL) query gives back

                    //Make the Query against Virtuoso
                    VirtuosoCommand cmd = this._db.CreateCommand();
                    cmd.CommandText = "SPARQL " /*define output:format '_JAVA_' "*/ + sparqlQuery;
                    VirtuosoDataAdapter adapter = new VirtuosoDataAdapter(cmd);
                    adapter.Fill(results);

                    //Try to detect the return type based on the DataTable configuration
                    if (results.Rows.Count == 0 && results.Columns.Count > 0)
                    {
                        if (resultsHandler == null) throw new ArgumentNullException("Cannot handler SPARQL Results with a null Results Handler");

                        //No Rows but some columns implies empty SELECT results
                        SparqlResultSet rset = new SparqlResultSet();
                        foreach (DataColumn col in results.Columns)
                        {
                            if (!resultsHandler.HandleVariable(col.ColumnName)) ParserHelper.Stop();
                        }
                    }
                    else if (results.Rows.Count == 1 && results.Columns.Count == 1 && !Regex.IsMatch(sparqlQuery, "SELECT", RegexOptions.IgnoreCase))
                    {
                        //Added a fix here suggested by Alexander Sidorov - not entirely happy with this fix as what happens if SELECT just happens to occur in a URI/Variable Name?

                        //Single Row and Column implies ASK/DESCRIBE/CONSTRUCT results
                        bool result;
                        int r;
                        decimal rdec;
                        double rdbl;
                        float rflt;

                        if (results.Rows[0][0].ToString().Equals(String.Empty))
                        {
                            //Empty Results - no need to do anything
                        }
                        else if (Boolean.TryParse(results.Rows[0][0].ToString(), out result))
                        {
                            //Parseable Boolean so ASK Results
                            if (resultsHandler == null) throw new ArgumentNullException("Cannot handle a Boolean result with a null Results Handler");
                            resultsHandler.HandleBooleanResult(result);
                        }
                        else if (Int32.TryParse(results.Rows[0][0].ToString(), out r))
                        {
                            if (resultsHandler == null) throw new ArgumentNullException("Cannot handle SPARQL results with a null Results Handler");

                            //Parseable Integer so Aggregate SELECT Query Results
                            if (!resultsHandler.HandleVariable("Result")) ParserHelper.Stop();
                            Set s = new Set();
                            s.Add("Result", resultsHandler.CreateLiteralNode(r.ToString(), new Uri(XmlSpecsHelper.XmlSchemaDataTypeInteger)));
                            if (!resultsHandler.HandleResult(new SparqlResult(s))) ParserHelper.Stop();
                        }
                        else if (Single.TryParse(results.Rows[0][0].ToString(), out rflt))
                        {
                            if (resultsHandler == null) throw new ArgumentNullException("Cannot handle SPARQL results with a null Results Handler");

                            //Parseable Single so Aggregate SELECT Query Results
                            if (!resultsHandler.HandleVariable("Result")) ParserHelper.Stop();
                            Set s = new Set();
                            s.Add("Result", resultsHandler.CreateLiteralNode(rflt.ToString(), new Uri(XmlSpecsHelper.XmlSchemaDataTypeFloat)));
                            if (!resultsHandler.HandleResult(new SparqlResult(s))) ParserHelper.Stop();
                        }
                        else if (Double.TryParse(results.Rows[0][0].ToString(), out rdbl))
                        {
                            if (resultsHandler == null) throw new ArgumentNullException("Cannot handle SPARQL results with a null Results Handler");

                            //Parseable Double so Aggregate SELECT Query Results
                            if (!resultsHandler.HandleVariable("Result")) ParserHelper.Stop();
                            Set s = new Set();
                            s.Add("Result", resultsHandler.CreateLiteralNode(rdbl.ToString(), new Uri(XmlSpecsHelper.XmlSchemaDataTypeDouble)));
                            if (!resultsHandler.HandleResult(new SparqlResult(s))) ParserHelper.Stop();
                        }
                        else if (Decimal.TryParse(results.Rows[0][0].ToString(), out rdec))
                        {
                            //Parseable Decimal so Aggregate SELECT Query Results
                            if (!resultsHandler.HandleVariable("Result")) ParserHelper.Stop();
                            Set s = new Set();
                            s.Add("Result", resultsHandler.CreateLiteralNode(rdec.ToString(), new Uri(XmlSpecsHelper.XmlSchemaDataTypeDecimal)));
                            if (!resultsHandler.HandleResult(new SparqlResult(s))) ParserHelper.Stop();
                        }
                        else
                        {
                            //String so try and parse as Turtle
                            try
                            {
                                //Use StringParser to parse
                                String data = results.Rows[0][0].ToString();
                                TurtleParser ttlparser = new TurtleParser();
                                ttlparser.Load(rdfHandler, new StringReader(data));
                            }
                            catch (RdfParseException)
                            {
                                if (resultsHandler == null) throw new ArgumentNullException("Cannot handle SPARQL results with a null Results Handler");

                                //If it failed to parse then it might be the result of one of the aggregate
                                //functions that Virtuoso extends Sparql with
                                if (!resultsHandler.HandleVariable(results.Columns[0].ColumnName)) ParserHelper.Stop();
                                Set s = new Set();
                                s.Add(results.Columns[0].ColumnName, this.LoadNode(resultsHandler, results.Rows[0][0]));
                                //Nothing was returned here previously - fix submitted by Aleksandr A. Zaripov [[email protected]]
                                if (!resultsHandler.HandleResult(new SparqlResult(s))) ParserHelper.Stop();
                            }
                        }
                    }
                    else
                    {
                        //Any other number of rows/columns we have to assume that it's normal SELECT results
                        //Changed in response to bug report by Aleksandr A. Zaripov [[email protected]]

                        if (resultsHandler == null) throw new ArgumentNullException("Cannot handle SPARQL results with a null Results Handler");

                        //Get Result Variables
                        List<String> vars = new List<string>();
                        foreach (DataColumn col in results.Columns)
                        {
                            vars.Add(col.ColumnName);
                            if (!resultsHandler.HandleVariable(col.ColumnName)) ParserHelper.Stop();
                        }

                        //Convert each solution into a SPARQLResult
                        foreach (DataRow r in results.Rows)
                        {
                            Set s = new Set();
                            foreach (String var in vars)
                            {
                                if (r[var] != null)
                                {
                                    s.Add(var, this.LoadNode(resultsHandler, r[var]));
                                }
                            }
                            if (!resultsHandler.HandleResult(new SparqlResult(s))) ParserHelper.Stop();
                        }
                    }
                }

                if (resultsHandler != null) resultsHandler.EndResults(true);
            }
            catch (RdfParsingTerminatedException)
            {
                if (resultsHandler != null) resultsHandler.EndResults(true);
            }
            catch
            {
                if (resultsHandler != null) resultsHandler.EndResults(false);
                throw;
            }
        }