Changeset: 7567eee12001 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/7567eee12001 Modified Files: monetdb5/mal/mal_interpreter.c monetdb5/mal/mal_runtime.c sql/test/SQLancer/Tests/sqlancer19.SQL.py Branch: default Log Message:
Check MAL recursive calls by tag at query queue, so it doesn't create issues when multiple complex function calls are done by multiple dataflow workers at the same time diffs (118 lines): diff --git a/monetdb5/mal/mal_interpreter.c b/monetdb5/mal/mal_interpreter.c --- a/monetdb5/mal/mal_interpreter.c +++ b/monetdb5/mal/mal_interpreter.c @@ -751,6 +751,8 @@ str runMALsequence(Client cntxt, MalBlkP nstk->stkdepth = nstk->stksize + stk->stkdepth; nstk->calldepth = stk->calldepth + 1; nstk->up = stk; + /* inherit tag, because it will be used when doing profiling */ + nstk->tag = stk->tag; if (nstk->calldepth > 256) { ret= createException(MAL, "mal.interpreter", MAL_CALLDEPTH_FAIL); GDKfree(nstk); diff --git a/monetdb5/mal/mal_runtime.c b/monetdb5/mal/mal_runtime.c --- a/monetdb5/mal/mal_runtime.c +++ b/monetdb5/mal/mal_runtime.c @@ -222,16 +222,13 @@ runtimeProfileInit(Client cntxt, MalBlkP if (stk->up) { i = qtail; while (i != qhead) { - if (QRYqueue[i].mb && QRYqueue[i].stk == stk->up) { - QRYqueue[i].stk = stk; - mb->tag = stk->tag = qtag++; + if (QRYqueue[i].tag == stk->tag) { MT_lock_unset(&mal_delayLock); return; } if (++i >= qsize) i = 0; } -// assert(0); } i=qtail; while (i != qhead){ @@ -257,7 +254,7 @@ runtimeProfileInit(Client cntxt, MalBlkP // add new invocation cntxt->idle = 0; QRYqueue[qhead].mb = mb; - QRYqueue[qhead].tag = qtag++; + QRYqueue[qhead].tag = stk->tag = mb->tag = qtag++; QRYqueue[qhead].stk = stk; // for status pause 'p'/running '0'/ quiting 'q' QRYqueue[qhead].finished = 0; QRYqueue[qhead].start = time(0); @@ -273,7 +270,6 @@ runtimeProfileInit(Client cntxt, MalBlkP QRYqueue[qhead].status = "running"; QRYqueue[qhead].cntxt = cntxt; QRYqueue[qhead].ticks = GDKusec(); - stk->tag = mb->tag = QRYqueue[qhead].tag; advanceQRYqueue(); MT_lock_unset(&mal_delayLock); } @@ -292,13 +288,11 @@ runtimeProfileFinish(Client cntxt, MalBl MT_lock_set(&mal_delayLock); i=qtail; while (i != qhead){ - if ( QRYqueue[i].stk == stk){ - if( stk->up){ - // recursive call - QRYqueue[i].stk = stk->up; - mb->tag = stk->tag; - found = true; - break; + if (QRYqueue[i].tag == stk->tag) { + if (stk->up){ + // recursive call, just return + MT_lock_unset(&mal_delayLock); + return; } QRYqueue[i].status = "finished"; QRYqueue[i].finished = time(0); @@ -315,8 +309,7 @@ runtimeProfileFinish(Client cntxt, MalBl found = true; break; } - i++; - if ( i >= qsize) + if (++i >= qsize) i = 0; } @@ -324,6 +317,7 @@ runtimeProfileFinish(Client cntxt, MalBl // finished query is not found, we want to print some informational // messages for debugging. if (!found) { + assert(0); TRC_INFO_IF(MAL_SERVER) { TRC_INFO_ENDIF(MAL_SERVER, "runtimeProfilerFinish: stk (%p) not found in QRYqueue", stk); i = qtail; @@ -335,8 +329,7 @@ runtimeProfileFinish(Client cntxt, MalBl QRYqueue[i].username, QRYqueue[i].start, QRYqueue[i].status, QRYqueue[i].query); } - i++; - if ( i >= qsize) + if (++i >= qsize) i = 0; } } diff --git a/sql/test/SQLancer/Tests/sqlancer19.SQL.py b/sql/test/SQLancer/Tests/sqlancer19.SQL.py --- a/sql/test/SQLancer/Tests/sqlancer19.SQL.py +++ b/sql/test/SQLancer/Tests/sqlancer19.SQL.py @@ -343,6 +343,17 @@ with SQLTestCase() as cli: .assertSucceeded().assertDataResultMatch([(True,)]) cli.execute("SELECT 3 >= ALL(SELECT vx.vc0 FROM storage((SELECT 'sys', 't3' FROM rt3))) FROM (SELECT 0) vx(vc0);") \ .assertSucceeded().assertDataResultMatch([(True,)]) + cli.execute(""" + SELECT 5 <> ALL((SELECT 2 FROM t3 FULL OUTER JOIN (SELECT 1) AS sub1n0(subc1n0) ON 2 < ANY(SELECT 1)) + UNION ALL (SELECT 1 FROM t3 RIGHT OUTER JOIN (SELECT 4) AS sub1n0(subc1n0) ON TRUE + CROSS JOIN (SELECT FALSE FROM t3) AS sub1n1(subc1n0))) FROM t3; + """).assertSucceeded().assertDataResultMatch([(True,),(True,),(True,),(True,),(True,),(True,)]) + # this query triggers a lot MAL user function calls at the moment. It allows to test concurrency issues with the query queue + cli.execute(""" + SELECT 5 <> ALL((SELECT 2 FROM rt3 FULL OUTER JOIN (SELECT 1) AS sub1n0(subc1n0) ON 2 < ANY(SELECT 1)) + UNION ALL (SELECT 1 FROM rt3 RIGHT OUTER JOIN (SELECT 4) AS sub1n0(subc1n0) ON TRUE + CROSS JOIN (SELECT FALSE FROM rt3) AS sub1n1(subc1n0))) FROM rt3; + """).assertSucceeded().assertDataResultMatch([(True,),(True,),(True,),(True,),(True,),(True,)]) cli.execute("ROLLBACK;") cli.execute(""" _______________________________________________ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org