@Override
  public Result getNextBoolean() throws ExecException {
    Result r = accumChild(null, DataType.CHARARRAY);
    if (r != null) {
      return r;
    }

    Result left, right;

    left = lhs.getNextString();
    right = rhs.getNextString();

    if (left.returnStatus != POStatus.STATUS_OK || left.result == null) return left;
    if (right.returnStatus != POStatus.STATUS_OK || right.result == null) return right;

    if (impl.match((String) (left.result), (String) (right.result))) {
      left.result = Boolean.TRUE;
    } else {
      left.result = Boolean.FALSE;
    }
    illustratorMarkup(null, left.result, (Boolean) left.result ? 0 : 1);
    return left;
  }
  @Override
  public Result getNextTuple() throws ExecException {
    Result res = new Result();
    int noItems = inputs.size();
    if (inputBags == null) {
      accumulateData();
      if (!loadLastBag()) {
        res.returnStatus = POStatus.STATUS_EOP;
        clearMemory();
        return res;
      }
    }

    if (its != null) {
      // we check if we are done with processing
      // we do that by checking if all the iterators are used up
      boolean finished = true;
      boolean empty = false;
      for (int i = 0; i < its.length; i++) {
        if (inputBags[i].size() == 0) {
          empty = true;
          break;
        }
        finished &= !its[i].hasNext();
      }
      if (empty) {
        // if one bag is empty, there doesn't exist non-null cross product.
        // simply clear all the input tuples of the first bag and finish.
        int index = inputs.size() - 1;
        for (Result resOfLastBag = inputs.get(index).getNextTuple();
            resOfLastBag.returnStatus != POStatus.STATUS_EOP;
            resOfLastBag = inputs.get(index).getNextTuple()) ;
        res.returnStatus = POStatus.STATUS_EOP;
        clearMemory();
        return res;
      } else if (finished && !loadLastBag()) {
        res.returnStatus = POStatus.STATUS_EOP;
        clearMemory();
        return res;
      }
    }

    if (data == null) {
      // getNext being called for the first time or starting on new input
      // data we instantiate the template array and start populating it
      // with data
      data = new Tuple[noItems];
      data[noItems - 1] = tupleOfLastBag;
      for (int i = 0; i < noItems - 1; ++i) {
        data[i] = its[i].next();
      }
      res.result = createTuple(data);
      res.returnStatus = POStatus.STATUS_OK;
      return res;
    } else {
      data[noItems - 1] = tupleOfLastBag;
      int length = noItems - 1;
      for (int index = 0; index < length; ++index) {
        if (its[index].hasNext()) {
          data[index] = its[index].next();
          res.result = createTuple(data);
          res.returnStatus = POStatus.STATUS_OK;
          return res;
        } else {
          // reset this index's iterator so cross product can be
          // achieved we would be resetting this way only for the
          // indexes from the end when the first index which needs to
          // be flattened has reached the last element in its
          // iterator, we won't come here - instead, we reset all
          // iterators at the beginning of this method.
          its[index] = (inputBags[index]).iterator();
          data[index] = its[index].next();
        }
      }
      res.result = createTuple(data);
      res.returnStatus = POStatus.STATUS_OK;
      return res;
    }
  }