Line data Source code
1 : /*
2 : * SPDX-License-Identifier: MPL-2.0
3 : *
4 : * This Source Code Form is subject to the terms of the Mozilla Public
5 : * License, v. 2.0. If a copy of the MPL was not distributed with this
6 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
7 : *
8 : * Copyright 2024 MonetDB Foundation;
9 : * Copyright August 2008 - 2023 MonetDB B.V.;
10 : * Copyright 1997 - July 2008 CWI.
11 : */
12 :
13 : #include "monetdb_config.h"
14 : #include "mal.h"
15 : #include "mal_interpreter.h"
16 : #include "mal_authorize.h"
17 : #include "mal_client.h"
18 : #include "mal_runtime.h"
19 : #include "gdk_time.h"
20 : #include "mal_exception.h"
21 : #include "mal_internal.h"
22 :
23 : /* (c) M.L. Kersten
24 : * The queries currently in execution are returned to the front-end for managing expensive ones.
25 : */
26 :
27 : static str
28 1 : SYSMONstatistics(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
29 : {
30 1 : (void) mb;
31 :
32 : /* Temporary hack not allowing MAL clients (mclient -lmal)
33 : to use this function */
34 1 : if (cntxt->sqlcontext == NULL)
35 0 : throw(MAL, "SYSMONstatistics",
36 : SQLSTATE(42000) "Calling from a mclient -lmal.");
37 :
38 1 : BAT *user, *querycount, *totalticks, *started, *finished, *maxquery,
39 : *maxticks;
40 1 : bat *u = getArgReference_bat(stk, pci, 0);
41 1 : bat *c = getArgReference_bat(stk, pci, 1);
42 1 : bat *t = getArgReference_bat(stk, pci, 2);
43 1 : bat *s = getArgReference_bat(stk, pci, 3);
44 1 : bat *f = getArgReference_bat(stk, pci, 4);
45 1 : bat *m = getArgReference_bat(stk, pci, 5);
46 1 : bat *q = getArgReference_bat(stk, pci, 6);
47 1 : size_t i;
48 1 : timestamp tsn = timestamp_nil;
49 1 : str msg = MAL_SUCCEED;
50 :
51 1 : user = COLnew(0, TYPE_str, usrstatscnt, TRANSIENT);
52 1 : querycount = COLnew(0, TYPE_lng, usrstatscnt, TRANSIENT);
53 1 : totalticks = COLnew(0, TYPE_lng, usrstatscnt, TRANSIENT);
54 1 : started = COLnew(0, TYPE_timestamp, usrstatscnt, TRANSIENT);
55 1 : finished = COLnew(0, TYPE_timestamp, usrstatscnt, TRANSIENT);
56 1 : maxticks = COLnew(0, TYPE_lng, usrstatscnt, TRANSIENT);
57 1 : maxquery = COLnew(0, TYPE_str, usrstatscnt, TRANSIENT);
58 1 : if (user == NULL || querycount == NULL || totalticks == NULL
59 1 : || started == NULL || finished == NULL || maxquery == NULL
60 1 : || maxticks == NULL) {
61 0 : BBPreclaim(user);
62 0 : BBPreclaim(started);
63 0 : BBPreclaim(querycount);
64 0 : BBPreclaim(totalticks);
65 0 : BBPreclaim(finished);
66 0 : BBPreclaim(maxticks);
67 0 : BBPreclaim(maxquery);
68 0 : throw(MAL, "SYSMONstatistics", SQLSTATE(HY013) MAL_MALLOC_FAIL);
69 : }
70 :
71 1 : MT_lock_set(&mal_delayLock);
72 : // FIXME: what if there are multiple users with ADMIN privilege?
73 7 : for (i = 0; i < usrstatscnt; i++) {
74 : /* We can stop at the first empty entry */
75 6 : if (USRstats[i].username == NULL)
76 : break;
77 :
78 5 : if (BUNappend(user, USRstats[i].username, false) != GDK_SUCCEED) {
79 0 : msg = createException(MAL, "SYSMONstatistics",
80 : "Failed to append 'user'");
81 0 : goto bailout;
82 : }
83 5 : if (BUNappend(querycount, &USRstats[i].querycount, false) != GDK_SUCCEED) {
84 0 : msg = createException(MAL, "SYSMONstatistics",
85 : "Failed to append 'querycount'");
86 0 : goto bailout;
87 : }
88 5 : if (BUNappend(totalticks, &USRstats[i].totalticks, false) != GDK_SUCCEED) {
89 0 : msg = createException(MAL, "SYSMONstatistics",
90 : "Failed to append 'totalticks'");
91 0 : goto bailout;
92 : }
93 : /* convert number of seconds into a timestamp */
94 5 : if (USRstats[i].maxquery != 0) {
95 5 : tsn = timestamp_fromtime(USRstats[i].started);
96 5 : if (is_timestamp_nil(tsn)) {
97 0 : msg = createException(MAL, "SYSMONstatistics",
98 : SQLSTATE(22003)
99 : "failed to convert start time");
100 0 : goto bailout;
101 : }
102 5 : if (BUNappend(started, &tsn, false) != GDK_SUCCEED) {
103 0 : msg = createException(MAL, "SYSMONstatistics",
104 : "Failed to append 'started'");
105 0 : goto bailout;
106 : }
107 :
108 5 : if (USRstats[i].finished == 0) {
109 0 : tsn = timestamp_nil;
110 : } else {
111 5 : tsn = timestamp_fromtime(USRstats[i].finished);
112 5 : if (is_timestamp_nil(tsn)) {
113 0 : msg = createException(MAL, "SYSMONstatistics",
114 : SQLSTATE(22003)
115 : "failed to convert finish time");
116 0 : goto bailout;
117 : }
118 : }
119 5 : if (BUNappend(finished, &tsn, false) != GDK_SUCCEED) {
120 0 : msg = createException(MAL, "SYSMONstatistics",
121 : "Failed to append 'finished'");
122 0 : goto bailout;
123 : }
124 : } else {
125 0 : tsn = timestamp_nil;
126 0 : if (BUNappend(started, &tsn, false) != GDK_SUCCEED) {
127 0 : msg = createException(MAL, "SYSMONstatistics",
128 : "Failed to append 'started'");
129 0 : goto bailout;
130 : }
131 0 : if (BUNappend(finished, &tsn, false) != GDK_SUCCEED) {
132 0 : msg = createException(MAL, "SYSMONstatistics",
133 : "Failed to append 'finished'");
134 0 : goto bailout;
135 : }
136 : }
137 :
138 5 : if (BUNappend(maxticks, &USRstats[i].maxticks, false) != GDK_SUCCEED) {
139 0 : msg = createException(MAL, "SYSMONstatistics",
140 : "Failed to append 'maxticks'");
141 0 : goto bailout;
142 : }
143 5 : if (USRstats[i].maxquery == 0) {
144 0 : if (BUNappend(maxquery, "none", false) != GDK_SUCCEED) {
145 0 : msg = createException(MAL, "SYSMONstatistics",
146 : "Failed to append 'maxquery' 1");
147 0 : goto bailout;
148 : }
149 : } else {
150 5 : if (BUNappend(maxquery, USRstats[i].maxquery, false) != GDK_SUCCEED) {
151 0 : msg = createException(MAL, "SYSMONstatistics",
152 : "Failed to append 'maxquery' 2");
153 0 : goto bailout;
154 : }
155 : }
156 : }
157 1 : MT_lock_unset(&mal_delayLock);
158 1 : *u = user->batCacheid;
159 1 : BBPkeepref(user);
160 1 : *c = querycount->batCacheid;
161 1 : BBPkeepref(querycount);
162 1 : *t = totalticks->batCacheid;
163 1 : BBPkeepref(totalticks);
164 1 : *s = started->batCacheid;
165 1 : BBPkeepref(started);
166 1 : *f = finished->batCacheid;
167 1 : BBPkeepref(finished);
168 1 : *m = maxticks->batCacheid;
169 1 : BBPkeepref(maxticks);
170 1 : *q = maxquery->batCacheid;
171 1 : BBPkeepref(maxquery);
172 1 : return MAL_SUCCEED;
173 :
174 0 : bailout:
175 0 : MT_lock_unset(&mal_delayLock);
176 0 : BBPunfix(user->batCacheid);
177 0 : BBPunfix(querycount->batCacheid);
178 0 : BBPunfix(totalticks->batCacheid);
179 0 : BBPunfix(started->batCacheid);
180 0 : BBPunfix(finished->batCacheid);
181 0 : BBPunfix(maxticks->batCacheid);
182 0 : BBPunfix(maxquery->batCacheid);
183 0 : return msg;
184 : }
185 :
186 : static str
187 36 : SYSMONqueue(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
188 : {
189 36 : (void) mb;
190 :
191 : /* Temporary hack not allowing MAL clients (mclient -lmal)
192 : to use this function */
193 36 : if (cntxt->sqlcontext == NULL)
194 0 : throw(MAL, "SYSMONqueue",
195 : SQLSTATE(42000) "Calling from a mclient -lmal.");
196 :
197 36 : bat *t = getArgReference_bat(stk, pci, 0),
198 36 : *s = getArgReference_bat(stk, pci, 1),
199 36 : *u = getArgReference_bat(stk, pci, 2),
200 36 : *sd = getArgReference_bat(stk, pci, 3),
201 36 : *ss = getArgReference_bat(stk, pci, 4),
202 36 : *q = getArgReference_bat(stk, pci, 5),
203 36 : *f = getArgReference_bat(stk, pci, 6),
204 36 : *w = getArgReference_bat(stk, pci, 7),
205 36 : *m = getArgReference_bat(stk, pci, 8);
206 :
207 36 : BUN sz = (BUN) qsize;
208 36 : BAT *tag = COLnew(0, TYPE_lng, sz, TRANSIENT),
209 36 : *sessionid = COLnew(0, TYPE_int, sz, TRANSIENT),
210 36 : *user = COLnew(0, TYPE_str, sz, TRANSIENT),
211 36 : *started = COLnew(0, TYPE_timestamp, sz, TRANSIENT),
212 36 : *status = COLnew(0, TYPE_str, sz, TRANSIENT),
213 36 : *query = COLnew(0, TYPE_str, sz, TRANSIENT),
214 36 : *finished = COLnew(0, TYPE_timestamp, sz, TRANSIENT),
215 36 : *workers = COLnew(0, TYPE_int, sz, TRANSIENT),
216 36 : *memory = COLnew(0, TYPE_int, sz, TRANSIENT);
217 :
218 36 : lng qtag;
219 36 : int wrk, mem;
220 36 : timestamp tsn;
221 36 : str userqueue = NULL, msg = MAL_SUCCEED;
222 :
223 : /* If pci->argc == 10, arg 9 type is a string */
224 36 : bool getall = false, admin = pci->argc == 10 ? true : false;
225 36 : if (admin) {
226 9 : assert(getArgType(mb, pci, 9) == TYPE_str);
227 9 : userqueue = *getArgReference_str(stk, pci, 9);
228 9 : if (strcmp("ALL", userqueue) == 0)
229 4 : getall = true;
230 : }
231 :
232 36 : if (tag == NULL || sessionid == NULL || user == NULL ||
233 36 : query == NULL || started == NULL || finished == NULL ||
234 36 : workers == NULL || memory == NULL) {
235 0 : BBPreclaim(tag);
236 0 : BBPreclaim(sessionid);
237 0 : BBPreclaim(user);
238 0 : BBPreclaim(started);
239 0 : BBPreclaim(status);
240 0 : BBPreclaim(query);
241 0 : BBPreclaim(finished);
242 0 : BBPreclaim(workers);
243 0 : BBPreclaim(memory);
244 0 : throw(MAL, "SYSMONqueue", SQLSTATE(HY001) MAL_MALLOC_FAIL);
245 : }
246 :
247 36 : MT_lock_set(&mal_delayLock);
248 1556 : 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 1520 : if (QRYqueue[i].query &&
254 1434 : ((admin && getall) ||
255 40 : (admin && strcmp(QRYqueue[i].username, userqueue) == 0) ||
256 : ((admin == false)
257 1362 : && strcmp(QRYqueue[i].username, cntxt->username) == 0))) {
258 1390 : qtag = (lng) QRYqueue[i].tag;
259 2780 : if (BUNappend(tag, &qtag, false) != GDK_SUCCEED ||
260 2780 : BUNappend(user, QRYqueue[i].username, false) != GDK_SUCCEED ||
261 1390 : BUNappend(sessionid, &(QRYqueue[i].idx), false) != GDK_SUCCEED
262 1390 : || BUNappend(query, QRYqueue[i].query, false) != GDK_SUCCEED
263 1390 : || BUNappend(status, QRYqueue[i].status, false) != GDK_SUCCEED)
264 0 : goto bailout;
265 : /* convert number of seconds into a timestamp */
266 1390 : tsn = timestamp_fromtime(QRYqueue[i].start);
267 1390 : if (is_timestamp_nil(tsn)) {
268 0 : msg = createException(MAL, "SYSMONqueue",
269 : SQLSTATE(22003) "Cannot convert time.");
270 0 : goto bailout;
271 : }
272 1390 : if (BUNappend(started, &tsn, false) != GDK_SUCCEED)
273 0 : goto bailout;
274 1390 : if (QRYqueue[i].finished == 0)
275 38 : tsn = timestamp_nil;
276 : else {
277 1352 : tsn = timestamp_fromtime(QRYqueue[i].finished);
278 1352 : 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 1390 : if (BUNappend(finished, &tsn, false) != GDK_SUCCEED)
286 0 : goto bailout;
287 1390 : if (QRYqueue[i].mb)
288 38 : wrk = (int) ATOMIC_GET(&QRYqueue[i].mb->workers);
289 : else
290 1352 : wrk = QRYqueue[i].workers;
291 1390 : if (QRYqueue[i].mb)
292 38 : mem = (int) (1 + QRYqueue[i].mb->memory / LL_CONSTANT(1048576));
293 : else
294 1352 : mem = QRYqueue[i].memory;
295 2780 : if (BUNappend(workers, &wrk, false) != GDK_SUCCEED ||
296 1390 : BUNappend(memory, &mem, false) != GDK_SUCCEED)
297 0 : goto bailout;
298 : }
299 : }
300 36 : MT_lock_unset(&mal_delayLock);
301 36 : *t = tag->batCacheid;
302 36 : BBPkeepref(tag);
303 36 : *s = sessionid->batCacheid;
304 36 : BBPkeepref(sessionid);
305 36 : *u = user->batCacheid;
306 36 : BBPkeepref(user);
307 36 : *sd = started->batCacheid;
308 36 : BBPkeepref(started);
309 36 : *ss = status->batCacheid;
310 36 : BBPkeepref(status);
311 36 : *q = query->batCacheid;
312 36 : BBPkeepref(query);
313 36 : *f = finished->batCacheid;
314 36 : BBPkeepref(finished);
315 36 : *w = workers->batCacheid;
316 36 : BBPkeepref(workers);
317 36 : *m = memory->batCacheid;
318 36 : BBPkeepref(memory);
319 36 : return MAL_SUCCEED;
320 :
321 0 : bailout:
322 0 : MT_lock_unset(&mal_delayLock);
323 0 : BBPunfix(tag->batCacheid);
324 0 : BBPunfix(sessionid->batCacheid);
325 0 : BBPunfix(user->batCacheid);
326 0 : BBPunfix(started->batCacheid);
327 0 : BBPunfix(status->batCacheid);
328 0 : BBPunfix(query->batCacheid);
329 0 : BBPunfix(finished->batCacheid);
330 0 : BBPunfix(workers->batCacheid);
331 0 : BBPunfix(memory->batCacheid);
332 0 : return msg ? msg : createException(MAL, "SYSMONqueue",
333 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
334 : }
335 :
336 : static str
337 1 : SYSMONpause(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
338 : {
339 1 : (void) mb;
340 :
341 : /* Temporary hack not allowing MAL clients (mclient -lmal)
342 : to use this function */
343 1 : if (cntxt->sqlcontext == NULL)
344 0 : throw(MAL, "SYSMONpause",
345 : SQLSTATE(42000) "Calling from a mclient -lmal.");
346 :
347 1 : oid tag = 0;
348 1 : size_t i = 0;
349 1 : bool paused = false;
350 1 : bool admin = pci->argc == 3 ? true : false;
351 1 : int owner = -1;
352 :
353 1 : assert(getArgType(mb, pci, 1) == TYPE_lng);
354 :
355 1 : if ((tag = (oid) *getArgReference_lng(stk, pci, 1)) < 1)
356 0 : throw(MAL, "SYSMONpause", SQLSTATE(22003) "Tag must be positive.");
357 1 : if (tag == cntxt->curprg->def->tag)
358 0 : throw(MAL, "SYSMONpause",
359 : SQLSTATE(HY009) "SYSMONpause cannot pause itself.");
360 :
361 1 : MT_lock_set(&mal_delayLock);
362 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 324 : LIB_STARTUP_FUNC(init_sysmon_mal)
532 324 : { mal_module("sysmon", NULL, sysmon_init_funcs); }
|