| 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 - 2019 MonetDB B.V. |
| 7 | */ |
| 8 | |
| 9 | #ifndef _MAL_CLIENT_H_ |
| 10 | #define _MAL_CLIENT_H_ |
| 11 | |
| 12 | #include "mal.h" |
| 13 | /*#define MAL_CLIENT_DEBUG */ |
| 14 | |
| 15 | #include "mal_resolve.h" |
| 16 | |
| 17 | #define SCENARIO_PROPERTIES 8 |
| 18 | |
| 19 | enum clientmode { |
| 20 | FREECLIENT, |
| 21 | FINISHCLIENT, |
| 22 | RUNCLIENT, |
| 23 | BLOCKCLIENT |
| 24 | }; |
| 25 | |
| 26 | /* |
| 27 | * The prompt structure is designed to simplify recognition of the |
| 28 | * language framework for interaction. For access through an API we |
| 29 | * assume the prompt is an ASCII string surrounded by a \001 character. This |
| 30 | * simplifies recognition. The information between the prompt brackets |
| 31 | * can be used to pass the mode to the front-end. Moreover, the prompt |
| 32 | * can be dropped if a single stream of information is expected from the |
| 33 | * server (see mal_profiler.c). |
| 34 | * |
| 35 | * The user can request server-side compilation as part of the |
| 36 | * initialization string. See the documentation on Scenarios. |
| 37 | */ |
| 38 | typedef struct CLIENT_INPUT { |
| 39 | bstream *fdin; |
| 40 | size_t yycur; |
| 41 | int listing; |
| 42 | char *prompt; |
| 43 | struct CLIENT_INPUT *next; |
| 44 | } ClientInput; |
| 45 | |
| 46 | typedef struct CLIENT { |
| 47 | int idx; /* entry in mal_clients */ |
| 48 | oid user; /* user id in the auth administration */ |
| 49 | str username; /* for event processor */ |
| 50 | /* |
| 51 | * The actions for a client is separated into several stages: |
| 52 | * parsing, strategic optimization, tactical optimization, and |
| 53 | * execution. The routines to handle them are obtained once the |
| 54 | * scenario is chosen. Each stage carries a state descriptor, but |
| 55 | * they share the IO state description. A backup structure is |
| 56 | * provided to temporarily switch to another scenario. |
| 57 | */ |
| 58 | str scenario; /* scenario management references */ |
| 59 | str oldscenario; |
| 60 | void *state[SCENARIO_PROPERTIES], *oldstate[SCENARIO_PROPERTIES]; |
| 61 | MALfcn phase[SCENARIO_PROPERTIES], oldphase[SCENARIO_PROPERTIES]; |
| 62 | char itrace; /* trace execution using interactive mdb */ |
| 63 | /* if set to 'S' it will put the process to sleep */ |
| 64 | bit sqlprofiler; /* control off-line sql performance monitoring */ |
| 65 | /* |
| 66 | * Each session comes with resource limitations and predefined settings. |
| 67 | */ |
| 68 | char optimizer[IDLENGTH];/* The optimizer pipe preferred for this session */ |
| 69 | int workerlimit; /* maximum number of workthreads processing a query */ |
| 70 | int memorylimit; /* Memory claim highwater mark, 0 = no limit */ |
| 71 | lng querytimeout; /* query abort after x usec, 0 = no limit*/ |
| 72 | lng sessiontimeout; /* session abort after x usec, 0 = no limit */ |
| 73 | |
| 74 | time_t login; /* Time when this session started */ |
| 75 | lng session; /* usec since start of server */ |
| 76 | time_t idle; /* Time when the session became idle */ |
| 77 | |
| 78 | /* |
| 79 | * For program debugging and performance trace we keep the actual resource claims. |
| 80 | */ |
| 81 | time_t lastcmd; /* set when query is received */ |
| 82 | |
| 83 | /* The user can request a TRACE SQL statement, calling for collecting the events locally */ |
| 84 | BAT *profticks; |
| 85 | BAT *profstmt; |
| 86 | |
| 87 | ATOMIC_TYPE lastprint; /* when we last printed the query, to be depricated */ |
| 88 | /* |
| 89 | * Communication channels for the interconnect are stored here. |
| 90 | * It is perfectly legal to have a client without input stream. |
| 91 | * It will simply terminate after consuming the input buffer. |
| 92 | */ |
| 93 | str srcFile; /* NULL for stdin, or file name */ |
| 94 | bstream *fdin; |
| 95 | size_t yycur; /* the scanners current position */ |
| 96 | /* |
| 97 | * Keeping track of instructions executed is a valuable tool for |
| 98 | * script processing and debugging. It can be changed at runtime |
| 99 | * for individual clients using the operation clients.listing(mask). |
| 100 | * A listing bit controls the level of detail to be generated during |
| 101 | * program execution tracing. The lowest level (1) simply dumps the |
| 102 | * input, (2) also demonstrates the MAL internal structure, (4) adds |
| 103 | * the type information. |
| 104 | */ |
| 105 | int listing; |
| 106 | str prompt; /* acknowledge prompt */ |
| 107 | size_t promptlength; |
| 108 | ClientInput *bak; /* used for recursive script and string execution */ |
| 109 | |
| 110 | stream *fdout; /* streams from and to user. */ |
| 111 | /* |
| 112 | * In interactive mode, reading one line at a time, we should be |
| 113 | * aware of parsing compound structures, such as functions and |
| 114 | * barrier blocks. The level of nesting is maintained in blkmode, |
| 115 | * which is reset to zero upon encountering an end instruction, or |
| 116 | * the closing bracket has been detected. Once the complete |
| 117 | * structure has been parsed the program can be checked and |
| 118 | * executed. Nesting is indicated using a '+' before the prompt. |
| 119 | */ |
| 120 | int blkmode; /* control block parsing */ |
| 121 | /* |
| 122 | * The MAL debugger uses the client record to keep track of any |
| 123 | * pervasive debugger command. For detailed information on the |
| 124 | * debugger features. |
| 125 | */ |
| 126 | int debug; |
| 127 | enum clientmode mode; /* FREECLIENT..BLOCKED */ |
| 128 | /* |
| 129 | * Client records are organized into a two-level dependency tree, |
| 130 | * where children may be created to deal with parallel processing |
| 131 | * activities. Each client runs in its own process thread. Its |
| 132 | * identity is retained here for access by others (=father). |
| 133 | */ |
| 134 | MT_Sema s; /* sema to (de)activate thread */ |
| 135 | Thread mythread; |
| 136 | str errbuf; /* location of GDK exceptions */ |
| 137 | struct CLIENT *father; |
| 138 | /* |
| 139 | * Each client has a private entry point into the namespace and |
| 140 | * object space (the global variables). Moreover, the parser needs |
| 141 | * some administration variables to keep track of critical elements. |
| 142 | */ |
| 143 | Module usermodule; /* private user scope */ |
| 144 | Module curmodule; /* where to deliver the symbol, used by parser , only freed globally */ |
| 145 | Symbol curprg; /* container for the malparser */ |
| 146 | Symbol backup; /* saving the parser context for functions,commands/patterns */ |
| 147 | MalStkPtr glb; /* global variable stack */ |
| 148 | /* |
| 149 | * Some statistics on client behavior becomes relevant for server |
| 150 | * maintenance. The scenario loop is used as a frame of reference. |
| 151 | * We measure the elapsed time after a request has been received and |
| 152 | * we have to wait for the next one. |
| 153 | */ |
| 154 | int actions; |
| 155 | |
| 156 | /* |
| 157 | * Here are pointers to scenario backends contexts. For the time |
| 158 | * being just SQL. We need a pointer for each of them, since they |
| 159 | * have to be able to interoperate with each other, e.g. both |
| 160 | * contexts at the same time are in use. |
| 161 | */ |
| 162 | void *sqlcontext; |
| 163 | |
| 164 | /* |
| 165 | * The workload for replication/replay is saved initially as a MAL block. |
| 166 | * It is split into the capturing part (wlc) and the replay part (wlr). |
| 167 | * This allows a single server to act as both a master and a replica. |
| 168 | */ |
| 169 | int wlc_kind; // used by master to characterise the compound transaction |
| 170 | MalBlkPtr wlc; |
| 171 | |
| 172 | /* |
| 173 | * Errors during copy into are collected in a user specific column set |
| 174 | */ |
| 175 | BAT *error_row; |
| 176 | BAT *error_fld; |
| 177 | BAT *error_msg; |
| 178 | BAT *error_input; |
| 179 | |
| 180 | size_t blocksize; |
| 181 | protocol_version protocol; |
| 182 | bool filetrans; /* whether the client can read files for us */ |
| 183 | const char *(*getquery)(struct CLIENT *); |
| 184 | } *Client, ClientRec; |
| 185 | |
| 186 | mal_export bool MCinit(void); |
| 187 | |
| 188 | mal_export int MAL_MAXCLIENTS; |
| 189 | mal_export ClientRec *mal_clients; |
| 190 | |
| 191 | mal_export Client MCgetClient(int id); |
| 192 | mal_export Client MCinitClient(oid user, bstream *fin, stream *fout); |
| 193 | mal_export int MCinitClientThread(Client c); |
| 194 | mal_export Client MCforkClient(Client father); |
| 195 | mal_export void MCstopClients(Client c); |
| 196 | mal_export int MCshutdowninprogress(void); |
| 197 | mal_export int MCactiveClients(void); |
| 198 | mal_export void MCcloseClient(Client c); |
| 199 | mal_export str MCsuspendClient(int id); |
| 200 | mal_export str MCawakeClient(int id); |
| 201 | mal_export int MCpushClientInput(Client c, bstream *new_input, int listing, char *prompt); |
| 202 | mal_export int MCvalid(Client c); |
| 203 | |
| 204 | mal_export str PROFinitClient(Client c); |
| 205 | mal_export str PROFexitClient(Client c); |
| 206 | #endif /* _MAL_CLIENT_H_ */ |
| 207 | |