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-04-26 00:35:57 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          30 : SYSMONqueue(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     188             : {
     189          30 :         (void) mb;
     190             : 
     191             :         /* Temporary hack not allowing MAL clients (mclient -lmal)
     192             :            to use this function */
     193          30 :         if (cntxt->sqlcontext == NULL)
     194           0 :                 throw(MAL, "SYSMONqueue",
     195             :                           SQLSTATE(42000) "Calling from a mclient -lmal.");
     196             : 
     197          30 :         bat *t = getArgReference_bat(stk, pci, 0),
     198          30 :                         *s = getArgReference_bat(stk, pci, 1),
     199          30 :                         *u = getArgReference_bat(stk, pci, 2),
     200          30 :                         *sd = getArgReference_bat(stk, pci, 3),
     201          30 :                         *ss = getArgReference_bat(stk, pci, 4),
     202          30 :                         *q = getArgReference_bat(stk, pci, 5),
     203          30 :                         *f = getArgReference_bat(stk, pci, 6),
     204          30 :                         *w = getArgReference_bat(stk, pci, 7),
     205          30 :                         *m = getArgReference_bat(stk, pci, 8);
     206             : 
     207          30 :         BUN sz = (BUN) qsize;
     208          30 :         BAT *tag = COLnew(0, TYPE_lng, sz, TRANSIENT),
     209          31 :                         *sessionid = COLnew(0, TYPE_int, sz, TRANSIENT),
     210          31 :                         *user = COLnew(0, TYPE_str, sz, TRANSIENT),
     211          31 :                         *started = COLnew(0, TYPE_timestamp, sz, TRANSIENT),
     212          31 :                         *status = COLnew(0, TYPE_str, sz, TRANSIENT),
     213          30 :                         *query = COLnew(0, TYPE_str, sz, TRANSIENT),
     214          31 :                         *finished = COLnew(0, TYPE_timestamp, sz, TRANSIENT),
     215          31 :                         *workers = COLnew(0, TYPE_int, sz, TRANSIENT),
     216          31 :                         *memory = COLnew(0, TYPE_int, sz, TRANSIENT);
     217             : 
     218          31 :         lng qtag;
     219          31 :         int wrk, mem;
     220          31 :         timestamp tsn;
     221          31 :         str userqueue = NULL, msg = MAL_SUCCEED;
     222             : 
     223             :         /* If pci->argc == 10, arg 9 type is a string */
     224          31 :         bool getall = false, admin = pci->argc == 10 ? true : false;
     225          31 :         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          31 :         if (tag == NULL || sessionid == NULL || user == NULL ||
     233          31 :                 query == NULL || started == NULL || finished == NULL ||
     234          31 :                 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          31 :         MT_lock_set(&mal_delayLock);
     248        1295 :         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        1264 :                 if (QRYqueue[i].query &&
     254        1255 :                         ((admin && getall) ||
     255          40 :                          (admin && strcmp(QRYqueue[i].username, userqueue) == 0) ||
     256             :                          ((admin == false)
     257        1183 :                           && strcmp(QRYqueue[i].username, cntxt->username) == 0))) {
     258        1211 :                         qtag = (lng) QRYqueue[i].tag;
     259        2422 :                         if (BUNappend(tag, &qtag, false) != GDK_SUCCEED ||
     260        2422 :                                 BUNappend(user, QRYqueue[i].username, false) != GDK_SUCCEED ||
     261        1211 :                                 BUNappend(sessionid, &(QRYqueue[i].idx), false) != GDK_SUCCEED
     262        1211 :                                 || BUNappend(query, QRYqueue[i].query, false) != GDK_SUCCEED
     263        1211 :                                 || BUNappend(status, QRYqueue[i].status, false) != GDK_SUCCEED)
     264           0 :                                 goto bailout;
     265             :                         /* convert number of seconds into a timestamp */
     266        1211 :                         tsn = timestamp_fromtime(QRYqueue[i].start);
     267        1211 :                         if (is_timestamp_nil(tsn)) {
     268           0 :                                 msg = createException(MAL, "SYSMONqueue",
     269             :                                                                           SQLSTATE(22003) "Cannot convert time.");
     270           0 :                                 goto bailout;
     271             :                         }
     272        1211 :                         if (BUNappend(started, &tsn, false) != GDK_SUCCEED)
     273           0 :                                 goto bailout;
     274        1211 :                         if (QRYqueue[i].finished == 0)
     275          33 :                                 tsn = timestamp_nil;
     276             :                         else {
     277        1178 :                                 tsn = timestamp_fromtime(QRYqueue[i].finished);
     278        1178 :                                 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        1211 :                         if (BUNappend(finished, &tsn, false) != GDK_SUCCEED)
     286           0 :                                 goto bailout;
     287        1211 :                         if (QRYqueue[i].mb)
     288          33 :                                 wrk = (int) ATOMIC_GET(&QRYqueue[i].mb->workers);
     289             :                         else
     290        1178 :                                 wrk = QRYqueue[i].workers;
     291        1211 :                         if (QRYqueue[i].mb)
     292          33 :                                 mem = (int) (1 + QRYqueue[i].mb->memory / LL_CONSTANT(1048576));
     293             :                         else
     294        1178 :                                 mem = QRYqueue[i].memory;
     295        2422 :                         if (BUNappend(workers, &wrk, false) != GDK_SUCCEED ||
     296        1211 :                                 BUNappend(memory, &mem, false) != GDK_SUCCEED)
     297           0 :                                 goto bailout;
     298             :                 }
     299             :         }
     300          31 :         MT_lock_unset(&mal_delayLock);
     301          31 :         *t = tag->batCacheid;
     302          31 :         BBPkeepref(tag);
     303          31 :         *s = sessionid->batCacheid;
     304          31 :         BBPkeepref(sessionid);
     305          31 :         *u = user->batCacheid;
     306          31 :         BBPkeepref(user);
     307          31 :         *sd = started->batCacheid;
     308          31 :         BBPkeepref(started);
     309          31 :         *ss = status->batCacheid;
     310          31 :         BBPkeepref(status);
     311          31 :         *q = query->batCacheid;
     312          31 :         BBPkeepref(query);
     313          31 :         *f = finished->batCacheid;
     314          31 :         BBPkeepref(finished);
     315          31 :         *w = workers->batCacheid;
     316          31 :         BBPkeepref(workers);
     317          31 :         *m = memory->batCacheid;
     318          31 :         BBPkeepref(memory);
     319          31 :         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         334 : LIB_STARTUP_FUNC(init_sysmon_mal)
     532         334 : { mal_module("sysmon", NULL, sysmon_init_funcs); }

Generated by: LCOV version 1.14