TupleIdSequence* DisjunctionPredicate::getAllMatches(
    ValueAccessor *accessor,
    // const SubBlocksReference *sub_blocks_ref,
    const TupleIdSequence *filter,
    const TupleIdSequence *existence_map) const {
  if (has_static_result_) {
    return GenerateSequenceForStaticResult(accessor, filter, existence_map, static_result_);
  } else {
    tuple_id end_pos = accessor->getEndPositionVirtual();
    TupleIdSequence *union_result = new TupleIdSequence(end_pos);

#ifdef QUICKSTEP_ENABLE_VECTOR_PREDICATE_SHORT_CIRCUIT
    std::unique_ptr<TupleIdSequence> current_filter(new TupleIdSequence(end_pos));
    if (filter != nullptr) {
      current_filter->assignFrom(*filter);
    } else if (existence_map != nullptr) {
      current_filter->assignFrom(*existence_map);
    } else {
      current_filter->setRange(0, end_pos, true);
    }
#endif  // QUICKSTEP_ENABLE_VECTOR_PREDICATE_SHORT_CIRCUIT

    for (PtrList<Predicate>::const_iterator it = dynamic_operand_list_.begin();
         it != dynamic_operand_list_.end();
         ++it) {
#ifdef QUICKSTEP_ENABLE_VECTOR_PREDICATE_SHORT_CIRCUIT
      std::unique_ptr<TupleIdSequence> operand_result(it->getAllMatches(accessor,
                                                                        // sub_blocks_ref,
                                                                        current_filter.get(),
                                                                        existence_map));
#else
      std::unique_ptr<TupleIdSequence> operand_result(it->getAllMatches(accessor,
                                                                        // sub_blocks_ref,
                                                                        filter,
                                                                        existence_map));
#endif  // QUICKSTEP_ENABLE_VECTOR_PREDICATE_SHORT_CIRCUIT
      union_result->unionWith(*operand_result);

#ifdef QUICKSTEP_ENABLE_VECTOR_PREDICATE_SHORT_CIRCUIT
      // Don't bother checking tuples which are already known to match some
      // part of the union.
      operand_result->invert();
      current_filter->intersectWith(*operand_result);
#endif  // QUICKSTEP_ENABLE_VECTOR_PREDICATE_SHORT_CIRCUIT
    }

    return union_result;
  }
}
ColumnVectorPtr ScalarUnaryExpression::getAllValuesForJoin(
    const relation_id left_relation_id,
    ValueAccessor *left_accessor,
    const relation_id right_relation_id,
    ValueAccessor *right_accessor,
    const std::vector<std::pair<tuple_id, tuple_id>> &joined_tuple_ids,
    ColumnVectorCache *cv_cache) const {
  if (fast_operator_.get() == nullptr) {
    return ColumnVectorPtr(
        ColumnVector::MakeVectorOfValue(getType(),
                                        static_value_,
                                        joined_tuple_ids.size()));
  } else {
#ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN
    const attribute_id operand_attr_id = operand_->getAttributeIdForValueAccessor();
    if (operand_attr_id != -1) {
      const relation_id operand_relation_id = operand_->getRelationIdForValueAccessor();
      DCHECK_NE(operand_relation_id, -1);
      DCHECK((operand_relation_id == left_relation_id)
             || (operand_relation_id == right_relation_id));
      const bool using_left_relation = (operand_relation_id == left_relation_id);
      ValueAccessor *operand_accessor = using_left_relation ? left_accessor
                                                            : right_accessor;
      return ColumnVectorPtr(
          fast_operator_->applyToValueAccessorForJoin(operand_accessor,
                                                      using_left_relation,
                                                      operand_attr_id,
                                                      joined_tuple_ids));
    }
#endif  // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN

    ColumnVectorPtr operand_result(
        operand_->getAllValuesForJoin(left_relation_id,
                                      left_accessor,
                                      right_relation_id,
                                      right_accessor,
                                      joined_tuple_ids,
                                      cv_cache));
    return ColumnVectorPtr(
        fast_operator_->applyToColumnVector(*operand_result));
  }
}
ColumnVectorPtr ScalarUnaryExpression::getAllValues(
    ValueAccessor *accessor,
    const SubBlocksReference *sub_blocks_ref,
    ColumnVectorCache *cv_cache) const {
  if (fast_operator_.get() == nullptr) {
    return ColumnVectorPtr(
        ColumnVector::MakeVectorOfValue(getType(),
                                        static_value_,
                                        accessor->getNumTuplesVirtual()));
  } else {
#ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_SELECTION
    const attribute_id operand_attr_id = operand_->getAttributeIdForValueAccessor();
    if (operand_attr_id != -1) {
      return ColumnVectorPtr(
          fast_operator_->applyToValueAccessor(accessor, operand_attr_id));
    }
#endif  // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_SELECTION

    ColumnVectorPtr operand_result(
        operand_->getAllValues(accessor, sub_blocks_ref, cv_cache));
    return ColumnVectorPtr(
        fast_operator_->applyToColumnVector(*operand_result));
  }
}