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 | |