Changeset: 9951c4e33293 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=9951c4e33293 Modified Files: clients/Tests/MAL-signatures.stable.out clients/Tests/MAL-signatures.stable.out.int128 gdk/gdk_bbp.c gdk/gdk_sample.c gdk/gdk_system.h monetdb5/mal/mal_dataflow.c monetdb5/modules/mal/querylog.c monetdb5/modules/mal/remote.c monetdb5/modules/mal/tablet.c monetdb5/optimizer/opt_pipes.c sql/backends/monet5/UDF/capi/capi.c sql/backends/monet5/UDF/pyapi3/pyapi3.c sql/backends/monet5/sql.c sql/backends/monet5/sql_scenario.c sql/backends/monet5/wlr.c sql/server/sql_mvc.h sql/storage/bat/bat_storage.c sql/storage/sql_storage.h sql/storage/store.c tools/monetdbe/monetdbe.c Branch: unlock Log Message:
Merge with default branch. diffs (truncated from 1939 to 300 lines): diff --git a/clients/Tests/MAL-signatures.stable.out b/clients/Tests/MAL-signatures.stable.out --- a/clients/Tests/MAL-signatures.stable.out +++ b/clients/Tests/MAL-signatures.stable.out @@ -9701,6 +9701,7 @@ stdout of test 'MAL-signatures` in direc [ "inspect", "getDefinition", "pattern inspect.getDefinition(X_1:str, X_2:str):bat[:str] ", "INSPECTgetDefinition;", "" ] [ "inspect", "getEnvironment", "command inspect.getEnvironment() (X_0:bat[:str], X_1:bat[:str]) ", "INSPECTgetEnvironment;", "" ] [ "inspect", "getEnvironment", "command inspect.getEnvironment(X_1:str):str ", "INSPECTgetEnvironmentKey;", "" ] +[ "inspect", "getExistence", "pattern inspect.getExistence(X_1:str, X_2:str):bit ", "INSPECTgetExistence;", "" ] [ "inspect", "getFunction", "pattern inspect.getFunction():bat[:str] ", "INSPECTgetAllFunctions;", "" ] [ "inspect", "getKind", "pattern inspect.getKind():bat[:str] ", "INSPECTgetkind;", "" ] [ "inspect", "getModule", "pattern inspect.getModule():bat[:str] ", "INSPECTgetAllModules;", "" ] @@ -10185,11 +10186,12 @@ stdout of test 'MAL-signatures` in direc [ "remote", "exec", "pattern remote.exec(X_1:str, X_2:str, X_3:str, X_4:ptr, X_5:str...):void ", "RMTexec;", "" ] [ "remote", "exec", "pattern remote.exec(X_1:str, X_2:str, X_3:str, X_4:str...):str ", "RMTexec;", "" ] [ "remote", "exec", "pattern remote.exec(X_1:str, X_2:str, X_3:str, X_4:str...):str... ", "RMTexec;", "" ] +[ "remote", "exec", "pattern remote.exec(X_1:str, X_2:str, X_3:str, X_4:str...):void ", "RMTexec;", "" ] [ "remote", "get", "pattern remote.get(X_1:str, X_2:str):any ", "RMTget;", "" ] [ "remote", "isalive", "command remote.isalive(X_1:str):int ", "RMTisalive;", "" ] [ "remote", "prelude", "command remote.prelude():void ", "RMTprelude;", "" ] [ "remote", "put", "pattern remote.put(X_1:str, X_2:any):str ", "RMTput;", "" ] -[ "remote", "register", "pattern remote.register(X_1:str, X_2:str, X_3:str):void ", "RMTregister;", "" ] +[ "remote", "register", "pattern remote.register(X_1:str, X_2:str, X_3:str):str ", "RMTregister;", "" ] [ "remote", "register_supervisor", "command remote.register_supervisor(X_1:str, X_2:str):int ", "RMTregisterSupervisor;", "" ] [ "remote", "resolve", "command remote.resolve(X_1:str):bat[:str] ", "RMTresolve;", "" ] [ "sample", "subuniform", "pattern sample.subuniform(X_1:bat[:any], X_2:dbl):bat[:oid] ", "SAMPLEuniform;", "" ] diff --git a/clients/Tests/MAL-signatures.stable.out.int128 b/clients/Tests/MAL-signatures.stable.out.int128 --- a/clients/Tests/MAL-signatures.stable.out.int128 +++ b/clients/Tests/MAL-signatures.stable.out.int128 @@ -12115,6 +12115,7 @@ stdout of test 'MAL-signatures` in direc [ "inspect", "getDefinition", "pattern inspect.getDefinition(X_1:str, X_2:str):bat[:str] ", "INSPECTgetDefinition;", "" ] [ "inspect", "getEnvironment", "command inspect.getEnvironment() (X_0:bat[:str], X_1:bat[:str]) ", "INSPECTgetEnvironment;", "" ] [ "inspect", "getEnvironment", "command inspect.getEnvironment(X_1:str):str ", "INSPECTgetEnvironmentKey;", "" ] +[ "inspect", "getExistence", "pattern inspect.getExistence(X_1:str, X_2:str):bit ", "INSPECTgetExistence;", "" ] [ "inspect", "getFunction", "pattern inspect.getFunction():bat[:str] ", "INSPECTgetAllFunctions;", "" ] [ "inspect", "getKind", "pattern inspect.getKind():bat[:str] ", "INSPECTgetkind;", "" ] [ "inspect", "getModule", "pattern inspect.getModule():bat[:str] ", "INSPECTgetAllModules;", "" ] @@ -12605,11 +12606,12 @@ stdout of test 'MAL-signatures` in direc [ "remote", "exec", "pattern remote.exec(X_1:str, X_2:str, X_3:str, X_4:ptr, X_5:str...):void ", "RMTexec;", "" ] [ "remote", "exec", "pattern remote.exec(X_1:str, X_2:str, X_3:str, X_4:str...):str ", "RMTexec;", "" ] [ "remote", "exec", "pattern remote.exec(X_1:str, X_2:str, X_3:str, X_4:str...):str... ", "RMTexec;", "" ] +[ "remote", "exec", "pattern remote.exec(X_1:str, X_2:str, X_3:str, X_4:str...):void ", "RMTexec;", "" ] [ "remote", "get", "pattern remote.get(X_1:str, X_2:str):any ", "RMTget;", "" ] [ "remote", "isalive", "command remote.isalive(X_1:str):int ", "RMTisalive;", "" ] [ "remote", "prelude", "command remote.prelude():void ", "RMTprelude;", "" ] [ "remote", "put", "pattern remote.put(X_1:str, X_2:any):str ", "RMTput;", "" ] -[ "remote", "register", "pattern remote.register(X_1:str, X_2:str, X_3:str):void ", "RMTregister;", "" ] +[ "remote", "register", "pattern remote.register(X_1:str, X_2:str, X_3:str):str ", "RMTregister;", "" ] [ "remote", "register_supervisor", "command remote.register_supervisor(X_1:str, X_2:str):int ", "RMTregisterSupervisor;", "" ] [ "remote", "resolve", "command remote.resolve(X_1:str):bat[:str] ", "RMTresolve;", "" ] [ "sample", "subuniform", "pattern sample.subuniform(X_1:bat[:any], X_2:dbl):bat[:oid] ", "SAMPLEuniform;", "" ] 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,7 +33,78 @@ 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) + + if ((err = monetdbe_query(mdbe, "DELETE FROM test WHERE x < 0; ", &result, NULL)) != NULL) + error(err) + + if ((err = monetdbe_query(mdbe, "SELECT * FROM test; ", &result, NULL)) != NULL) + error(err) + + monetdbe_column* appendable_columns[2]; + + 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) + appendable_columns[c] = rcol; + 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_append(mdbe, "sys", "test", appendable_columns, 2)) != NULL) + error(err) + + if ((err = monetdbe_cleanup_result(mdbe, result)) != NULL) + error(err) + + if ((err = monetdbe_query(mdbe, "SELECT * FROM test; ", &result, NULL)) != NULL) error(err) fprintf(stdout, "Query result with %zu cols and %"PRId64" rows\n", result->ncols, result->nrows); @@ -110,6 +181,7 @@ main(void) if ((err = monetdbe_execute(stmt, &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++) { diff --git a/design.txt b/design.txt new file mode 100644 --- /dev/null +++ b/design.txt @@ -0,0 +1,113 @@ +Creating a table returning SQL function + + rel_semantic + | + |-> create_funct + |-> rel_psm + |->rel_ceate_func + |->mvc_create_func (just to have an initialized unregistered sql_func object.) + |->rel_create_function (this function add the necessary flags (ddl_create_function) so that CREATE statement is compiled into a DDL msql program and a pointer to the previous object) + + Engine + |->SQLcreate_function + | + |->create_func + |->mvc_create_func now adding it to the session transaction. + |->calls sql_parse with the m_deps flag on the original SQL CREATE FUNCTION query to find the table/column/argument dependencies and add them to the system catalogue. The query is somehow stored together with the function. + + + + +calling a SQL function (SELECT * from bbp();) + + First the outer statements are transormed into nested relational plans + + the BBP() is recognized as a function cal rel2bin_table; + + the will end up in a call to stmt *stmt_Nop(backend *be, stmt *ops, sql_subfunc *f) + which will end up in backend_create_subfunc => backend_create_func => backend_create_sql_func finally ending up in rel_parse with the m_instantiate flag + + We end up with relational subplan which is equivalent to a call to the table returning function + + So backend_create_sql_func will not only parse and optimize the query and its outcoming relational plan, but it will also compile it into a MAL program/function through backend_dumpstmt. + + + So the outer query is compiled into a MAL program that looks like this + + | function user.main():void; | + | X_1:void := querylog.define("explain select * from bbp();":str, "default_pi | + : pe":str, 10:int); : + | barrier X_69:bit := language.dataflow(); | + | X_8:bat[:str] := bat.pack(".%1":str, ".%1":str); | + | X_9:bat[:str] := bat.pack("id":str, "name":str); | + | X_10:bat[:str] := bat.pack("int":str, "clob":str); | + | X_11:bat[:int] := bat.pack(32:int, 0:int); | + | X_12:bat[:int] := bat.pack(0:int, 0:int); | + | (X_5:bat[:int], X_6:bat[:str]) := user.bbp(); | + | exit X_69:bit; | + | sql.resultSet(X_8:bat[:str], X_9:bat[:str], X_10:bat[:str], X_11:bat[:int], | + : X_12:bat[:int], X_5:bat[:int], X_6:bat[:str]); : + | end user.main; + + + Downside is that the user.bbp() function is compiled and optimized separately from the rest of the query + +monetdbe_append(foo, EB1, ..., EBN) + +do sql_table* t = create_sql_table(..., .., tt_table, 0, SQL_DECLARED_TABLE, CA_COMMIT) +then loop over monetdbe_column monetdbe_columns* {EB1, EBN} + convert EBi -> Bi + RBi = RMTput Bi + Add RBi to a list of remote BAT identifier ri_list. + sql_subtype tpe = getsqltype(Bi|EBi) + mvc_create_column(sql, t, columns[i].name, &tpe) + +voila a initialized sql_table* t object plust ri_list of remote BAT identifier. + +now pass t to sql_gencode.h:backend_create_remote_import(backend*be, sql_table*t) + +Which should have all information necessary to create the following function: + +local maken +function user.%temp(X1, ..., XN) + m:=sql.mvc(); + sql.append(m, "foo", "column1", X1); + . + . + . + sql.append(m, "foo", "columnn", Xn); + c := aggr.count(Xn); + sql.affectedRows(m, c); +end + +function user.%temp2() + remote.put() + +Register this function and remotely execute it: +remote.register(conn, user, %temp) +remote.exec(conn, user, %temp, RB1, ..., RBN) + +Now in case of a SQL REMOTE INSERT INTO statement: + +INSERT INTO R(foo) SELECT * FROM BAR; // ALLEEN AUTOMCOMMIT + +REL_INSERT(R(foo), REL(SELECT * FROM BAR)) + + +SELECT * FROM BAR +VALUES () ()) + + B1, ..., BN + +REL_INSERT(R(foo) + +function user.%temp(X1, ..., XN) + m:=sql.mvc(); + sql.append(m, "foo", "column1", X1); + . + . + . + sql.append(m, "foo", "columnn", Xn); + c := aggr.count(Xn); + sql.affectedRows(m, c); +end diff --git a/gdk/gdk_bbp.c b/gdk/gdk_bbp.c --- a/gdk/gdk_bbp.c +++ b/gdk/gdk_bbp.c @@ -250,7 +250,7 @@ static volatile MT_Id locked_by = 0; } while (0) static int BBPunloadCnt = 0; -static MT_Lock GDKunloadLock = MT_LOCK_INITIALIZER("GDKunloadLock"); +static MT_Lock GDKunloadLock = MT_LOCK_INITIALIZER(GDKunloadLock); void BBPlock(void) diff --git a/gdk/gdk_posix.c b/gdk/gdk_posix.c --- a/gdk/gdk_posix.c +++ b/gdk/gdk_posix.c @@ -1048,7 +1048,7 @@ MT_sleep_ms(unsigned int ms) } #if !defined(HAVE_LOCALTIME_R) || !defined(HAVE_GMTIME_R) || !defined(HAVE_ASCTIME_R) || !defined(HAVE_CTIME_R) -static MT_Lock timelock = MT_LOCK_INITIALIZER("timelock"); +static MT_Lock timelock = MT_LOCK_INITIALIZER(timelock); #endif #ifndef HAVE_LOCALTIME_R @@ -1108,7 +1108,7 @@ ctime_r(const time_t *restrict t, char * #endif #ifndef HAVE_STRERROR_R -static MT_Lock strerrlock = MT_LOCK_INITIALIZER("strerrlock"); +static MT_Lock strerrlock = MT_LOCK_INITIALIZER(strerrlock); int strerror_r(int errnum, char *buf, size_t buflen) diff --git a/gdk/gdk_sample.c b/gdk/gdk_sample.c --- a/gdk/gdk_sample.c +++ b/gdk/gdk_sample.c @@ -172,11 +172,11 @@ BATsample_with_seed(BAT *b, BUN n, unsig return do_batsample(b, n, rse, NULL); } +static MT_Lock rse_lock = MT_LOCK_INITIALIZER(rse_lock); _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list