code: public void validateAndSetQuery() {
      if (aggregator == null || aggregator.isEmpty()) {
        throw new IllegalArgumentException("Missing the aggregation function");
      }
      try {
        agg = Aggregators.get(aggregator);
      } catch (NoSuchElementException nse) {
        throw new IllegalArgumentException(
            "No such aggregation function: " + aggregator);
      }
      
      // we must have at least one TSUID OR a metric
      if ((tsuids == null || tsuids.isEmpty()) && 
          (metric == null || metric.isEmpty())) {
        throw new IllegalArgumentException(
            "Missing the metric or tsuids, provide at least one");
      }
      
      // Make sure we have a filter list
      if (filters == null) {
        filters = new ArrayList<TagVFilter>();
      }
  
      // parse the downsampler if we have one
      if (downsample != null && !downsample.isEmpty()) {
        // downsampler given, so parse it
        downsample_specifier = new DownsamplingSpecification(downsample);
      } else {
        // no downsampler
        downsample_specifier = DownsamplingSpecification.NO_DOWNSAMPLER;
      }
      checkHistogramQuery();
    }
docs: Runs through query parameters to make sure it's a valid request.
  This includes parsing the aggregator, downsampling info, metrics, tags or
  timeseries and setting the local parsed fields needed by the TSD for proper
  execution. If no exceptions are thrown, the query is considered valid.
  <b>Note:</b> You do not need to call this directly as it will be executed
  by the {@link TSQuery} object the sub query is assigned to.
  @throws IllegalArgumentException if something is wrong with the query