/** * 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; }