static SEXP applyFilter()

in src/DataFrame.cpp [337:415]


static SEXP applyFilter(SEXP df, DataFrameFilterRequest::Filter const& filter) {
  SHIELD(df);
  int nrow = asInt(RI->nrow(df));
  if (filter.has_true_()) {
    return RI->rep(true, nrow);
  }
  if (filter.has_composed()) {
    switch (filter.composed().type()) {
      case DataFrameFilterRequest_Filter_ComposedFilter_Type_AND: {
        PrSEXP result = RI->rep(true, nrow);
        for (auto const& f : filter.composed().filters()) {
          result = RI->vectorAnd(result, applyFilter(df, f));
        }
        return result;
      }
      case DataFrameFilterRequest_Filter_ComposedFilter_Type_OR: {
        PrSEXP result = RI->rep(false, nrow);
        for (auto const& f : filter.composed().filters()) {
          result = RI->vectorOr(result, applyFilter(df, f));
        }
        return result;
      }
      case DataFrameFilterRequest_Filter_ComposedFilter_Type_NOT: {
        PrSEXP result = RI->rep(true, nrow);
        for (auto const& f : filter.composed().filters()) {
          result = RI->vectorAnd(result, applyFilter(df, f));
        }
        return RI->vectorNot(result);
      }
      default:
        return RI->rep(true, nrow);
    }
  }
  if (filter.has_operator_()) {
    ShieldSEXP column = RI->doubleSubscript(df, filter.operator_().column() + 1);
    std::string cls = getClasses(column);
    std::string const& strValue = filter.operator_().value();
    PrSEXP value;
    if (cls == "integer") {
      value = RI->asInteger(strValue);
    } else if (cls == "numeric") {
      value = RI->asDouble(strValue);
    } else if (cls == "logical") {
      value = RI->asLogical(strValue);
    } else {
      value = toSEXP(strValue);
    }
    switch (filter.operator_().type()) {
      case DataFrameFilterRequest_Filter_Operator_Type_EQ:
        return RI->eq(column, value);
      case DataFrameFilterRequest_Filter_Operator_Type_NEQ:
        return RI->neq(column, value);
      case DataFrameFilterRequest_Filter_Operator_Type_LESS:
        return RI->less(column, value);
      case DataFrameFilterRequest_Filter_Operator_Type_GREATER:
        return RI->greater(column, value);
      case DataFrameFilterRequest_Filter_Operator_Type_LEQ:
        return RI->leq(column, value);
      case DataFrameFilterRequest_Filter_Operator_Type_GEQ:
        return RI->geq(column, value);
      case DataFrameFilterRequest_Filter_Operator_Type_REGEX:
        try {
          return RI->grepl(strValue, column);
        } catch (RError const&) {
        }
      default:
        return RI->rep(true, nrow);
    }
  }
  if (filter.has_nafilter()) {
    ShieldSEXP column = RI->doubleSubscript(df, filter.nafilter().column() + 1);
    if (filter.nafilter().isna()) {
      return RI->isNa(column);
    } else {
      return RI->vectorNot(RI->isNa(column));
    }
  }
  return RI->rep(true, nrow);
}