Skip to content

Commit

Permalink
Fix slice() error with gctorture() (tidyverse#2794)
Browse files Browse the repository at this point in the history
* fix slice() error with gctorture()

* add test

* return DataFrame instead of SEXP or RObject

to avoid destruction when calling `~GroupedHybridEnv()` via `~GroupedCallProxy()` aka `~CallProxy()`
  • Loading branch information
krlmlr committed May 17, 2017
1 parent 496d777 commit aece1a5
Show file tree
Hide file tree
Showing 6 changed files with 27 additions and 23 deletions.
21 changes: 11 additions & 10 deletions DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -26,23 +26,24 @@ Imports:
tibble (>= 1.3.0.9008),
utils
Suggests:
bit64,
covr,
dbplyr,
dtplyr,
DBI,
RMySQL,
RPostgreSQL,
RSQLite,
testthat,
knitr,
microbenchmark,
ggplot2,
mgcv,
hms,
knitr,
Lahman (>= 3.0-1),
mgcv,
microbenchmark,
nycflights13,
rmarkdown,
dtplyr,
bit64,
hms
RMySQL,
RPostgreSQL,
RSQLite,
testthat,
withr
VignetteBuilder: knitr
LinkingTo: Rcpp (>= 0.12.0),
BH (>= 1.58.0-1),
Expand Down
4 changes: 2 additions & 2 deletions src/mutate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ SEXP validate_unquoted_value(SEXP value, int nrows, SymbolString& name) {
return value;
}

SEXP mutate_not_grouped(DataFrame df, const QuosureList& dots) {
DataFrame mutate_not_grouped(DataFrame df, const QuosureList& dots) {
const int nexpr = dots.size();
const int nrows = df.nrows();

Expand Down Expand Up @@ -130,7 +130,7 @@ SEXP mutate_not_grouped(DataFrame df, const QuosureList& dots) {
}

template <typename Data, typename Subsets>
SEXP mutate_grouped(const DataFrame& df, const QuosureList& dots) {
DataFrame mutate_grouped(const DataFrame& df, const QuosureList& dots) {
LOG_VERBOSE << "checking zero rows";

// special 0 rows case
Expand Down
14 changes: 5 additions & 9 deletions src/slice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class CountIndices {
int n_neg;
};

SEXP slice_grouped(GroupedDataFrame gdf, const QuosureList& dots) {
DataFrame slice_grouped(GroupedDataFrame gdf, const QuosureList& dots) {
typedef GroupedCallProxy<GroupedDataFrame, LazyGroupedSubsets> Proxy;

const DataFrame& data = gdf.data();
Expand Down Expand Up @@ -112,18 +112,17 @@ SEXP slice_grouped(GroupedDataFrame gdf, const QuosureList& dots) {
indx.push_back(indices[j++]);
k++;
}

}
}

DataFrame res = subset(data, indx, names, classes_grouped<GroupedDataFrame>());
set_vars(res, get_vars(data));
strip_index(res);

return GroupedDataFrame(res).data();

}

SEXP slice_not_grouped(const DataFrame& df, const QuosureList& dots) {
DataFrame slice_not_grouped(const DataFrame& df, const QuosureList& dots) {
CharacterVector names = df.names();

const NamedQuosure& quosure = dots[0];
Expand Down Expand Up @@ -154,8 +153,7 @@ SEXP slice_not_grouped(const DataFrame& df, const QuosureList& dots) {
// special case where only NA
if (counter.get_n_negative() == 0) {
std::vector<int> indices;
DataFrame res = subset(df, indices, df.names(), classes_not_grouped());
return res;
return subset(df, indices, df.names(), classes_not_grouped());
}

// just negatives (out of range is dealt with early in CountIndices).
Expand All @@ -181,9 +179,7 @@ SEXP slice_not_grouped(const DataFrame& df, const QuosureList& dots) {
indices[i++] = j++;
}

DataFrame res = subset(df, indices, df.names(), classes_not_grouped());
return res;

return subset(df, indices, df.names(), classes_not_grouped());
}

// [[Rcpp::export]]
Expand Down
4 changes: 2 additions & 2 deletions src/summarise.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ SEXP validate_unquoted_value(SEXP value, int nrows, const SymbolString& name) {
}

template <typename Data, typename Subsets>
SEXP summarise_grouped(const DataFrame& df, const QuosureList& dots) {
DataFrame summarise_grouped(const DataFrame& df, const QuosureList& dots) {
Data gdf(df);

int nexpr = dots.size();
Expand Down Expand Up @@ -113,7 +113,7 @@ SEXP summarise_grouped(const DataFrame& df, const QuosureList& dots) {
}


SEXP summarise_not_grouped(DataFrame df, const QuosureList& dots) {
DataFrame summarise_not_grouped(DataFrame df, const QuosureList& dots) {
int nexpr = dots.size();
if (nexpr == 0) return DataFrame();

Expand Down
1 change: 1 addition & 0 deletions tests/testthat/helper-torture.R
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
with_gctorture2 <- withr::with_(gctorture2)
6 changes: 6 additions & 0 deletions tests/testthat/test-slice.r
Original file line number Diff line number Diff line change
Expand Up @@ -107,3 +107,9 @@ test_that("slice works with zero-column data frames (#2490)", {
1L
)
})

test_that("slice works under gctorture2", {
x <- tibble(y = 1:10)
with_gctorture2(999, x2 <- slice(x, 1:10))
expect_identical(x, x2)
})

0 comments on commit aece1a5

Please sign in to comment.