code: func (e *MergeJoinExec) fetchNextOuterRows(ctx context.Context, requiredRows int) (err error) {
  	// It's hard to calculate selectivity if there is any filter or it's inner join,
  	// so we just push the requiredRows down when it's outer join and has no filter.
  	if e.isOuterJoin && len(e.outerTable.filter) == 0 {
  		e.outerTable.chk.SetRequiredRows(requiredRows, e.maxChunkSize)
  	}
  
  	err = e.outerTable.reader.Next(ctx, chunk.NewRecordBatch(e.outerTable.chk))
  	if err != nil {
  		return err
  	}
  
  	e.outerTable.iter.Begin()
  	e.outerTable.selected, err = expression.VectorizedFilter(e.ctx, e.outerTable.filter, e.outerTable.iter, e.outerTable.selected)
  	if err != nil {
  		return err
  	}
  	e.outerTable.row = e.outerTable.iter.Begin()
  	return nil
  }
docs: // fetchNextOuterRows fetches the next Chunk of outer table. Rows in a Chunk
  // may not all belong to the same join key, but are guaranteed to be sorted
  // according to the join key.