Changeset: 9f8fe940b47a for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=9f8fe940b47a
Modified Files:
        ctest/tools/monetdbe/example_proxy.c
        monetdb5/modules/mal/remote.c
        sql/backends/monet5/sql_result.c
        tools/monetdbe/monetdbe.c
Branch: monetdbe-proxy
Log Message:

create a local MAL function that executes a remote prepared call.


diffs (209 lines):

diff --git a/ctest/tools/monetdbe/example_proxy.c 
b/ctest/tools/monetdbe/example_proxy.c
--- a/ctest/tools/monetdbe/example_proxy.c
+++ b/ctest/tools/monetdbe/example_proxy.c
@@ -34,10 +34,8 @@ main(void)
                error("Failed to open database")
 
        // Assumes the existance of a table test (x INT, y STRING)  on the 
remote.
-       if ((err = monetdbe_query(mdbe, "INSERT INTO test VALUES (100, 
'WHAAT'); ", NULL, NULL)) != NULL)
-               error(err)
-
-       if ((err = monetdbe_query(mdbe, "SELECT x, y, 1 AS z FROM test; ", 
&result, NULL)) != NULL)
+       monetdbe_statement *stmt = NULL;
+       if ((err = monetdbe_prepare(mdbe, "SELECT y, 1 FROM test WHERE x = ?", 
&stmt)) != NULL)
                error(err)
 
        fprintf(stdout, "Query result with %zu cols and %"PRId64" rows\n", 
result->ncols, result->nrows);
diff --git a/monetdb5/modules/mal/remote.c b/monetdb5/modules/mal/remote.c
--- a/monetdb5/modules/mal/remote.c
+++ b/monetdb5/modules/mal/remote.c
@@ -1284,7 +1284,7 @@ str RMTexec(Client cntxt, MalBlkPtr mb, 
 
        /* Temporary hack:
         * use a callback to immediately handle columnar results before hdl is 
destroyed. */
-       if(tmp == MAL_SUCCEED && rcb && mhdl && mapi_get_querytype(mhdl) == 
Q_TABLE) {
+       if(tmp == MAL_SUCCEED && rcb && mhdl && (mapi_get_querytype(mhdl) == 
Q_TABLE || mapi_get_querytype(mhdl) == Q_PREPARE)) {
 
                int fields = mapi_get_field_count(mhdl);
 
@@ -1294,7 +1294,7 @@ str RMTexec(Client cntxt, MalBlkPtr mb, 
                        char* s = mapi_get_name(mhdl, i);
                        if (s == NULL)
                                s = "";
-                       printf("%s%s", " ", s);
+                       printf("%s%s\n", " ", s);
                }
 
                char buf[256] = {0};
diff --git a/sql/backends/monet5/sql_result.c b/sql/backends/monet5/sql_result.c
--- a/sql/backends/monet5/sql_result.c
+++ b/sql/backends/monet5/sql_result.c
@@ -1018,6 +1018,10 @@ mvc_export_prepare_columnar(stream *out,
                }
        }
 
+       // Little hack to get the name of the corresponding compiled MAL 
function known to the result receiver.
+       if (BUNappend(btable, q->f->imp, false) != GDK_SUCCEED)
+               goto bailout;
+
        mvc_export_binary_bat(out, btype);
        mvc_export_binary_bat(out, bdigits);
        mvc_export_binary_bat(out, bscale);
@@ -1124,6 +1128,7 @@ mvc_export_prepare(backend *b, stream *o
        if (b->client->protocol == PROTOCOL_COLUMNAR) {
                if (mnstr_flush(out) < 0) return -1;
                mvc_export_prepare_columnar(out, q, nrows, r);
+
        }
        else {
                if (r && is_project(r->op) && r->exps) {
diff --git a/tools/monetdbe/monetdbe.c b/tools/monetdbe/monetdbe.c
--- a/tools/monetdbe/monetdbe.c
+++ b/tools/monetdbe/monetdbe.c
@@ -662,9 +662,6 @@ monetdbe_open_remote(monetdbe_database_i
        garbageCollector(c, mb, stk, TRUE);
        freeStack(stk);
 
-       printf("yeah a connect string: %s!\n", mdbe->mid);
-
-
        return 0;
 }
 
@@ -918,6 +915,115 @@ monetdbe_result_cb(void* context, char* 
        return MAL_SUCCEED;
 }
 
+struct prepare_callback_context {
+       monetdbe_result** result;
+       monetdbe_database_internal *mdbe;
+};
+
+static str
+monetdbe_prepare_cb(void* context, char* tblname, columnar_result* results, 
size_t nr_results) {
+       (void) tblname;
+       monetdbe_database_internal *mdbe        = ((struct callback_context*) 
context)->mdbe;
+
+       if (nr_results != 6) // 1) btype 2) bdigits 3) bscale 4) bschema 5) 
btable 6) bcolumn
+               return createException(SQL, "monetdbe.monetdbe_prepare_cb", 
SQLSTATE(42000) "result table for prepared statement is wrong.");
+
+       backend *be = NULL;
+       if ((mdbe->msg = getBackendContext(mdbe->c, &be)) != NULL)
+               return mdbe->msg;
+
+       BAT* btype = NULL;
+       BAT* bdigits = NULL;
+       BAT* bscale = NULL;
+       BAT* bschema = NULL;
+       BAT* btable = NULL;
+       BAT* bcolumn = NULL;
+
+       if (!(btype             = BATdescriptor(results[0].id)) ||
+               !(bdigits       = BATdescriptor(results[1].id)) ||
+               !(bscale        = BATdescriptor(results[2].id)) ||
+               !(bschema       = BATdescriptor(results[3].id)) ||
+               !(btable        = BATdescriptor(results[4].id)) ||
+               !(bcolumn       = BATdescriptor(results[5].id)))
+               return createException(SQL, "monetdbe.monetdbe_prepare_cb", 
SQLSTATE(42000) "Cannot access prepare result");
+
+       size_t nparams = BATcount(btype);
+
+       if (nparams     != BATcount(bdigits) ||
+               nparams         != BATcount(bscale) ||
+               nparams         != BATcount(bschema) ||
+               nparams + 1 != BATcount(btable) ||
+               nparams         != BATcount(bcolumn))
+               return createException(SQL, "monetdbe.monetdbe_prepare_cb", 
SQLSTATE(42000) "prepare results are incorrect.");
+
+       BATiter bi = bat_iterator(btable);
+       char* function =  BUNtvar(bi, BATcount(btable)-1);
+
+       char nme[16];
+       const char *name = number2name(nme, sizeof(nme), ++be->remote);
+       Symbol prg = newFunction(putName(userRef), putName(name), 
FUNCTIONsymbol);
+       MalBlkPtr mb = prg->def;
+
+       InstrPtr OuterFunc = getInstrPtr(mb, 0);
+       OuterFunc->retc = OuterFunc->argc = 0;
+
+       InstrPtr e = newInstruction(mb, remoteRef, execRef);
+       e->retc = e->argc = 0;
+       e = pushStr(mb, e, mdbe->mid);
+       e = pushStr(mb, e, userRef);
+       e = pushStr(mb, e, function);
+
+       InstrPtr r = newInstruction(mb, NULL, NULL);
+       r->barrier= RETURNsymbol;
+       r->retc = r->argc = 0;
+
+       for (size_t i = 0; i < nparams; i++) {
+
+               char* table =  BUNtvar(bi, i);
+
+               if (strNil(table)) {
+                       // input argument
+                       int type = *(int*) Tloc(btype, i);
+                       int idx = newVariable(mb, NULL, 0, type);
+                       OuterFunc = pushArgument(mb, OuterFunc, idx);
+
+                       InstrPtr p = newFcnCall(mb, remoteRef, putRef);
+                       setArgType(mb, p, 0, TYPE_str);
+                       p = pushStr(mb, p, mdbe->mid);
+                       p = pushArgument(mb, p, idx);
+
+                       e = pushArgument(mb, e, getArg(p, 0));
+               }
+               else {
+                       // output argument
+                       int type =  newBatType(*(int*) Tloc(btype, i));
+                       int local2 = newTmpVariable(mb, TYPE_str);
+
+                       InstrPtr g = newFcnCall(mb, remoteRef, getRef);
+                       setArgType(mb, g, 0, type);
+                       g = pushStr(mb, g, mdbe->mid);
+                       g = pushArgument(mb, g, local2);
+
+                       e = pushReturn(mb, e, local2);
+
+                       r = pushArgument(mb, r, getArg(g, 0));
+                       r = pushReturn(mb, r, getArg(g, 0));
+                       OuterFunc = pushReturn(mb, OuterFunc, getArg(g, 0));
+
+               }
+       }
+
+       pushInstruction(mb, e);
+
+       pushInstruction(mb, r);
+
+       if ( (mdbe->msg = chkProgram(mdbe->c->usermodule, mb)) != MAL_SUCCEED ) 
{
+               return mdbe->msg;
+       }
+
+       return MAL_SUCCEED;
+}
+
 static char*
 monetdbe_query_remote(monetdbe_database_internal *mdbe, char* query, 
monetdbe_result** result, monetdbe_cnt* affected_rows, int *prepare_id)
 {
@@ -979,8 +1085,18 @@ monetdbe_query_remote(monetdbe_database_
         * prepare the call back routine and its context
         * and pass it over as a pointer to remote.exec.
         */
-       struct callback_context context = {.result = result, .mdbe = mdbe};
-       columnar_result_callback rcb = {.context = &context, .call = 
monetdbe_result_cb};
+       columnar_result_callback rcb;
+       if (!prepare_id) {
+               struct callback_context context = {.result = result, .mdbe = 
mdbe};
+               rcb.context = &context;
+               rcb.call = monetdbe_result_cb;
+       }
+       else {
+               struct callback_context context = {.result = result, .mdbe = 
mdbe};
+               rcb.context = &context;
+               rcb.call = monetdbe_prepare_cb;
+       }
+
        ValRecord v;
        ptr vp = (ptr) &rcb;
        
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to