Line data Source code
1 : /*
2 : * SPDX-License-Identifier: MPL-2.0
3 : *
4 : * This Source Code Form is subject to the terms of the Mozilla Public
5 : * License, v. 2.0. If a copy of the MPL was not distributed with this
6 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
7 : *
8 : * Copyright 2024 MonetDB Foundation;
9 : * Copyright August 2008 - 2023 MonetDB B.V.;
10 : * Copyright 1997 - July 2008 CWI.
11 : */
12 :
13 : #include "monetdb_config.h"
14 : #include "mal.h"
15 : #include "mal_interpreter.h"
16 : #include "mal_authorize.h"
17 : #include "mal_client.h"
18 : #include "mal_runtime.h"
19 : #include "gdk_time.h"
20 : #include "mal_exception.h"
21 : #include "mal_internal.h"
22 :
23 : /* (c) M.L. Kersten
24 : * The queries currently in execution are returned to the front-end for managing expensive ones.
25 : */
26 :
27 : static str
28 1 : SYSMONstatistics(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
29 : {
30 1 : (void) mb;
31 :
32 : /* Temporary hack not allowing MAL clients (mclient -lmal)
33 : to use this function */
34 1 : if (cntxt->sqlcontext == NULL)
35 0 : throw(MAL, "SYSMONstatistics",
36 : SQLSTATE(42000) "Calling from a mclient -lmal.");
37 :
38 1 : BAT *user, *querycount, *totalticks, *started, *finished, *maxquery,
39 : *maxticks;
40 1 : bat *u = getArgReference_bat(stk, pci, 0);
41 1 : bat *c = getArgReference_bat(stk, pci, 1);
42 1 : bat *t = getArgReference_bat(stk, pci, 2);
43 1 : bat *s = getArgReference_bat(stk, pci, 3);
44 1 : bat *f = getArgReference_bat(stk, pci, 4);
45 1 : bat *m = getArgReference_bat(stk, pci, 5);
46 1 : bat *q = getArgReference_bat(stk, pci, 6);
47 1 : size_t i;
48 1 : timestamp tsn = timestamp_nil;
49 1 : str msg = MAL_SUCCEED;
50 :
51 1 : user = COLnew(0, TYPE_str, usrstatscnt, TRANSIENT);
52 1 : querycount = COLnew(0, TYPE_lng, usrstatscnt, TRANSIENT);
53 1 : totalticks = COLnew(0, TYPE_lng, usrstatscnt, TRANSIENT);
54 1 : started = COLnew(0, TYPE_timestamp, usrstatscnt, TRANSIENT);
55 1 : finished = COLnew(0, TYPE_timestamp, usrstatscnt, TRANSIENT);
56 1 : maxticks = COLnew(0, TYPE_lng, usrstatscnt, TRANSIENT);
57 1 : maxquery = COLnew(0, TYPE_str, usrstatscnt, TRANSIENT);
58 1 : if (user == NULL || querycount == NULL || totalticks == NULL
59 1 : || started == NULL || finished == NULL || maxquery == NULL
60 1 : || maxticks == NULL) {
61 0 : BBPreclaim(user);
62 0 : BBPreclaim(started);
63 0 : BBPreclaim(querycount);
64 0 : BBPreclaim(totalticks);
65 0 : BBPreclaim(finished);
66 0 : BBPreclaim(maxticks);
67 0 : BBPreclaim(maxquery);
68 0 : throw(MAL, "SYSMONstatistics", SQLSTATE(HY013) MAL_MALLOC_FAIL);
69 : }
70 :
71 1 : MT_lock_set(&mal_delayLock);
72 : // FIXME: what if there are multiple users with ADMIN privilege?
73 7 : for (i = 0; i < usrstatscnt; i++) {
74 : /* We can stop at the first empty entry */
75 6 : if (USRstats[i].username == NULL)
76 : break;
77 :
78 5 : if (BUNappend(user, USRstats[i].username, false) != GDK_SUCCEED) {
79 0 : msg = createException(MAL, "SYSMONstatistics",
80 : "Failed to append 'user'");
81 0 : goto bailout;
82 : }
83 5 : if (BUNappend(querycount, &USRstats[i].querycount, false) != GDK_SUCCEED) {
84 0 : msg = createException(MAL, "SYSMONstatistics",
85 : "Failed to append 'querycount'");
86 0 : goto bailout;
87 : }
88 5 : if (BUNappend(totalticks, &USRstats[i].totalticks, false) != GDK_SUCCEED) {
89 0 : msg = createException(MAL, "SYSMONstatistics",
90 : "Failed to append 'totalticks'");
91 0 : goto bailout;
92 : }
93 : /* convert number of seconds into a timestamp */
94 5 : if (USRstats[i].maxquery != 0) {
95 5 : tsn = timestamp_fromtime(USRstats[i].started);
96 5 : if (is_timestamp_nil(tsn)) {
97 0 : msg = createException(MAL, "SYSMONstatistics",
98 : SQLSTATE(22003)
99 : "failed to convert start time");
100 0 : goto bailout;
101 : }
102 5 : if (BUNappend(started, &tsn, false) != GDK_SUCCEED) {
103 0 : msg = createException(MAL, "SYSMONstatistics",
104 : "Failed to append 'started'");
105 0 : goto bailout;
106 : }
107 :
108 5 : if (USRstats[i].finished == 0) {
109 0 : tsn = timestamp_nil;
110 : } else {
111 5 : tsn = timestamp_fromtime(USRstats[i].finished);
112 5 : if (is_timestamp_nil(tsn)) {
113 0 : msg = createException(MAL, "SYSMONstatistics",
114 : SQLSTATE(22003)
115 : "failed to convert finish time");
116 0 : goto bailout;
117 : }
118 : }
119 5 : if (BUNappend(finished, &tsn, false) != GDK_SUCCEED) {
120 0 : msg = createException(MAL, "SYSMONstatistics",
121 : "Failed to append 'finished'");
122 0 : goto bailout;
123 : }
124 : } else {
125 0 : tsn = timestamp_nil;
126 0 : if (BUNappend(started, &tsn, false) != GDK_SUCCEED) {
127 0 : msg = createException(MAL, "SYSMONstatistics",
128 : "Failed to append 'started'");
129 0 : goto bailout;
130 : }
131 0 : if (BUNappend(finished, &tsn, false) != GDK_SUCCEED) {
132 0 : msg = createException(MAL, "SYSMONstatistics",
133 : "Failed to append 'finished'");
134 0 : goto bailout;
135 : }
136 : }
137 :
138 5 : if (BUNappend(maxticks, &USRstats[i].maxticks, false) != GDK_SUCCEED) {
139 0 : msg = createException(MAL, "SYSMONstatistics",
140 : "Failed to append 'maxticks'");
141 0 : goto bailout;
142 : }
143 5 : if (USRstats[i].maxquery == 0) {
144 0 : if (BUNappend(maxquery, "none", false) != GDK_SUCCEED) {
145 0 : msg = createException(MAL, "SYSMONstatistics",
146 : "Failed to append 'maxquery' 1");
147 0 : goto bailout;
148 : }
149 : } else {
150 5 : if (BUNappend(maxquery, USRstats[i].maxquery, false) != GDK_SUCCEED) {
151 0 : msg = createException(MAL, "SYSMONstatistics",
152 : "Failed to append 'maxquery' 2");
153 0 : goto bailout;
154 : }
155 : }
156 : }
157 1 : MT_lock_unset(&mal_delayLock);
158 1 : *u = user->batCacheid;
159 1 : BBPkeepref(user);
160 1 : *c = querycount->batCacheid;
161 1 : BBPkeepref(querycount);
162 1 : *t = totalticks->batCacheid;
163 1 : BBPkeepref(totalticks);
164 1 : *s = started->batCacheid;
165 1 : BBPkeepref(started);
166 1 : *f = finished->batCacheid;
167 1 : BBPkeepref(finished);
168 1 : *m = maxticks->batCacheid;
169 1 : BBPkeepref(maxticks);
170 1 : *q = maxquery->batCacheid;
171 1 : BBPkeepref(maxquery);
172 1 : return MAL_SUCCEED;
173 :
174 0 : bailout:
175 0 : MT_lock_unset(&mal_delayLock);
176 0 : BBPunfix(user->batCacheid);
177 0 : BBPunfix(querycount->batCacheid);
178 0 : BBPunfix(totalticks->batCacheid);
179 0 : BBPunfix(started->batCacheid);
180 0 : BBPunfix(finished->batCacheid);
181 0 : BBPunfix(maxticks->batCacheid);
182 0 : BBPunfix(maxquery->batCacheid);
183 0 : return msg;
184 : }
185 :
186 : static str
187 30 : SYSMONqueue(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
188 : {
189 30 : (void) mb;
190 :
191 : /* Temporary hack not allowing MAL clients (mclient -lmal)
192 : to use this function */
193 30 : if (cntxt->sqlcontext == NULL)
194 0 : throw(MAL, "SYSMONqueue",
195 : SQLSTATE(42000) "Calling from a mclient -lmal.");
196 :
197 30 : bat *t = getArgReference_bat(stk, pci, 0),
198 30 : *s = getArgReference_bat(stk, pci, 1),
199 30 : *u = getArgReference_bat(stk, pci, 2),
200 30 : *sd = getArgReference_bat(stk, pci, 3),
201 30 : *ss = getArgReference_bat(stk, pci, 4),
202 30 : *q = getArgReference_bat(stk, pci, 5),
203 30 : *f = getArgReference_bat(stk, pci, 6),
204 30 : *w = getArgReference_bat(stk, pci, 7),
205 30 : *m = getArgReference_bat(stk, pci, 8);
206 :
207 30 : BUN sz = (BUN) qsize;
208 30 : BAT *tag = COLnew(0, TYPE_lng, sz, TRANSIENT),
209 31 : *sessionid = COLnew(0, TYPE_int, sz, TRANSIENT),
210 31 : *user = COLnew(0, TYPE_str, sz, TRANSIENT),
211 31 : *started = COLnew(0, TYPE_timestamp, sz, TRANSIENT),
212 31 : *status = COLnew(0, TYPE_str, sz, TRANSIENT),
213 30 : *query = COLnew(0, TYPE_str, sz, TRANSIENT),
214 31 : *finished = COLnew(0, TYPE_timestamp, sz, TRANSIENT),
215 31 : *workers = COLnew(0, TYPE_int, sz, TRANSIENT),
216 31 : *memory = COLnew(0, TYPE_int, sz, TRANSIENT);
217 :
218 31 : lng qtag;
219 31 : int wrk, mem;
220 31 : timestamp tsn;
221 31 : str userqueue = NULL, msg = MAL_SUCCEED;
222 :
223 : /* If pci->argc == 10, arg 9 type is a string */
224 31 : bool getall = false, admin = pci->argc == 10 ? true : false;
225 31 : if (admin) {
226 9 : assert(getArgType(mb, pci, 9) == TYPE_str);
227 9 : userqueue = *getArgReference_str(stk, pci, 9);
228 9 : if (strcmp("ALL", userqueue) == 0)
229 4 : getall = true;
230 : }
231 :
232 31 : if (tag == NULL || sessionid == NULL || user == NULL ||
233 31 : query == NULL || started == NULL || finished == NULL ||
234 31 : workers == NULL || memory == NULL) {
235 0 : BBPreclaim(tag);
236 0 : BBPreclaim(sessionid);
237 0 : BBPreclaim(user);
238 0 : BBPreclaim(started);
239 0 : BBPreclaim(status);
240 0 : BBPreclaim(query);
241 0 : BBPreclaim(finished);
242 0 : BBPreclaim(workers);
243 0 : BBPreclaim(memory);
244 0 : throw(MAL, "SYSMONqueue", SQLSTATE(HY001) MAL_MALLOC_FAIL);
245 : }
246 :
247 31 : MT_lock_set(&mal_delayLock);
248 1295 : for (size_t i = 0; i < qsize; i++) {
249 : /* Filtering the queries according to how SYSMONqueue was called.
250 : Either:
251 : SYSADMIN calls sys.queue("ALL") or SYSADMIN calls sys.queue(USER)
252 : or any user calls sys.queue() to retrieve its own queue. */
253 1264 : if (QRYqueue[i].query &&
254 1255 : ((admin && getall) ||
255 40 : (admin && strcmp(QRYqueue[i].username, userqueue) == 0) ||
256 : ((admin == false)
257 1183 : && strcmp(QRYqueue[i].username, cntxt->username) == 0))) {
258 1211 : qtag = (lng) QRYqueue[i].tag;
259 2422 : if (BUNappend(tag, &qtag, false) != GDK_SUCCEED ||
260 2422 : BUNappend(user, QRYqueue[i].username, false) != GDK_SUCCEED ||
261 1211 : BUNappend(sessionid, &(QRYqueue[i].idx), false) != GDK_SUCCEED
262 1211 : || BUNappend(query, QRYqueue[i].query, false) != GDK_SUCCEED
263 1211 : || BUNappend(status, QRYqueue[i].status, false) != GDK_SUCCEED)
264 0 : goto bailout;
265 : /* convert number of seconds into a timestamp */
266 1211 : tsn = timestamp_fromtime(QRYqueue[i].start);
267 1211 : if (is_timestamp_nil(tsn)) {
268 0 : msg = createException(MAL, "SYSMONqueue",
269 : SQLSTATE(22003) "Cannot convert time.");
270 0 : goto bailout;
271 : }
272 1211 : if (BUNappend(started, &tsn, false) != GDK_SUCCEED)
273 0 : goto bailout;
274 1211 : if (QRYqueue[i].finished == 0)
275 33 : tsn = timestamp_nil;
276 : else {
277 1178 : tsn = timestamp_fromtime(QRYqueue[i].finished);
278 1178 : if (is_timestamp_nil(tsn)) {
279 0 : msg = createException(MAL, "SYSMONqueue",
280 : SQLSTATE(22003)
281 : "Cannot convert time.");
282 0 : goto bailout;
283 : }
284 : }
285 1211 : if (BUNappend(finished, &tsn, false) != GDK_SUCCEED)
286 0 : goto bailout;
287 1211 : if (QRYqueue[i].mb)
288 33 : wrk = (int) ATOMIC_GET(&QRYqueue[i].mb->workers);
289 : else
290 1178 : wrk = QRYqueue[i].workers;
291 1211 : if (QRYqueue[i].mb)
292 33 : mem = (int) (1 + QRYqueue[i].mb->memory / LL_CONSTANT(1048576));
293 : else
294 1178 : mem = QRYqueue[i].memory;
295 2422 : if (BUNappend(workers, &wrk, false) != GDK_SUCCEED ||
296 1211 : BUNappend(memory, &mem, false) != GDK_SUCCEED)
297 0 : goto bailout;
298 : }
299 : }
300 31 : MT_lock_unset(&mal_delayLock);
301 31 : *t = tag->batCacheid;
302 31 : BBPkeepref(tag);
303 31 : *s = sessionid->batCacheid;
304 31 : BBPkeepref(sessionid);
305 31 : *u = user->batCacheid;
306 31 : BBPkeepref(user);
307 31 : *sd = started->batCacheid;
308 31 : BBPkeepref(started);
309 31 : *ss = status->batCacheid;
310 31 : BBPkeepref(status);
311 31 : *q = query->batCacheid;
312 31 : BBPkeepref(query);
313 31 : *f = finished->batCacheid;
314 31 : BBPkeepref(finished);
315 31 : *w = workers->batCacheid;
316 31 : BBPkeepref(workers);
317 31 : *m = memory->batCacheid;
318 31 : BBPkeepref(memory);
319 31 : return MAL_SUCCEED;
320 :
321 0 : bailout:
322 0 : MT_lock_unset(&mal_delayLock);
323 0 : BBPunfix(tag->batCacheid);
324 0 : BBPunfix(sessionid->batCacheid);
325 0 : BBPunfix(user->batCacheid);
326 0 : BBPunfix(started->batCacheid);
327 0 : BBPunfix(status->batCacheid);
328 0 : BBPunfix(query->batCacheid);
329 0 : BBPunfix(finished->batCacheid);
330 0 : BBPunfix(workers->batCacheid);
331 0 : BBPunfix(memory->batCacheid);
332 0 : return msg ? msg : createException(MAL, "SYSMONqueue",
333 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
334 : }
335 :
336 : static str
337 1 : SYSMONpause(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
338 : {
339 1 : (void) mb;
340 :
341 : /* Temporary hack not allowing MAL clients (mclient -lmal)
342 : to use this function */
343 1 : if (cntxt->sqlcontext == NULL)
344 0 : throw(MAL, "SYSMONpause",
345 : SQLSTATE(42000) "Calling from a mclient -lmal.");
346 :
347 1 : oid tag = 0;
348 1 : size_t i = 0;
349 1 : bool paused = false;
350 1 : bool admin = pci->argc == 3 ? true : false;
351 1 : int owner = -1;
352 :
353 1 : assert(getArgType(mb, pci, 1) == TYPE_lng);
354 :
355 1 : if ((tag = (oid) *getArgReference_lng(stk, pci, 1)) < 1)
356 0 : throw(MAL, "SYSMONpause", SQLSTATE(22003) "Tag must be positive.");
357 1 : if (tag == cntxt->curprg->def->tag)
358 0 : throw(MAL, "SYSMONpause",
359 : SQLSTATE(HY009) "SYSMONpause cannot pause itself.");
360 :
361 1 : MT_lock_set(&mal_delayLock);
362 4 : for (i = 0; i < qsize; i++) {
363 3 : if (QRYqueue[i].tag == tag) {
364 1 : if (QRYqueue[i].stk) {
365 1 : if (admin
366 0 : || (owner = strcmp(QRYqueue[i].username, cntxt->username)) == 0) {
367 1 : QRYqueue[i].stk->status = 'p';
368 1 : QRYqueue[i].status = "paused";
369 1 : paused = true;
370 : }
371 : /* tag found, but either not admin or user cannot
372 : pause that query with OID ctag */
373 : break;
374 : }
375 : /* tag found, but query could have already finished...
376 : stack is 0 by this time.. potential problem?
377 : using MAL fcn alarm.sleep exposes the above */
378 : break;
379 : }
380 : }
381 1 : MT_lock_unset(&mal_delayLock);
382 :
383 1 : return paused ? MAL_SUCCEED :
384 0 : i == qsize ? createException(MAL, "SYSMONpause",
385 : SQLSTATE(42 S12) "Tag " OIDFMT
386 : " unknown.",
387 0 : tag) : createException(MAL,
388 : "SYSMONpause",
389 : SQLSTATE(HY009)
390 : "Tag " OIDFMT
391 : " unknown to the user.",
392 : tag);
393 : }
394 :
395 : static str
396 1 : SYSMONresume(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
397 : {
398 1 : (void) mb;
399 :
400 : /* Temporary hack not allowing MAL clients (mclient -lmal)
401 : to use this function */
402 1 : if (cntxt->sqlcontext == NULL)
403 0 : throw(MAL, "SYSMONresume",
404 : SQLSTATE(42000) "Calling from a mclient -lmal.");
405 :
406 1 : oid tag = 0;
407 1 : size_t i = 0;
408 1 : bool paused = false;
409 1 : bool admin = pci->argc == 3 ? true : false;
410 1 : int owner = -1;
411 :
412 1 : assert(getArgType(mb, pci, 1) == TYPE_lng);
413 :
414 1 : if ((tag = (oid) *getArgReference_lng(stk, pci, 1)) < 1)
415 0 : throw(MAL, "SYSMONresume", SQLSTATE(22003) "Tag must be positive.");
416 1 : if (tag == cntxt->curprg->def->tag)
417 0 : throw(MAL, "SYSMONresume",
418 : SQLSTATE(HY009) "SYSMONresume cannot pause itself.");
419 :
420 1 : MT_lock_set(&mal_delayLock);
421 4 : for (i = 0; i < qsize; i++) {
422 3 : if (QRYqueue[i].tag == tag) {
423 1 : if (QRYqueue[i].stk) {
424 1 : if (admin
425 0 : || (owner = strcmp(QRYqueue[i].username, cntxt->username)) == 0) {
426 1 : QRYqueue[i].stk->status = 0;
427 1 : QRYqueue[i].status = "running";
428 1 : paused = true;
429 : }
430 : /* tag found, but either not admin or user cannot
431 : pause that query with OID ctag */
432 : break;
433 : }
434 : /* tag found, but query could have already finished...
435 : stack is 0 by this time.. potential problem?
436 : using MAL fcn alarm.sleep exposes the above */
437 : break;
438 : }
439 : }
440 1 : MT_lock_unset(&mal_delayLock);
441 :
442 1 : return paused ? MAL_SUCCEED :
443 0 : i == qsize ? createException(MAL, "SYSMONresume",
444 : SQLSTATE(42 S12) "Tag " OIDFMT
445 : " unknown.",
446 0 : tag) : createException(MAL,
447 : "SYSMONresume",
448 : SQLSTATE(HY009)
449 : "Tag " OIDFMT
450 : " unknown to the user.",
451 : tag);
452 : }
453 :
454 : static str
455 1 : SYSMONstop(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
456 : {
457 1 : (void) mb;
458 :
459 : /* Temporary hack not allowing MAL clients (mclient -lmal)
460 : to use this function */
461 1 : if (cntxt->sqlcontext == NULL)
462 0 : throw(MAL, "SYSMONstop",
463 : SQLSTATE(42000) "Calling from a mclient -lmal.");
464 :
465 1 : oid tag = 0;
466 1 : size_t i = 0;
467 1 : bool paused = false;
468 1 : bool admin = pci->argc == 3 ? true : false;
469 1 : int owner = -1;
470 :
471 1 : assert(getArgType(mb, pci, 1) == TYPE_lng);
472 :
473 1 : if ((tag = (oid) *getArgReference_lng(stk, pci, 1)) < 1)
474 0 : throw(MAL, "SYSMONstop", SQLSTATE(22003) "Tag must be positive.");
475 1 : if (tag == cntxt->curprg->def->tag)
476 0 : throw(MAL, "SYSMONstop",
477 : SQLSTATE(HY009) "SYSMONstop cannot pause itself.");
478 :
479 1 : MT_lock_set(&mal_delayLock);
480 9 : for (i = 0; i < qsize; i++) {
481 8 : if (QRYqueue[i].tag == tag) {
482 1 : if (QRYqueue[i].stk) {
483 1 : if (admin
484 0 : || (owner = strcmp(QRYqueue[i].username, cntxt->username)) == 0) {
485 1 : QRYqueue[i].stk->status = 'q';
486 1 : QRYqueue[i].status = "stopping";
487 1 : paused = true;
488 : }
489 : /* tag found, but either not admin or user cannot
490 : pause that query with OID ctag */
491 : break;
492 : }
493 : /* tag found, but query could have already finished...
494 : stack is 0 by this time.. potential problem?
495 : using MAL fcn alarm.sleep exposes the above */
496 : break;
497 : }
498 : }
499 1 : MT_lock_unset(&mal_delayLock);
500 :
501 1 : return paused ? MAL_SUCCEED :
502 0 : i == qsize ? createException(MAL, "SYSMONstop",
503 : SQLSTATE(42 S12) "Tag " OIDFMT
504 : " unknown.",
505 0 : tag) : createException(MAL,
506 : "SYSMONstop",
507 : SQLSTATE(HY009)
508 : "Tag " OIDFMT
509 : " unknown to the user.",
510 : tag);
511 : }
512 :
513 : #include "mel.h"
514 : mel_func sysmon_init_funcs[] = {
515 : pattern("sysmon", "pause", SYSMONpause, true, "Suspend query execution with OID id", args(0, 1, arg("id", lng))),
516 : pattern("sysmon", "pause", SYSMONpause, true, "Sysadmin call, suspend query execution with OID id belonging to user", args(0, 2, arg("id", lng), arg("user", str))),
517 : pattern("sysmon", "resume", SYSMONresume, true, "Resume query execution with OID id", args(0, 1, arg("id", lng))),
518 : pattern("sysmon", "resume", SYSMONresume, true, "Sysadmin call, resume query execution with OID id belonging to user", args(0, 2, arg("id", lng), arg("user", str))),
519 : pattern("sysmon", "stop", SYSMONstop, true, "Stop query execution with OID id", args(0, 1, arg("id", lng))),
520 : pattern("sysmon", "stop", SYSMONstop, true, "Sysadmin call, stop query execution with OID id belonging to user", args(0, 2, arg("id", lng), arg("user", str))),
521 : pattern("sysmon", "queue", SYSMONqueue, false, "A queue of queries that are currently being executed or recently finished", args(9, 9, batarg("tag", lng), batarg("sessionid", int), batarg("user", str), batarg("started", timestamp), batarg("status", str), batarg("query", str), batarg("finished", timestamp), batarg("workers", int), batarg("memory", int))),
522 : pattern("sysmon", "queue", SYSMONqueue, false, "Sysadmin call, to see either the global queue or user queue of queries that are currently being executed or recently finished", args(9, 10, batarg("tag", lng), batarg("sessionid", int), batarg("user", str), batarg("started", timestamp), batarg("status", str), batarg("query", str), batarg("finished", timestamp), batarg("workers", int), batarg("memory", int), arg("user", str))),
523 : pattern("sysmon", "user_statistics", SYSMONstatistics, false, "", args(7, 7, batarg("user", str), batarg("querycount", lng), batarg("totalticks", lng), batarg("started", timestamp), batarg("finished", timestamp), batarg("maxticks", lng), batarg("maxquery", str))),
524 : { .imp=NULL }
525 : };
526 : #include "mal_import.h"
527 : #ifdef _MSC_VER
528 : #undef read
529 : #pragma section(".CRT$XCU",read)
530 : #endif
531 334 : LIB_STARTUP_FUNC(init_sysmon_mal)
532 334 : { mal_module("sysmon", NULL, sysmon_init_funcs); }
|