Changeset: 3a940cccfc2a for MonetDB URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=3a940cccfc2a Modified Files: monetdb5/extras/rapi/rapi.c monetdb5/extras/rapi/rapi.h monetdb5/extras/rapi/rapi.mal sql/backends/monet5/Tests/All sql/backends/monet5/Tests/rapi00.sql sql/backends/monet5/Tests/rapi01.sql sql/backends/monet5/Tests/rapi02.sql Branch: RIntegration Log Message:
R API: select rfunc(a,b) from sometable; select * from rfunc(); now working. diffs (truncated from 862 to 300 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 @@ -117,6 +117,7 @@ static int rapiInitialized = FALSE; void writeConsole(const char * buf, int buflen) { (void) buflen; THRprintf(GDKout, "%s", buf); + fprintf(stderr, "%s", buf); } void writeConsoleEx(const char * buf, int buflen, int foo) { (void) buflen; @@ -131,39 +132,35 @@ static int RAPIinitialize(void) { ParseStatus status; char rlibs[BUFSIZ]; char rapiinclude[BUFSIZ]; + MT_lock_init(&rapiLock, "rapi_lock"); // adapted from Rinit.c (JRI package) - MT_lock_init(&rapiLock, "rapi_lock"); - - if (!getenv("R_HOME")) { - return 1; - } + if (!getenv("R_HOME")) { + return 1; + } // TODO: put this into dbfarm snprintf(rlibs, BUFSIZ, "%s%c%s%c%s%c%s", - LOCALSTATEDIR, DIR_SEP, "monetdb5", DIR_SEP, "rapi", - DIR_SEP, "libs"); - - - setenv("R_LIBS_USER",rlibs,TRUE); + LOCALSTATEDIR, DIR_SEP, "monetdb5", DIR_SEP, "rapi", + DIR_SEP, "libs"); + setenv("R_LIBS_USER", rlibs, TRUE); #ifdef RIF_HAS_RSIGHAND - R_SignalHandlers=0; + R_SignalHandlers=0; #endif - { - int stat=Rf_initialize_R(rargc, rargv); - if (stat<0) { - return 2; - } - } + { + int stat = Rf_initialize_R(rargc, rargv); + if (stat < 0) { + return 2; + } + } #ifdef RIF_HAS_RSIGHAND - R_SignalHandlers=0; + R_SignalHandlers=0; #endif - /* disable stack checking, because threads will thow it off */ - R_CStackLimit = (uintptr_t) -1; - - R_Interactive = 0; + /* disable stack checking, because threads will thow it off */ + R_CStackLimit = (uintptr_t) -1; + R_Interactive = FALSE; ptr_R_WriteConsole = writeConsole; ptr_R_WriteConsoleEx = writeConsoleEx; R_Outputfile = NULL; @@ -174,23 +171,21 @@ static int RAPIinitialize(void) { // run the R environment initialization script rapi.R snprintf(rapiinclude, BUFSIZ, "source(\"%s\")", - locate_file("rapi",".R",0)); - R_tryEval( - VECTOR_ELT( - R_ParseVector( - mkString(rapiinclude),1, &status, R_NilValue), 0),R_GlobalEnv,&evalErr); + locate_file("rapi", ".R", 0)); + R_tryEval(VECTOR_ELT(R_ParseVector( + mkString(rapiinclude), 1, &status, R_NilValue), 0), R_GlobalEnv, &evalErr); rapiInitialized++; return 0; } -str RAPIparser(int *ret, str *rcall){ +str RAPIparser(int *ret, str *rcall) { ParseStatus status; str msg = NULL; (void) ret; (void) R_ParseVector(mkString(*rcall), INT_MAX, &status, R_NilValue); - if (status != PARSE_OK) + if (status != PARSE_OK) msg = createException(MAL, "rapi.eval", "%s", *rcall); free(*rcall); return msg; @@ -198,11 +193,11 @@ str RAPIparser(int *ret, str *rcall){ str RAPIeval(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci) { str exprStr = *(str*) getArgReference(stk, pci, pci->retc); - SEXP x, env,retval; + SEXP x, env, retval; SEXP varname = R_NilValue; SEXP varvalue = R_NilValue; ParseStatus status; - int i,j, k=1; + int i, j, k = 1; char buf[64] = "rapi"; char argnames[1000] = ""; char* rcall; @@ -215,14 +210,13 @@ str RAPIeval(Client cntxt, MalBlkPtr mb, BUN cnt; int initstatus = 0; - rcall = malloc(strlen(exprStr) + sizeof(argnames) + 100); - if (rcall==NULL) { + if (rcall == NULL) { throw(MAL, "rapi.eval", MAL_MALLOC_FAIL); } args = (str*) GDKzalloc(sizeof(str) * pci->argc); - if (args == NULL){ + if (args == NULL) { free(rcall); throw(MAL, "rapi.eval", MAL_MALLOC_FAIL); } @@ -232,7 +226,7 @@ str RAPIeval(Client cntxt, MalBlkPtr mb, initstatus = RAPIinitialize(); if (initstatus != 0) { msg = createException(MAL, "rapi.eval", - "failed to initialize R environment (%i)",initstatus); + "failed to initialize R environment (%i)", initstatus); goto wrapup; } } @@ -252,21 +246,22 @@ str RAPIeval(Client cntxt, MalBlkPtr mb, for (i = pci->retc + 1; i < pci->argc; i++) { // check for BAT or scalar first, keep code left if (!isaBatType(getArgType(mb,pci,i))) { - b = BATnew(TYPE_void, getArgType(mb,pci,i),0); - if (b == NULL){ - msg= createException(MAL, "rapi.eval", MAL_MALLOC_FAIL); + b = BATnew(TYPE_void, getArgType(mb, pci, i), 0); + if (b == NULL) { + msg = createException(MAL, "rapi.eval", MAL_MALLOC_FAIL); goto wrapup; } if ( getArgType(mb,pci,i) == TYPE_str) - BUNappend(b, *(str*) getArgReference(stk,pci,i), FALSE); - else BUNappend(b, getArgReference(stk,pci,i), FALSE); - BATsetcount(b,1); - BATseqbase(b,0); + BUNappend(b, *(str*) getArgReference(stk, pci, i), FALSE); + else + BUNappend(b, getArgReference(stk, pci, i), FALSE); + BATsetcount(b, 1); + BATseqbase(b, 0); BATsettrivprop(b); } else { b = BATdescriptor(*(int*) getArgReference(stk, pci, i)); - if (b == NULL){ - msg= createException(MAL, "rapi.eval", MAL_MALLOC_FAIL); + if (b == NULL) { + msg = createException(MAL, "rapi.eval", MAL_MALLOC_FAIL); goto wrapup; } } @@ -276,43 +271,49 @@ str RAPIeval(Client cntxt, MalBlkPtr mb, switch (ATOMstorage(getTailType(getArgType(mb,pci,i)))) { case TYPE_bte: - BAT_TO_INTSXP(b,bte,varvalue); + BAT_TO_INTSXP(b, bte, varvalue) + ; break; case TYPE_sht: - BAT_TO_INTSXP(b,sht,varvalue); + BAT_TO_INTSXP(b, sht, varvalue) + ; break; case TYPE_int: - BAT_TO_INTSXP(b,int,varvalue); + BAT_TO_INTSXP(b, int, varvalue) + ; break; case TYPE_flt: - BAT_TO_REALSXP(b,flt,varvalue); + BAT_TO_REALSXP(b, flt, varvalue) + ; break; case TYPE_dbl: - BAT_TO_REALSXP(b,dbl,varvalue); + BAT_TO_REALSXP(b, dbl, varvalue) + ; break; case TYPE_lng: /* R's integers are stored as int, so we cannot be sure long will fit */ - BAT_TO_REALSXP(b,lng,varvalue); + BAT_TO_REALSXP(b, lng, varvalue) + ; break; case TYPE_str: { // there is only one string type, thus no macro here - BUN p = 0, q = 0, j=0; + BUN p = 0, q = 0, j = 0; BATiter li; li = bat_iterator(b); varvalue = PROTECT(NEW_STRING(BATcount(b))); - BATloop(b, p, q) { - const char *t = (const char *) BUNtail(li, p); - if (t == str_nil) { - SET_STRING_ELT(varvalue, j, NA_STRING); - } else { - SET_STRING_ELT(varvalue, j, mkCharCE(t,CE_UTF8)); - } - j++; + BATloop(b, p, q) + { + const char *t = (const char *) BUNtail(li, p); + if (t == str_nil) { + SET_STRING_ELT(varvalue, j, NA_STRING); + } else { + SET_STRING_ELT(varvalue, j, mkCharCE(t, CE_UTF8)); } + j++; } + } break; default: // no clue what type to consider - msg = createException(MAL, "rapi.eval", - "unknown argument type"); + msg = createException(MAL, "rapi.eval", "unknown argument type"); goto wrapup; } BBPreleaseref(b->batCacheid); @@ -329,17 +330,18 @@ str RAPIeval(Client cntxt, MalBlkPtr mb, * this is also compatible with PL/R */ for (i = pci->retc + 1; i < pci->argc; i++) { - strcat(argnames,args[i]); - if (i < pci->argc-1) { - strcat(argnames,","); + strcat(argnames, args[i]); + if (i < pci->argc - 1) { + strcat(argnames, ","); } } - sprintf(rcall, "ret <- as.data.frame((function(%s){%s})(%s),nm=NA,stringsAsFactors=F)\n", argnames, - exprStr, argnames); + sprintf(rcall, + "ret <- as.data.frame((function(%s){%s})(%s),nm=NA,stringsAsFactors=F)\n", + argnames, exprStr, argnames); - #ifdef _RAPI_DEBUG_ - mnstr_printf(cntxt->fdout, "# Executed R expression %s\n", rcall); - #endif +#ifdef _RAPI_DEBUG_ + mnstr_printf(cntxt->fdout, "# Executed R expression %s\n", rcall); +#endif x = R_ParseVector(mkString(rcall), INT_MAX, &status, R_NilValue); if (status != PARSE_OK) { @@ -350,12 +352,12 @@ str RAPIeval(Client cntxt, MalBlkPtr mb, /* parsing creates a separate call for each statement, since our r code can consist of multiple statements, we need to evaluate each vector entry */ if (LENGTH(x) != 1) { msg = createException(MAL, "rapi.eval", "%s", exprStr); - goto wrapup; + goto wrapup; } - retval = R_tryEval(VECTOR_ELT(x, 0), env,&evalErr); + retval = R_tryEval(VECTOR_ELT(x, 0), env, &evalErr); if (evalErr != FALSE) { msg = createException(MAL, "rapi.eval", "%s", exprStr); - goto wrapup; + goto wrapup; } // ret should be a data frame with exactly as many columns as we need from retc @@ -371,75 +373,86 @@ str RAPIeval(Client cntxt, MalBlkPtr mb, for (i = 0; i < pci->retc; i++) { SEXP ret_col = VECTOR_ELT(retval, i); int bat_type = ATOMstorage(getTailType(getArgType(mb,pci,i))); - int *ret = (int *)getArgReference(stk, pci, i); - cnt = (BUN)ret_rows; + int *ret = (int *) getArgReference(stk, pci, i); + cnt = (BUN) ret_rows; // check if return type is indeed a BAT if (!isaBatType(getArgType(mb,pci,i))) { - msg = createException(MAL, "rapi.eval","I only like BAT return types"); + msg = createException(MAL, "rapi.eval", + "I only like BAT return types"); goto wrapup; } // hand over the vector into a BAT switch (bat_type) { - case TYPE_int: { _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list