Пример #1
0
  /**
   * This methods checks if rewrite can be applied using the index and also verifies all conditions
   * of the operator tree.
   *
   * @param topOp - TableScanOperator for a single the operator tree branch
   * @param indexes - Map of a table and list of indexes on it
   * @return - true if rewrite can be applied on the current branch; false otherwise
   * @throws SemanticException
   */
  private boolean checkIfRewriteCanBeApplied(
      TableScanOperator topOp, Table baseTable, Map<Table, List<Index>> indexes)
      throws SemanticException {
    boolean canApply = false;
    // Context for checking if this optimization can be applied to the input query
    RewriteCanApplyCtx canApplyCtx = RewriteCanApplyCtx.getInstance(parseContext);
    Map<String, Operator<? extends Serializable>> topOps = parseContext.getTopOps();

    canApplyCtx.setBaseTableName(baseTableName);
    canApplyCtx.populateRewriteVars(topOp);

    Map<Index, Set<String>> indexTableMap = getIndexToKeysMap(indexes.get(baseTable));
    Iterator<Index> indexMapItr = indexTableMap.keySet().iterator();
    Index index = null;
    while (indexMapItr.hasNext()) {
      // we rewrite the original query using the first valid index encountered
      // this can be changed if we have a better mechanism to
      // decide which index will produce a better rewrite
      index = indexMapItr.next();
      canApply = canApplyCtx.isIndexUsableForQueryBranchRewrite(index, indexTableMap.get(index));
      if (canApply) {
        canApply = checkIfAllRewriteCriteriaIsMet(canApplyCtx);
        // break here if any valid index is found to apply rewrite
        if (canApply) {
          // check if aggregation function is set.
          // If not, set it using the only indexed column
          if (canApplyCtx.getAggFunction() == null) {
            // strip of the start and end braces [...]
            String aggregationFunction = indexTableMap.get(index).toString();
            aggregationFunction =
                aggregationFunction.substring(1, aggregationFunction.length() - 1);
            canApplyCtx.setAggFunction("_count_of_" + aggregationFunction + "");
          }
        }
        break;
      }
    }
    indexTableName = index.getIndexTableName();

    if (canApply && topOps.containsValue(topOp)) {
      Iterator<String> topOpNamesItr = topOps.keySet().iterator();
      while (topOpNamesItr.hasNext()) {
        String topOpName = topOpNamesItr.next();
        if (topOps.get(topOpName).equals(topOp)) {
          tsOpToProcess.put(topOpName, canApplyCtx);
        }
      }
    }

    if (tsOpToProcess.size() == 0) {
      canApply = false;
    } else {
      canApply = true;
    }
    return canApply;
  }