Skip to content

Commit ee9f287

Browse files
Moving to shared input validation routine
1 parent 0c268e0 commit ee9f287

File tree

5 files changed

+28
-45
lines changed

5 files changed

+28
-45
lines changed

R/data.table.R

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2915,19 +2915,11 @@ setDT = function(x, keep.rownames=FALSE, key=NULL, check.names=FALSE) {
29152915
if (!missing(key)) setkeyv(x, key) # fix for #1169
29162916
if (check.names) setattr(x, "names", make.names(names(x), unique=TRUE))
29172917
if (selfrefok(x) > 0L) return(invisible(x)) else setalloccol(x)
2918-
} else if (is.data.frame(x)) {
2919-
# check no matrix-like columns, #3760. Allow a single list(matrix) is unambiguous and depended on by some revdeps, #3581
2920-
# for performance, only warn on the first such column, #5426
2921-
for (jj in seq_along(x)) {
2922-
if (inherits(x[[jj]], "POSIXlt")) {
2923-
.Call(Cerr_posixl_column_r, jj)
2924-
}
2925-
if (length(dim(x[[jj]])) > 1L) {
2926-
.Call(Cwarn_matrix_column_r, jj)
2927-
break
2928-
}
2929-
}
2918+
}
2919+
2920+
.Call(Ccheck_problematic_columns, x)
29302921

2922+
if (is.data.frame(x)) {
29312923
# Done to avoid affecting other copies of x when we setattr() below (#4784)
29322924
x = .shallow(x)
29332925

src/assign.c

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -198,20 +198,33 @@ static SEXP shallow(SEXP dt, SEXP cols, R_len_t n)
198198
return(newdt);
199199
}
200200

201-
// Wrapped in a function so the same message is issued for the data.frame case at the R level
202-
void warn_matrix_column(/* 1-indexed */ int i) {
203-
warning(_("Some columns are a multi-column type (such as a matrix column), for example column %d. setDT will retain these columns as-is but subsequent operations like grouping and joining may fail. Please consider as.data.table() instead which will create a new column for each embedded column."), i);
204-
}
201+
// check no matrix-like columns, #3760. Allow a single list(matrix) is unambiguous and depended on by some revdeps, #3581
202+
// for performance, only warn on the first such column, #5426
203+
SEXP check_problematic_columns(SEXP x) {
204+
if (!isNewList(x))
205+
return R_NilValue;
206+
207+
SEXP xi;
208+
for (R_len_t i=0; i<LENGTH(x); ++i) {
209+
xi = VECTOR_ELT(x, i);
205210

206-
void err_posixl_column(/* 1-indexed */ int i) {
207-
error(_("Column %d has class 'POSIXlt'. Please convert it to POSIXct (using as.POSIXct) and run setDT() again, or use as.data.table() instead. We do not recommend the use of POSIXlt at all because it uses 40 bytes to store one date."), i);
211+
if (Rf_inherits(xi, "POSIXlt")) {
212+
error(_("Column %d has class 'POSIXlt'. Please convert it to POSIXct (using as.POSIXct) and run setDT() again, or use as.data.table() instead. We do not recommend the use of POSIXlt at all because it uses 40 bytes to store one date."), i+1);
213+
}
214+
215+
if (length(getAttrib(xi, R_DimSymbol)) > 1) {
216+
warning(_("Some columns are a multi-column type (such as a matrix column), for example column %d. setDT will retain these columns as-is but subsequent operations like grouping and joining may fail. Please consider as.data.table() instead which will create a new column for each embedded column."), i+1);
217+
break;
218+
}
219+
}
220+
221+
return R_NilValue;
208222
}
209223

210-
// input validation for setDT() list input; assume is.list(x) was tested in R
224+
// input validation for setDT() list input; assume is.list(x) and check_problematic_columns() was tested in R
211225
SEXP setdt_nrows(SEXP x)
212226
{
213227
int base_length = 0;
214-
bool test_matrix_cols = true;
215228

216229
for (R_len_t i = 0; i < LENGTH(x); ++i) {
217230
SEXP xi = VECTOR_ELT(x, i);
@@ -220,20 +233,12 @@ SEXP setdt_nrows(SEXP x)
220233
* e.g. in package eplusr which calls setDT on a list when parsing JSON. Operations which
221234
* fail for NULL columns will give helpful error at that point, #3480 and #3471 */
222235
if (Rf_isNull(xi)) continue;
223-
if (Rf_inherits(xi, "POSIXlt")) {
224-
err_posixl_column(i+1);
225-
}
226236
SEXP dim_xi = getAttrib(xi, R_DimSymbol);
227237
R_len_t len_xi;
228238
// NB: LENGTH() produces an undefined large number here on R 3.3.0.
229239
// There's also a note in NEWS for R 3.1.0 saying length() should always be used by packages,
230240
// but with some overhead for being a function/not macro...
231-
R_len_t n_dim = length(dim_xi);
232-
if (n_dim) {
233-
if (test_matrix_cols && n_dim > 1) {
234-
warn_matrix_column(i+1);
235-
test_matrix_cols = false;
236-
}
241+
if (length(dim_xi)) {
237242
len_xi = INTEGER(dim_xi)[0];
238243
} else {
239244
len_xi = LENGTH(xi);

src/data.table.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -181,8 +181,6 @@ SEXP dt_na(SEXP x, SEXP cols);
181181
SEXP alloccol(SEXP dt, R_len_t n, Rboolean verbose);
182182
const char *memrecycle(const SEXP target, const SEXP where, const int start, const int len, SEXP source, const int sourceStart, const int sourceLen, const int colnum, const char *colname);
183183
SEXP shallowwrapper(SEXP dt, SEXP cols);
184-
void warn_matrix_column(int i);
185-
void err_posixl_column(int i);
186184

187185
SEXP dogroups(SEXP dt, SEXP dtcols, SEXP groups, SEXP grpcols, SEXP jiscols,
188186
SEXP xjiscols, SEXP grporder, SEXP order, SEXP starts,
@@ -329,8 +327,7 @@ SEXP glast(SEXP);
329327
SEXP gfirst(SEXP);
330328
SEXP gnthvalue(SEXP, SEXP);
331329
SEXP dim(SEXP);
332-
SEXP warn_matrix_column_r(SEXP);
333-
SEXP err_posixl_column_r(SEXP);
330+
SEXP check_problematic_columns(SEXP);
334331
SEXP gvar(SEXP, SEXP);
335332
SEXP gsd(SEXP, SEXP);
336333
SEXP gprod(SEXP, SEXP);

src/init.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,8 +150,7 @@ R_CallMethodDef callMethods[] = {
150150
{"CstartsWithAny", (DL_FUNC)&startsWithAny, -1},
151151
{"CconvertDate", (DL_FUNC)&convertDate, -1},
152152
{"Cnotchin", (DL_FUNC)&notchin, -1},
153-
{"Cwarn_matrix_column_r", (DL_FUNC)&warn_matrix_column_r, -1},
154-
{"Cerr_posixl_column_r", (DL_FUNC)&err_posixl_column_r, -1},
153+
{"Ccheck_problematic_columns", (DL_FUNC)&check_problematic_columns, -1},
155154
{NULL, NULL, 0}
156155
};
157156

src/wrappers.c

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -120,13 +120,3 @@ SEXP dim(SEXP x)
120120
UNPROTECT(1);
121121
return ans;
122122
}
123-
124-
SEXP warn_matrix_column_r(SEXP i) {
125-
warn_matrix_column(INTEGER(i)[0]);
126-
return R_NilValue;
127-
}
128-
129-
SEXP err_posixl_column_r(SEXP i) {
130-
err_posixl_column(INTEGER(i)[0]);
131-
return R_NilValue;
132-
}

0 commit comments

Comments
 (0)