public TableAccessInfo analyzeTableAccess() throws SemanticException {

    // Set up the rules for the graph walker for group by and join operators
    Map<SemanticRule, SemanticNodeProcessor> opRules = new LinkedHashMap<SemanticRule, SemanticNodeProcessor>();
    opRules.put(new RuleRegExp("R1", GroupByOperator.getOperatorName() + "%"),
        new GroupByProcessor(pGraphContext));
    opRules.put(new RuleRegExp("R2", JoinOperator.getOperatorName() + "%"),
        new JoinProcessor(pGraphContext));
    opRules.put(new RuleRegExp("R3", MapJoinOperator.getOperatorName() + "%"),
        new JoinProcessor(pGraphContext));

    TableAccessCtx tableAccessCtx = new TableAccessCtx();
    SemanticDispatcher disp = new DefaultRuleDispatcher(getDefaultProc(), opRules, tableAccessCtx);
    SemanticGraphWalker ogw = new DefaultGraphWalker(disp);

    // Create a list of topOp nodes and walk!
    List<Node> topNodes = new ArrayList<Node>();
    topNodes.addAll(pGraphContext.getTopOps().values());
    ogw.startWalking(topNodes, null);

    return tableAccessCtx.getTableAccessInfo();
  }
TableAccessAnalyzer walks the operator graph from joins and group bys
to the table scan operator backing it. It checks whether the operators
in the path are pass-through of the base table (no aggregations/joins),
and if the keys are mapped by expressions that do not modify the bucket
for the key. If all the keys for a join/group by are clean pass-through
of the base table columns, we can consider this operator as a candidate
for improvement through bucketing.
ql/src/java/org/apache/hadoop/hive/ql/parse/TableAccessAnalyzer.java