private List<Byte> joinOneGroup(boolean clear) throws HiveException {
    for (int pos = 0; pos < order.length; pos++) {
      emitUnmatchedRows(pos, true);
    }
    int[] smallestPos = findSmallestKey();
    List<Byte> listOfNeedFetchNext = null;
    if (smallestPos != null) {
      listOfNeedFetchNext = joinObject(smallestPos, clear);
      if ((listOfNeedFetchNext.size() > 0) && clear) {
        // listOfNeedFetchNext contains all tables that we have joined data in their
        // candidateStorage, and we need to clear candidate storage and promote their
        // nextGroupStorage to candidateStorage and fetch data until we reach a
        // new group.
        for (Byte b : listOfNeedFetchNext) {
          try {
            fetchNextGroup(b);
          } catch (Exception e) {
            throw new HiveException(e);
          }
        }
      }
    }
    return listOfNeedFetchNext;
  }
Decides if the actual row must be an unmatched row.

Unmatched rows are those which are not part of the inner-join.
The current implementation has issues processing filtered rows in FOJ conditions.
Putting them in a separate group also reduces processing done for them.
ql/src/java/org/apache/hadoop/hive/ql/exec/CommonMergeJoinOperator.java