LCOV - code coverage report
Current view: top level - monetdb5/modules/mal - clients.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 300 584 51.4 %
Date: 2021-10-13 02:24:04 Functions: 27 41 65.9 %

          Line data    Source code
       1             : /*
       2             :  * This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0.  If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       5             :  *
       6             :  * Copyright 1997 - July 2008 CWI, August 2008 - 2021 MonetDB B.V.
       7             :  */
       8             : 
       9             : /*
      10             :  * author Martin Kersten, Fabian Groffen
      11             :  * Client Management
      12             :  * Each online client is represented with an entry in the clients table.
      13             :  * The client may inspect his record at run-time and partially change its properties.
      14             :  * The administrator sees all client records and has the right to adjust global properties.
      15             :  */
      16             : 
      17             : 
      18             : #include "monetdb_config.h"
      19             : #include "clients.h"
      20             : #include "mcrypt.h"
      21             : #include "mal_scenario.h"
      22             : #include "mal_instruction.h"
      23             : #include "mal_runtime.h"
      24             : #include "mal_client.h"
      25             : #include "mal_authorize.h"
      26             : #include "mal_internal.h"
      27             : #include "opt_pipes.h"
      28             : #include "gdk_time.h"
      29             : 
      30             : static int
      31           1 : pseudo(bat *ret, BAT *b, str X1,str X2) {
      32             :         char buf[BUFSIZ];
      33           1 :         snprintf(buf,BUFSIZ,"%s_%s", X1,X2);
      34           1 :         if (BBPindex(buf) <= 0 && BBPrename(b->batCacheid, buf) != 0)
      35             :                 return -1;
      36           1 :         if (BATroles(b,X2) != GDK_SUCCEED)
      37             :                 return -1;
      38           1 :         *ret = b->batCacheid;
      39           1 :         BBPkeepref(*ret);
      40           1 :         return 0;
      41             : }
      42             : 
      43             : static str
      44           1 : CLTsetListing(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
      45             : {
      46             :         (void) mb;
      47           1 :         *getArgReference_int(stk,pci,0) = cntxt->listing;
      48           1 :         cntxt->listing = *getArgReference_int(stk,pci,1);
      49           1 :         return MAL_SUCCEED;
      50             : }
      51             : 
      52             : static str
      53           1 : CLTgetClientId(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
      54             : {
      55             :         (void) mb;
      56           1 :         if(cntxt - mal_clients < 0 || cntxt - mal_clients >= MAL_MAXCLIENTS)
      57           0 :                 throw(MAL, "clients.getClientId", "Illegal client index");
      58           1 :         *getArgReference_int(stk,pci,0) = (int) (cntxt - mal_clients);
      59           1 :         return MAL_SUCCEED;
      60             : }
      61             : 
      62             : static str
      63           0 : CLTgetScenario(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
      64             : {
      65             :         (void) mb;
      66           0 :         if (cntxt->scenario)
      67           0 :                 *getArgReference_str(stk,pci,0) = GDKstrdup(cntxt->scenario);
      68             :         else
      69           0 :                 *getArgReference_str(stk,pci,0) = GDKstrdup("nil");
      70           0 :         if(*getArgReference_str(stk,pci,0) == NULL)
      71           0 :                 throw(MAL, "clients.getScenario", SQLSTATE(HY013) MAL_MALLOC_FAIL);
      72             :         return MAL_SUCCEED;
      73             : }
      74             : 
      75             : static str
      76           0 : CLTsetScenario(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
      77             : {
      78             :         str msg = MAL_SUCCEED;
      79             : 
      80             :         (void) mb;
      81           0 :         msg = setScenario(cntxt, *getArgReference_str(stk,pci,1));
      82           0 :         *getArgReference_str(stk,pci,0) = 0;
      83           0 :         if (msg == NULL) {
      84           0 :                 *getArgReference_str(stk,pci,0) = GDKstrdup(cntxt->scenario);
      85           0 :                 if(*getArgReference_str(stk,pci,0) == NULL)
      86           0 :                         throw(MAL, "clients.setScenario", SQLSTATE(HY013) MAL_MALLOC_FAIL);
      87             :         }
      88             :         return msg;
      89             : }
      90             : 
      91             : static void
      92           1 : CLTtimeConvert(time_t l, char *s)
      93             : {
      94           1 :         struct tm localt = (struct tm) {0};
      95             : 
      96           1 :         (void) localtime_r(&l, &localt);
      97             : 
      98             : #ifdef HAVE_ASCTIME_R3
      99             :         asctime_r(&localt, s, 26);
     100             : #else
     101           1 :         asctime_r(&localt, s);
     102             : #endif
     103           1 :         s[24] = 0;              /* remove newline */
     104           1 : }
     105             : 
     106             : static str
     107           1 : CLTInfo(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     108             : {
     109           1 :         bat *ret=  getArgReference_bat(stk,pci,0);
     110             :         bat *ret2=  getArgReference_bat(stk,pci,0);
     111           1 :         BAT *b = COLnew(0, TYPE_str, 12, TRANSIENT);
     112           1 :         BAT *bn = COLnew(0, TYPE_str, 12, TRANSIENT);
     113             :         char buf[32]; /* 32 bytes are enough */
     114             : 
     115             :         (void) mb;
     116           1 :         if (b == 0 || bn == 0){
     117           0 :                 if ( b != 0) BBPunfix(b->batCacheid);
     118           0 :                 if ( bn != 0) BBPunfix(bn->batCacheid);
     119           0 :                 throw(MAL, "clients.info", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     120             :         }
     121             : 
     122           1 :         (void) snprintf(buf, sizeof(buf), ""LLFMT"", (lng) cntxt->user);
     123           2 :         if (BUNappend(b, "user", false) != GDK_SUCCEED ||
     124           1 :                 BUNappend(bn, buf, false) != GDK_SUCCEED)
     125           0 :                 goto bailout;
     126             : 
     127           2 :         if (BUNappend(b, "scenario", false) != GDK_SUCCEED ||
     128           1 :                 BUNappend(bn, cntxt->scenario, false) != GDK_SUCCEED)
     129           0 :                 goto bailout;
     130             : 
     131           1 :         (void) snprintf(buf, sizeof(buf), "%d", cntxt->listing);
     132           2 :         if (BUNappend(b, "listing", false) != GDK_SUCCEED ||
     133           1 :                 BUNappend(bn, buf, false) != GDK_SUCCEED)
     134           0 :                 goto bailout;
     135             : 
     136           1 :         (void) snprintf(buf, sizeof(buf), "%d", cntxt->debug);
     137           2 :         if (BUNappend(b, "debug", false) != GDK_SUCCEED ||
     138           1 :                 BUNappend(bn, buf, false) != GDK_SUCCEED)
     139           0 :                 goto bailout;
     140             : 
     141           1 :         CLTtimeConvert(cntxt->login, buf);
     142           2 :         if (BUNappend(b, "login", false) != GDK_SUCCEED ||
     143           1 :                 BUNappend(bn, buf, false) != GDK_SUCCEED)
     144           0 :                 goto bailout;
     145           1 :         if (pseudo(ret,b,"client","info"))
     146           0 :                 goto bailout;
     147           1 :         BBPkeepref(*ret2= bn->batCacheid);
     148           1 :         return MAL_SUCCEED;
     149             : 
     150           0 : bailout:
     151           0 :         BBPunfix(b->batCacheid);
     152           0 :         BBPunfix(bn->batCacheid);
     153           0 :         throw(MAL, "clients.info", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     154             : }
     155             : 
     156             : static str
     157           0 : CLTLogin(bat *nme, bat *ret)
     158             : {
     159           0 :         BAT *b = COLnew(0, TYPE_str, 12, TRANSIENT);
     160           0 :         BAT *u = COLnew(0, TYPE_oid, 12, TRANSIENT);
     161             :         int i;
     162             :         char s[32];
     163             : 
     164           0 :         if (b == 0 || u == 0)
     165           0 :                 goto bailout;
     166             : 
     167           0 :         for (i = 0; i < MAL_MAXCLIENTS; i++) {
     168           0 :                 Client c = mal_clients+i;
     169           0 :                 if (c->mode >= RUNCLIENT && !is_oid_nil(c->user)) {
     170           0 :                         CLTtimeConvert(c->login, s);
     171           0 :                         if (BUNappend(b, s, false) != GDK_SUCCEED ||
     172           0 :                                 BUNappend(u, &c->user, false) != GDK_SUCCEED)
     173           0 :                                 goto bailout;
     174             :                 }
     175             :         }
     176           0 :         if (pseudo(ret,b,"client","login") ||
     177           0 :                 pseudo(nme,u,"client","name"))
     178           0 :                 goto bailout;
     179             :         return MAL_SUCCEED;
     180             : 
     181           0 : bailout:
     182           0 :         BBPreclaim(b);
     183           0 :         BBPreclaim(u);
     184           0 :         throw(MAL, "clients.getLogins", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     185             : }
     186             : 
     187             : static str
     188           1 : CLTquit(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     189             : {
     190             :         str msg = MAL_SUCCEED;
     191           1 :         int idx = cntxt->idx;
     192             :         (void) mb;              /* fool compiler */
     193             : 
     194           1 :         if ( pci->argc == 2 && cntxt->user == MAL_ADMIN)
     195           0 :                 idx = *getArgReference_int(stk,pci,1);
     196             : 
     197           1 :         if ( idx < 0 || idx > MAL_MAXCLIENTS)
     198           0 :                 throw(MAL,"clients.quit", "Illegal session id");
     199             : 
     200             :         /* A user can only quite a session under the same id */
     201           1 :         MT_lock_set(&mal_contextLock);
     202           1 :         if (mal_clients[idx].mode == FREECLIENT)
     203           0 :                 msg = createException(MAL,"clients.stop","Session not active anymore");
     204             :         else
     205           1 :                 mal_clients[idx].mode = FINISHCLIENT;
     206           1 :         MT_lock_unset(&mal_contextLock);
     207           1 :         return msg;
     208             : }
     209             : 
     210             : /* Stopping a client in a softmanner by setting the time out marker */
     211             : static str
     212           0 : CLTstop(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     213             : {
     214           0 :         int idx = cntxt->idx;
     215             :         str msg = MAL_SUCCEED;
     216             : 
     217             :         (void) mb;
     218           0 :         if (cntxt->user == MAL_ADMIN)
     219           0 :                 idx = *getArgReference_int(stk,pci,1);
     220             : 
     221           0 :         if ( idx < 0 || idx > MAL_MAXCLIENTS)
     222           0 :                 throw(MAL,"clients.stop","Illegal session id");
     223             : 
     224           0 :         MT_lock_set(&mal_contextLock);
     225           0 :         if (mal_clients[idx].mode == FREECLIENT)
     226           0 :                 msg = createException(MAL,"clients.stop","Session not active anymore");
     227             :         else
     228           0 :                 mal_clients[idx].querytimeout = 1; /* stop client in one microsecond */
     229             :         /* this forces the designated client to stop at the next instruction */
     230           0 :         MT_lock_unset(&mal_contextLock);
     231           0 :         return msg;
     232             : }
     233             : 
     234             : static str
     235           4 : CLTsetoptimizer(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     236             : {
     237           4 :         int idx = cntxt->idx;
     238             :         str opt, msg = MAL_SUCCEED;
     239             : 
     240             :         (void) mb;
     241           4 :         if( pci->argc == 3 && cntxt->user == MAL_ADMIN){
     242           2 :                 idx = *getArgReference_int(stk,pci,1);
     243           2 :                 opt = *getArgReference_str(stk,pci,2);
     244             :         } else {
     245           2 :                 opt = *getArgReference_str(stk,pci,1);
     246             :         }
     247             : 
     248           4 :         if (idx < 0 || idx > MAL_MAXCLIENTS)
     249           0 :                 throw(MAL,"clients.setoptimizer","Illegal session id");
     250           4 :         if (strNil(opt))
     251           0 :                 throw(MAL,"clients.setoptimizer","Input string cannot be NULL");
     252           4 :         if (strlen(opt) >= sizeof(mal_clients[idx].optimizer))
     253           0 :                 throw(MAL,"clients.setoptimizer","Input string is too large");
     254           4 :         if (!isOptimizerPipe(opt))
     255           1 :                 throw(MAL, "clients.setoptimizer", "Valid optimizer pipe expected");
     256             : 
     257           3 :         MT_lock_set(&mal_contextLock);
     258           3 :         if (mal_clients[idx].mode == FREECLIENT)
     259           0 :                 msg = createException(MAL,"clients.setoptimizer","Session not active anymore");
     260             :         else
     261           3 :                 strcpy_len(mal_clients[idx].optimizer, opt, sizeof(mal_clients[idx].optimizer));
     262           3 :         MT_lock_unset(&mal_contextLock);
     263           3 :         return msg;
     264             : }
     265             : 
     266             : static str
     267           3 : CLTsetworkerlimit(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     268             : {
     269             :         str msg = MAL_SUCCEED;
     270           3 :         int idx = cntxt->idx, limit;
     271             : 
     272             :         (void) mb;
     273           3 :         if (pci->argc == 3 && cntxt->user == MAL_ADMIN){
     274           1 :                 idx = *getArgReference_int(stk,pci,1);
     275           1 :                 limit = *getArgReference_int(stk,pci,2);
     276             :         } else {
     277           2 :                 limit = *getArgReference_int(stk,pci,1);
     278             :         }
     279             : 
     280           3 :         if( idx < 0 || idx > MAL_MAXCLIENTS)
     281           0 :                 throw(MAL,"clients.setworkerlimit","Illegal session id");
     282           3 :         if( is_int_nil(limit))
     283           0 :                 throw(MAL, "clients.setworkerlimit","The number of workers cannot be NULL");
     284           3 :         if( limit < 0)
     285           1 :                 throw(MAL, "clients.setworkerlimit","The number of workers cannot be negative");
     286             : 
     287           2 :         MT_lock_set(&mal_contextLock);
     288           2 :         if (mal_clients[idx].mode == FREECLIENT)
     289           0 :                 msg = createException(MAL,"clients.setworkerlimit","Session not active anymore");
     290             :         else
     291           2 :                 mal_clients[idx].workerlimit = limit;
     292           2 :         MT_lock_unset(&mal_contextLock);
     293           2 :         return msg;
     294             : }
     295             : 
     296             : static str
     297           0 : CLTsetmemorylimit(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     298             : {
     299             :         str msg = MAL_SUCCEED;
     300           0 :         int idx = cntxt->idx, limit;
     301             : 
     302             :         (void) mb;
     303           0 :         if (pci->argc == 3 && cntxt->user == MAL_ADMIN){
     304           0 :                 idx = *getArgReference_sht(stk,pci,1);
     305           0 :                 limit = *getArgReference_int(stk,pci,2);
     306             :         } else {
     307           0 :                 limit = *getArgReference_int(stk,pci,1);
     308             :         }
     309             : 
     310           0 :         if( idx < 0 || idx > MAL_MAXCLIENTS)
     311           0 :                 throw(MAL,"clients.setmemorylimit","Illegal session id");
     312           0 :         if( is_int_nil(limit))
     313           0 :                 throw(MAL, "clients.setmemorylimit", "The memmory limit cannot be NULL");
     314           0 :         if( limit < 0)
     315           0 :                 throw(MAL, "clients.setmemorylimit", "The memmory limit cannot be negative");
     316           0 :         if( (size_t) limit > GDK_mem_maxsize / 1048576)
     317           0 :                 throw(MAL,"clients.setmemorylimit","Memory claim beyond physical memory");
     318             : 
     319           0 :         MT_lock_set(&mal_contextLock);
     320           0 :         if (mal_clients[idx].mode == FREECLIENT)
     321           0 :                 msg = createException(MAL,"clients.setmemorylimit","Session not active anymore");
     322             :         else
     323           0 :                 mal_clients[idx].memorylimit = limit;
     324           0 :         MT_lock_unset(&mal_contextLock);
     325           0 :         return msg;
     326             : }
     327             : 
     328             : static str
     329           0 : CLTstopSession(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     330             : {
     331             :         str msg = MAL_SUCCEED;
     332           0 :         int idx = cntxt->idx;
     333             : 
     334           0 :         if (cntxt->user == MAL_ADMIN) {
     335           0 :                 switch( getArgType(mb,pci,1)){
     336           0 :                 case TYPE_bte:
     337           0 :                         idx = *getArgReference_bte(stk,pci,1);
     338           0 :                         break;
     339           0 :                 case TYPE_sht:
     340           0 :                         idx = *getArgReference_sht(stk,pci,1);
     341           0 :                         break;
     342           0 :                 case TYPE_int:
     343           0 :                         idx = *getArgReference_int(stk,pci,1);
     344           0 :                         break;
     345           0 :                 default:
     346           0 :                         throw(MAL,"clients.stopSession","Unexpected index type");
     347             :                 }
     348           0 :         }
     349           0 :         if( idx < 0 || idx > MAL_MAXCLIENTS)
     350           0 :                 throw(MAL,"clients.stopSession","Illegal session id");
     351             : 
     352           0 :         MT_lock_set(&mal_contextLock);
     353           0 :         if (mal_clients[idx].mode == FREECLIENT) {
     354           0 :                 msg = createException(MAL,"clients.stopSession","Session not active anymore");
     355             :         } else {
     356           0 :                 mal_clients[idx].querytimeout = 1; /* stop client in one microsecond */
     357           0 :                 mal_clients[idx].sessiontimeout = 1; /* stop client session */
     358             :         }
     359           0 :         MT_lock_unset(&mal_contextLock);
     360             :         /* this forces the designated client to stop at the next instruction */
     361           0 :         return msg;
     362             : }
     363             : 
     364             : /* Queries can be temporarily suspended */
     365             : static str
     366           0 : CLTsuspend(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     367             : {
     368             :         str msg = MAL_SUCCEED;
     369           0 :         int idx = cntxt->idx;
     370             : 
     371           0 :         if (cntxt->user == MAL_ADMIN)
     372           0 :                 idx = *getArgReference_int(stk,pci,1);
     373             :         (void) mb;
     374             : 
     375           0 :         if( idx < 0 || idx > MAL_MAXCLIENTS)
     376           0 :                 throw(MAL,"clients.suspend", "Illegal session id");
     377             : 
     378           0 :         MT_lock_set(&mal_contextLock);
     379           0 :         if (mal_clients[idx].mode == FREECLIENT)
     380           0 :                 msg = createException(MAL,"clients.suspend","Session not active anymore");
     381             :         else
     382           0 :                 msg = MCsuspendClient(idx);
     383           0 :         MT_lock_unset(&mal_contextLock);
     384           0 :         return msg;
     385             : }
     386             : 
     387             : static str
     388           0 : CLTwakeup(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     389             : {
     390             :         str msg = MAL_SUCCEED;
     391           0 :         int idx = cntxt->idx;
     392             : 
     393           0 :         if (cntxt->user == MAL_ADMIN)
     394           0 :                 idx = *getArgReference_int(stk,pci,1);
     395             :         (void) mb;
     396             : 
     397           0 :         if( idx < 0 || idx > MAL_MAXCLIENTS)
     398           0 :                 throw(MAL,"clients.wakeup", "Illegal session id");
     399             : 
     400           0 :         MT_lock_set(&mal_contextLock);
     401           0 :         if (mal_clients[idx].mode == FREECLIENT)
     402           0 :                 msg = createException(MAL,"clients.wakeup","Session not active anymore");
     403             :         else
     404           0 :                 msg = MCawakeClient(idx);
     405           0 :         MT_lock_unset(&mal_contextLock);
     406           0 :         return msg;
     407             : }
     408             : 
     409             : /* Set session time out based in seconds. As of December 2019, this function is deprecated */
     410             : static str
     411        2377 : CLTsetSessionTimeout(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     412             : {
     413             :         str msg = MAL_SUCCEED;
     414             :         lng sto;
     415        2377 :         int idx = cntxt->idx;
     416             : 
     417             :         (void) mb;
     418        2377 :         if( idx < 0 || idx > MAL_MAXCLIENTS)
     419           0 :                 throw(MAL,"clients.setsession","Illegal session id %d", idx);
     420        2377 :         sto = *getArgReference_lng(stk,pci,1);
     421        2377 :         if (is_lng_nil(sto))
     422           0 :                 throw(MAL,"clients.setsession","Session timeout cannot be NULL");
     423        2377 :         if (sto < 0)
     424           0 :                 throw(MAL,"clients.setsession","Session timeout should be >= 0");
     425             : 
     426        2377 :         MT_lock_set(&mal_contextLock);
     427        2377 :         if (mal_clients[idx].mode == FREECLIENT)
     428           0 :                 msg = createException(MAL,"clients.setsession","Session not active anymore");
     429             :         else
     430        2377 :                 mal_clients[idx].sessiontimeout = sto * 1000000;
     431        2377 :         MT_lock_unset(&mal_contextLock);
     432        2377 :         return msg;
     433             : }
     434             : 
     435             : /* Set the current query timeout in seconds. As of December 2019, this function is deprecated */
     436             : static str
     437           0 : CLTsetTimeout(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     438             : {
     439             :         str msg = MAL_SUCCEED;
     440             :         lng qto,sto = 0;
     441           0 :         int idx = cntxt->idx;
     442             : 
     443             :         (void) mb;
     444           0 :         if( idx < 0 || idx > MAL_MAXCLIENTS)
     445           0 :                 throw(MAL,"clients.settimeout","Illegal session id %d", idx);
     446           0 :         qto = *getArgReference_lng(stk,pci,1);
     447           0 :         if (is_lng_nil(qto))
     448           0 :                 throw(MAL,"clients.settimeout","Query timeout cannot be NULL");
     449           0 :         if (qto < 0)
     450           0 :                 throw(MAL,"clients.settimeout","Query timeout should be >= 0");
     451           0 :         if (pci->argc == 3) {
     452           0 :                 sto = *getArgReference_lng(stk,pci,2);
     453           0 :                 if (is_lng_nil(sto))
     454           0 :                         throw(MAL,"clients.settimeout","Session timeout cannot be NULL");
     455           0 :                 if( sto < 0)
     456           0 :                         throw(MAL,"clients.settimeout","Session timeout should be >= 0");
     457             :         }
     458             : 
     459           0 :         MT_lock_set(&mal_contextLock);
     460           0 :         if (mal_clients[idx].mode == FREECLIENT) {
     461           0 :                 msg = createException(MAL, "clients.settimeout","Session not active anymore");
     462             :         } else {
     463           0 :                 if (pci->argc == 3)
     464           0 :                         mal_clients[idx].sessiontimeout = sto * 1000000;
     465           0 :                 mal_clients[idx].querytimeout = qto * 1000000;
     466             :         }
     467           0 :         MT_lock_unset(&mal_contextLock);
     468           0 :         return msg;
     469             : }
     470             : 
     471             : /* set query timeout based in seconds, converted into microseconds */
     472             : static str
     473          16 : CLTqueryTimeout(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     474             : {
     475             :         str msg = MAL_SUCCEED;
     476          16 :         int qto, idx = cntxt->idx;
     477             : 
     478          16 :         if (cntxt->user == MAL_ADMIN && pci->argc == 3){
     479           1 :                 switch( getArgType(mb,pci,1)){
     480           0 :                 case TYPE_bte:
     481           0 :                         idx = *getArgReference_bte(stk,pci,1);
     482           0 :                         break;
     483           0 :                 case TYPE_sht:
     484           0 :                         idx = *getArgReference_sht(stk,pci,1);
     485           0 :                         break;
     486           1 :                 case TYPE_int:
     487           1 :                         idx = *getArgReference_int(stk,pci,1);
     488           1 :                         break;
     489           0 :                 default:
     490           0 :                         throw(MAL,"clients.queryTimeout","Unexpected index type");
     491             :                 }
     492           1 :                 qto = *getArgReference_int(stk,pci,2);
     493             :         } else {
     494          15 :                 qto = *getArgReference_int(stk,pci,1);
     495             :         }
     496          16 :         if (is_int_nil(qto))
     497           0 :                 throw(MAL,"clients.queryTimeout","Query timeout cannot be NULL");
     498          16 :         if( qto < 0)
     499           1 :                 throw(MAL,"clients.queryTimeout","Query timeout should be >= 0");
     500             : 
     501          15 :         MT_lock_set(&mal_contextLock);
     502          15 :         if (mal_clients[idx].mode == FREECLIENT)
     503           0 :                 msg = createException(MAL,"clients.queryTimeout","Session not active anymore");
     504             :         else {
     505          15 :                 lng timeout_micro = (lng) qto * 1000000;
     506          15 :                 mal_clients[idx].querytimeout = timeout_micro;
     507          15 :                 QryCtx *qry_ctx = MT_thread_get_qry_ctx();
     508          15 :                 qry_ctx->querytimeout = timeout_micro;
     509             :         }
     510          15 :         MT_lock_unset(&mal_contextLock);
     511          15 :         return msg;
     512             : }
     513             : 
     514             : // set query timeout based in microseconds
     515             : static str
     516           3 : CLTqueryTimeoutMicro(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     517             : {
     518             :         str msg = MAL_SUCCEED;
     519           3 :         int idx = cntxt->idx;
     520           3 :         lng qto = *getArgReference_lng(stk,pci,1);
     521             :         (void) mb;
     522             : 
     523           3 :         if (is_lng_nil(qto))
     524           0 :                 throw(MAL,"clients.queryTimeout","Query timeout cannot be NULL");
     525           3 :         if( qto < 0)
     526           0 :                 throw(MAL,"clients.queryTimeout","Query timeout should be >= 0");
     527             : 
     528           3 :         MT_lock_set(&mal_contextLock);
     529           3 :         if (mal_clients[idx].mode == FREECLIENT)
     530           0 :                 msg = createException(MAL,"clients.queryTimeout","Session not active anymore");
     531             :         else {
     532           3 :                 mal_clients[idx].querytimeout = qto;
     533           3 :                 QryCtx *qry_ctx = MT_thread_get_qry_ctx();
     534           3 :                 qry_ctx->querytimeout = qto;
     535             :         }
     536           3 :         MT_lock_unset(&mal_contextLock);
     537           3 :         return msg;
     538             : }
     539             : 
     540             : /* Set the current session timeout in seconds */
     541             : static str
     542           3 : CLTsessionTimeout(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     543             : {
     544             :         str msg = MAL_SUCCEED;
     545           3 :         int sto = -1, idx = cntxt->idx;
     546             : 
     547           3 :         if(cntxt->user == MAL_ADMIN && pci->argc == 3){
     548           1 :                 switch( getArgType(mb,pci,1)){
     549           0 :                 case TYPE_bte:
     550           0 :                         idx = *getArgReference_bte(stk,pci,1);
     551           0 :                         break;
     552           0 :                 case TYPE_sht:
     553           0 :                         idx = *getArgReference_sht(stk,pci,1);
     554           0 :                         break;
     555           1 :                 case TYPE_int:
     556           1 :                         idx = *getArgReference_int(stk,pci,1);
     557           1 :                         break;
     558           0 :                 default:
     559           0 :                         throw(MAL,"clients.sessionTimeout","Unexpected index type");
     560             :                 }
     561           1 :                 sto = *getArgReference_int(stk,pci,2);
     562             :         } else {
     563           2 :                 sto = *getArgReference_int(stk,pci,1);
     564             :         }
     565           3 :         if (is_int_nil(sto))
     566           0 :                 throw(MAL,"clients.sessionTimeout","Session timeout cannot be NULL");
     567           3 :         if( sto < 0)
     568           1 :                 throw(MAL,"clients.sessionTimeout","Session timeout should be >= 0");
     569           2 :         if( idx < 0 || idx > MAL_MAXCLIENTS)
     570           0 :                 throw(MAL,"clients.sessionTimeout","Illegal session id %d", idx);
     571             : 
     572           2 :         MT_lock_set(&mal_contextLock);
     573           2 :         if (mal_clients[idx].mode == FREECLIENT)
     574           0 :                 msg = createException(MAL,"clients.sessionTimeout","Session not active anymore");
     575             :         else
     576           2 :                 mal_clients[idx].sessiontimeout = (lng) sto * 1000000;
     577           2 :         MT_lock_unset(&mal_contextLock);
     578           2 :         return msg;
     579             : }
     580             : 
     581             : /* Retrieve the session time out */
     582             : static str
     583           0 : CLTgetProfile(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     584             : {
     585           0 :         str *opt=  getArgReference_str(stk,pci,0);
     586           0 :         int *qto=  getArgReference_int(stk,pci,1);
     587           0 :         int *sto=  getArgReference_int(stk,pci,2);
     588           0 :         int *wlim=  getArgReference_int(stk,pci,3);
     589           0 :         int *mlim=  getArgReference_int(stk,pci,4);
     590             :         (void) mb;
     591           0 :         if (!(*opt = GDKstrdup(cntxt->optimizer)))
     592           0 :                 throw(MAL, "clients.getProfile", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     593           0 :         *qto = (int)(cntxt->querytimeout / 1000000);
     594           0 :         *sto = (int)(cntxt->sessiontimeout / 1000000);
     595           0 :         *wlim = cntxt->workerlimit;
     596           0 :         *mlim = cntxt->memorylimit;
     597           0 :         return MAL_SUCCEED;
     598             : }
     599             : 
     600             : /* Long running queries are traced in the logger
     601             :  * with a message from the interpreter.
     602             :  * This value should be set to minutes to avoid a lengthly log */
     603             : static str
     604           0 : CLTsetPrintTimeout(void *ret, int *secs)
     605             : {
     606             :         (void) ret;
     607           0 :         if (is_int_nil(*secs))
     608           0 :                 setqptimeout(0);
     609             :         else
     610           0 :                 setqptimeout((lng) *secs * 60 * 1000000);
     611           0 :         return MAL_SUCCEED;
     612             : }
     613             : 
     614          13 : static str CLTmd5sum(str *ret, str *pw) {
     615          26 :         if (strNil(*pw)) {
     616           1 :                 *ret = GDKstrdup(str_nil);
     617             :         } else {
     618          12 :                 char *mret = mcrypt_MD5Sum(*pw, strlen(*pw));
     619             : 
     620          12 :                 if (!mret)
     621           0 :                         throw(MAL, "clients.md5sum", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     622          12 :                 *ret = GDKstrdup(mret);
     623          12 :                 free(mret);
     624             :         }
     625          13 :         if (*ret == NULL)
     626           0 :                 throw(MAL, "clients.md5sum", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     627             :         return MAL_SUCCEED;
     628             : }
     629             : 
     630           1 : static str CLTsha1sum(str *ret, str *pw) {
     631           2 :         if (strNil(*pw)) {
     632           0 :                 *ret = GDKstrdup(str_nil);
     633             :         } else {
     634           1 :                 char *mret = mcrypt_SHA1Sum(*pw, strlen(*pw));
     635             : 
     636           1 :                 if (!mret)
     637           0 :                         throw(MAL, "clients.sha1sum", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     638           1 :                 *ret = GDKstrdup(mret);
     639           1 :                 free(mret);
     640             :         }
     641           1 :         if (*ret == NULL)
     642           0 :                 throw(MAL, "clients.sha1sum", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     643             :         return MAL_SUCCEED;
     644             : }
     645             : 
     646           1 : static str CLTripemd160sum(str *ret, str *pw) {
     647           2 :         if (strNil(*pw)) {
     648           0 :                 *ret = GDKstrdup(str_nil);
     649             :         } else {
     650           1 :                 char *mret = mcrypt_RIPEMD160Sum(*pw, strlen(*pw));
     651             : 
     652           1 :                 if (!mret)
     653           0 :                         throw(MAL, "clients.ripemd160sum", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     654           1 :                 *ret = GDKstrdup(mret);
     655           1 :                 free(mret);
     656             :         }
     657           1 :         if (*ret == NULL)
     658           0 :                 throw(MAL, "clients.ripemd160sum", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     659             :         return MAL_SUCCEED;
     660             : }
     661             : 
     662           4 : static str CLTsha2sum(str *ret, str *pw, int *bits) {
     663           8 :         if (strNil(*pw) || is_int_nil(*bits)) {
     664           0 :                 *ret = GDKstrdup(str_nil);
     665             :         } else {
     666             :                 char *mret = 0;
     667           4 :                 switch (*bits) {
     668           1 :                         case 512:
     669           1 :                                 mret = mcrypt_SHA512Sum(*pw, strlen(*pw));
     670           1 :                                 break;
     671           1 :                         case 384:
     672           1 :                                 mret = mcrypt_SHA384Sum(*pw, strlen(*pw));
     673           1 :                                 break;
     674           1 :                         case 256:
     675           1 :                                 mret = mcrypt_SHA256Sum(*pw, strlen(*pw));
     676           1 :                                 break;
     677           1 :                         case 224:
     678           1 :                                 mret = mcrypt_SHA224Sum(*pw, strlen(*pw));
     679           1 :                                 break;
     680           0 :                         default:
     681             :                                 (void)mret;
     682           0 :                                 throw(ILLARG, "clients.sha2sum", "wrong number of bits "
     683             :                                                 "for SHA2 sum: %d", *bits);
     684             :                 }
     685           4 :                 if (!mret)
     686           0 :                         throw(MAL, "clients.sha2sum", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     687           4 :                 *ret = GDKstrdup(mret);
     688           4 :                 free(mret);
     689             :         }
     690           4 :         if (*ret == NULL)
     691           0 :                 throw(MAL, "clients.sha2sum", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     692             :         return MAL_SUCCEED;
     693             : }
     694             : 
     695           1 : static str CLTbackendsum(str *ret, str *pw) {
     696           2 :         if (strNil(*pw)) {
     697           0 :                 *ret = GDKstrdup(str_nil);
     698             :         } else {
     699           1 :                 char *mret = mcrypt_BackendSum(*pw, strlen(*pw));
     700           1 :                 if (mret == NULL)
     701           0 :                         throw(MAL, "clients.backendsum", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     702           1 :                 *ret = GDKstrdup(mret);
     703           1 :                 free(mret);
     704             :         }
     705           1 :         if (*ret == NULL)
     706           0 :                 throw(MAL, "clients.backendsum", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     707             :         return MAL_SUCCEED;
     708             : }
     709             : 
     710           3 : static str CLTaddUser(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci) {
     711           3 :         oid *ret = getArgReference_oid(stk, pci, 0);
     712           3 :         str *usr = getArgReference_str(stk, pci, 1);
     713           3 :         str *pw = getArgReference_str(stk, pci, 2);
     714             : 
     715             :         (void)mb;
     716             : 
     717           3 :         return AUTHaddUser(ret, cntxt, *usr, *pw);
     718             : }
     719             : 
     720           1 : static str CLTremoveUser(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci) {
     721             :         str *usr;
     722             :         (void)mb;
     723             : 
     724           1 :         usr = getArgReference_str(stk, pci, 1);
     725             : 
     726           1 :         return AUTHremoveUser(cntxt, *usr);
     727             : }
     728             : 
     729           5 : static str CLTgetUsername(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci) {
     730           5 :         str *ret = getArgReference_str(stk, pci, 0);
     731             :         (void)mb;
     732             : 
     733           5 :         return AUTHgetUsername(ret, cntxt);
     734             : }
     735             : 
     736           1 : static str CLTgetPasswordHash(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci) {
     737           1 :         str *ret = getArgReference_str(stk, pci, 0);
     738           1 :         str *user = getArgReference_str(stk, pci, 1);
     739             : 
     740             :         (void)mb;
     741             : 
     742           1 :         return AUTHgetPasswordHash(ret, cntxt, *user);
     743             : }
     744             : 
     745           0 : static str CLTchangeUsername(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci) {
     746           0 :         str *old = getArgReference_str(stk, pci, 1);
     747           0 :         str *new = getArgReference_str(stk, pci, 2);
     748             : 
     749             :         (void)mb;
     750             : 
     751           0 :         return AUTHchangeUsername(cntxt, *old, *new);
     752             : }
     753             : 
     754           0 : static str CLTchangePassword(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci) {
     755           0 :         str *old = getArgReference_str(stk, pci, 1);
     756           0 :         str *new = getArgReference_str(stk, pci, 2);
     757             : 
     758             :         (void)mb;
     759             : 
     760           0 :         return AUTHchangePassword(cntxt, *old, *new);
     761             : }
     762             : 
     763           2 : static str CLTsetPassword(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci) {
     764           2 :         str *usr = getArgReference_str(stk, pci, 1);
     765           2 :         str *new = getArgReference_str(stk, pci, 2);
     766             : 
     767             :         (void)mb;
     768             : 
     769           2 :         return AUTHsetPassword(cntxt, *usr, *new);
     770             : }
     771             : 
     772           3 : static str CLTcheckPermission(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci) {
     773           3 :         str *usr = getArgReference_str(stk, pci, 1);
     774           3 :         str *pw = getArgReference_str(stk, pci, 2);
     775             :         str ch = "";
     776             :         str algo = "SHA1";
     777             :         oid id;
     778             :         str pwd,msg;
     779             : 
     780             :         (void)mb;
     781             : 
     782           3 :         if (!(pwd = mcrypt_SHA1Sum(*pw, strlen(*pw))))
     783           0 :                 throw(MAL, "clients.checkPermission", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     784           3 :         msg = AUTHcheckCredentials(&id, cntxt, *usr, pwd, ch, algo);
     785           3 :         free(pwd);
     786           3 :         return msg;
     787             : }
     788             : 
     789           2 : static str CLTgetUsers(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci) {
     790           2 :         bat *ret1 = getArgReference_bat(stk, pci, 0);
     791           2 :         bat *ret2 = getArgReference_bat(stk, pci, 1);
     792             :         BAT *uid, *nme;
     793             :         str tmp;
     794             : 
     795             :         (void)mb;
     796             : 
     797           2 :         tmp = AUTHgetUsers(&uid, &nme, cntxt);
     798           2 :         if (tmp)
     799             :                 return tmp;
     800           2 :         BBPkeepref(*ret1 = uid->batCacheid);
     801           2 :         BBPkeepref(*ret2 = nme->batCacheid);
     802           2 :         return(MAL_SUCCEED);
     803             : }
     804             : 
     805             : str
     806           2 : CLTshutdown(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci) {
     807           2 :         str *ret  = getArgReference_str(stk,pci,0);
     808             :         int delay;
     809             :         bit force = FALSE;
     810             :         int leftover;
     811           2 :         char buf[1024]={"safe to stop last connection"};
     812             : 
     813           2 :         if ( pci->argc == 3)
     814           1 :                 force = *getArgReference_bit(stk,pci,2);
     815             : 
     816             :         (void) mb;
     817           2 :         switch( getArgType(mb,pci,1)){
     818           2 :         case TYPE_bte:
     819           2 :                 delay = *getArgReference_bte(stk,pci,1);
     820           2 :                 break;
     821           0 :         case TYPE_sht:
     822           0 :                 delay = *getArgReference_sht(stk,pci,1);
     823           0 :                 break;
     824           0 :         default:
     825           0 :                 delay = *getArgReference_int(stk,pci,1);
     826           0 :                 break;
     827             :         }
     828             : 
     829           2 :         if (cntxt->user != MAL_ADMIN)
     830           0 :                 throw(MAL,"mal.shutdown", "Administrator rights required");
     831           2 :         if (is_int_nil(delay))
     832           0 :                 throw(MAL,"mal.shutdown", "Delay cannot be NULL");
     833           2 :         if (delay < 0)
     834           0 :                 throw(MAL,"mal.shutdown", "Delay cannot be negative");
     835           2 :         if (is_bit_nil(force))
     836           0 :                 throw(MAL,"mal.shutdown", "Force cannot be NULL");
     837           2 :         MCstopClients(cntxt);
     838             :         do{
     839           2 :                 if ( (leftover = MCactiveClients()-1) )
     840           0 :                         MT_sleep_ms(1000);
     841           2 :                 delay --;
     842           2 :         } while (delay > 0 && leftover > 1);
     843           2 :         if( delay == 0 && leftover > 1)
     844           0 :                 snprintf(buf, 1024,"%d client sessions still running",leftover);
     845           2 :         *ret = GDKstrdup(buf);
     846           2 :         if ( force)
     847           1 :                 GDKprepareExit();
     848           2 :         if (*ret == NULL)
     849           0 :                 throw(MAL, "mal.shutdown", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     850             :         return MAL_SUCCEED;
     851             : }
     852             : 
     853             : str
     854          42 : CLTsessions(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     855             : {
     856             :         BAT *id = NULL, *user = NULL, *login = NULL, *sessiontimeout = NULL, *querytimeout = NULL, *idle= NULL;
     857             :         BAT *opt = NULL, *wlimit = NULL, *mlimit = NULL;
     858          42 :         bat *idId = getArgReference_bat(stk,pci,0);
     859          42 :         bat *userId = getArgReference_bat(stk,pci,1);
     860          42 :         bat *loginId = getArgReference_bat(stk,pci,2);
     861          42 :         bat *idleId = getArgReference_bat(stk,pci,3);
     862          42 :         bat *optId = getArgReference_bat(stk,pci,4);
     863          42 :         bat *sessiontimeoutId = getArgReference_bat(stk,pci,5);
     864          42 :         bat *querytimeoutId = getArgReference_bat(stk,pci,6);
     865          42 :         bat *wlimitId = getArgReference_bat(stk,pci,7);
     866          42 :         bat *mlimitId = getArgReference_bat(stk,pci,8);
     867             :         Client c;
     868             :         timestamp ret;
     869             :         int timeout;
     870             :         str msg = NULL;
     871             : 
     872             :         (void) cntxt;
     873             :         (void) mb;
     874             : 
     875          42 :         id = COLnew(0, TYPE_int, 0, TRANSIENT);
     876          42 :         user = COLnew(0, TYPE_str, 0, TRANSIENT);
     877          42 :         login = COLnew(0, TYPE_timestamp, 0, TRANSIENT);
     878          42 :         opt = COLnew(0, TYPE_str, 0, TRANSIENT);
     879          42 :         sessiontimeout = COLnew(0, TYPE_int, 0, TRANSIENT);
     880          42 :         querytimeout = COLnew(0, TYPE_int, 0, TRANSIENT);
     881          42 :         wlimit = COLnew(0, TYPE_int, 0, TRANSIENT);
     882          42 :         mlimit = COLnew(0, TYPE_int, 0, TRANSIENT);
     883          42 :         idle = COLnew(0, TYPE_timestamp, 0, TRANSIENT);
     884             : 
     885          42 :         if (id == NULL || user == NULL || login == NULL || sessiontimeout == NULL || idle == NULL || querytimeout == NULL ||
     886          42 :            opt == NULL || wlimit == NULL || mlimit == NULL ){
     887           0 :                 if ( id) BBPunfix(id->batCacheid);
     888           0 :                 if ( user) BBPunfix(user->batCacheid);
     889           0 :                 if ( login) BBPunfix(login->batCacheid);
     890           0 :                 if ( sessiontimeout) BBPunfix(sessiontimeout->batCacheid);
     891           0 :                 if ( querytimeout) BBPunfix(querytimeout->batCacheid);
     892           0 :                 if ( idle) BBPunfix(idle->batCacheid);
     893             : 
     894           0 :                 if ( opt) BBPunfix(opt->batCacheid);
     895           0 :                 if ( wlimit) BBPunfix(wlimit->batCacheid);
     896           0 :                 if ( mlimit) BBPunfix(mlimit->batCacheid);
     897           0 :                 throw(SQL,"sql.sessions", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     898             :         }
     899             : 
     900          42 :         MT_lock_set(&mal_contextLock);
     901             : 
     902        2730 :         for (c = mal_clients; c < mal_clients + MAL_MAXCLIENTS; c++) {
     903        2688 :                 if (c->mode == RUNCLIENT) {
     904          42 :                         if (BUNappend(user, c->username, false) != GDK_SUCCEED)
     905           0 :                                 goto bailout;
     906          42 :                         ret = timestamp_fromtime(c->login);
     907          42 :                         if (is_timestamp_nil(ret)) {
     908           0 :                                 msg = createException(SQL, "sql.sessions", SQLSTATE(22003) "Failed to convert user logged time");
     909           0 :                                 goto bailout;
     910             :                         }
     911          42 :                         if (BUNappend(id, &c->idx, false) != GDK_SUCCEED)
     912           0 :                                 goto bailout;
     913          42 :                         if (BUNappend(login, &ret, false) != GDK_SUCCEED)
     914           0 :                                 goto bailout;
     915          42 :                         timeout = (int)(c->sessiontimeout / 1000000);
     916          42 :                         if (BUNappend(sessiontimeout, &timeout, false) != GDK_SUCCEED)
     917           0 :                                 goto bailout;
     918          42 :                         timeout = (int)(c->querytimeout / 1000000);
     919          42 :                         if (BUNappend(querytimeout, &timeout, false) != GDK_SUCCEED)
     920           0 :                                 goto bailout;
     921          42 :                         if( c->idle){
     922           0 :                                 ret = timestamp_fromtime(c->idle);
     923           0 :                                 if (is_timestamp_nil(ret)) {
     924           0 :                                         msg = createException(SQL, "sql.sessions", SQLSTATE(22003) "Failed to convert user logged time");
     925           0 :                                         goto bailout;
     926             :                                 }
     927             :                         } else
     928          42 :                                 ret = timestamp_nil;
     929          42 :                         if (BUNappend(idle, &ret, false) != GDK_SUCCEED)
     930           0 :                                 goto bailout;
     931          42 :                         if (BUNappend(opt, &c->optimizer, false) != GDK_SUCCEED)
     932           0 :                                 goto bailout;
     933          42 :                         if (BUNappend(wlimit, &c->workerlimit, false) != GDK_SUCCEED)
     934           0 :                                 goto bailout;
     935          42 :                         if (BUNappend(mlimit, &c->memorylimit, false) != GDK_SUCCEED)
     936           0 :                                 goto bailout;
     937             :                 }
     938             :         }
     939          42 :         MT_lock_unset(&mal_contextLock);
     940          42 :         BBPkeepref(*idId = id->batCacheid);
     941          42 :         BBPkeepref(*userId = user->batCacheid);
     942          42 :         BBPkeepref(*loginId = login->batCacheid);
     943          42 :         BBPkeepref(*sessiontimeoutId = sessiontimeout->batCacheid);
     944          42 :         BBPkeepref(*querytimeoutId = querytimeout->batCacheid);
     945          42 :         BBPkeepref(*idleId = idle->batCacheid);
     946             : 
     947          42 :         BBPkeepref(*optId = opt->batCacheid);
     948          42 :         BBPkeepref(*wlimitId = wlimit->batCacheid);
     949          42 :         BBPkeepref(*mlimitId = mlimit->batCacheid);
     950          42 :         return MAL_SUCCEED;
     951             : 
     952           0 : bailout:
     953           0 :         MT_lock_unset(&mal_contextLock);
     954           0 :         BBPunfix(id->batCacheid);
     955           0 :         BBPunfix(user->batCacheid);
     956           0 :         BBPunfix(login->batCacheid);
     957           0 :         BBPunfix(sessiontimeout->batCacheid);
     958           0 :         BBPunfix(querytimeout->batCacheid);
     959           0 :         BBPunfix(idle->batCacheid);
     960             : 
     961           0 :         BBPunfix(opt->batCacheid);
     962           0 :         BBPunfix(wlimit->batCacheid);
     963           0 :         BBPunfix(mlimit->batCacheid);
     964           0 :         return msg;
     965             : }
     966             : 
     967             : static str
     968           0 : CLTgetSessionID(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     969             : {
     970             :         (void) mb;
     971             :         (void) stk;
     972             :         (void) pci;
     973           0 :         *getArgReference_int(stk,pci,0) = cntxt->idx;
     974           0 :         return MAL_SUCCEED;
     975             : }
     976             : 
     977             : #include "mel.h"
     978             : mel_func clients_init_funcs[] = {
     979             :  pattern("clients", "setListing", CLTsetListing, false, "Turn on/off echo of MAL instructions:\n1 - echo input,\n2 - show mal instruction,\n4 - show details of type resolutoin, \n8 - show binding information.", args(1,2, arg("",int),arg("flag",int))),
     980             :  pattern("clients", "getId", CLTgetClientId, false, "Return a number that uniquely represents the current client.", args(1,1, arg("",int))),
     981             :  pattern("clients", "getInfo", CLTInfo, false, "Pseudo bat with client attributes.", args(2,2, batarg("",str),batarg("",str))),
     982             :  pattern("clients", "getScenario", CLTgetScenario, false, "Retrieve current scenario name.", args(1,1, arg("",str))),
     983             :  pattern("clients", "setScenario", CLTsetScenario, false, "Switch to other scenario handler, return previous one.", args(1,2, arg("",str),arg("msg",str))),
     984             :  pattern("clients", "quit", CLTquit, false, "Terminate the client session.", args(1,1, arg("",void))),
     985             :  pattern("clients", "quit", CLTquit, false, "Terminate the session for a single client using a soft error.\nIt is the privilige of the console user.", args(1,2, arg("",void),arg("idx",int))),
     986             :  command("clients", "getLogins", CLTLogin, false, "Pseudo bat of client id and login time.", args(2,2, batarg("user",oid),batarg("start",str))),
     987             :  pattern("clients", "stop", CLTstop, false, "Stop the query execution at the next eligble statement.", args(0,1, arg("id",int))),
     988             :  pattern("clients", "suspend", CLTsuspend, false, "Put a client process to sleep for some time.\nIt will simple sleep for a second at a time, until\nthe awake bit has been set in its descriptor", args(1,2, arg("",void),arg("id",int))),
     989             :  pattern("clients", "wakeup", CLTwakeup, false, "Wakeup a client process", args(1,2, arg("",void),arg("id",int))),
     990             :  pattern("clients", "getprofile", CLTgetProfile, false, "Retrieve the profile settings for a client", args(5,5, arg("opt",str),arg("q",int),arg("s",int),arg("w",int),arg("m",int))),
     991             :  pattern("clients", "setsession", CLTsetSessionTimeout, false, "Abort a session after  n seconds.", args(1,2, arg("",void),arg("n",lng))),
     992             :  pattern("clients", "settimeout", CLTsetTimeout, false, "Abort a query after  n seconds.", args(1,2, arg("",void),arg("n",lng))),
     993             :  pattern("clients", "settimeout", CLTsetTimeout, false, "Abort a query after q seconds (q=0 means run undisturbed).\nThe session timeout aborts the connection after spending too\nmany seconds on query processing.", args(1,3, arg("",void),arg("q",lng),arg("s",lng))),
     994             :  pattern("clients", "setQryTimeoutMicro", CLTqueryTimeoutMicro, false, "", args(1,2, arg("",void),arg("n",lng))),
     995             :  pattern("clients", "setquerytimeout", CLTqueryTimeout, false, "", args(1,2, arg("",void),arg("n",int))),
     996             :  pattern("clients", "setquerytimeout", CLTqueryTimeout, false, "", args(1,3, arg("",void),arg("sid",bte),arg("n",int))),
     997             :  pattern("clients", "setquerytimeout", CLTqueryTimeout, false, "", args(1,3, arg("",void),arg("sid",sht),arg("n",int))),
     998             :  pattern("clients", "setquerytimeout", CLTqueryTimeout, false, "A query is aborted after q seconds (q=0 means run undisturbed).", args(1,3, arg("",void),arg("sid",int),arg("n",int))),
     999             :  pattern("clients", "setsessiontimeout", CLTsessionTimeout, false, "", args(1,2, arg("",void),arg("n",int))),
    1000             :  pattern("clients", "setsessiontimeout", CLTsessionTimeout, false, "", args(1,3, arg("",void),arg("sid",bte),arg("n",int))),
    1001             :  pattern("clients", "setsessiontimeout", CLTsessionTimeout, false, "", args(1,3, arg("",void),arg("sid",sht),arg("n",int))),
    1002             :  pattern("clients", "setsessiontimeout", CLTsessionTimeout, false, "Set the session timeout for a particulat session id", args(1,3, arg("",void),arg("sid",int),arg("n",int))),
    1003             :  pattern("clients", "setoptimizer", CLTsetoptimizer, false, "", args(1,2, arg("",void),arg("opt",str))),
    1004             :  pattern("clients", "setoptimizer", CLTsetoptimizer, false, "Set the session optimizer", args(1,3, arg("",void),arg("sid",int),arg("opt",str))),
    1005             :  pattern("clients", "setworkerlimit", CLTsetworkerlimit, false, "", args(1,2, arg("",void),arg("n",int))),
    1006             :  pattern("clients", "setworkerlimit", CLTsetworkerlimit, false, "Limit the number of worker threads per query", args(1,3, arg("",void),arg("sid",int),arg("n",int))),
    1007             :  pattern("clients", "setmemorylimit", CLTsetmemorylimit, false, "", args(1,2, arg("",void),arg("n",int))),
    1008             :  pattern("clients", "setmemorylimit", CLTsetmemorylimit, false, "Limit the memory claim in MB per query", args(1,3, arg("",void),arg("sid",int),arg("n",int))),
    1009             :  pattern("clients", "stopsession", CLTstopSession, false, "", args(1,2, arg("",void),arg("sid",bte))),
    1010             :  pattern("clients", "stopsession", CLTstopSession, false, "", args(1,2, arg("",void),arg("sid",sht))),
    1011             :  pattern("clients", "stopsession", CLTstopSession, false, "Stop a particular session", args(1,2, arg("",void),arg("sid",int))),
    1012             :  command("clients", "setprinttimeout", CLTsetPrintTimeout, false, "Print running query every so many seconds.", args(1,2, arg("",void),arg("n",int))),
    1013             :  pattern("clients", "shutdown", CLTshutdown, false, "", args(1,2, arg("",str),arg("delay",int))),
    1014             :  pattern("clients", "shutdown", CLTshutdown, false, "Close all other client connections. Return if it succeeds.\nIf forced is set then always stop the system the hard way", args(1,3, arg("",str),arg("delay",int),arg("forced",bit))),
    1015             :  command("clients", "md5sum", CLTmd5sum, false, "Return hex string representation of the MD5 hash of the given string", args(1,2, arg("",str),arg("pw",str))),
    1016             :  command("clients", "sha1sum", CLTsha1sum, false, "Return hex string representation of the SHA-1 hash of the given string", args(1,2, arg("",str),arg("pw",str))),
    1017             :  command("clients", "sha2sum", CLTsha2sum, false, "Return hex string representation of the SHA-2 hash with bits of the given string", args(1,3, arg("",str),arg("pw",str),arg("bits",int))),
    1018             :  command("clients", "ripemd160sum", CLTripemd160sum, false, "Return hex string representation of the RIPEMD160 hash of the given string", args(1,2, arg("",str),arg("pw",str))),
    1019             :  command("clients", "backendsum", CLTbackendsum, false, "Return hex string representation of the currently used hash of the given string", args(1,2, arg("",str),arg("pw",str))),
    1020             :  pattern("clients", "addUser", CLTaddUser, false, "Allow user with password access to the given scenarios", args(1,3, arg("",oid),arg("nme",str),arg("pw",str))),
    1021             :  pattern("clients", "removeUser", CLTremoveUser, false, "Remove the given user from the system", args(1,2, arg("",void),arg("nme",str))),
    1022             :  pattern("clients", "getUsername", CLTgetUsername, false, "Return the username of the currently logged in user", args(1,1, arg("",str))),
    1023             :  pattern("clients", "getPasswordHash", CLTgetPasswordHash, false, "Return the password hash of the given user", args(1,2, arg("",str),arg("user",str))),
    1024             :  pattern("clients", "changeUsername", CLTchangeUsername, false, "Change the username of the user into the new string", args(1,3, arg("",void),arg("old",str),arg("new",str))),
    1025             :  pattern("clients", "changePassword", CLTchangePassword, false, "Change the password for the current user", args(1,3, arg("",void),arg("old",str),arg("new",str))),
    1026             :  pattern("clients", "setPassword", CLTsetPassword, false, "Set the password for the given user", args(1,3, arg("",void),arg("user",str),arg("pass",str))),
    1027             :  pattern("clients", "checkPermission", CLTcheckPermission, false, "Check permission for a user, requires hashed password (backendsum)", args(1,3, arg("",void),arg("usr",str),arg("pw",str))),
    1028             :  pattern("clients", "getUsers", CLTgetUsers, false, "return a BAT with user id and one with name available in the system", args(2,2, batarg("",oid),batarg("",str))),
    1029             :  pattern("clients", "current_sessionid", CLTgetSessionID, false, "return current session ID", args(1,1, arg("",int))),
    1030             :  { .imp=NULL }
    1031             : };
    1032             : #include "mal_import.h"
    1033             : #ifdef _MSC_VER
    1034             : #undef read
    1035             : #pragma section(".CRT$XCU",read)
    1036             : #endif
    1037         259 : LIB_STARTUP_FUNC(init_clients_mal)
    1038         259 : { mal_module("clients", NULL, clients_init_funcs); }

Generated by: LCOV version 1.14