def query(self, dataset_key, query, query_type="sql", parameters=None):
        """Query an existing dataset

        :param dataset_key: Dataset identifier, in the form of owner/id or of
            a url
        :type dataset_key: str
        :param query: SQL or SPARQL query
        :type query: str
        :param query_type: The type of the query. Must be either 'sql' or
            'sparql'. (Default value = "sql")
        :type query_type: {'sql', 'sparql'}, optional
        :param parameters: parameters to the query - if SPARQL query, this
            should be a dict containing named parameters, if SQL query,then
            this should be a list containing positional parameters.
            Boolean values will be converted to xsd:boolean, Integer values to
            xsd:integer, and other Numeric values to xsd:decimal. Anything
            else is treated as a String literal (Default value = None)
        :type parameters: query parameters, optional
        :returns: Object containing the results of the query
        :rtype: Results
        :raises RuntimeError: If a server error occurs
        """
        # TODO Move network request to RestApiClient
        owner_id, dataset_id = parse_dataset_key(dataset_key)
        params = {
            "query": query
        }
        if parameters and query_type == "sparql":
            # if SPARQL, then the parameters should be a Mapping containing
            # named parameters
            params["parameters"] = ",".join(
                ["{}={}".format(k, convert_to_sparql_literal(parameters[k]))
                 for k in parameters.keys()])
        elif parameters and query_type == "sql":
            # if SQL, then the parameters should be an array with positional
            # parameters, need to unwind them to $data_world_paramN for each
            # 0-indexed position N
            parameters = {"$data_world_param{}".format(i): x
                          for i, x in enumerate(parameters)}
            params["parameters"] = ",".join(["{}={}".format(
                k, convert_to_sparql_literal(parameters[k]))
                for k in parameters.keys()])
        url = "{0}://{1}/{2}/{3}/{4}".format(self._protocol, self._query_host,
                                             query_type, owner_id, dataset_id)
        headers = {
            'User-Agent': _user_agent(),
            'Accept': 'application/sparql-results+json',
            'Authorization': 'Bearer {0}'.format(self._config.auth_token)
        }
        response = requests.get(url, params=params, headers=headers)
        if response.status_code == 200:
            return QueryResults(response.json())
        raise RuntimeError(
            'Error executing query: {}'.format(response.content))