Changeset: f501170bee19 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=f501170bee19
Modified Files:
        ctest/tools/monetdbe/example_proxy.c
        design.txt
        monetdb5/modules/mal/remote.c
        monetdb5/optimizer/opt_prelude.c
        monetdb5/optimizer/opt_prelude.h
        sql/backends/monet5/sql_execute.c
        tools/monetdbe/monetdbe.c
Branch: monetdbe-proxy
Log Message:

Basic functionality monetdbe/remote proxy is working.


diffs (truncated from 574 to 300 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
@@ -33,12 +33,76 @@ main(void)
        if (monetdbe_open(&mdbe, 
"mapi:monetdb://127.0.0.1:50000?database=devdb", &opt))
                error("Failed to open database")
 
+       if ((err = monetdbe_query(mdbe, "SELECT x, y, 1 AS some_int FROM test; 
", &result, NULL)) != NULL)
+               error(err)
+
+       fprintf(stdout, "Query result with %zu cols and %"PRId64" rows\n", 
result->ncols, result->nrows);
+       for (int64_t r = 0; r < result->nrows; r++) {
+               for (size_t c = 0; c < result->ncols; c++) {
+                       monetdbe_column* rcol;
+                       if ((err = monetdbe_result_fetch(result, &rcol, c)) != 
NULL)
+                               error(err)
+                       switch (rcol->type) {
+                               case monetdbe_int8_t: {
+                                       monetdbe_column_int8_t * col = 
(monetdbe_column_int8_t *) rcol;
+                                       if (col->data[r] == col->null_value) {
+                                               printf("NULL");
+                                       } else {
+                                               printf("%d", col->data[r]);
+                                       }
+                                       break;
+                               }
+                               case monetdbe_int16_t: {
+                                       monetdbe_column_int16_t * col = 
(monetdbe_column_int16_t *) rcol;
+                                       if (col->data[r] == col->null_value) {
+                                               printf("NULL");
+                                       } else {
+                                               printf("%d", col->data[r]);
+                                       }
+                                       break;
+                               }
+                               case monetdbe_int32_t: {
+                                       monetdbe_column_int32_t * col = 
(monetdbe_column_int32_t *) rcol;
+                                       if (col->data[r] == col->null_value) {
+                                               printf("NULL");
+                                       } else {
+                                               printf("%d", col->data[r]);
+                                       }
+                                       break;
+                               }
+                               case monetdbe_str: {
+                                       monetdbe_column_str * col = 
(monetdbe_column_str *) rcol;
+                                       if (col->is_null(col->data[r])) {
+                                               printf("NULL");
+                                       } else {
+                                               printf("%s", (char*) 
col->data[r]);
+                                       }
+                                       break;
+                               }
+                               default: {
+                                       printf("UNKNOWN");
+                               }
+                       }
+
+                       if (c + 1 < result->ncols) {
+                               printf(", ");
+                       }
+               }
+               printf("\n");
+       }
+
+       if ((err = monetdbe_cleanup_result(mdbe, result)) != NULL)
+               error(err)
+
+       if ((err = monetdbe_query(mdbe, "INSERT INTO test VALUES (100, 
'temp');", NULL, NULL)) != NULL)
+               error(err)
+
        // Assumes the existance of a table test (x INT, y STRING)  on the 
remote.
        monetdbe_statement *stmt = NULL;
-       if ((err = monetdbe_prepare(mdbe, "SELECT y, 1 FROM test WHERE x = ?", 
&stmt)) != NULL)
+       if ((err = monetdbe_prepare(mdbe, "SELECT y, x, 1 AS some_fixed_int 
FROM test WHERE x = ?", &stmt)) != NULL)
                error(err)
 
-       int x = 10;
+       int x = 100;
 
        if ((err = monetdbe_bind(stmt, &x, 0)) != NULL)
                error(err)
@@ -104,9 +168,6 @@ main(void)
        if ((err = monetdbe_cleanup_result(mdbe, result)) != NULL)
                error(err)
 
-       if ((err = monetdbe_query(mdbe, "DELETE FROM test where x = 100;", 
NULL, NULL)) != NULL)
-               error(err)
-
        if ((err = monetdbe_query(mdbe, "SELECT x, y, 1 AS some_int FROM test 
WHERE x > 10; ", &result, NULL)) != NULL)
                error(err)
 
@@ -165,6 +226,9 @@ main(void)
                printf("\n");
        }
 
+       if ((err = monetdbe_query(mdbe, "DELETE FROM test where x = 100;", 
NULL, NULL)) != NULL)
+               error(err)
+
        if ((err = monetdbe_cleanup_result(mdbe, result)) != NULL)
                error(err)
 
diff --git a/design.txt b/design.txt
--- a/design.txt
+++ b/design.txt
@@ -98,3 +98,16 @@ Plan
 Expand sqlStatementIntern to incorporate prepared statements.
 
 use remote to call sql.prepare on the remote side. Remote should return 
similar info as regular mapi.
+
+
+function user.%2():any;
+    X_0:any := remote.put("_monetdb_0":str, true:bit);
+    X_3:any := remote.put("_monetdb_0":str, "SELECT x, y, 1 AS some_int FROM 
test WHERE x > 10; ":str);
+    remote.exec("_monetdb_0":str, "sql":str, "eval":str, 0x7fffffffdba0:ptr, 
X_3:any, X_0:any);
+    return :void;
+
+function user.%2():any;
+    X_0:str := remote.put("_monetdb_0":str, true:bit);
+    X_3:str := remote.put("_monetdb_0":str, "SELECT x, y, 1 AS some_int FROM 
test WHERE x > 10; ":str);
+    remote.exec("_monetdb_0":str, "sql":str, "eval":str, 0x7fffffffdba0:ptr, 
X_3:str, X_0:str);
+    return :void;
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
@@ -1194,11 +1194,19 @@ str RMTexec(Client cntxt, MalBlkPtr mb, 
        (void)cntxt;
        (void)mb;
 
-       for (i = 0; i < pci->retc; i++) {
-               tmp = *getArgReference_str(stk, pci, i);
-               if (tmp == NULL || strcmp(tmp, (str)str_nil) == 0)
-                       throw(ILLARG, "remote.exec", ILLEGAL_ARGUMENT
-                                       ": return value %d is NULL or nil", i);
+       columnar_result_callback* rcb = NULL;
+       ValRecord *v = &(stk)->stk[(pci)->argv[4]];
+       if (pci->retc == 1 && (pci->argc >= 4) && (v->vtype == TYPE_ptr) ) {
+               rcb = (columnar_result_callback*) v->val.pval;
+               i = 1; //There is only one (void) return argument.
+       }
+       else {
+               for (i = 0; i < pci->retc; i++) {
+                       tmp = *getArgReference_str(stk, pci, i);
+                       if (tmp == NULL || strcmp(tmp, (str)str_nil) == 0)
+                               throw(ILLARG, "remote.exec", ILLEGAL_ARGUMENT
+                                               ": return value %d is NULL or 
nil", i);
+               }
        }
        conn = *getArgReference_str(stk, pci, i++);
        if (conn == NULL || strcmp(conn, (str)str_nil) == 0)
@@ -1216,11 +1224,6 @@ str RMTexec(Client cntxt, MalBlkPtr mb, 
        /* this call should be a single transaction over the channel*/
        MT_lock_set(&c->lock);
 
-       columnar_result_callback* rcb = NULL;
-       ValRecord *v = &(stk)->stk[(pci)->argv[3]];
-       if (pci->retc == 0 && (pci->argc >= 4) && (v->vtype == TYPE_ptr) ) {
-               rcb = (columnar_result_callback*) v->val.pval;
-       }
 
        if(!rcb && pci->argc - pci->retc < 3) /* conn, mod, func, ... */
                throw(MAL, "remote.exec", ILLEGAL_ARGUMENT  " MAL instruction 
misses arguments");
@@ -1228,14 +1231,14 @@ str RMTexec(Client cntxt, MalBlkPtr mb, 
        len = 0;
        /* count how big a buffer we need */
        len += 2 * (pci->retc > 1);
-       for (i = 0; i < pci->retc; i++) {
-               len += 2 * (i > 0);
-               len += strlen(*getArgReference_str(stk, pci, i));
-       }
+       if (!rcb)
+               for (i = 0; i < pci->retc; i++) {
+                       len += 2 * (i > 0);
+                       len += strlen(*getArgReference_str(stk, pci, i));
+               }
 
        const int arg_index = rcb?4:3;
 
-
        len += strlen(mod) + strlen(func) + 6;
        for (i = arg_index; i < pci->argc - pci->retc; i++) {
                len += 2 * (i > arg_index);
@@ -1250,16 +1253,17 @@ str RMTexec(Client cntxt, MalBlkPtr mb, 
 
        if (pci->retc > 1)
                qbuf[len++] = '(';
-       for (i = 0; i < pci->retc; i++)
-               len += snprintf(&qbuf[len], buflen - len, "%s%s",
-                               (i > 0 ? ", " : ""), *getArgReference_str(stk, 
pci, i));
+       if (!rcb)
+               for (i = 0; i < pci->retc; i++)
+                       len += snprintf(&qbuf[len], buflen - len, "%s%s",
+                                       (i > 0 ? ", " : ""), 
*getArgReference_str(stk, pci, i));
 
        if (pci->retc > 1)
                qbuf[len++] = ')';
 
        /* build the function invocation string in qbuf */
 
-       if (pci->retc > 0) {
+       if (!rcb && pci->retc > 0) {
                len += snprintf(&qbuf[len], buflen - len, " := %s.%s(", mod, 
func);
        }
        else {
@@ -1288,14 +1292,7 @@ str RMTexec(Client cntxt, MalBlkPtr mb, 
 
                int fields = mapi_get_field_count(mhdl);
 
-               columnar_result* results = GDKzalloc(sizeof(columnar_result) * 
fields);         
-
-               for (int i = 0; i < fields; i++) {
-                       char* s = mapi_get_name(mhdl, i);
-                       if (s == NULL)
-                               s = "";
-                       printf("%s%s\n", " ", s);
-               }
+               columnar_result* results = GDKzalloc(sizeof(columnar_result) * 
fields);
 
                char buf[256] = {0};
 
@@ -1330,6 +1327,7 @@ str RMTexec(Client cntxt, MalBlkPtr mb, 
                }
                else {
                        tmp = rcb->call(rcb->context, tblname, results, fields);
+                       GDKfree(rcb);
                }
                GDKfree(results);
        }
@@ -1585,7 +1583,8 @@ mel_func remote_init_funcs[] = {
  pattern("remote", "exec", RMTexec, false, "remotely executes <mod>.<func> and 
returns the handle to its result", args(1,4, 
vararg("",str),arg("conn",str),arg("mod",str),arg("func",str))),
  pattern("remote", "exec", RMTexec, false, "remotely executes <mod>.<func> 
using the argument list of remote objects and returns the handle to its 
result", args(1,5, 
arg("",str),arg("conn",str),arg("mod",str),arg("func",str),vararg("",str))),
  pattern("remote", "exec", RMTexec, false, "remotely executes <mod>.<func> 
using the argument list of remote objects and returns the handle to its 
result", args(1,5, 
vararg("",str),arg("conn",str),arg("mod",str),arg("func",str),vararg("",str))),
- pattern("remote", "exec", RMTexec, false, "remotely executes <mod>.<func> 
using the argument list of remote objects using and applying function pointer 
rcb as result handling callback.", args(1,5, 
vararg("",str),arg("conn",str),arg("mod",str),arg("func",str),arg("rcb",ptr))),
+ pattern("remote", "exec", RMTexec, false, "remotely executes <mod>.<func> 
using the argument list of remote objects using and applying function pointer 
rcb as result handling callback.", args(1,6, 
vararg("",str),arg("conn",str),arg("mod",str),arg("func",str),arg("rcb",ptr), 
vararg("",str))),
+ pattern("remote", "exec2", RMTexec, false, "remotely executes <mod>.<func> 
using the argument list of remote objects using and applying function pointer 
rcb as result handling callback.", args(0,5, 
arg("conn",str),arg("mod",str),arg("func",str),arg("rcb",ptr), vararg("",str))),
  command("remote", "isalive", RMTisalive, false, "check if conn is still valid 
and connected", args(1,2, arg("",int),arg("conn",str))),
  pattern("remote", "batload", RMTbatload, false, "create a BAT of the given 
type and size, and load values from the input stream", args(1,3, 
batargany("",1),argany("tt",1),arg("size",int))),
  pattern("remote", "batbincopy", RMTbincopyto, false, "dump BAT b in binary 
form to the stream", args(1,2, arg("",void),batargany("b",0))),
diff --git a/monetdb5/optimizer/opt_prelude.c b/monetdb5/optimizer/opt_prelude.c
--- a/monetdb5/optimizer/opt_prelude.c
+++ b/monetdb5/optimizer/opt_prelude.c
@@ -125,6 +125,7 @@ str emptybindRef;
 str eqRef;
 str evalRef;
 str execRef;
+str exec2Ref;
 str expandRef;
 str exportOperationRef;
 str export_tableRef;
@@ -432,6 +433,7 @@ void optimizerInit(void)
        eqRef = putName("==");
        evalRef = putName("eval");
        execRef = putName("exec");
+       exec2Ref = putName("exec2");
        expandRef = putName("expand");
        exportOperationRef = putName("exportOperation");
        export_tableRef = putName("export_table");
diff --git a/monetdb5/optimizer/opt_prelude.h b/monetdb5/optimizer/opt_prelude.h
--- a/monetdb5/optimizer/opt_prelude.h
+++ b/monetdb5/optimizer/opt_prelude.h
@@ -122,6 +122,7 @@ mal_export  str emptybindRef;
 mal_export  str eqRef;
 mal_export  str evalRef;
 mal_export  str execRef;
+mal_export  str exec2Ref;
 mal_export  str expandRef;
 mal_export  str exportOperationRef;
 mal_export  str export_tableRef;
diff --git a/sql/backends/monet5/sql_execute.c 
b/sql/backends/monet5/sql_execute.c
--- a/sql/backends/monet5/sql_execute.c
+++ b/sql/backends/monet5/sql_execute.c
@@ -324,6 +324,7 @@ SQLstatementIntern(Client c, str *expr, 
        stream *buf = NULL;
        str msg = MAL_SUCCEED;
        backend *be = NULL, *sql = (backend *) c->sqlcontext;
+       Symbol backup = NULL;
        size_t len = strlen(*expr);
 
 #ifdef _SQL_COMPILE
@@ -424,6 +425,11 @@ SQLstatementIntern(Client c, str *expr, 
         * Scan the complete string for SQL statements, stop at the first error.
         */
        c->sqlcontext = sql;
+       if (c->curprg) {
+               backup = c->curprg;
+               c->curprg = NULL;
+       }
+
        while (msg == MAL_SUCCEED && m->scanner.rs->pos < m->scanner.rs->len) {
                sql_rel *r;
 
@@ -629,6 +635,9 @@ endofcompile:
        if (execute)
                MSresetInstructions(c->curprg->def, 1);
 
+       if (backup)
+               c->curprg = backup;
+
        c->sqlcontext = be;
        backend_destroy(sql);
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to