@SuppressWarnings("unchecked")
  private static <T extends Operator<?>> T findFirstPossibleParent(
      Operator<?> start, Class<T> target, boolean trustScript, boolean preserveSortOrder)
          throws SemanticException {
    Operator<?> cursor = CorrelationUtilities.getSingleParent(start);
    for (; cursor != null; cursor = CorrelationUtilities.getSingleParent(cursor)) {
      if (target.isAssignableFrom(cursor.getClass())) {
        return (T) cursor;
      }
      if (cursor instanceof CommonJoinOperator) {
        for (Operator<?> op : ((CommonJoinOperator<?>) cursor).getParentOperators()) {
          if (target.isAssignableFrom(op.getClass())) {
            return (T) op;
          }
        }
        return null;
      }
      if (cursor instanceof ScriptOperator && !trustScript) {
        return null;
      }
      if (!(cursor instanceof SelectOperator
          || cursor instanceof FilterOperator
          || cursor instanceof ForwardOperator
          || cursor instanceof ScriptOperator
          || (cursor instanceof GroupByOperator
              && (!preserveSortOrder
                  || ((GroupByOperator) cursor).getConf().getMode() != Mode.HASH)) // Not order preserving
          || cursor instanceof ReduceSinkOperator)) {
        return null;
      }
    }
    return null;
  }
@param operator the input operator
@param throwException if throw a exception when the input operator has multiple children
@return the single child or null when the input operator has multiple children and
        throwException is false;
@throws SemanticException
ql/src/java/org/apache/hadoop/hive/ql/optimizer/correlation/CorrelationUtilities.java