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); }
|