Changeset: 9832790b17a3 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=9832790b17a3
Modified Files:
monetdb5/extras/rapi/rapi.c
Branch: Dec2016
Log Message:
Dynamically allocate space for R command in rapi.eval.
This fixes bug 4034.
diffs (116 lines):
diff --git a/monetdb5/extras/rapi/rapi.c b/monetdb5/extras/rapi/rapi.c
--- a/monetdb5/extras/rapi/rapi.c
+++ b/monetdb5/extras/rapi/rapi.c
@@ -238,9 +238,10 @@ str RAPIeval(Client cntxt, MalBlkPtr mb,
ParseStatus status;
int i = 0;
char argbuf[64];
- char argnames[10000] = "";
+ char *argnames = NULL;
+ size_t argnameslen;
size_t pos;
- char* rcall;
+ char* rcall = NULL;
size_t rcalllen;
int ret_cols = 0; /* int because pci->retc is int, too*/
str *args;
@@ -265,15 +266,8 @@ str RAPIeval(Client cntxt, MalBlkPtr mb,
sqlfun = *(sql_func**) getArgReference(stk, pci, pci->retc);
}
- rcalllen = strlen(exprStr) + sizeof(argnames) + 100;
- rcall = malloc(rcalllen);
- if (rcall == NULL) {
- throw(MAL, "rapi.eval", MAL_MALLOC_FAIL);
- }
-
args = (str*) GDKzalloc(sizeof(str) * pci->argc);
if (args == NULL) {
- free(rcall);
throw(MAL, "rapi.eval", MAL_MALLOC_FAIL);
}
@@ -297,6 +291,7 @@ str RAPIeval(Client cntxt, MalBlkPtr mb,
}
}
// the first unknown argument is the group, we don't really care for
the rest.
+ argnameslen = 2;
for (i = pci->retc + 2; i < pci->argc; i++) {
if (args[i] == NULL) {
if (!seengrp && grouped) {
@@ -307,6 +302,7 @@ str RAPIeval(Client cntxt, MalBlkPtr mb,
args[i] = GDKstrdup(argbuf);
}
}
+ argnameslen += strlen(args[i]) + 2; /* extra for ", " */
}
// install the MAL variables into the R environment
@@ -360,20 +356,27 @@ str RAPIeval(Client cntxt, MalBlkPtr mb,
* this is also compatible with PL/R
*/
pos = 0;
- for (i = pci->retc + 2; i < pci->argc && pos < sizeof(argnames); i++) {
- pos += snprintf(argnames + pos, sizeof(argnames) - pos, "%s%s",
+ argnames = malloc(argnameslen);
+ if (argnames == NULL) {
+ msg = createException(MAL, "rapi.eval", MAL_MALLOC_FAIL);
+ goto wrapup;
+ }
+ argnames[0] = '\0';
+ for (i = pci->retc + 2; i < pci->argc; i++) {
+ pos += snprintf(argnames + pos, argnameslen - pos, "%s%s",
args[i], i < pci->argc - 1 ? ",
" : "");
}
- if (pos >= sizeof(argnames)) {
- msg = createException(MAL, "rapi.eval", "Command too large");
+ rcalllen = 2 * pos + strlen(exprStr) + 100;
+ rcall = malloc(rcalllen);
+ if (rcall == NULL) {
+ msg = createException(MAL, "rapi.eval", MAL_MALLOC_FAIL);
goto wrapup;
}
- if (snprintf(rcall, rcalllen,
- "ret <- as.data.frame((function(%s){%s})(%s),
nm=NA, stringsAsFactors=F)\n",
- argnames, exprStr, argnames) >= (int)
rcalllen) {
- msg = createException(MAL, "rapi.eval", "Command too large");
- goto wrapup;
- }
+ snprintf(rcall, rcalllen,
+ "ret <- as.data.frame((function(%s){%s})(%s), nm=NA,
stringsAsFactors=F)\n",
+ argnames, exprStr, argnames);
+ free(argnames);
+ argnames = NULL;
#ifdef _RAPI_DEBUG_
printf("# R call %s\n",rcall);
#endif
@@ -421,7 +424,7 @@ str RAPIeval(Client cntxt, MalBlkPtr mb,
if (bat_type == TYPE_any || bat_type == TYPE_void) {
getArgType(mb,pci,i) = bat_type;
msg = createException(MAL, "rapi.eval",
-
"Unknown return value, possibly projecting with no parameters.");
+ "Unknown
return value, possibly projecting with no parameters.");
goto wrapup;
}
@@ -429,7 +432,7 @@ str RAPIeval(Client cntxt, MalBlkPtr mb,
b = sexp_to_bat(ret_col, bat_type);
if (b == NULL) {
msg = createException(MAL, "rapi.eval",
-
"Failed to convert column %i", i);
+ "Failed to
convert column %i", i);
goto wrapup;
}
// bat return
@@ -449,7 +452,10 @@ str RAPIeval(Client cntxt, MalBlkPtr mb,
UNPROTECT(1);
wrapup:
MT_lock_unset(&rapiLock);
- free(rcall);
+ if (argnames)
+ free(argnames);
+ if (rcall)
+ free(rcall);
for (i = 0; i < pci->argc; i++)
GDKfree(args[i]);
GDKfree(args);
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list