code: @SuppressWarnings({ "unchecked" })
      public static SelectResults<Object> executeOnBuckets(String queryString, Object[] queryParameters, Region region,
  	    Set<Object> keys) throws QueryException {
  	if ((queryString == null) || (queryString.length() == 0)) {
  	    throw new QueryException("You must specify query string for execution.");
  	}
  
  	int limit = extractLimit(queryString);
  
  	BucketOrientedQueryFunctionArgument functionArgument = new BucketOrientedQueryFunctionArgument(queryString,
  		queryParameters);
  
  	BucketOrientedQueryFunction function = new BucketOrientedQueryFunction();
  
  	FunctionService.registerFunction(function);
  
  	List<List<Object>> queryResults;
  
  	try {
  	    queryResults = (List<List<Object>>) FunctionService.onRegion(region).withFilter(keys)
  		    .withArgs(functionArgument).execute(function).getResult();
  	} catch (FunctionException e) {
  	    logger.error("Failed to execute bucket oriented query function: " + function, e);
  
  	    throw new QueryException(e.getMessage());
  	}
  	
  	return formatSelectResults(queryResults, limit);
      }
docs: Executes a particular query with parameters on specified region using a set of keys that represents buckets. The
  set of buckets is determined by keys of entries that are stored in such buckets: - real and fake keys can be used
  (such key should have the same routing object as bucket's keys have); - it will be enough to specify one key for
  each bucket. Work of this method is based on execution of function.
  
  @see BucketOrientedQueryFunction
  @param queryString OQL query string.
  @param queryParameters Query parameters.
  @param region Partitioned region on which query will be executed.
  @param keys Set of keys that specify buckets.
  @return Query results as instance of {@link SelectResults}.
  @throws QueryException When in case of query execution failure.