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

Generated by: LCOV version 1.14