Changeset: 6ba95b007411 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=6ba95b007411 Modified Files: sql/server/sql_mvc.h Branch: scoping2 Log Message:
Merged with default diffs (truncated from 2443 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 @@ -8771,6 +8771,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;", "" ] @@ -9244,11 +9245,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 @@ -12067,6 +12067,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;", "" ] @@ -12546,11 +12547,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/common/utils/matomic.h b/common/utils/matomic.h --- a/common/utils/matomic.h +++ b/common/utils/matomic.h @@ -220,6 +220,7 @@ typedef PVOID volatile ATOMIC_PTR_TYPE; #define ATOMIC_PTR_GET(var) (*(var)) #define ATOMIC_PTR_SET(var, val) _InterlockedExchangePointer(var, (PVOID) (val)) #define ATOMIC_PTR_XCG(var, val) _InterlockedExchangePointer(var, (PVOID) (val)) +#pragma intrinsic(_InterlockedCompareExchangePointer) static inline bool ATOMIC_PTR_CAS(ATOMIC_PTR_TYPE *var, void **exp, void *des) { 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_aggr.c b/gdk/gdk_aggr.c --- a/gdk/gdk_aggr.c +++ b/gdk/gdk_aggr.c @@ -3487,6 +3487,7 @@ BATmin_skipnil(BAT *b, void *aggr, bit s const oid *ords = (const oid *) (pb ? pb->torderidx->base : b->torderidx->base) + ORDERIDXOFF; BUN r; if (!b->tnonil) { + MT_thread_setalgorithm(pb ? "binsearch on parent oidx" : "binsearch on oids"); r = binsearch(ords, 0, b->ttype, Tloc(b, 0), b->tvheap ? b->tvheap->base : NULL, b->twidth, 0, BATcount(b), @@ -3502,6 +3503,7 @@ BATmin_skipnil(BAT *b, void *aggr, bit s /* no non-nil values */ pos = oid_nil; } else { + MT_thread_setalgorithm(pb ? "using parent oidx" : "using oids"); pos = ords[r]; } } else if ((VIEWtparent(b) == 0 || @@ -3510,6 +3512,8 @@ BATmin_skipnil(BAT *b, void *aggr, bit s Imprints *imprints = VIEWtparent(b) ? BBPdescriptor(VIEWtparent(b))->timprints : b->timprints; int i; + + MT_thread_setalgorithm(VIEWtparent(b) ? "using parent imprints" : "using imprints"); pos = oid_nil; /* find first non-empty bin */ for (i = 0; i < imprints->bits; i++) { @@ -3591,6 +3595,7 @@ BATmax_skipnil(BAT *b, void *aggr, bit s BATcheckorderidx(pb))) { _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list