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