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

Reply via email to