LCOV - code coverage report
Current view: top level - monetdb5/modules/mal - sysmon.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 205 302 67.9 %
Date: 2024-10-03 20:03:20 Functions: 6 6 100.0 %

          Line data    Source code
       1             : /*
       2             :  * SPDX-License-Identifier: MPL-2.0
       3             :  *
       4             :  * This Source Code Form is subject to the terms of the Mozilla Public
       5             :  * License, v. 2.0.  If a copy of the MPL was not distributed with this
       6             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       7             :  *
       8             :  * Copyright 2024 MonetDB Foundation;
       9             :  * Copyright August 2008 - 2023 MonetDB B.V.;
      10             :  * Copyright 1997 - July 2008 CWI.
      11             :  */
      12             : 
      13             : #include "monetdb_config.h"
      14             : #include "mal.h"
      15             : #include "mal_interpreter.h"
      16             : #include "mal_authorize.h"
      17             : #include "mal_client.h"
      18             : #include "mal_runtime.h"
      19             : #include "gdk_time.h"
      20             : #include "mal_exception.h"
      21             : #include "mal_internal.h"
      22             : 
      23             : /* (c) M.L. Kersten
      24             :  * The queries currently in execution are returned to the front-end for managing expensive ones.
      25             :  */
      26             : 
      27             : static str
      28           1 : SYSMONstatistics(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
      29             : {
      30           1 :         (void) mb;
      31             : 
      32             :         /* Temporary hack not allowing MAL clients (mclient -lmal)
      33             :            to use this function */
      34           1 :         if (cntxt->sqlcontext == NULL)
      35           0 :                 throw(MAL, "SYSMONstatistics",
      36             :                           SQLSTATE(42000) "Calling from a mclient -lmal.");
      37             : 
      38           1 :         BAT *user, *querycount, *totalticks, *started, *finished, *maxquery,
      39             :                         *maxticks;
      40           1 :         bat *u = getArgReference_bat(stk, pci, 0);
      41           1 :         bat *c = getArgReference_bat(stk, pci, 1);
      42           1 :         bat *t = getArgReference_bat(stk, pci, 2);
      43           1 :         bat *s = getArgReference_bat(stk, pci, 3);
      44           1 :         bat *f = getArgReference_bat(stk, pci, 4);
      45           1 :         bat *m = getArgReference_bat(stk, pci, 5);
      46           1 :         bat *q = getArgReference_bat(stk, pci, 6);
      47           1 :         size_t i;
      48           1 :         timestamp tsn = timestamp_nil;
      49           1 :         str msg = MAL_SUCCEED;
      50             : 
      51           1 :         user = COLnew(0, TYPE_str, usrstatscnt, TRANSIENT);
      52           1 :         querycount = COLnew(0, TYPE_lng, usrstatscnt, TRANSIENT);
      53           1 :         totalticks = COLnew(0, TYPE_lng, usrstatscnt, TRANSIENT);
      54           1 :         started = COLnew(0, TYPE_timestamp, usrstatscnt, TRANSIENT);
      55           1 :         finished = COLnew(0, TYPE_timestamp, usrstatscnt, TRANSIENT);
      56           1 :         maxticks = COLnew(0, TYPE_lng, usrstatscnt, TRANSIENT);
      57           1 :         maxquery = COLnew(0, TYPE_str, usrstatscnt, TRANSIENT);
      58           1 :         if (user == NULL || querycount == NULL || totalticks == NULL
      59           1 :                 || started == NULL || finished == NULL || maxquery == NULL
      60           1 :                 || maxticks == NULL) {
      61           0 :                 BBPreclaim(user);
      62           0 :                 BBPreclaim(started);
      63           0 :                 BBPreclaim(querycount);
      64           0 :                 BBPreclaim(totalticks);
      65           0 :                 BBPreclaim(finished);
      66           0 :                 BBPreclaim(maxticks);
      67           0 :                 BBPreclaim(maxquery);
      68           0 :                 throw(MAL, "SYSMONstatistics", SQLSTATE(HY013) MAL_MALLOC_FAIL);
      69             :         }
      70             : 
      71           1 :         MT_lock_set(&mal_delayLock);
      72             :         // FIXME: what if there are multiple users with ADMIN privilege?
      73           7 :         for (i = 0; i < usrstatscnt; i++) {
      74             :                 /* We can stop at the first empty entry */
      75           6 :                 if (USRstats[i].username == NULL)
      76             :                         break;
      77             : 
      78           5 :                 if (BUNappend(user, USRstats[i].username, false) != GDK_SUCCEED) {
      79           0 :                         msg = createException(MAL, "SYSMONstatistics",
      80             :                                                                   "Failed to append 'user'");
      81           0 :                         goto bailout;
      82             :                 }
      83           5 :                 if (BUNappend(querycount, &USRstats[i].querycount, false) != GDK_SUCCEED) {
      84           0 :                         msg = createException(MAL, "SYSMONstatistics",
      85             :                                                                   "Failed to append 'querycount'");
      86           0 :                         goto bailout;
      87             :                 }
      88           5 :                 if (BUNappend(totalticks, &USRstats[i].totalticks, false) != GDK_SUCCEED) {
      89           0 :                         msg = createException(MAL, "SYSMONstatistics",
      90             :                                                                   "Failed to append 'totalticks'");
      91           0 :                         goto bailout;
      92             :                 }
      93             :                 /* convert number of seconds into a timestamp */
      94           5 :                 if (USRstats[i].maxquery != 0) {
      95           5 :                         tsn = timestamp_fromtime(USRstats[i].started);
      96           5 :                         if (is_timestamp_nil(tsn)) {
      97           0 :                                 msg = createException(MAL, "SYSMONstatistics",
      98             :                                                                           SQLSTATE(22003)
      99             :                                                                           "failed to convert start time");
     100           0 :                                 goto bailout;
     101             :                         }
     102           5 :                         if (BUNappend(started, &tsn, false) != GDK_SUCCEED) {
     103           0 :                                 msg = createException(MAL, "SYSMONstatistics",
     104             :                                                                           "Failed to append 'started'");
     105           0 :                                 goto bailout;
     106             :                         }
     107             : 
     108           5 :                         if (USRstats[i].finished == 0) {
     109           0 :                                 tsn = timestamp_nil;
     110             :                         } else {
     111           5 :                                 tsn = timestamp_fromtime(USRstats[i].finished);
     112           5 :                                 if (is_timestamp_nil(tsn)) {
     113           0 :                                         msg = createException(MAL, "SYSMONstatistics",
     114             :                                                                                   SQLSTATE(22003)
     115             :                                                                                   "failed to convert finish time");
     116           0 :                                         goto bailout;
     117             :                                 }
     118             :                         }
     119           5 :                         if (BUNappend(finished, &tsn, false) != GDK_SUCCEED) {
     120           0 :                                 msg = createException(MAL, "SYSMONstatistics",
     121             :                                                                           "Failed to append 'finished'");
     122           0 :                                 goto bailout;
     123             :                         }
     124             :                 } else {
     125           0 :                         tsn = timestamp_nil;
     126           0 :                         if (BUNappend(started, &tsn, false) != GDK_SUCCEED) {
     127           0 :                                 msg = createException(MAL, "SYSMONstatistics",
     128             :                                                                           "Failed to append 'started'");
     129           0 :                                 goto bailout;
     130             :                         }
     131           0 :                         if (BUNappend(finished, &tsn, false) != GDK_SUCCEED) {
     132           0 :                                 msg = createException(MAL, "SYSMONstatistics",
     133             :                                                                           "Failed to append 'finished'");
     134           0 :                                 goto bailout;
     135             :                         }
     136             :                 }
     137             : 
     138           5 :                 if (BUNappend(maxticks, &USRstats[i].maxticks, false) != GDK_SUCCEED) {
     139           0 :                         msg = createException(MAL, "SYSMONstatistics",
     140             :                                                                   "Failed to append 'maxticks'");
     141           0 :                         goto bailout;
     142             :                 }
     143           5 :                 if (USRstats[i].maxquery == 0) {
     144           0 :                         if (BUNappend(maxquery, "none", false) != GDK_SUCCEED) {
     145           0 :                                 msg = createException(MAL, "SYSMONstatistics",
     146             :                                                                           "Failed to append 'maxquery' 1");
     147           0 :                                 goto bailout;
     148             :                         }
     149             :                 } else {
     150           5 :                         if (BUNappend(maxquery, USRstats[i].maxquery, false) != GDK_SUCCEED) {
     151           0 :                                 msg = createException(MAL, "SYSMONstatistics",
     152             :                                                                           "Failed to append 'maxquery' 2");
     153           0 :                                 goto bailout;
     154             :                         }
     155             :                 }
     156             :         }
     157           1 :         MT_lock_unset(&mal_delayLock);
     158           1 :         *u = user->batCacheid;
     159           1 :         BBPkeepref(user);
     160           1 :         *c = querycount->batCacheid;
     161           1 :         BBPkeepref(querycount);
     162           1 :         *t = totalticks->batCacheid;
     163           1 :         BBPkeepref(totalticks);
     164           1 :         *s = started->batCacheid;
     165           1 :         BBPkeepref(started);
     166           1 :         *f = finished->batCacheid;
     167           1 :         BBPkeepref(finished);
     168           1 :         *m = maxticks->batCacheid;
     169           1 :         BBPkeepref(maxticks);
     170           1 :         *q = maxquery->batCacheid;
     171           1 :         BBPkeepref(maxquery);
     172           1 :         return MAL_SUCCEED;
     173             : 
     174           0 :   bailout:
     175           0 :         MT_lock_unset(&mal_delayLock);
     176           0 :         BBPunfix(user->batCacheid);
     177           0 :         BBPunfix(querycount->batCacheid);
     178           0 :         BBPunfix(totalticks->batCacheid);
     179           0 :         BBPunfix(started->batCacheid);
     180           0 :         BBPunfix(finished->batCacheid);
     181           0 :         BBPunfix(maxticks->batCacheid);
     182           0 :         BBPunfix(maxquery->batCacheid);
     183           0 :         return msg;
     184             : }
     185             : 
     186             : static str
     187          36 : SYSMONqueue(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     188             : {
     189          36 :         (void) mb;
     190             : 
     191             :         /* Temporary hack not allowing MAL clients (mclient -lmal)
     192             :            to use this function */
     193          36 :         if (cntxt->sqlcontext == NULL)
     194           0 :                 throw(MAL, "SYSMONqueue",
     195             :                           SQLSTATE(42000) "Calling from a mclient -lmal.");
     196             : 
     197          36 :         bat *t = getArgReference_bat(stk, pci, 0),
     198          36 :                         *s = getArgReference_bat(stk, pci, 1),
     199          36 :                         *u = getArgReference_bat(stk, pci, 2),
     200          36 :                         *sd = getArgReference_bat(stk, pci, 3),
     201          36 :                         *ss = getArgReference_bat(stk, pci, 4),
     202          36 :                         *q = getArgReference_bat(stk, pci, 5),
     203          36 :                         *f = getArgReference_bat(stk, pci, 6),
     204          36 :                         *w = getArgReference_bat(stk, pci, 7),
     205          36 :                         *m = getArgReference_bat(stk, pci, 8);
     206             : 
     207          36 :         BUN sz = (BUN) qsize;
     208          36 :         BAT *tag = COLnew(0, TYPE_lng, sz, TRANSIENT),
     209          36 :                         *sessionid = COLnew(0, TYPE_int, sz, TRANSIENT),
     210          36 :                         *user = COLnew(0, TYPE_str, sz, TRANSIENT),
     211          36 :                         *started = COLnew(0, TYPE_timestamp, sz, TRANSIENT),
     212          36 :                         *status = COLnew(0, TYPE_str, sz, TRANSIENT),
     213          36 :                         *query = COLnew(0, TYPE_str, sz, TRANSIENT),
     214          36 :                         *finished = COLnew(0, TYPE_timestamp, sz, TRANSIENT),
     215          36 :                         *workers = COLnew(0, TYPE_int, sz, TRANSIENT),
     216          36 :                         *memory = COLnew(0, TYPE_int, sz, TRANSIENT);
     217             : 
     218          36 :         lng qtag;
     219          36 :         int wrk, mem;
     220          36 :         timestamp tsn;
     221          36 :         str userqueue = NULL, msg = MAL_SUCCEED;
     222             : 
     223             :         /* If pci->argc == 10, arg 9 type is a string */
     224          36 :         bool getall = false, admin = pci->argc == 10 ? true : false;
     225          36 :         if (admin) {
     226           9 :                 assert(getArgType(mb, pci, 9) == TYPE_str);
     227           9 :                 userqueue = *getArgReference_str(stk, pci, 9);
     228           9 :                 if (strcmp("ALL", userqueue) == 0)
     229           4 :                         getall = true;
     230             :         }
     231             : 
     232          36 :         if (tag == NULL || sessionid == NULL || user == NULL ||
     233          36 :                 query == NULL || started == NULL || finished == NULL ||
     234          36 :                 workers == NULL || memory == NULL) {
     235           0 :                 BBPreclaim(tag);
     236           0 :                 BBPreclaim(sessionid);
     237           0 :                 BBPreclaim(user);
     238           0 :                 BBPreclaim(started);
     239           0 :                 BBPreclaim(status);
     240           0 :                 BBPreclaim(query);
     241           0 :                 BBPreclaim(finished);
     242           0 :                 BBPreclaim(workers);
     243           0 :                 BBPreclaim(memory);
     244           0 :                 throw(MAL, "SYSMONqueue", SQLSTATE(HY001) MAL_MALLOC_FAIL);
     245             :         }
     246             : 
     247          36 :         MT_lock_set(&mal_delayLock);
     248        1684 :         for (size_t i = 0; i < qsize; i++) {
     249             :                 /* Filtering the queries according to how SYSMONqueue was called.
     250             :                    Either:
     251             :                    SYSADMIN calls sys.queue("ALL") or SYSADMIN calls sys.queue(USER)
     252             :                    or any user calls sys.queue() to retrieve its own queue. */
     253        1648 :                 if (QRYqueue[i].query &&
     254        1608 :                         ((admin && getall) ||
     255          40 :                          (admin && strcmp(QRYqueue[i].username, userqueue) == 0) ||
     256             :                          ((admin == false)
     257        1536 :                           && strcmp(QRYqueue[i].username, cntxt->username) == 0))) {
     258        1564 :                         qtag = (lng) QRYqueue[i].tag;
     259        3128 :                         if (BUNappend(tag, &qtag, false) != GDK_SUCCEED ||
     260        3128 :                                 BUNappend(user, QRYqueue[i].username, false) != GDK_SUCCEED ||
     261        1564 :                                 BUNappend(sessionid, &(QRYqueue[i].idx), false) != GDK_SUCCEED
     262        1564 :                                 || BUNappend(query, QRYqueue[i].query, false) != GDK_SUCCEED
     263        1564 :                                 || BUNappend(status, QRYqueue[i].status, false) != GDK_SUCCEED)
     264           0 :                                 goto bailout;
     265             :                         /* convert number of seconds into a timestamp */
     266        1564 :                         tsn = timestamp_fromtime(QRYqueue[i].start);
     267        1564 :                         if (is_timestamp_nil(tsn)) {
     268           0 :                                 msg = createException(MAL, "SYSMONqueue",
     269             :                                                                           SQLSTATE(22003) "Cannot convert time.");
     270           0 :                                 goto bailout;
     271             :                         }
     272        1564 :                         if (BUNappend(started, &tsn, false) != GDK_SUCCEED)
     273           0 :                                 goto bailout;
     274        1564 :                         if (QRYqueue[i].finished == 0)
     275          38 :                                 tsn = timestamp_nil;
     276             :                         else {
     277        1526 :                                 tsn = timestamp_fromtime(QRYqueue[i].finished);
     278        1526 :                                 if (is_timestamp_nil(tsn)) {
     279           0 :                                         msg = createException(MAL, "SYSMONqueue",
     280             :                                                                                   SQLSTATE(22003)
     281             :                                                                                   "Cannot convert time.");
     282           0 :                                         goto bailout;
     283             :                                 }
     284             :                         }
     285        1564 :                         if (BUNappend(finished, &tsn, false) != GDK_SUCCEED)
     286           0 :                                 goto bailout;
     287        1564 :                         if (QRYqueue[i].mb)
     288          38 :                                 wrk = (int) ATOMIC_GET(&QRYqueue[i].mb->workers);
     289             :                         else
     290        1526 :                                 wrk = QRYqueue[i].workers;
     291        1564 :                         if (QRYqueue[i].mb)
     292          38 :                                 mem = (int) (1 + QRYqueue[i].mb->memory / LL_CONSTANT(1048576));
     293             :                         else
     294        1526 :                                 mem = QRYqueue[i].memory;
     295        3128 :                         if (BUNappend(workers, &wrk, false) != GDK_SUCCEED ||
     296        1564 :                                 BUNappend(memory, &mem, false) != GDK_SUCCEED)
     297           0 :                                 goto bailout;
     298             :                 }
     299             :         }
     300          36 :         MT_lock_unset(&mal_delayLock);
     301          36 :         *t = tag->batCacheid;
     302          36 :         BBPkeepref(tag);
     303          36 :         *s = sessionid->batCacheid;
     304          36 :         BBPkeepref(sessionid);
     305          36 :         *u = user->batCacheid;
     306          36 :         BBPkeepref(user);
     307          36 :         *sd = started->batCacheid;
     308          36 :         BBPkeepref(started);
     309          36 :         *ss = status->batCacheid;
     310          36 :         BBPkeepref(status);
     311          36 :         *q = query->batCacheid;
     312          36 :         BBPkeepref(query);
     313          36 :         *f = finished->batCacheid;
     314          36 :         BBPkeepref(finished);
     315          36 :         *w = workers->batCacheid;
     316          36 :         BBPkeepref(workers);
     317          36 :         *m = memory->batCacheid;
     318          36 :         BBPkeepref(memory);
     319          36 :         return MAL_SUCCEED;
     320             : 
     321           0 :   bailout:
     322           0 :         MT_lock_unset(&mal_delayLock);
     323           0 :         BBPunfix(tag->batCacheid);
     324           0 :         BBPunfix(sessionid->batCacheid);
     325           0 :         BBPunfix(user->batCacheid);
     326           0 :         BBPunfix(started->batCacheid);
     327           0 :         BBPunfix(status->batCacheid);
     328           0 :         BBPunfix(query->batCacheid);
     329           0 :         BBPunfix(finished->batCacheid);
     330           0 :         BBPunfix(workers->batCacheid);
     331           0 :         BBPunfix(memory->batCacheid);
     332           0 :         return msg ? msg : createException(MAL, "SYSMONqueue",
     333             :                                                                            SQLSTATE(HY013) MAL_MALLOC_FAIL);
     334             : }
     335             : 
     336             : static str
     337           1 : SYSMONpause(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     338             : {
     339           1 :         (void) mb;
     340             : 
     341             :         /* Temporary hack not allowing MAL clients (mclient -lmal)
     342             :            to use this function */
     343           1 :         if (cntxt->sqlcontext == NULL)
     344           0 :                 throw(MAL, "SYSMONpause",
     345             :                           SQLSTATE(42000) "Calling from a mclient -lmal.");
     346             : 
     347           1 :         oid tag = 0;
     348           1 :         size_t i = 0;
     349           1 :         bool paused = false;
     350           1 :         bool admin = pci->argc == 3 ? true : false;
     351           1 :         int owner = -1;
     352             : 
     353           1 :         assert(getArgType(mb, pci, 1) == TYPE_lng);
     354             : 
     355           1 :         if ((tag = (oid) *getArgReference_lng(stk, pci, 1)) < 1)
     356           0 :                 throw(MAL, "SYSMONpause", SQLSTATE(22003) "Tag must be positive.");
     357           1 :         if (tag == cntxt->curprg->def->tag)
     358           0 :                 throw(MAL, "SYSMONpause",
     359             :                           SQLSTATE(HY009) "SYSMONpause cannot pause itself.");
     360             : 
     361           1 :         MT_lock_set(&mal_delayLock);
     362           4 :         for (i = 0; i < qsize; i++) {
     363           3 :                 if (QRYqueue[i].tag == tag) {
     364           1 :                         if (QRYqueue[i].stk) {
     365           1 :                                 if (admin
     366           0 :                                         || (owner = strcmp(QRYqueue[i].username, cntxt->username)) == 0) {
     367           1 :                                         QRYqueue[i].stk->status = 'p';
     368           1 :                                         QRYqueue[i].status = "paused";
     369           1 :                                         paused = true;
     370             :                                 }
     371             :                                 /* tag found, but either not admin or user cannot
     372             :                                    pause that query with OID ctag */
     373             :                                 break;
     374             :                         }
     375             :                         /* tag found, but query could have already finished...
     376             :                            stack is 0 by this time.. potential problem?
     377             :                            using MAL fcn alarm.sleep exposes the above */
     378             :                         break;
     379             :                 }
     380             :         }
     381           1 :         MT_lock_unset(&mal_delayLock);
     382             : 
     383           1 :         return paused ? MAL_SUCCEED :
     384           0 :                         i == qsize ? createException(MAL, "SYSMONpause",
     385             :                                                                                  SQLSTATE(42 S12) "Tag " OIDFMT
     386             :                                                                                  " unknown.",
     387           0 :                                                                                  tag) : createException(MAL,
     388             :                                                                                                                                 "SYSMONpause",
     389             :                                                                                                                                 SQLSTATE(HY009)
     390             :                                                                                                                                 "Tag " OIDFMT
     391             :                                                                                                                                 " unknown to the user.",
     392             :                                                                                                                                 tag);
     393             : }
     394             : 
     395             : static str
     396           1 : SYSMONresume(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     397             : {
     398           1 :         (void) mb;
     399             : 
     400             :         /* Temporary hack not allowing MAL clients (mclient -lmal)
     401             :            to use this function */
     402           1 :         if (cntxt->sqlcontext == NULL)
     403           0 :                 throw(MAL, "SYSMONresume",
     404             :                           SQLSTATE(42000) "Calling from a mclient -lmal.");
     405             : 
     406           1 :         oid tag = 0;
     407           1 :         size_t i = 0;
     408           1 :         bool paused = false;
     409           1 :         bool admin = pci->argc == 3 ? true : false;
     410           1 :         int owner = -1;
     411             : 
     412           1 :         assert(getArgType(mb, pci, 1) == TYPE_lng);
     413             : 
     414           1 :         if ((tag = (oid) *getArgReference_lng(stk, pci, 1)) < 1)
     415           0 :                 throw(MAL, "SYSMONresume", SQLSTATE(22003) "Tag must be positive.");
     416           1 :         if (tag == cntxt->curprg->def->tag)
     417           0 :                 throw(MAL, "SYSMONresume",
     418             :                           SQLSTATE(HY009) "SYSMONresume cannot pause itself.");
     419             : 
     420           1 :         MT_lock_set(&mal_delayLock);
     421           4 :         for (i = 0; i < qsize; i++) {
     422           3 :                 if (QRYqueue[i].tag == tag) {
     423           1 :                         if (QRYqueue[i].stk) {
     424           1 :                                 if (admin
     425           0 :                                         || (owner = strcmp(QRYqueue[i].username, cntxt->username)) == 0) {
     426           1 :                                         QRYqueue[i].stk->status = 0;
     427           1 :                                         QRYqueue[i].status = "running";
     428           1 :                                         paused = true;
     429             :                                 }
     430             :                                 /* tag found, but either not admin or user cannot
     431             :                                    pause that query with OID ctag */
     432             :                                 break;
     433             :                         }
     434             :                         /* tag found, but query could have already finished...
     435             :                            stack is 0 by this time.. potential problem?
     436             :                            using MAL fcn alarm.sleep exposes the above */
     437             :                         break;
     438             :                 }
     439             :         }
     440           1 :         MT_lock_unset(&mal_delayLock);
     441             : 
     442           1 :         return paused ? MAL_SUCCEED :
     443           0 :                         i == qsize ? createException(MAL, "SYSMONresume",
     444             :                                                                                  SQLSTATE(42 S12) "Tag " OIDFMT
     445             :                                                                                  " unknown.",
     446           0 :                                                                                  tag) : createException(MAL,
     447             :                                                                                                                                 "SYSMONresume",
     448             :                                                                                                                                 SQLSTATE(HY009)
     449             :                                                                                                                                 "Tag " OIDFMT
     450             :                                                                                                                                 " unknown to the user.",
     451             :                                                                                                                                 tag);
     452             : }
     453             : 
     454             : static str
     455           1 : SYSMONstop(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     456             : {
     457           1 :         (void) mb;
     458             : 
     459             :         /* Temporary hack not allowing MAL clients (mclient -lmal)
     460             :            to use this function */
     461           1 :         if (cntxt->sqlcontext == NULL)
     462           0 :                 throw(MAL, "SYSMONstop",
     463             :                           SQLSTATE(42000) "Calling from a mclient -lmal.");
     464             : 
     465           1 :         oid tag = 0;
     466           1 :         size_t i = 0;
     467           1 :         bool paused = false;
     468           1 :         bool admin = pci->argc == 3 ? true : false;
     469           1 :         int owner = -1;
     470             : 
     471           1 :         assert(getArgType(mb, pci, 1) == TYPE_lng);
     472             : 
     473           1 :         if ((tag = (oid) *getArgReference_lng(stk, pci, 1)) < 1)
     474           0 :                 throw(MAL, "SYSMONstop", SQLSTATE(22003) "Tag must be positive.");
     475           1 :         if (tag == cntxt->curprg->def->tag)
     476           0 :                 throw(MAL, "SYSMONstop",
     477             :                           SQLSTATE(HY009) "SYSMONstop cannot pause itself.");
     478             : 
     479           1 :         MT_lock_set(&mal_delayLock);
     480           9 :         for (i = 0; i < qsize; i++) {
     481           8 :                 if (QRYqueue[i].tag == tag) {
     482           1 :                         if (QRYqueue[i].stk) {
     483           1 :                                 if (admin
     484           0 :                                         || (owner = strcmp(QRYqueue[i].username, cntxt->username)) == 0) {
     485           1 :                                         QRYqueue[i].stk->status = 'q';
     486           1 :                                         QRYqueue[i].status = "stopping";
     487           1 :                                         paused = true;
     488             :                                 }
     489             :                                 /* tag found, but either not admin or user cannot
     490             :                                    pause that query with OID ctag */
     491             :                                 break;
     492             :                         }
     493             :                         /* tag found, but query could have already finished...
     494             :                            stack is 0 by this time.. potential problem?
     495             :                            using MAL fcn alarm.sleep exposes the above */
     496             :                         break;
     497             :                 }
     498             :         }
     499           1 :         MT_lock_unset(&mal_delayLock);
     500             : 
     501           1 :         return paused ? MAL_SUCCEED :
     502           0 :                         i == qsize ? createException(MAL, "SYSMONstop",
     503             :                                                                                  SQLSTATE(42 S12) "Tag " OIDFMT
     504             :                                                                                  " unknown.",
     505           0 :                                                                                  tag) : createException(MAL,
     506             :                                                                                                                                 "SYSMONstop",
     507             :                                                                                                                                 SQLSTATE(HY009)
     508             :                                                                                                                                 "Tag " OIDFMT
     509             :                                                                                                                                 " unknown to the user.",
     510             :                                                                                                                                 tag);
     511             : }
     512             : 
     513             : #include "mel.h"
     514             : mel_func sysmon_init_funcs[] = {
     515             :         pattern("sysmon", "pause", SYSMONpause, true, "Suspend query execution with OID id", args(0, 1, arg("id", lng))),
     516             :         pattern("sysmon", "pause", SYSMONpause, true, "Sysadmin call, suspend query execution with OID id belonging to user", args(0, 2, arg("id", lng), arg("user", str))),
     517             :         pattern("sysmon", "resume", SYSMONresume, true, "Resume query execution with OID id", args(0, 1, arg("id", lng))),
     518             :         pattern("sysmon", "resume", SYSMONresume, true, "Sysadmin call, resume query execution with OID id belonging to user", args(0, 2, arg("id", lng), arg("user", str))),
     519             :         pattern("sysmon", "stop", SYSMONstop, true, "Stop query execution with OID id", args(0, 1, arg("id", lng))),
     520             :         pattern("sysmon", "stop", SYSMONstop, true, "Sysadmin call, stop query execution with OID id belonging to user", args(0, 2, arg("id", lng), arg("user", str))),
     521             :         pattern("sysmon", "queue", SYSMONqueue, false, "A queue of queries that are currently being executed or recently finished", args(9, 9, batarg("tag", lng), batarg("sessionid", int), batarg("user", str), batarg("started", timestamp), batarg("status", str), batarg("query", str), batarg("finished", timestamp), batarg("workers", int), batarg("memory", int))),
     522             :         pattern("sysmon", "queue", SYSMONqueue, false, "Sysadmin call, to see either the global queue or user queue of queries that are currently being executed or recently finished", args(9, 10, batarg("tag", lng), batarg("sessionid", int), batarg("user", str), batarg("started", timestamp), batarg("status", str), batarg("query", str), batarg("finished", timestamp), batarg("workers", int), batarg("memory", int), arg("user", str))),
     523             :         pattern("sysmon", "user_statistics", SYSMONstatistics, false, "", args(7, 7, batarg("user", str), batarg("querycount", lng), batarg("totalticks", lng), batarg("started", timestamp), batarg("finished", timestamp), batarg("maxticks", lng), batarg("maxquery", str))),
     524             :         { .imp=NULL }
     525             : };
     526             : #include "mal_import.h"
     527             : #ifdef _MSC_VER
     528             : #undef read
     529             : #pragma section(".CRT$XCU",read)
     530             : #endif
     531         320 : LIB_STARTUP_FUNC(init_sysmon_mal)
     532         320 : { mal_module("sysmon", NULL, sysmon_init_funcs); }

Generated by: LCOV version 1.14