Merge lp:~brianaker/drizzle/bug-fix-654219 into lp:~drizzle-trunk/drizzle/development
- bug-fix-654219
- Merge into development
Proposed by
Brian Aker
Status: | Merged |
---|---|
Approved by: | Brian Aker |
Approved revision: | not available |
Merged at revision: | 1822 |
Proposed branch: | lp:~brianaker/drizzle/bug-fix-654219 |
Merge into: | lp:~drizzle-trunk/drizzle/development |
Diff against target: |
3037 lines (+292/-2456) (has conflicts) 17 files modified
plugin/drizzle_protocol/drizzle_protocol.cc (+34/-883) plugin/drizzle_protocol/drizzle_protocol.h (+15/-66) plugin/drizzle_protocol/errmsg.cc (+1/-93) plugin/drizzle_protocol/errmsg.h (+0/-80) plugin/drizzle_protocol/net_serv.cc (+0/-896) plugin/drizzle_protocol/net_serv.h (+0/-94) plugin/drizzle_protocol/options.h (+0/-125) plugin/drizzle_protocol/pack.cc (+0/-132) plugin/drizzle_protocol/pack.h (+0/-34) plugin/drizzle_protocol/plugin.ini (+10/-5) plugin/drizzle_protocol/status_table.h (+13/-8) plugin/information_schema_dictionary/key_column_usage.cc (+51/-2) plugin/information_schema_dictionary/key_column_usage.h (+3/-0) plugin/information_schema_dictionary/tests/r/key_column_usage.result (+36/-36) tests/include.am (+2/-2) tests/suite/regression/r/654219.result (+63/-0) tests/suite/regression/t/654219.test (+64/-0) Text conflict in plugin/drizzle_protocol/drizzle_protocol.cc Contents conflict in plugin/drizzle_protocol/vio.cc Contents conflict in plugin/drizzle_protocol/vio.h Contents conflict in plugin/drizzle_protocol/viosocket.cc |
To merge this branch: | bzr merge lp:~brianaker/drizzle/bug-fix-654219 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Drizzle Merge Team | Pending | ||
Review via email: mp+37684@code.launchpad.net |
Commit message
Description of the change
This fixes bug 654219.
To post a comment you must log in.
Revision history for this message
Lee Bieber (kalebral-deactivatedaccount) wrote : | # |
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'plugin/drizzle_protocol/drizzle_protocol.cc' | |||
2 | --- plugin/drizzle_protocol/drizzle_protocol.cc 2010-10-02 21:15:42 +0000 | |||
3 | +++ plugin/drizzle_protocol/drizzle_protocol.cc 2010-10-06 01:14:00 +0000 | |||
4 | @@ -1,6 +1,7 @@ | |||
6 | 1 | /* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*- | 1 | /* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*- |
7 | 2 | * vim:expandtab:shiftwidth=2:tabstop=2:smarttab: | 2 | * vim:expandtab:shiftwidth=2:tabstop=2:smarttab: |
8 | 3 | * | 3 | * |
9 | 4 | <<<<<<< TREE | ||
10 | 4 | * Copyright (C) 2008 Sun Microsystems | 5 | * Copyright (C) 2008 Sun Microsystems |
11 | 5 | * | 6 | * |
12 | 6 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
13 | @@ -15,8 +16,26 @@ | |||
14 | 15 | * You should have received a copy of the GNU General Public License | 16 | * You should have received a copy of the GNU General Public License |
15 | 16 | * along with this program; if not, write to the Free Software | 17 | * along with this program; if not, write to the Free Software |
16 | 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
17 | 19 | ======= | ||
18 | 20 | * Copyright (C) 2010 Brian Aker | ||
19 | 21 | * | ||
20 | 22 | * This program is free software; you can redistribute it and/or modify | ||
21 | 23 | * it under the terms of the GNU General Public License as published by | ||
22 | 24 | * the Free Software Foundation; either version 2 of the License, or | ||
23 | 25 | * (at your option) any later version. | ||
24 | 26 | * | ||
25 | 27 | * This program is distributed in the hope that it will be useful, | ||
26 | 28 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
27 | 29 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
28 | 30 | * GNU General Public License for more details. | ||
29 | 31 | * | ||
30 | 32 | * You should have received a copy of the GNU General Public License | ||
31 | 33 | * along with this program; if not, write to the Free Software | ||
32 | 34 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
33 | 35 | >>>>>>> MERGE-SOURCE | ||
34 | 18 | */ | 36 | */ |
35 | 19 | 37 | ||
36 | 38 | |||
37 | 20 | #include "config.h" | 39 | #include "config.h" |
38 | 21 | #include <drizzled/gettext.h> | 40 | #include <drizzled/gettext.h> |
39 | 22 | #include <drizzled/error.h> | 41 | #include <drizzled/error.h> |
40 | @@ -29,13 +48,8 @@ | |||
41 | 29 | #include <iostream> | 48 | #include <iostream> |
42 | 30 | #include <boost/program_options.hpp> | 49 | #include <boost/program_options.hpp> |
43 | 31 | #include <drizzled/module/option_map.h> | 50 | #include <drizzled/module/option_map.h> |
44 | 32 | #include "pack.h" | ||
45 | 33 | #include "errmsg.h" | ||
46 | 34 | #include "drizzle_protocol.h" | 51 | #include "drizzle_protocol.h" |
51 | 35 | #include "options.h" | 52 | #include "plugin/drizzle_protocol/status_table.h" |
48 | 36 | #include "table_function.h" | ||
49 | 37 | |||
50 | 38 | #define PROTOCOL_VERSION 10 | ||
52 | 39 | 53 | ||
53 | 40 | namespace po= boost::program_options; | 54 | namespace po= boost::program_options; |
54 | 41 | using namespace drizzled; | 55 | using namespace drizzled; |
55 | @@ -44,18 +58,15 @@ | |||
56 | 44 | namespace drizzle_protocol | 58 | namespace drizzle_protocol |
57 | 45 | { | 59 | { |
58 | 46 | 60 | ||
59 | 47 | |||
60 | 48 | static const uint32_t DRIZZLE_TCP_PORT= 4427; | ||
61 | 49 | static const unsigned int PACKET_BUFFER_EXTRA_ALLOC= 1024; | ||
62 | 50 | static uint32_t port; | 61 | static uint32_t port; |
63 | 51 | static uint32_t connect_timeout; | 62 | static uint32_t connect_timeout; |
64 | 52 | static uint32_t read_timeout; | 63 | static uint32_t read_timeout; |
65 | 53 | static uint32_t write_timeout; | 64 | static uint32_t write_timeout; |
66 | 54 | static uint32_t retry_count; | 65 | static uint32_t retry_count; |
67 | 55 | static uint32_t buffer_length; | 66 | static uint32_t buffer_length; |
69 | 56 | static char* bind_address= NULL; | 67 | static char* bind_address; |
70 | 57 | 68 | ||
72 | 58 | static plugin::TableFunction* drizzle_status_table_function_ptr= NULL; | 69 | static const uint32_t DRIZZLE_TCP_PORT= 4427; |
73 | 59 | 70 | ||
74 | 60 | ListenDrizzleProtocol::~ListenDrizzleProtocol() | 71 | ListenDrizzleProtocol::~ListenDrizzleProtocol() |
75 | 61 | { | 72 | { |
76 | @@ -70,770 +81,11 @@ | |||
77 | 70 | 81 | ||
78 | 71 | in_port_t ListenDrizzleProtocol::getPort(void) const | 82 | in_port_t ListenDrizzleProtocol::getPort(void) const |
79 | 72 | { | 83 | { |
80 | 73 | char *env; | ||
81 | 74 | |||
82 | 75 | if (port == 0) | ||
83 | 76 | { | ||
84 | 77 | port= DRIZZLE_TCP_PORT; | ||
85 | 78 | |||
86 | 79 | if ((env = getenv("DRIZZLE_TCP_PORT"))) | ||
87 | 80 | port= (uint32_t) atoi(env); | ||
88 | 81 | |||
89 | 82 | assert(port != 0); | ||
90 | 83 | } | ||
91 | 84 | |||
92 | 85 | return (in_port_t) port; | 84 | return (in_port_t) port; |
93 | 86 | } | 85 | } |
94 | 87 | 86 | ||
844 | 88 | plugin::Client *ListenDrizzleProtocol::getClient(int fd) | 87 | static int init(drizzled::module::Context &context) |
845 | 89 | { | 88 | { |
97 | 90 | int new_fd; | ||
98 | 91 | new_fd= acceptTcp(fd); | ||
99 | 92 | if (new_fd == -1) | ||
100 | 93 | return NULL; | ||
101 | 94 | |||
102 | 95 | return new (nothrow) ClientDrizzleProtocol(new_fd, using_mysql41_protocol); | ||
103 | 96 | } | ||
104 | 97 | |||
105 | 98 | drizzled::atomic<uint64_t> ClientDrizzleProtocol::connectionCount; | ||
106 | 99 | drizzled::atomic<uint64_t> ClientDrizzleProtocol::failedConnections; | ||
107 | 100 | drizzled::atomic<uint64_t> ClientDrizzleProtocol::connected; | ||
108 | 101 | |||
109 | 102 | ClientDrizzleProtocol::ClientDrizzleProtocol(int fd, bool using_mysql41_protocol_arg): | ||
110 | 103 | using_mysql41_protocol(using_mysql41_protocol_arg) | ||
111 | 104 | { | ||
112 | 105 | net.vio= 0; | ||
113 | 106 | |||
114 | 107 | if (fd == -1) | ||
115 | 108 | return; | ||
116 | 109 | |||
117 | 110 | if (drizzleclient_net_init_sock(&net, fd, 0, buffer_length)) | ||
118 | 111 | throw bad_alloc(); | ||
119 | 112 | |||
120 | 113 | drizzleclient_net_set_read_timeout(&net, read_timeout); | ||
121 | 114 | drizzleclient_net_set_write_timeout(&net, write_timeout); | ||
122 | 115 | net.retry_count=retry_count; | ||
123 | 116 | } | ||
124 | 117 | |||
125 | 118 | ClientDrizzleProtocol::~ClientDrizzleProtocol() | ||
126 | 119 | { | ||
127 | 120 | if (net.vio) | ||
128 | 121 | drizzleclient_vio_close(net.vio); | ||
129 | 122 | } | ||
130 | 123 | |||
131 | 124 | int ClientDrizzleProtocol::getFileDescriptor(void) | ||
132 | 125 | { | ||
133 | 126 | return drizzleclient_net_get_sd(&net); | ||
134 | 127 | } | ||
135 | 128 | |||
136 | 129 | bool ClientDrizzleProtocol::isConnected() | ||
137 | 130 | { | ||
138 | 131 | return net.vio != 0; | ||
139 | 132 | } | ||
140 | 133 | |||
141 | 134 | bool ClientDrizzleProtocol::isReading(void) | ||
142 | 135 | { | ||
143 | 136 | return net.reading_or_writing == 1; | ||
144 | 137 | } | ||
145 | 138 | |||
146 | 139 | bool ClientDrizzleProtocol::isWriting(void) | ||
147 | 140 | { | ||
148 | 141 | return net.reading_or_writing == 2; | ||
149 | 142 | } | ||
150 | 143 | |||
151 | 144 | bool ClientDrizzleProtocol::flush() | ||
152 | 145 | { | ||
153 | 146 | if (net.vio == NULL) | ||
154 | 147 | return false; | ||
155 | 148 | bool ret= drizzleclient_net_write(&net, (unsigned char*) packet.ptr(), | ||
156 | 149 | packet.length()); | ||
157 | 150 | packet.length(0); | ||
158 | 151 | return ret; | ||
159 | 152 | } | ||
160 | 153 | |||
161 | 154 | void ClientDrizzleProtocol::close(void) | ||
162 | 155 | { | ||
163 | 156 | if (net.vio) | ||
164 | 157 | { | ||
165 | 158 | drizzleclient_net_close(&net); | ||
166 | 159 | drizzleclient_net_end(&net); | ||
167 | 160 | connected.decrement(); | ||
168 | 161 | } | ||
169 | 162 | } | ||
170 | 163 | |||
171 | 164 | bool ClientDrizzleProtocol::authenticate() | ||
172 | 165 | { | ||
173 | 166 | bool connection_is_valid; | ||
174 | 167 | |||
175 | 168 | connectionCount.increment(); | ||
176 | 169 | connected.increment(); | ||
177 | 170 | |||
178 | 171 | /* Use "connect_timeout" value during connection phase */ | ||
179 | 172 | drizzleclient_net_set_read_timeout(&net, connect_timeout); | ||
180 | 173 | drizzleclient_net_set_write_timeout(&net, connect_timeout); | ||
181 | 174 | |||
182 | 175 | connection_is_valid= checkConnection(); | ||
183 | 176 | |||
184 | 177 | if (connection_is_valid) | ||
185 | 178 | sendOK(); | ||
186 | 179 | else | ||
187 | 180 | { | ||
188 | 181 | sendError(session->main_da.sql_errno(), session->main_da.message()); | ||
189 | 182 | failedConnections.increment(); | ||
190 | 183 | return false; | ||
191 | 184 | } | ||
192 | 185 | |||
193 | 186 | /* Connect completed, set read/write timeouts back to default */ | ||
194 | 187 | drizzleclient_net_set_read_timeout(&net, read_timeout); | ||
195 | 188 | drizzleclient_net_set_write_timeout(&net, write_timeout); | ||
196 | 189 | return true; | ||
197 | 190 | } | ||
198 | 191 | |||
199 | 192 | bool ClientDrizzleProtocol::readCommand(char **l_packet, uint32_t *packet_length) | ||
200 | 193 | { | ||
201 | 194 | /* | ||
202 | 195 | This thread will do a blocking read from the client which | ||
203 | 196 | will be interrupted when the next command is received from | ||
204 | 197 | the client, the connection is closed or "net_wait_timeout" | ||
205 | 198 | number of seconds has passed | ||
206 | 199 | */ | ||
207 | 200 | #ifdef NEVER | ||
208 | 201 | /* We can do this much more efficiently with poll timeouts or watcher thread, | ||
209 | 202 | disabling for now, which means net_wait_timeout == read_timeout. */ | ||
210 | 203 | drizzleclient_net_set_read_timeout(&net, | ||
211 | 204 | session->variables.net_wait_timeout); | ||
212 | 205 | #endif | ||
213 | 206 | |||
214 | 207 | net.pkt_nr=0; | ||
215 | 208 | |||
216 | 209 | *packet_length= drizzleclient_net_read(&net); | ||
217 | 210 | if (*packet_length == packet_error) | ||
218 | 211 | { | ||
219 | 212 | /* Check if we can continue without closing the connection */ | ||
220 | 213 | |||
221 | 214 | if(net.last_errno== CR_NET_PACKET_TOO_LARGE) | ||
222 | 215 | my_error(ER_NET_PACKET_TOO_LARGE, MYF(0)); | ||
223 | 216 | if (session->main_da.status() == Diagnostics_area::DA_ERROR) | ||
224 | 217 | sendError(session->main_da.sql_errno(), session->main_da.message()); | ||
225 | 218 | else | ||
226 | 219 | sendOK(); | ||
227 | 220 | |||
228 | 221 | if (net.error != 3) | ||
229 | 222 | return false; // We have to close it. | ||
230 | 223 | |||
231 | 224 | net.error= 0; | ||
232 | 225 | *packet_length= 0; | ||
233 | 226 | return true; | ||
234 | 227 | } | ||
235 | 228 | |||
236 | 229 | *l_packet= (char*) net.read_pos; | ||
237 | 230 | |||
238 | 231 | /* | ||
239 | 232 | 'packet_length' contains length of data, as it was stored in packet | ||
240 | 233 | header. In case of malformed header, drizzleclient_net_read returns zero. | ||
241 | 234 | If packet_length is not zero, drizzleclient_net_read ensures that the returned | ||
242 | 235 | number of bytes was actually read from network. | ||
243 | 236 | There is also an extra safety measure in drizzleclient_net_read: | ||
244 | 237 | it sets packet[packet_length]= 0, but only for non-zero packets. | ||
245 | 238 | */ | ||
246 | 239 | |||
247 | 240 | if (*packet_length == 0) /* safety */ | ||
248 | 241 | { | ||
249 | 242 | /* Initialize with COM_SLEEP packet */ | ||
250 | 243 | (*l_packet)[0]= (unsigned char) COM_SLEEP; | ||
251 | 244 | *packet_length= 1; | ||
252 | 245 | } | ||
253 | 246 | else if (using_mysql41_protocol) | ||
254 | 247 | { | ||
255 | 248 | /* Map from MySQL commands to Drizzle commands. */ | ||
256 | 249 | switch ((int)(*l_packet)[0]) | ||
257 | 250 | { | ||
258 | 251 | case 0: /* SLEEP */ | ||
259 | 252 | case 1: /* QUIT */ | ||
260 | 253 | case 2: /* INIT_DB */ | ||
261 | 254 | case 3: /* QUERY */ | ||
262 | 255 | break; | ||
263 | 256 | |||
264 | 257 | case 8: /* SHUTDOWN */ | ||
265 | 258 | (*l_packet)[0]= (unsigned char) COM_SHUTDOWN; | ||
266 | 259 | break; | ||
267 | 260 | |||
268 | 261 | case 14: /* PING */ | ||
269 | 262 | (*l_packet)[0]= (unsigned char) COM_SHUTDOWN; | ||
270 | 263 | break; | ||
271 | 264 | |||
272 | 265 | |||
273 | 266 | default: | ||
274 | 267 | /* Just drop connection for MySQL commands we don't support. */ | ||
275 | 268 | (*l_packet)[0]= (unsigned char) COM_QUIT; | ||
276 | 269 | *packet_length= 1; | ||
277 | 270 | break; | ||
278 | 271 | } | ||
279 | 272 | } | ||
280 | 273 | |||
281 | 274 | /* Do not rely on drizzleclient_net_read, extra safety against programming errors. */ | ||
282 | 275 | (*l_packet)[*packet_length]= '\0'; /* safety */ | ||
283 | 276 | |||
284 | 277 | #ifdef NEVER | ||
285 | 278 | /* See comment above. */ | ||
286 | 279 | /* Restore read timeout value */ | ||
287 | 280 | drizzleclient_net_set_read_timeout(&net, | ||
288 | 281 | session->variables.net_read_timeout); | ||
289 | 282 | #endif | ||
290 | 283 | |||
291 | 284 | return true; | ||
292 | 285 | } | ||
293 | 286 | |||
294 | 287 | /** | ||
295 | 288 | Return ok to the client. | ||
296 | 289 | |||
297 | 290 | The ok packet has the following structure: | ||
298 | 291 | |||
299 | 292 | - 0 : Marker (1 byte) | ||
300 | 293 | - affected_rows : Stored in 1-9 bytes | ||
301 | 294 | - id : Stored in 1-9 bytes | ||
302 | 295 | - server_status : Copy of session->server_status; Can be used by client | ||
303 | 296 | to check if we are inside an transaction. | ||
304 | 297 | New in 4.0 client | ||
305 | 298 | - warning_count : Stored in 2 bytes; New in 4.1 client | ||
306 | 299 | - message : Stored as packed length (1-9 bytes) + message. | ||
307 | 300 | Is not stored if no message. | ||
308 | 301 | |||
309 | 302 | @param session Thread handler | ||
310 | 303 | @param affected_rows Number of rows changed by statement | ||
311 | 304 | @param id Auto_increment id for first row (if used) | ||
312 | 305 | @param message Message to send to the client (Used by mysql_status) | ||
313 | 306 | */ | ||
314 | 307 | |||
315 | 308 | void ClientDrizzleProtocol::sendOK() | ||
316 | 309 | { | ||
317 | 310 | unsigned char buff[DRIZZLE_ERRMSG_SIZE+10],*pos; | ||
318 | 311 | const char *message= NULL; | ||
319 | 312 | uint32_t tmp; | ||
320 | 313 | |||
321 | 314 | if (!net.vio) // hack for re-parsing queries | ||
322 | 315 | { | ||
323 | 316 | return; | ||
324 | 317 | } | ||
325 | 318 | |||
326 | 319 | buff[0]=0; // No fields | ||
327 | 320 | if (session->main_da.status() == Diagnostics_area::DA_OK) | ||
328 | 321 | { | ||
329 | 322 | if (client_capabilities & CLIENT_FOUND_ROWS && session->main_da.found_rows()) | ||
330 | 323 | pos=drizzleclient_net_store_length(buff+1,session->main_da.found_rows()); | ||
331 | 324 | else | ||
332 | 325 | pos=drizzleclient_net_store_length(buff+1,session->main_da.affected_rows()); | ||
333 | 326 | pos=drizzleclient_net_store_length(pos, session->main_da.last_insert_id()); | ||
334 | 327 | int2store(pos, session->main_da.server_status()); | ||
335 | 328 | pos+=2; | ||
336 | 329 | tmp= min(session->main_da.total_warn_count(), (uint32_t)65535); | ||
337 | 330 | message= session->main_da.message(); | ||
338 | 331 | } | ||
339 | 332 | else | ||
340 | 333 | { | ||
341 | 334 | pos=drizzleclient_net_store_length(buff+1,0); | ||
342 | 335 | pos=drizzleclient_net_store_length(pos, 0); | ||
343 | 336 | int2store(pos, session->server_status); | ||
344 | 337 | pos+=2; | ||
345 | 338 | tmp= min(session->total_warn_count, (uint32_t)65535); | ||
346 | 339 | } | ||
347 | 340 | |||
348 | 341 | /* We can only return up to 65535 warnings in two bytes */ | ||
349 | 342 | int2store(pos, tmp); | ||
350 | 343 | pos+= 2; | ||
351 | 344 | |||
352 | 345 | session->main_da.can_overwrite_status= true; | ||
353 | 346 | |||
354 | 347 | if (message && message[0]) | ||
355 | 348 | { | ||
356 | 349 | size_t length= strlen(message); | ||
357 | 350 | pos=drizzleclient_net_store_length(pos,length); | ||
358 | 351 | memcpy(pos,(unsigned char*) message,length); | ||
359 | 352 | pos+=length; | ||
360 | 353 | } | ||
361 | 354 | drizzleclient_net_write(&net, buff, (size_t) (pos-buff)); | ||
362 | 355 | drizzleclient_net_flush(&net); | ||
363 | 356 | |||
364 | 357 | session->main_da.can_overwrite_status= false; | ||
365 | 358 | } | ||
366 | 359 | |||
367 | 360 | /** | ||
368 | 361 | Send eof (= end of result set) to the client. | ||
369 | 362 | |||
370 | 363 | The eof packet has the following structure: | ||
371 | 364 | |||
372 | 365 | - 254 (DRIZZLE_PROTOCOL_NO_MORE_DATA) : Marker (1 byte) | ||
373 | 366 | - warning_count : Stored in 2 bytes; New in 4.1 client | ||
374 | 367 | - status_flag : Stored in 2 bytes; | ||
375 | 368 | For flags like SERVER_MORE_RESULTS_EXISTS. | ||
376 | 369 | |||
377 | 370 | Note that the warning count will not be sent if 'no_flush' is set as | ||
378 | 371 | we don't want to report the warning count until all data is sent to the | ||
379 | 372 | client. | ||
380 | 373 | */ | ||
381 | 374 | |||
382 | 375 | void ClientDrizzleProtocol::sendEOF() | ||
383 | 376 | { | ||
384 | 377 | /* Set to true if no active vio, to work well in case of --init-file */ | ||
385 | 378 | if (net.vio != 0) | ||
386 | 379 | { | ||
387 | 380 | session->main_da.can_overwrite_status= true; | ||
388 | 381 | writeEOFPacket(session->main_da.server_status(), | ||
389 | 382 | session->main_da.total_warn_count()); | ||
390 | 383 | drizzleclient_net_flush(&net); | ||
391 | 384 | session->main_da.can_overwrite_status= false; | ||
392 | 385 | } | ||
393 | 386 | packet.shrink(buffer_length); | ||
394 | 387 | } | ||
395 | 388 | |||
396 | 389 | |||
397 | 390 | void ClientDrizzleProtocol::sendError(uint32_t sql_errno, const char *err) | ||
398 | 391 | { | ||
399 | 392 | uint32_t length; | ||
400 | 393 | /* | ||
401 | 394 | buff[]: sql_errno:2 + ('#':1 + SQLSTATE_LENGTH:5) + DRIZZLE_ERRMSG_SIZE:512 | ||
402 | 395 | */ | ||
403 | 396 | unsigned char buff[2+1+SQLSTATE_LENGTH+DRIZZLE_ERRMSG_SIZE], *pos; | ||
404 | 397 | |||
405 | 398 | assert(sql_errno); | ||
406 | 399 | assert(err && err[0]); | ||
407 | 400 | |||
408 | 401 | /* | ||
409 | 402 | It's one case when we can push an error even though there | ||
410 | 403 | is an OK or EOF already. | ||
411 | 404 | */ | ||
412 | 405 | session->main_da.can_overwrite_status= true; | ||
413 | 406 | |||
414 | 407 | /* Abort multi-result sets */ | ||
415 | 408 | session->server_status&= ~SERVER_MORE_RESULTS_EXISTS; | ||
416 | 409 | |||
417 | 410 | /** | ||
418 | 411 | Send a error string to client. | ||
419 | 412 | |||
420 | 413 | For SIGNAL/RESIGNAL and GET DIAGNOSTICS functionality it's | ||
421 | 414 | critical that every error that can be intercepted is issued in one | ||
422 | 415 | place only, my_message_sql. | ||
423 | 416 | */ | ||
424 | 417 | |||
425 | 418 | if (net.vio == 0) | ||
426 | 419 | { | ||
427 | 420 | return; | ||
428 | 421 | } | ||
429 | 422 | |||
430 | 423 | int2store(buff,sql_errno); | ||
431 | 424 | pos= buff+2; | ||
432 | 425 | |||
433 | 426 | /* The first # is to make the client backward compatible */ | ||
434 | 427 | buff[2]= '#'; | ||
435 | 428 | pos= (unsigned char*) strcpy((char*) buff+3, drizzle_errno_to_sqlstate(sql_errno)); | ||
436 | 429 | pos+= strlen(drizzle_errno_to_sqlstate(sql_errno)); | ||
437 | 430 | |||
438 | 431 | char *tmp= strncpy((char*)pos, err, DRIZZLE_ERRMSG_SIZE-1); | ||
439 | 432 | tmp+= strlen((char*)pos); | ||
440 | 433 | tmp[0]= '\0'; | ||
441 | 434 | length= (uint32_t)(tmp-(char*)buff); | ||
442 | 435 | err= (char*) buff; | ||
443 | 436 | |||
444 | 437 | drizzleclient_net_write_command(&net,(unsigned char) 255, (unsigned char*) "", 0, (unsigned char*) err, length); | ||
445 | 438 | |||
446 | 439 | session->main_da.can_overwrite_status= false; | ||
447 | 440 | } | ||
448 | 441 | |||
449 | 442 | /** | ||
450 | 443 | Send name and type of result to client. | ||
451 | 444 | |||
452 | 445 | Sum fields has table name empty and field_name. | ||
453 | 446 | |||
454 | 447 | @param Session Thread data object | ||
455 | 448 | @param list List of items to send to client | ||
456 | 449 | @param flag Bit mask with the following functions: | ||
457 | 450 | - 1 send number of rows | ||
458 | 451 | - 2 send default values | ||
459 | 452 | - 4 don't write eof packet | ||
460 | 453 | |||
461 | 454 | @retval | ||
462 | 455 | 0 ok | ||
463 | 456 | @retval | ||
464 | 457 | 1 Error (Note that in this case the error is not sent to the | ||
465 | 458 | client) | ||
466 | 459 | */ | ||
467 | 460 | bool ClientDrizzleProtocol::sendFields(List<Item> *list) | ||
468 | 461 | { | ||
469 | 462 | List_iterator_fast<Item> it(*list); | ||
470 | 463 | Item *item; | ||
471 | 464 | unsigned char buff[80]; | ||
472 | 465 | String tmp((char*) buff,sizeof(buff),&my_charset_bin); | ||
473 | 466 | |||
474 | 467 | unsigned char *row_pos= drizzleclient_net_store_length(buff, list->elements); | ||
475 | 468 | (void) drizzleclient_net_write(&net, buff, (size_t) (row_pos-buff)); | ||
476 | 469 | |||
477 | 470 | while ((item=it++)) | ||
478 | 471 | { | ||
479 | 472 | char *pos; | ||
480 | 473 | SendField field; | ||
481 | 474 | item->make_field(&field); | ||
482 | 475 | |||
483 | 476 | packet.length(0); | ||
484 | 477 | |||
485 | 478 | if (store(STRING_WITH_LEN("def")) || | ||
486 | 479 | store(field.db_name) || | ||
487 | 480 | store(field.table_name) || | ||
488 | 481 | store(field.org_table_name) || | ||
489 | 482 | store(field.col_name) || | ||
490 | 483 | store(field.org_col_name) || | ||
491 | 484 | packet.realloc(packet.length()+12)) | ||
492 | 485 | goto err; | ||
493 | 486 | |||
494 | 487 | /* Store fixed length fields */ | ||
495 | 488 | pos= (char*) packet.ptr()+packet.length(); | ||
496 | 489 | *pos++= 12; // Length of packed fields | ||
497 | 490 | /* No conversion */ | ||
498 | 491 | int2store(pos, field.charsetnr); | ||
499 | 492 | int4store(pos+2, field.length); | ||
500 | 493 | |||
501 | 494 | if (using_mysql41_protocol) | ||
502 | 495 | { | ||
503 | 496 | /* Switch to MySQL field numbering. */ | ||
504 | 497 | switch (field.type) | ||
505 | 498 | { | ||
506 | 499 | case DRIZZLE_TYPE_LONG: | ||
507 | 500 | pos[6]= 3; | ||
508 | 501 | break; | ||
509 | 502 | |||
510 | 503 | case DRIZZLE_TYPE_DOUBLE: | ||
511 | 504 | pos[6]= 5; | ||
512 | 505 | break; | ||
513 | 506 | |||
514 | 507 | case DRIZZLE_TYPE_NULL: | ||
515 | 508 | pos[6]= 6; | ||
516 | 509 | break; | ||
517 | 510 | |||
518 | 511 | case DRIZZLE_TYPE_TIMESTAMP: | ||
519 | 512 | pos[6]= 7; | ||
520 | 513 | break; | ||
521 | 514 | |||
522 | 515 | case DRIZZLE_TYPE_LONGLONG: | ||
523 | 516 | pos[6]= 8; | ||
524 | 517 | break; | ||
525 | 518 | |||
526 | 519 | case DRIZZLE_TYPE_DATETIME: | ||
527 | 520 | pos[6]= 12; | ||
528 | 521 | break; | ||
529 | 522 | |||
530 | 523 | case DRIZZLE_TYPE_DATE: | ||
531 | 524 | pos[6]= 14; | ||
532 | 525 | break; | ||
533 | 526 | |||
534 | 527 | case DRIZZLE_TYPE_VARCHAR: | ||
535 | 528 | pos[6]= 15; | ||
536 | 529 | break; | ||
537 | 530 | |||
538 | 531 | case DRIZZLE_TYPE_DECIMAL: | ||
539 | 532 | pos[6]= (char)246; | ||
540 | 533 | break; | ||
541 | 534 | |||
542 | 535 | case DRIZZLE_TYPE_ENUM: | ||
543 | 536 | pos[6]= (char)247; | ||
544 | 537 | break; | ||
545 | 538 | |||
546 | 539 | case DRIZZLE_TYPE_BLOB: | ||
547 | 540 | pos[6]= (char)252; | ||
548 | 541 | break; | ||
549 | 542 | } | ||
550 | 543 | } | ||
551 | 544 | else | ||
552 | 545 | { | ||
553 | 546 | /* Add one to compensate for tinyint removal from enum. */ | ||
554 | 547 | pos[6]= field.type + 1; | ||
555 | 548 | } | ||
556 | 549 | |||
557 | 550 | int2store(pos+7,field.flags); | ||
558 | 551 | pos[9]= (char) field.decimals; | ||
559 | 552 | pos[10]= 0; // For the future | ||
560 | 553 | pos[11]= 0; // For the future | ||
561 | 554 | pos+= 12; | ||
562 | 555 | |||
563 | 556 | packet.length((uint32_t) (pos - packet.ptr())); | ||
564 | 557 | if (flush()) | ||
565 | 558 | break; | ||
566 | 559 | } | ||
567 | 560 | |||
568 | 561 | /* | ||
569 | 562 | Mark the end of meta-data result set, and store session->server_status, | ||
570 | 563 | to show that there is no cursor. | ||
571 | 564 | Send no warning information, as it will be sent at statement end. | ||
572 | 565 | */ | ||
573 | 566 | writeEOFPacket(session->server_status, session->total_warn_count); | ||
574 | 567 | return 0; | ||
575 | 568 | |||
576 | 569 | err: | ||
577 | 570 | my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), | ||
578 | 571 | MYF(0)); | ||
579 | 572 | return 1; | ||
580 | 573 | } | ||
581 | 574 | |||
582 | 575 | bool ClientDrizzleProtocol::store(Field *from) | ||
583 | 576 | { | ||
584 | 577 | if (from->is_null()) | ||
585 | 578 | return store(); | ||
586 | 579 | char buff[MAX_FIELD_WIDTH]; | ||
587 | 580 | String str(buff,sizeof(buff), &my_charset_bin); | ||
588 | 581 | |||
589 | 582 | from->val_str(&str); | ||
590 | 583 | |||
591 | 584 | return netStoreData((const unsigned char *)str.ptr(), str.length()); | ||
592 | 585 | } | ||
593 | 586 | |||
594 | 587 | bool ClientDrizzleProtocol::store(void) | ||
595 | 588 | { | ||
596 | 589 | char buff[1]; | ||
597 | 590 | buff[0]= (char)251; | ||
598 | 591 | return packet.append(buff, sizeof(buff), PACKET_BUFFER_EXTRA_ALLOC); | ||
599 | 592 | } | ||
600 | 593 | |||
601 | 594 | bool ClientDrizzleProtocol::store(int32_t from) | ||
602 | 595 | { | ||
603 | 596 | char buff[12]; | ||
604 | 597 | return netStoreData((unsigned char*) buff, | ||
605 | 598 | (size_t) (internal::int10_to_str(from, buff, -10) - buff)); | ||
606 | 599 | } | ||
607 | 600 | |||
608 | 601 | bool ClientDrizzleProtocol::store(uint32_t from) | ||
609 | 602 | { | ||
610 | 603 | char buff[11]; | ||
611 | 604 | return netStoreData((unsigned char*) buff, | ||
612 | 605 | (size_t) (internal::int10_to_str(from, buff, 10) - buff)); | ||
613 | 606 | } | ||
614 | 607 | |||
615 | 608 | bool ClientDrizzleProtocol::store(int64_t from) | ||
616 | 609 | { | ||
617 | 610 | char buff[22]; | ||
618 | 611 | return netStoreData((unsigned char*) buff, | ||
619 | 612 | (size_t) (internal::int64_t10_to_str(from, buff, -10) - buff)); | ||
620 | 613 | } | ||
621 | 614 | |||
622 | 615 | bool ClientDrizzleProtocol::store(uint64_t from) | ||
623 | 616 | { | ||
624 | 617 | char buff[21]; | ||
625 | 618 | return netStoreData((unsigned char*) buff, | ||
626 | 619 | (size_t) (internal::int64_t10_to_str(from, buff, 10) - buff)); | ||
627 | 620 | } | ||
628 | 621 | |||
629 | 622 | bool ClientDrizzleProtocol::store(double from, uint32_t decimals, String *buffer) | ||
630 | 623 | { | ||
631 | 624 | buffer->set_real(from, decimals, session->charset()); | ||
632 | 625 | return netStoreData((unsigned char*) buffer->ptr(), buffer->length()); | ||
633 | 626 | } | ||
634 | 627 | |||
635 | 628 | bool ClientDrizzleProtocol::store(const char *from, size_t length) | ||
636 | 629 | { | ||
637 | 630 | return netStoreData((const unsigned char *)from, length); | ||
638 | 631 | } | ||
639 | 632 | |||
640 | 633 | bool ClientDrizzleProtocol::wasAborted(void) | ||
641 | 634 | { | ||
642 | 635 | return net.error && net.vio != 0; | ||
643 | 636 | } | ||
644 | 637 | |||
645 | 638 | bool ClientDrizzleProtocol::haveMoreData(void) | ||
646 | 639 | { | ||
647 | 640 | return drizzleclient_net_more_data(&net); | ||
648 | 641 | } | ||
649 | 642 | |||
650 | 643 | bool ClientDrizzleProtocol::haveError(void) | ||
651 | 644 | { | ||
652 | 645 | return net.error || net.vio == 0; | ||
653 | 646 | } | ||
654 | 647 | |||
655 | 648 | bool ClientDrizzleProtocol::checkConnection(void) | ||
656 | 649 | { | ||
657 | 650 | uint32_t pkt_len= 0; | ||
658 | 651 | char *end; | ||
659 | 652 | |||
660 | 653 | // TCP/IP connection | ||
661 | 654 | { | ||
662 | 655 | char ip[NI_MAXHOST]; | ||
663 | 656 | uint16_t peer_port; | ||
664 | 657 | |||
665 | 658 | if (drizzleclient_net_peer_addr(&net, ip, &peer_port, NI_MAXHOST)) | ||
666 | 659 | { | ||
667 | 660 | my_error(ER_BAD_HOST_ERROR, MYF(0), session->getSecurityContext().getIp().c_str()); | ||
668 | 661 | return false; | ||
669 | 662 | } | ||
670 | 663 | |||
671 | 664 | session->getSecurityContext().setIp(ip); | ||
672 | 665 | } | ||
673 | 666 | drizzleclient_net_keepalive(&net, true); | ||
674 | 667 | |||
675 | 668 | uint32_t server_capabilites; | ||
676 | 669 | { | ||
677 | 670 | /* buff[] needs to big enough to hold the server_version variable */ | ||
678 | 671 | char buff[SERVER_VERSION_LENGTH + SCRAMBLE_LENGTH + 64]; | ||
679 | 672 | |||
680 | 673 | server_capabilites= CLIENT_BASIC_FLAGS; | ||
681 | 674 | |||
682 | 675 | if (using_mysql41_protocol) | ||
683 | 676 | server_capabilites|= CLIENT_PROTOCOL_MYSQL41; | ||
684 | 677 | |||
685 | 678 | #ifdef HAVE_COMPRESS | ||
686 | 679 | server_capabilites|= CLIENT_COMPRESS; | ||
687 | 680 | #endif /* HAVE_COMPRESS */ | ||
688 | 681 | |||
689 | 682 | end= buff + strlen(PANDORA_RELEASE_VERSION); | ||
690 | 683 | if ((end - buff) >= SERVER_VERSION_LENGTH) | ||
691 | 684 | end= buff + (SERVER_VERSION_LENGTH - 1); | ||
692 | 685 | memcpy(buff, PANDORA_RELEASE_VERSION, end - buff); | ||
693 | 686 | *end= 0; | ||
694 | 687 | end++; | ||
695 | 688 | |||
696 | 689 | int4store((unsigned char*) end, session->variables.pseudo_thread_id); | ||
697 | 690 | end+= 4; | ||
698 | 691 | |||
699 | 692 | /* We don't use scramble anymore. */ | ||
700 | 693 | memset(end, 'X', SCRAMBLE_LENGTH_323); | ||
701 | 694 | end+= SCRAMBLE_LENGTH_323; | ||
702 | 695 | *end++= 0; /* an empty byte for some reason */ | ||
703 | 696 | |||
704 | 697 | int2store(end, server_capabilites); | ||
705 | 698 | /* write server characteristics: up to 16 bytes allowed */ | ||
706 | 699 | end[2]=(char) default_charset_info->number; | ||
707 | 700 | int2store(end+3, session->server_status); | ||
708 | 701 | memset(end+5, 0, 13); | ||
709 | 702 | end+= 18; | ||
710 | 703 | |||
711 | 704 | /* Write scramble tail. */ | ||
712 | 705 | memset(end, 'X', SCRAMBLE_LENGTH - SCRAMBLE_LENGTH_323); | ||
713 | 706 | end+= (SCRAMBLE_LENGTH - SCRAMBLE_LENGTH_323); | ||
714 | 707 | *end++= 0; /* an empty byte for some reason */ | ||
715 | 708 | |||
716 | 709 | /* At this point we write connection message and read reply */ | ||
717 | 710 | if (drizzleclient_net_write_command(&net | ||
718 | 711 | , (unsigned char) PROTOCOL_VERSION | ||
719 | 712 | , (unsigned char*) "" | ||
720 | 713 | , 0 | ||
721 | 714 | , (unsigned char*) buff | ||
722 | 715 | , (size_t) (end-buff)) | ||
723 | 716 | || (pkt_len= drizzleclient_net_read(&net)) == packet_error | ||
724 | 717 | || pkt_len < MIN_HANDSHAKE_SIZE) | ||
725 | 718 | { | ||
726 | 719 | my_error(ER_HANDSHAKE_ERROR, MYF(0), session->getSecurityContext().getIp().c_str()); | ||
727 | 720 | return false; | ||
728 | 721 | } | ||
729 | 722 | } | ||
730 | 723 | if (packet.alloc(buffer_length)) | ||
731 | 724 | return false; /* The error is set by alloc(). */ | ||
732 | 725 | |||
733 | 726 | client_capabilities= uint2korr(net.read_pos); | ||
734 | 727 | |||
735 | 728 | |||
736 | 729 | client_capabilities|= ((uint32_t) uint2korr(net.read_pos + 2)) << 16; | ||
737 | 730 | session->max_client_packet_length= uint4korr(net.read_pos + 4); | ||
738 | 731 | end= (char*) net.read_pos + 32; | ||
739 | 732 | |||
740 | 733 | /* | ||
741 | 734 | Disable those bits which are not supported by the server. | ||
742 | 735 | This is a precautionary measure, if the client lies. See Bug#27944. | ||
743 | 736 | */ | ||
744 | 737 | client_capabilities&= server_capabilites; | ||
745 | 738 | |||
746 | 739 | if (end >= (char*) net.read_pos + pkt_len + 2) | ||
747 | 740 | { | ||
748 | 741 | my_error(ER_HANDSHAKE_ERROR, MYF(0), session->getSecurityContext().getIp().c_str()); | ||
749 | 742 | return false; | ||
750 | 743 | } | ||
751 | 744 | |||
752 | 745 | net.return_status= &session->server_status; | ||
753 | 746 | |||
754 | 747 | char *user= end; | ||
755 | 748 | char *passwd= strchr(user, '\0')+1; | ||
756 | 749 | uint32_t user_len= passwd - user - 1; | ||
757 | 750 | char *l_db= passwd; | ||
758 | 751 | |||
759 | 752 | /* | ||
760 | 753 | Old clients send null-terminated string as password; new clients send | ||
761 | 754 | the size (1 byte) + string (not null-terminated). Hence in case of empty | ||
762 | 755 | password both send '\0'. | ||
763 | 756 | |||
764 | 757 | This strlen() can't be easily deleted without changing client. | ||
765 | 758 | |||
766 | 759 | Cast *passwd to an unsigned char, so that it doesn't extend the sign for | ||
767 | 760 | *passwd > 127 and become 2**32-127+ after casting to uint. | ||
768 | 761 | */ | ||
769 | 762 | uint32_t passwd_len= client_capabilities & CLIENT_SECURE_CONNECTION ? | ||
770 | 763 | (unsigned char)(*passwd++) : strlen(passwd); | ||
771 | 764 | l_db= client_capabilities & CLIENT_CONNECT_WITH_DB ? l_db + passwd_len + 1 : 0; | ||
772 | 765 | |||
773 | 766 | /* strlen() can't be easily deleted without changing client */ | ||
774 | 767 | uint32_t db_len= l_db ? strlen(l_db) : 0; | ||
775 | 768 | |||
776 | 769 | if (passwd + passwd_len + db_len > (char *) net.read_pos + pkt_len) | ||
777 | 770 | { | ||
778 | 771 | my_error(ER_HANDSHAKE_ERROR, MYF(0), session->getSecurityContext().getIp().c_str()); | ||
779 | 772 | return false; | ||
780 | 773 | } | ||
781 | 774 | |||
782 | 775 | /* If username starts and ends in "'", chop them off */ | ||
783 | 776 | if (user_len > 1 && user[0] == '\'' && user[user_len - 1] == '\'') | ||
784 | 777 | { | ||
785 | 778 | user[user_len-1]= 0; | ||
786 | 779 | user++; | ||
787 | 780 | user_len-= 2; | ||
788 | 781 | } | ||
789 | 782 | |||
790 | 783 | session->getSecurityContext().setUser(user); | ||
791 | 784 | |||
792 | 785 | return session->checkUser(passwd, passwd_len, l_db); | ||
793 | 786 | } | ||
794 | 787 | |||
795 | 788 | bool ClientDrizzleProtocol::netStoreData(const unsigned char *from, size_t length) | ||
796 | 789 | { | ||
797 | 790 | size_t packet_length= packet.length(); | ||
798 | 791 | /* | ||
799 | 792 | The +9 comes from that strings of length longer than 16M require | ||
800 | 793 | 9 bytes to be stored (see drizzleclient_net_store_length). | ||
801 | 794 | */ | ||
802 | 795 | if (packet_length+9+length > packet.alloced_length() && | ||
803 | 796 | packet.realloc(packet_length+9+length)) | ||
804 | 797 | return 1; | ||
805 | 798 | unsigned char *to= drizzleclient_net_store_length((unsigned char*) packet.ptr()+packet_length, length); | ||
806 | 799 | memcpy(to,from,length); | ||
807 | 800 | packet.length((size_t) (to+length-(unsigned char*) packet.ptr())); | ||
808 | 801 | return 0; | ||
809 | 802 | } | ||
810 | 803 | |||
811 | 804 | /** | ||
812 | 805 | Format EOF packet according to the current client and | ||
813 | 806 | write it to the network output buffer. | ||
814 | 807 | */ | ||
815 | 808 | |||
816 | 809 | void ClientDrizzleProtocol::writeEOFPacket(uint32_t server_status, | ||
817 | 810 | uint32_t total_warn_count) | ||
818 | 811 | { | ||
819 | 812 | unsigned char buff[5]; | ||
820 | 813 | /* | ||
821 | 814 | Don't send warn count during SP execution, as the warn_list | ||
822 | 815 | is cleared between substatements, and mysqltest gets confused | ||
823 | 816 | */ | ||
824 | 817 | uint32_t tmp= min(total_warn_count, (uint32_t)65535); | ||
825 | 818 | buff[0]= DRIZZLE_PROTOCOL_NO_MORE_DATA; | ||
826 | 819 | int2store(buff+1, tmp); | ||
827 | 820 | /* | ||
828 | 821 | The following test should never be true, but it's better to do it | ||
829 | 822 | because if 'is_fatal_error' is set the server is not going to execute | ||
830 | 823 | other queries (see the if test in dispatch_command / COM_QUERY) | ||
831 | 824 | */ | ||
832 | 825 | if (session->is_fatal_error) | ||
833 | 826 | server_status&= ~SERVER_MORE_RESULTS_EXISTS; | ||
834 | 827 | int2store(buff + 3, server_status); | ||
835 | 828 | drizzleclient_net_write(&net, buff, 5); | ||
836 | 829 | } | ||
837 | 830 | |||
838 | 831 | static int init(module::Context &context) | ||
839 | 832 | { | ||
840 | 833 | drizzle_status_table_function_ptr= new DrizzleProtocolStatus; | ||
841 | 834 | |||
842 | 835 | context.add(drizzle_status_table_function_ptr); | ||
843 | 836 | |||
846 | 837 | const module::option_map &vm= context.getOptions(); | 89 | const module::option_map &vm= context.getOptions(); |
847 | 838 | if (vm.count("port")) | 90 | if (vm.count("port")) |
848 | 839 | { | 91 | { |
849 | @@ -875,7 +127,7 @@ | |||
850 | 875 | { | 127 | { |
851 | 876 | if (retry_count < 1 || retry_count > 100) | 128 | if (retry_count < 1 || retry_count > 100) |
852 | 877 | { | 129 | { |
854 | 878 | errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for retry_count\n")); | 130 | errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for retry_count")); |
855 | 879 | exit(-1); | 131 | exit(-1); |
856 | 880 | } | 132 | } |
857 | 881 | } | 133 | } |
858 | @@ -898,17 +150,16 @@ | |||
859 | 898 | { | 150 | { |
860 | 899 | bind_address= NULL; | 151 | bind_address= NULL; |
861 | 900 | } | 152 | } |
864 | 901 | 153 | ||
865 | 902 | context.add(new ListenDrizzleProtocol("drizzle_protocol", false)); | 154 | context.add(new StatusTable); |
866 | 155 | context.add(new ListenDrizzleProtocol("drizzle_protocol", true)); | ||
867 | 156 | |||
868 | 903 | return 0; | 157 | return 0; |
869 | 904 | } | 158 | } |
870 | 905 | 159 | ||
871 | 906 | static DRIZZLE_SYSVAR_UINT(port, port, PLUGIN_VAR_RQCMDARG, | 160 | static DRIZZLE_SYSVAR_UINT(port, port, PLUGIN_VAR_RQCMDARG, |
877 | 907 | N_("Port number to use for connection or 0 for " | 161 | N_("Port number to use for connection or 0 for default to with Drizzle/MySQL protocol."), |
878 | 908 | "default to, in order of " | 162 | NULL, NULL, DRIZZLE_TCP_PORT, 0, 65535, 0); |
874 | 909 | "preference, drizzle.cnf, $DRIZZLE_TCP_PORT, " | ||
875 | 910 | "built-in default (4427)."), | ||
876 | 911 | NULL, NULL, 0, 0, 65535, 0); | ||
879 | 912 | static DRIZZLE_SYSVAR_UINT(connect_timeout, connect_timeout, | 163 | static DRIZZLE_SYSVAR_UINT(connect_timeout, connect_timeout, |
880 | 913 | PLUGIN_VAR_RQCMDARG, N_("Connect Timeout."), | 164 | PLUGIN_VAR_RQCMDARG, N_("Connect Timeout."), |
881 | 914 | NULL, NULL, 10, 1, 300, 0); | 165 | NULL, NULL, 10, 1, 300, 0); |
882 | @@ -927,11 +178,8 @@ | |||
883 | 927 | static void init_options(drizzled::module::option_context &context) | 178 | static void init_options(drizzled::module::option_context &context) |
884 | 928 | { | 179 | { |
885 | 929 | context("port", | 180 | context("port", |
891 | 930 | po::value<uint32_t>(&port)->default_value(0), | 181 | po::value<uint32_t>(&port)->default_value(DRIZZLE_TCP_PORT), |
892 | 931 | N_("Port number to use for connection or 0 for " | 182 | N_("Port number to use for connection or 0 for default to with Drizzle/MySQL protocol.")); |
888 | 932 | "default to, in order of " | ||
889 | 933 | "preference, drizzle.cnf, $DRIZZLE_TCP_PORT, " | ||
890 | 934 | "built-in default (4427).")); | ||
893 | 935 | context("connect-timeout", | 183 | context("connect-timeout", |
894 | 936 | po::value<uint32_t>(&connect_timeout)->default_value(10), | 184 | po::value<uint32_t>(&connect_timeout)->default_value(10), |
895 | 937 | N_("Connect Timeout.")); | 185 | N_("Connect Timeout.")); |
896 | @@ -963,103 +211,6 @@ | |||
897 | 963 | NULL | 211 | NULL |
898 | 964 | }; | 212 | }; |
899 | 965 | 213 | ||
900 | 966 | static int drizzle_protocol_connection_count_func(drizzle_show_var *var, char *buff) | ||
901 | 967 | { | ||
902 | 968 | var->type= SHOW_LONGLONG; | ||
903 | 969 | var->value= buff; | ||
904 | 970 | *((uint64_t *)buff)= ClientDrizzleProtocol::connectionCount; | ||
905 | 971 | return 0; | ||
906 | 972 | } | ||
907 | 973 | |||
908 | 974 | static int drizzle_protocol_connected_count_func(drizzle_show_var *var, char *buff) | ||
909 | 975 | { | ||
910 | 976 | var->type= SHOW_LONGLONG; | ||
911 | 977 | var->value= buff; | ||
912 | 978 | *((uint64_t *)buff)= ClientDrizzleProtocol::connected; | ||
913 | 979 | return 0; | ||
914 | 980 | } | ||
915 | 981 | |||
916 | 982 | static int drizzle_protocol_failed_count_func(drizzle_show_var *var, char *buff) | ||
917 | 983 | { | ||
918 | 984 | var->type= SHOW_LONGLONG; | ||
919 | 985 | var->value= buff; | ||
920 | 986 | *((uint64_t *)buff)= ClientDrizzleProtocol::failedConnections; | ||
921 | 987 | return 0; | ||
922 | 988 | } | ||
923 | 989 | |||
924 | 990 | static st_show_var_func_container drizzle_protocol_connection_count= | ||
925 | 991 | { &drizzle_protocol_connection_count_func }; | ||
926 | 992 | |||
927 | 993 | static st_show_var_func_container drizzle_protocol_connected_count= | ||
928 | 994 | { &drizzle_protocol_connected_count_func }; | ||
929 | 995 | |||
930 | 996 | static st_show_var_func_container drizzle_protocol_failed_count= | ||
931 | 997 | { &drizzle_protocol_failed_count_func }; | ||
932 | 998 | |||
933 | 999 | static drizzle_show_var drizzle_protocol_status_variables[]= { | ||
934 | 1000 | {"Connections", | ||
935 | 1001 | (char*) &drizzle_protocol_connection_count, SHOW_FUNC}, | ||
936 | 1002 | {"Connected", | ||
937 | 1003 | (char*) &drizzle_protocol_connected_count, SHOW_FUNC}, | ||
938 | 1004 | {"Failed_connections", | ||
939 | 1005 | (char*) &drizzle_protocol_failed_count, SHOW_FUNC}, | ||
940 | 1006 | {NULL, NULL, SHOW_LONGLONG} | ||
941 | 1007 | }; | ||
942 | 1008 | |||
943 | 1009 | DrizzleProtocolStatus::Generator::Generator(drizzled::Field **fields) : | ||
944 | 1010 | plugin::TableFunction::Generator(fields) | ||
945 | 1011 | { | ||
946 | 1012 | status_var_ptr= drizzle_protocol_status_variables; | ||
947 | 1013 | } | ||
948 | 1014 | |||
949 | 1015 | bool DrizzleProtocolStatus::Generator::populate() | ||
950 | 1016 | { | ||
951 | 1017 | MY_ALIGNED_BYTE_ARRAY(buff_data, SHOW_VAR_FUNC_BUFF_SIZE, int64_t); | ||
952 | 1018 | char * const buff= (char *) &buff_data; | ||
953 | 1019 | drizzle_show_var tmp; | ||
954 | 1020 | |||
955 | 1021 | if (status_var_ptr->name) | ||
956 | 1022 | { | ||
957 | 1023 | std::ostringstream oss; | ||
958 | 1024 | string return_value; | ||
959 | 1025 | const char *value; | ||
960 | 1026 | int type; | ||
961 | 1027 | |||
962 | 1028 | push(status_var_ptr->name); | ||
963 | 1029 | |||
964 | 1030 | if (status_var_ptr->type == SHOW_FUNC) | ||
965 | 1031 | { | ||
966 | 1032 | ((mysql_show_var_func)((st_show_var_func_container *)status_var_ptr->value)->func)(&tmp, buff); | ||
967 | 1033 | value= buff; | ||
968 | 1034 | type= tmp.type; | ||
969 | 1035 | } | ||
970 | 1036 | else | ||
971 | 1037 | { | ||
972 | 1038 | value= status_var_ptr->value; | ||
973 | 1039 | type= status_var_ptr->type; | ||
974 | 1040 | } | ||
975 | 1041 | |||
976 | 1042 | switch(type) | ||
977 | 1043 | { | ||
978 | 1044 | case SHOW_LONGLONG: | ||
979 | 1045 | oss << *(uint64_t*) value; | ||
980 | 1046 | return_value= oss.str(); | ||
981 | 1047 | break; | ||
982 | 1048 | default: | ||
983 | 1049 | assert(0); | ||
984 | 1050 | } | ||
985 | 1051 | if (return_value.length()) | ||
986 | 1052 | push(return_value); | ||
987 | 1053 | else | ||
988 | 1054 | push(" "); | ||
989 | 1055 | |||
990 | 1056 | status_var_ptr++; | ||
991 | 1057 | |||
992 | 1058 | return true; | ||
993 | 1059 | } | ||
994 | 1060 | return false; | ||
995 | 1061 | } | ||
996 | 1062 | |||
997 | 1063 | } /* namespace drizzle_protocol */ | 214 | } /* namespace drizzle_protocol */ |
998 | 1064 | 215 | ||
999 | 1065 | DRIZZLE_PLUGIN(drizzle_protocol::init, drizzle_protocol::sys_variables, drizzle_protocol::init_options); | 216 | DRIZZLE_PLUGIN(drizzle_protocol::init, drizzle_protocol::sys_variables, drizzle_protocol::init_options); |
1000 | 1066 | 217 | ||
1001 | === modified file 'plugin/drizzle_protocol/drizzle_protocol.h' | |||
1002 | --- plugin/drizzle_protocol/drizzle_protocol.h 2010-09-01 19:17:03 +0000 | |||
1003 | +++ plugin/drizzle_protocol/drizzle_protocol.h 2010-10-06 01:14:00 +0000 | |||
1004 | @@ -1,11 +1,12 @@ | |||
1006 | 1 | /* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*- | 1 | /* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*- |
1007 | 2 | * vim:expandtab:shiftwidth=2:tabstop=2:smarttab: | 2 | * vim:expandtab:shiftwidth=2:tabstop=2:smarttab: |
1008 | 3 | * | 3 | * |
1010 | 4 | * Copyright (C) 2008 Sun Microsystems | 4 | * Copyright (C) 2010 Brian Aker |
1011 | 5 | * | 5 | * |
1012 | 6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
1013 | 7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
1015 | 8 | * the Free Software Foundation; version 2 of the License. | 8 | * the Free Software Foundation; either version 2 of the License, or |
1016 | 9 | * (at your option) any later version. | ||
1017 | 9 | * | 10 | * |
1018 | 10 | * This program is distributed in the hope that it will be useful, | 11 | * This program is distributed in the hope that it will be useful, |
1019 | 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1020 | @@ -17,6 +18,7 @@ | |||
1021 | 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
1022 | 18 | */ | 19 | */ |
1023 | 19 | 20 | ||
1024 | 21 | |||
1025 | 20 | #ifndef PLUGIN_DRIZZLE_PROTOCOL_DRIZZLE_PROTOCOL_H | 22 | #ifndef PLUGIN_DRIZZLE_PROTOCOL_DRIZZLE_PROTOCOL_H |
1026 | 21 | #define PLUGIN_DRIZZLE_PROTOCOL_DRIZZLE_PROTOCOL_H | 23 | #define PLUGIN_DRIZZLE_PROTOCOL_DRIZZLE_PROTOCOL_H |
1027 | 22 | 24 | ||
1028 | @@ -25,77 +27,24 @@ | |||
1029 | 25 | #include <drizzled/atomics.h> | 27 | #include <drizzled/atomics.h> |
1030 | 26 | #include "drizzled/plugin/table_function.h" | 28 | #include "drizzled/plugin/table_function.h" |
1031 | 27 | 29 | ||
1033 | 28 | #include "net_serv.h" | 30 | #include "plugin/mysql_protocol/mysql_protocol.h" |
1034 | 29 | 31 | ||
1035 | 30 | namespace drizzle_protocol | 32 | namespace drizzle_protocol |
1036 | 31 | { | 33 | { |
1037 | 32 | 34 | ||
1039 | 33 | class ListenDrizzleProtocol: public drizzled::plugin::ListenTcp | 35 | class ListenDrizzleProtocol: public ListenMySQLProtocol |
1040 | 34 | { | 36 | { |
1041 | 35 | private: | ||
1042 | 36 | bool using_mysql41_protocol; | ||
1043 | 37 | |||
1044 | 38 | public: | 37 | public: |
1045 | 39 | ListenDrizzleProtocol(std::string name_arg, bool using_mysql41_protocol_arg): | 38 | ListenDrizzleProtocol(std::string name_arg, bool using_mysql41_protocol_arg): |
1048 | 40 | drizzled::plugin::ListenTcp(name_arg), | 39 | ListenMySQLProtocol(name_arg, using_mysql41_protocol_arg) |
1047 | 41 | using_mysql41_protocol(using_mysql41_protocol_arg) | ||
1049 | 42 | { } | 40 | { } |
1106 | 43 | virtual ~ListenDrizzleProtocol(); | 41 | |
1107 | 44 | virtual const char* getHost(void) const; | 42 | ~ListenDrizzleProtocol(); |
1108 | 45 | virtual in_port_t getPort(void) const; | 43 | |
1109 | 46 | virtual drizzled::plugin::Client *getClient(int fd); | 44 | const char* getHost(void) const; |
1110 | 47 | }; | 45 | in_port_t getPort(void) const; |
1111 | 48 | 46 | }; | |
1112 | 49 | class ClientDrizzleProtocol: public drizzled::plugin::Client | 47 | |
1057 | 50 | { | ||
1058 | 51 | private: | ||
1059 | 52 | NET net; | ||
1060 | 53 | drizzled::String packet; | ||
1061 | 54 | uint32_t client_capabilities; | ||
1062 | 55 | bool using_mysql41_protocol; | ||
1063 | 56 | |||
1064 | 57 | bool checkConnection(void); | ||
1065 | 58 | bool netStoreData(const unsigned char *from, size_t length); | ||
1066 | 59 | void writeEOFPacket(uint32_t server_status, uint32_t total_warn_count); | ||
1067 | 60 | |||
1068 | 61 | public: | ||
1069 | 62 | ClientDrizzleProtocol(int fd, bool using_mysql41_protocol_arg); | ||
1070 | 63 | virtual ~ClientDrizzleProtocol(); | ||
1071 | 64 | |||
1072 | 65 | static drizzled::atomic<uint64_t> connectionCount; | ||
1073 | 66 | static drizzled::atomic<uint64_t> failedConnections; | ||
1074 | 67 | static drizzled::atomic<uint64_t> connected; | ||
1075 | 68 | |||
1076 | 69 | virtual int getFileDescriptor(void); | ||
1077 | 70 | virtual bool isConnected(); | ||
1078 | 71 | virtual bool isReading(void); | ||
1079 | 72 | virtual bool isWriting(void); | ||
1080 | 73 | virtual bool flush(void); | ||
1081 | 74 | virtual void close(void); | ||
1082 | 75 | |||
1083 | 76 | virtual bool authenticate(void); | ||
1084 | 77 | virtual bool readCommand(char **packet, uint32_t *packet_length); | ||
1085 | 78 | |||
1086 | 79 | virtual void sendOK(void); | ||
1087 | 80 | virtual void sendEOF(void); | ||
1088 | 81 | virtual void sendError(uint32_t sql_errno, const char *err); | ||
1089 | 82 | |||
1090 | 83 | virtual bool sendFields(drizzled::List<drizzled::Item> *list); | ||
1091 | 84 | |||
1092 | 85 | using Client::store; | ||
1093 | 86 | virtual bool store(drizzled::Field *from); | ||
1094 | 87 | virtual bool store(void); | ||
1095 | 88 | virtual bool store(int32_t from); | ||
1096 | 89 | virtual bool store(uint32_t from); | ||
1097 | 90 | virtual bool store(int64_t from); | ||
1098 | 91 | virtual bool store(uint64_t from); | ||
1099 | 92 | virtual bool store(double from, uint32_t decimals, drizzled::String *buffer); | ||
1100 | 93 | virtual bool store(const char *from, size_t length); | ||
1101 | 94 | |||
1102 | 95 | virtual bool haveError(void); | ||
1103 | 96 | virtual bool haveMoreData(void); | ||
1104 | 97 | virtual bool wasAborted(void); | ||
1105 | 98 | }; | ||
1113 | 99 | 48 | ||
1114 | 100 | } /* namespace drizzle_protocol */ | 49 | } /* namespace drizzle_protocol */ |
1115 | 101 | 50 | ||
1116 | 102 | 51 | ||
1117 | === modified file 'plugin/drizzle_protocol/errmsg.cc' | |||
1118 | --- plugin/drizzle_protocol/errmsg.cc 2010-03-04 18:06:27 +0000 | |||
1119 | +++ plugin/drizzle_protocol/errmsg.cc 2010-10-06 01:14:00 +0000 | |||
1120 | @@ -17,7 +17,7 @@ | |||
1121 | 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
1122 | 18 | */ | 18 | */ |
1123 | 19 | 19 | ||
1125 | 20 | /* Error messages for MySQL clients */ | 20 | /* Stub file for error messages */ |
1126 | 21 | 21 | ||
1127 | 22 | #include "config.h" | 22 | #include "config.h" |
1128 | 23 | #include <drizzled/gettext.h> | 23 | #include <drizzled/gettext.h> |
1129 | @@ -25,96 +25,4 @@ | |||
1130 | 25 | 25 | ||
1131 | 26 | namespace drizzle_protocol | 26 | namespace drizzle_protocol |
1132 | 27 | { | 27 | { |
1133 | 28 | |||
1134 | 29 | static const char *client_errors[]= | ||
1135 | 30 | { | ||
1136 | 31 | N_("Unknown Drizzle error"), | ||
1137 | 32 | N_("Can't create UNIX socket (%d)"), | ||
1138 | 33 | N_("Can't connect to local Drizzle server through socket '%-.100s' (%d)"), | ||
1139 | 34 | N_("Can't connect to Drizzle server on '%-.100s:%lu' (%d)"), | ||
1140 | 35 | N_("Can't create TCP/IP socket (%d)"), | ||
1141 | 36 | N_("Unknown Drizzle server host '%-.100s' (%d)"), | ||
1142 | 37 | N_("Drizzle server has gone away"), | ||
1143 | 38 | N_("Protocol mismatch; server version = %d, client version = %d"), | ||
1144 | 39 | N_("Drizzle client ran out of memory"), | ||
1145 | 40 | N_("Wrong host info"), | ||
1146 | 41 | N_("Localhost via UNIX socket"), | ||
1147 | 42 | N_("%-.100s via TCP/IP"), | ||
1148 | 43 | N_("Error in server handshake"), | ||
1149 | 44 | N_("Lost connection to Drizzle server during query"), | ||
1150 | 45 | N_("Commands out of sync; you can't run this command now"), | ||
1151 | 46 | N_("Named pipe: %-.32s"), | ||
1152 | 47 | N_("Can't wait for named pipe to host: %-.64s pipe: %-.32s (%lu)"), | ||
1153 | 48 | N_("Can't open named pipe to host: %-.64s pipe: %-.32s (%lu)"), | ||
1154 | 49 | N_("Can't set state of named pipe to host: %-.64s pipe: %-.32s (%lu)"), | ||
1155 | 50 | N_("Can't initialize character set %-.32s (path: %-.100s)"), | ||
1156 | 51 | N_("Got packet bigger than 'max_allowed_packet' bytes"), | ||
1157 | 52 | N_("Embedded server"), | ||
1158 | 53 | N_("Error on SHOW SLAVE STATUS:"), | ||
1159 | 54 | N_("Error on SHOW SLAVE HOSTS:"), | ||
1160 | 55 | N_("Error connecting to slave:"), | ||
1161 | 56 | N_("Error connecting to master:"), | ||
1162 | 57 | N_("SSL connection error"), | ||
1163 | 58 | N_("Malformed packet"), | ||
1164 | 59 | N_("(unused error message)"), | ||
1165 | 60 | N_("Invalid use of null pointer"), | ||
1166 | 61 | N_("Statement not prepared"), | ||
1167 | 62 | N_("No data supplied for parameters in prepared statement"), | ||
1168 | 63 | N_("Data truncated"), | ||
1169 | 64 | N_("No parameters exist in the statement"), | ||
1170 | 65 | N_("Invalid parameter number"), | ||
1171 | 66 | N_("Can't send long data for non-string/non-binary data types " | ||
1172 | 67 | "(parameter: %d)"), | ||
1173 | 68 | N_("Using unsupported buffer type: %d (parameter: %d)"), | ||
1174 | 69 | N_("Shared memory: %-.100s"), | ||
1175 | 70 | N_("(unused error message)"), | ||
1176 | 71 | N_("(unused error message)"), | ||
1177 | 72 | N_("(unused error message)"), | ||
1178 | 73 | N_("(unused error message)"), | ||
1179 | 74 | N_("(unused error message)"), | ||
1180 | 75 | N_("(unused error message)"), | ||
1181 | 76 | N_("(unused error message)"), | ||
1182 | 77 | N_("(unused error message)"), | ||
1183 | 78 | N_("(unused error message)"), | ||
1184 | 79 | N_("Wrong or unknown protocol"), | ||
1185 | 80 | N_("Invalid connection handle"), | ||
1186 | 81 | N_("Connection using old (pre-4.1.1) authentication protocol refused " | ||
1187 | 82 | "(client option 'secure_auth' enabled)"), | ||
1188 | 83 | N_("Row retrieval was canceled by drizzle_stmt_close() call"), | ||
1189 | 84 | N_("Attempt to read column without prior row fetch"), | ||
1190 | 85 | N_("Prepared statement contains no metadata"), | ||
1191 | 86 | N_("Attempt to read a row while there is no result set associated with " | ||
1192 | 87 | "the statement"), | ||
1193 | 88 | N_("This feature is not implemented yet"), | ||
1194 | 89 | N_("Lost connection to Drizzle server while waiting for initial " | ||
1195 | 90 | "communication packet, system error: %d"), | ||
1196 | 91 | N_("Lost connection to Drizzle server while reading initial communication " | ||
1197 | 92 | "packet, system error: %d"), | ||
1198 | 93 | N_("Lost connection to Drizzle server while sending authentication " | ||
1199 | 94 | "information, system error: %d"), | ||
1200 | 95 | N_("Lost connection to Drizzle server while reading authorization " | ||
1201 | 96 | "information, system error: %d"), | ||
1202 | 97 | N_("Lost connection to Drizzle server while setting initial database, " | ||
1203 | 98 | "system error: %d"), | ||
1204 | 99 | N_("Statement closed indirectly because of a preceding %s() call"), | ||
1205 | 100 | /* CR_NET_UNCOMPRESS_ERROR 08S01 */ | ||
1206 | 101 | N_("Couldn't uncompress communication packet"), | ||
1207 | 102 | /* CR_NET_READ_ERROR 08S01 */ | ||
1208 | 103 | N_("Got an error reading communication packets"), | ||
1209 | 104 | /* CR_NET_READ_INTERRUPTED 08S01 */ | ||
1210 | 105 | N_("Got timeout reading communication packets"), | ||
1211 | 106 | /* CR_NET_ERROR_ON_WRITE 08S01 */ | ||
1212 | 107 | N_("Got an error writing communication packets"), | ||
1213 | 108 | /* CR_NET_WRITE_INTERRUPTED 08S01 */ | ||
1214 | 109 | N_("Got timeout writing communication packets"), | ||
1215 | 110 | "" | ||
1216 | 111 | }; | ||
1217 | 112 | |||
1218 | 113 | |||
1219 | 114 | const char * | ||
1220 | 115 | drizzleclient_get_client_error(unsigned int err_index) | ||
1221 | 116 | { | ||
1222 | 117 | return _(client_errors[err_index]); | ||
1223 | 118 | } | ||
1224 | 119 | |||
1225 | 120 | } /* namespace drizzle_protocol */ | 28 | } /* namespace drizzle_protocol */ |
1226 | 121 | 29 | ||
1227 | === modified file 'plugin/drizzle_protocol/errmsg.h' | |||
1228 | --- plugin/drizzle_protocol/errmsg.h 2010-03-04 18:06:27 +0000 | |||
1229 | +++ plugin/drizzle_protocol/errmsg.h 2010-10-06 01:14:00 +0000 | |||
1230 | @@ -23,86 +23,6 @@ | |||
1231 | 23 | namespace drizzle_protocol | 23 | namespace drizzle_protocol |
1232 | 24 | { | 24 | { |
1233 | 25 | 25 | ||
1234 | 26 | /* Error messages for MySQL clients */ | ||
1235 | 27 | /* (Error messages for the daemon are in sql/share/errmsg.txt) */ | ||
1236 | 28 | |||
1237 | 29 | const char * drizzleclient_get_client_error(unsigned int err_index); | ||
1238 | 30 | |||
1239 | 31 | #define CR_MIN_ERROR 2000 /* For easier client code */ | ||
1240 | 32 | #define CR_MAX_ERROR 2999 | ||
1241 | 33 | #if !defined(ER) | ||
1242 | 34 | #define ER(X) drizzleclient_get_client_error((X)-CR_MIN_ERROR) | ||
1243 | 35 | #endif | ||
1244 | 36 | #define CLIENT_ERRMAP 2 /* Errormap used by my_error() */ | ||
1245 | 37 | |||
1246 | 38 | /* Do not add error numbers before CR_ERROR_FIRST. */ | ||
1247 | 39 | /* If necessary to add lower numbers, change CR_ERROR_FIRST accordingly. */ | ||
1248 | 40 | enum CR_CLIENT_ERRORS { | ||
1249 | 41 | CR_ERROR_FIRST =2000, /*Copy first error nr.*/ | ||
1250 | 42 | CR_UNKNOWN_ERROR =2000, | ||
1251 | 43 | CR_SOCKET_CREATE_ERROR =2001, | ||
1252 | 44 | CR_CONNECTION_ERROR =2002, | ||
1253 | 45 | CR_CONN_HOST_ERROR =2003, | ||
1254 | 46 | CR_IPSOCK_ERROR =2004, | ||
1255 | 47 | CR_UNKNOWN_HOST =2005, | ||
1256 | 48 | CR_SERVER_GONE_ERROR =2006, | ||
1257 | 49 | CR_VERSION_ERROR =2007, | ||
1258 | 50 | CR_OUT_OF_MEMORY =2008, | ||
1259 | 51 | CR_WRONG_HOST_INFO =2009, | ||
1260 | 52 | CR_LOCALHOST_CONNECTION =2010, | ||
1261 | 53 | CR_TCP_CONNECTION =2011, | ||
1262 | 54 | CR_SERVER_HANDSHAKE_ERR =2012, | ||
1263 | 55 | CR_SERVER_LOST =2013, | ||
1264 | 56 | CR_COMMANDS_OUT_OF_SYNC =2014, | ||
1265 | 57 | CR_NAMEDPIPE_CONNECTION =2015, | ||
1266 | 58 | CR_NAMEDPIPEWAIT_ERROR =2016, | ||
1267 | 59 | CR_NAMEDPIPEOPEN_ERROR =2017, | ||
1268 | 60 | CR_NAMEDPIPESETSTATE_ERROR =2018, | ||
1269 | 61 | CR_CANT_READ_CHARSET =2019, | ||
1270 | 62 | CR_NET_PACKET_TOO_LARGE =2020, | ||
1271 | 63 | CR_EMBEDDED_CONNECTION =2021, | ||
1272 | 64 | CR_PROBE_SLAVE_STATUS =2022, | ||
1273 | 65 | CR_PROBE_SLAVE_HOSTS =2023, | ||
1274 | 66 | CR_PROBE_SLAVE_CONNECT =2024, | ||
1275 | 67 | CR_PROBE_MASTER_CONNECT =2025, | ||
1276 | 68 | CR_SSL_CONNECTION_ERROR =2026, | ||
1277 | 69 | CR_MALFORMED_PACKET =2027, | ||
1278 | 70 | |||
1279 | 71 | CR_NULL_POINTER =2029, | ||
1280 | 72 | CR_NO_PREPARE_STMT =2030, | ||
1281 | 73 | CR_PARAMS_NOT_BOUND =2031, | ||
1282 | 74 | CR_DATA_TRUNCATED =2032, | ||
1283 | 75 | CR_NO_PARAMETERS_EXISTS =2033, | ||
1284 | 76 | CR_INVALID_PARAMETER_NO =2034, | ||
1285 | 77 | CR_INVALID_BUFFER_USE =2035, | ||
1286 | 78 | CR_UNSUPPORTED_PARAM_TYPE =2036, | ||
1287 | 79 | |||
1288 | 80 | CR_CONN_UNKNOW_PROTOCOL =2047, | ||
1289 | 81 | CR_INVALID_CONN_HANDLE =2048, | ||
1290 | 82 | CR_SECURE_AUTH =2049, | ||
1291 | 83 | CR_FETCH_CANCELED =2050, | ||
1292 | 84 | CR_NO_DATA =2051, | ||
1293 | 85 | CR_NO_STMT_METADATA =2052, | ||
1294 | 86 | CR_NO_RESULT_SET =2053, | ||
1295 | 87 | CR_NOT_IMPLEMENTED =2054, | ||
1296 | 88 | CR_SERVER_LOST_INITIAL_COMM_WAIT =2055, | ||
1297 | 89 | CR_SERVER_LOST_INITIAL_COMM_READ =2056, | ||
1298 | 90 | CR_SERVER_LOST_SEND_AUTH =2057, | ||
1299 | 91 | CR_SERVER_LOST_READ_AUTH =2058, | ||
1300 | 92 | CR_SERVER_LOST_SETTING_DB =2059, | ||
1301 | 93 | |||
1302 | 94 | CR_STMT_CLOSED =2060, | ||
1303 | 95 | |||
1304 | 96 | CR_NET_UNCOMPRESS_ERROR= 2061, | ||
1305 | 97 | CR_NET_READ_ERROR= 2062, | ||
1306 | 98 | CR_NET_READ_INTERRUPTED= 2063, | ||
1307 | 99 | CR_NET_ERROR_ON_WRITE= 2064, | ||
1308 | 100 | CR_NET_WRITE_INTERRUPTED= 2065, | ||
1309 | 101 | |||
1310 | 102 | /* Add error numbers before CR_ERROR_LAST and change it accordingly. */ | ||
1311 | 103 | CR_ERROR_LAST =2065 /*Copy last error nr:*/ | ||
1312 | 104 | }; | ||
1313 | 105 | |||
1314 | 106 | } /* namespace drizzle_protocol */ | 26 | } /* namespace drizzle_protocol */ |
1315 | 107 | 27 | ||
1316 | 108 | #endif /* PLUGIN_DRIZZLE_PROTOCOL_ERRMSG_H */ | 28 | #endif /* PLUGIN_DRIZZLE_PROTOCOL_ERRMSG_H */ |
1317 | 109 | 29 | ||
1318 | === removed file 'plugin/drizzle_protocol/net_serv.cc' | |||
1319 | --- plugin/drizzle_protocol/net_serv.cc 2010-05-19 01:22:29 +0000 | |||
1320 | +++ plugin/drizzle_protocol/net_serv.cc 1970-01-01 00:00:00 +0000 | |||
1321 | @@ -1,896 +0,0 @@ | |||
1322 | 1 | /* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*- | ||
1323 | 2 | * vim:expandtab:shiftwidth=2:tabstop=2:smarttab: | ||
1324 | 3 | * | ||
1325 | 4 | * Copyright (C) 2008 Sun Microsystems, Inc. | ||
1326 | 5 | * | ||
1327 | 6 | * This program is free software; you can redistribute it and/or modify | ||
1328 | 7 | * it under the terms of the GNU General Public License as published by | ||
1329 | 8 | * the Free Software Foundation; either version 2 of the License, or | ||
1330 | 9 | * (at your option) any later version. | ||
1331 | 10 | * | ||
1332 | 11 | * This program is distributed in the hope that it will be useful, | ||
1333 | 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1334 | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1335 | 14 | * GNU General Public License for more details. | ||
1336 | 15 | * | ||
1337 | 16 | * You should have received a copy of the GNU General Public License | ||
1338 | 17 | * along with this program; if not, write to the Free Software | ||
1339 | 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
1340 | 19 | */ | ||
1341 | 20 | |||
1342 | 21 | #include "config.h" | ||
1343 | 22 | #include <drizzled/session.h> | ||
1344 | 23 | |||
1345 | 24 | #include <assert.h> | ||
1346 | 25 | #include <stdio.h> | ||
1347 | 26 | #include <stdlib.h> | ||
1348 | 27 | #include <string.h> | ||
1349 | 28 | #include <signal.h> | ||
1350 | 29 | #include <errno.h> | ||
1351 | 30 | #include <sys/socket.h> | ||
1352 | 31 | #include <sys/poll.h> | ||
1353 | 32 | #include <zlib.h> | ||
1354 | 33 | #include <algorithm> | ||
1355 | 34 | |||
1356 | 35 | #include "errmsg.h" | ||
1357 | 36 | #include "vio.h" | ||
1358 | 37 | #include "net_serv.h" | ||
1359 | 38 | |||
1360 | 39 | using namespace std; | ||
1361 | 40 | |||
1362 | 41 | namespace drizzle_protocol | ||
1363 | 42 | { | ||
1364 | 43 | |||
1365 | 44 | /* | ||
1366 | 45 | The following handles the differences when this is linked between the | ||
1367 | 46 | client and the server. | ||
1368 | 47 | |||
1369 | 48 | This gives an error if a too big packet is found | ||
1370 | 49 | The server can change this with the -O switch, but because the client | ||
1371 | 50 | can't normally do this the client should have a bigger max_allowed_packet. | ||
1372 | 51 | */ | ||
1373 | 52 | |||
1374 | 53 | /* Constants when using compression */ | ||
1375 | 54 | #define NET_HEADER_SIZE 4 /* standard header size */ | ||
1376 | 55 | #define COMP_HEADER_SIZE 3 /* compression header extra size */ | ||
1377 | 56 | |||
1378 | 57 | #define MAX_PACKET_LENGTH (256L*256L*256L-1) | ||
1379 | 58 | const char *not_error_sqlstate= "00000"; | ||
1380 | 59 | |||
1381 | 60 | static bool net_write_buff(NET *net, const unsigned char *packet, uint32_t len); | ||
1382 | 61 | static int drizzleclient_net_real_write(NET *net, const unsigned char *packet, size_t len); | ||
1383 | 62 | |||
1384 | 63 | /** Init with packet info. */ | ||
1385 | 64 | |||
1386 | 65 | bool drizzleclient_net_init(NET *net, Vio* vio, uint32_t buffer_length) | ||
1387 | 66 | { | ||
1388 | 67 | net->vio = vio; | ||
1389 | 68 | net->max_packet= (uint32_t) buffer_length; | ||
1390 | 69 | net->max_packet_size= max(buffer_length, | ||
1391 | 70 | drizzled::global_system_variables.max_allowed_packet); | ||
1392 | 71 | |||
1393 | 72 | if (!(net->buff=(unsigned char*) malloc((size_t) net->max_packet+ | ||
1394 | 73 | NET_HEADER_SIZE + COMP_HEADER_SIZE))) | ||
1395 | 74 | return(1); | ||
1396 | 75 | net->buff_end=net->buff+net->max_packet; | ||
1397 | 76 | net->error=0; net->return_status=0; | ||
1398 | 77 | net->pkt_nr=net->compress_pkt_nr=0; | ||
1399 | 78 | net->write_pos=net->read_pos = net->buff; | ||
1400 | 79 | net->last_error[0]=0; | ||
1401 | 80 | net->compress=0; net->reading_or_writing=0; | ||
1402 | 81 | net->where_b = net->remain_in_buf=0; | ||
1403 | 82 | net->last_errno=0; | ||
1404 | 83 | net->unused= 0; | ||
1405 | 84 | |||
1406 | 85 | if (vio != 0) /* If real connection */ | ||
1407 | 86 | { | ||
1408 | 87 | net->fd = drizzleclient_vio_fd(vio); /* For perl DBI/DBD */ | ||
1409 | 88 | drizzleclient_vio_fastsend(vio); | ||
1410 | 89 | } | ||
1411 | 90 | return(0); | ||
1412 | 91 | } | ||
1413 | 92 | |||
1414 | 93 | bool drizzleclient_net_init_sock(NET * net, int sock, int flags, | ||
1415 | 94 | uint32_t buffer_length) | ||
1416 | 95 | { | ||
1417 | 96 | |||
1418 | 97 | Vio *drizzleclient_vio_tmp= drizzleclient_vio_new(sock, VIO_TYPE_TCPIP, flags); | ||
1419 | 98 | if (drizzleclient_vio_tmp == NULL) | ||
1420 | 99 | return true; | ||
1421 | 100 | else | ||
1422 | 101 | if (drizzleclient_net_init(net, drizzleclient_vio_tmp, buffer_length)) | ||
1423 | 102 | { | ||
1424 | 103 | /* Only delete the temporary vio if we didn't already attach it to the | ||
1425 | 104 | * NET object. | ||
1426 | 105 | */ | ||
1427 | 106 | if (drizzleclient_vio_tmp && (net->vio != drizzleclient_vio_tmp)) | ||
1428 | 107 | drizzleclient_vio_delete(drizzleclient_vio_tmp); | ||
1429 | 108 | else | ||
1430 | 109 | { | ||
1431 | 110 | (void) shutdown(sock, SHUT_RDWR); | ||
1432 | 111 | (void) close(sock); | ||
1433 | 112 | } | ||
1434 | 113 | return true; | ||
1435 | 114 | } | ||
1436 | 115 | return false; | ||
1437 | 116 | } | ||
1438 | 117 | |||
1439 | 118 | void drizzleclient_net_end(NET *net) | ||
1440 | 119 | { | ||
1441 | 120 | if (net->buff != NULL) | ||
1442 | 121 | free(net->buff); | ||
1443 | 122 | net->buff= NULL; | ||
1444 | 123 | return; | ||
1445 | 124 | } | ||
1446 | 125 | |||
1447 | 126 | void drizzleclient_net_close(NET *net) | ||
1448 | 127 | { | ||
1449 | 128 | if (net->vio != NULL) | ||
1450 | 129 | { | ||
1451 | 130 | drizzleclient_vio_delete(net->vio); | ||
1452 | 131 | net->vio= 0; | ||
1453 | 132 | } | ||
1454 | 133 | } | ||
1455 | 134 | |||
1456 | 135 | bool drizzleclient_net_peer_addr(NET *net, char *buf, uint16_t *port, size_t buflen) | ||
1457 | 136 | { | ||
1458 | 137 | return drizzleclient_vio_peer_addr(net->vio, buf, port, buflen); | ||
1459 | 138 | } | ||
1460 | 139 | |||
1461 | 140 | void drizzleclient_net_keepalive(NET *net, bool flag) | ||
1462 | 141 | { | ||
1463 | 142 | drizzleclient_vio_keepalive(net->vio, flag); | ||
1464 | 143 | } | ||
1465 | 144 | |||
1466 | 145 | int drizzleclient_net_get_sd(NET *net) | ||
1467 | 146 | { | ||
1468 | 147 | return net->vio->sd; | ||
1469 | 148 | } | ||
1470 | 149 | |||
1471 | 150 | bool drizzleclient_net_more_data(NET *net) | ||
1472 | 151 | { | ||
1473 | 152 | return (net->vio == 0 || net->vio->read_pos < net->vio->read_end); | ||
1474 | 153 | } | ||
1475 | 154 | |||
1476 | 155 | /** Realloc the packet buffer. */ | ||
1477 | 156 | |||
1478 | 157 | static bool drizzleclient_net_realloc(NET *net, size_t length) | ||
1479 | 158 | { | ||
1480 | 159 | unsigned char *buff; | ||
1481 | 160 | size_t pkt_length; | ||
1482 | 161 | |||
1483 | 162 | if (length >= net->max_packet_size) | ||
1484 | 163 | { | ||
1485 | 164 | /* @todo: 1 and 2 codes are identical. */ | ||
1486 | 165 | net->error= 1; | ||
1487 | 166 | net->last_errno= CR_NET_PACKET_TOO_LARGE; | ||
1488 | 167 | return(1); | ||
1489 | 168 | } | ||
1490 | 169 | pkt_length = (length+IO_SIZE-1) & ~(IO_SIZE-1); | ||
1491 | 170 | /* | ||
1492 | 171 | We must allocate some extra bytes for the end 0 and to be able to | ||
1493 | 172 | read big compressed blocks | ||
1494 | 173 | */ | ||
1495 | 174 | if (!(buff= (unsigned char*) realloc((char*) net->buff, pkt_length + | ||
1496 | 175 | NET_HEADER_SIZE + COMP_HEADER_SIZE))) | ||
1497 | 176 | { | ||
1498 | 177 | /* @todo: 1 and 2 codes are identical. */ | ||
1499 | 178 | net->error= 1; | ||
1500 | 179 | net->last_errno= CR_OUT_OF_MEMORY; | ||
1501 | 180 | /* In the server the error is reported by MY_WME flag. */ | ||
1502 | 181 | return(1); | ||
1503 | 182 | } | ||
1504 | 183 | net->buff=net->write_pos=buff; | ||
1505 | 184 | net->buff_end=buff+(net->max_packet= (uint32_t) pkt_length); | ||
1506 | 185 | return(0); | ||
1507 | 186 | } | ||
1508 | 187 | |||
1509 | 188 | |||
1510 | 189 | /** | ||
1511 | 190 | Check if there is any data to be read from the socket. | ||
1512 | 191 | |||
1513 | 192 | @param sd socket descriptor | ||
1514 | 193 | |||
1515 | 194 | @retval | ||
1516 | 195 | 0 No data to read | ||
1517 | 196 | @retval | ||
1518 | 197 | 1 Data or EOF to read | ||
1519 | 198 | @retval | ||
1520 | 199 | -1 Don't know if data is ready or not | ||
1521 | 200 | */ | ||
1522 | 201 | |||
1523 | 202 | static bool net_data_is_ready(int sd) | ||
1524 | 203 | { | ||
1525 | 204 | struct pollfd ufds; | ||
1526 | 205 | int res; | ||
1527 | 206 | |||
1528 | 207 | ufds.fd= sd; | ||
1529 | 208 | ufds.events= POLLIN | POLLPRI; | ||
1530 | 209 | if (!(res= poll(&ufds, 1, 0))) | ||
1531 | 210 | return 0; | ||
1532 | 211 | if (res < 0 || !(ufds.revents & (POLLIN | POLLPRI))) | ||
1533 | 212 | return 0; | ||
1534 | 213 | return 1; | ||
1535 | 214 | } | ||
1536 | 215 | |||
1537 | 216 | /** | ||
1538 | 217 | Remove unwanted characters from connection | ||
1539 | 218 | and check if disconnected. | ||
1540 | 219 | |||
1541 | 220 | Read from socket until there is nothing more to read. Discard | ||
1542 | 221 | what is read. | ||
1543 | 222 | |||
1544 | 223 | If there is anything when to read 'drizzleclient_net_clear' is called this | ||
1545 | 224 | normally indicates an error in the protocol. | ||
1546 | 225 | |||
1547 | 226 | When connection is properly closed (for TCP it means with | ||
1548 | 227 | a FIN packet), then select() considers a socket "ready to read", | ||
1549 | 228 | in the sense that there's EOF to read, but read() returns 0. | ||
1550 | 229 | |||
1551 | 230 | @param net NET handler | ||
1552 | 231 | @param clear_buffer if <> 0, then clear all data from comm buff | ||
1553 | 232 | */ | ||
1554 | 233 | |||
1555 | 234 | void drizzleclient_net_clear(NET *net, bool clear_buffer) | ||
1556 | 235 | { | ||
1557 | 236 | if (clear_buffer) | ||
1558 | 237 | { | ||
1559 | 238 | while (net_data_is_ready(net->vio->sd) > 0) | ||
1560 | 239 | { | ||
1561 | 240 | /* The socket is ready */ | ||
1562 | 241 | if (drizzleclient_vio_read(net->vio, net->buff, | ||
1563 | 242 | (size_t) net->max_packet) <= 0) | ||
1564 | 243 | { | ||
1565 | 244 | net->error= 2; | ||
1566 | 245 | break; | ||
1567 | 246 | } | ||
1568 | 247 | } | ||
1569 | 248 | } | ||
1570 | 249 | net->pkt_nr=net->compress_pkt_nr=0; /* Ready for new command */ | ||
1571 | 250 | net->write_pos=net->buff; | ||
1572 | 251 | return; | ||
1573 | 252 | } | ||
1574 | 253 | |||
1575 | 254 | |||
1576 | 255 | /** Flush write_buffer if not empty. */ | ||
1577 | 256 | |||
1578 | 257 | bool drizzleclient_net_flush(NET *net) | ||
1579 | 258 | { | ||
1580 | 259 | bool error= 0; | ||
1581 | 260 | if (net->buff != net->write_pos) | ||
1582 | 261 | { | ||
1583 | 262 | error=drizzleclient_net_real_write(net, net->buff, | ||
1584 | 263 | (size_t) (net->write_pos - net->buff)) ? 1 : 0; | ||
1585 | 264 | net->write_pos=net->buff; | ||
1586 | 265 | } | ||
1587 | 266 | /* Sync packet number if using compression */ | ||
1588 | 267 | if (net->compress) | ||
1589 | 268 | net->pkt_nr=net->compress_pkt_nr; | ||
1590 | 269 | return(error); | ||
1591 | 270 | } | ||
1592 | 271 | |||
1593 | 272 | |||
1594 | 273 | /***************************************************************************** | ||
1595 | 274 | ** Write something to server/client buffer | ||
1596 | 275 | *****************************************************************************/ | ||
1597 | 276 | |||
1598 | 277 | /** | ||
1599 | 278 | Write a logical packet with packet header. | ||
1600 | 279 | |||
1601 | 280 | Format: Packet length (3 bytes), packet number(1 byte) | ||
1602 | 281 | When compression is used a 3 byte compression length is added | ||
1603 | 282 | |||
1604 | 283 | @note | ||
1605 | 284 | If compression is used the original package is modified! | ||
1606 | 285 | */ | ||
1607 | 286 | |||
1608 | 287 | bool | ||
1609 | 288 | drizzleclient_net_write(NET *net,const unsigned char *packet,size_t len) | ||
1610 | 289 | { | ||
1611 | 290 | unsigned char buff[NET_HEADER_SIZE]; | ||
1612 | 291 | if (unlikely(!net->vio)) /* nowhere to write */ | ||
1613 | 292 | return 0; | ||
1614 | 293 | /* | ||
1615 | 294 | Big packets are handled by splitting them in packets of MAX_PACKET_LENGTH | ||
1616 | 295 | length. The last packet is always a packet that is < MAX_PACKET_LENGTH. | ||
1617 | 296 | (The last packet may even have a length of 0) | ||
1618 | 297 | */ | ||
1619 | 298 | while (len >= MAX_PACKET_LENGTH) | ||
1620 | 299 | { | ||
1621 | 300 | const uint32_t z_size = MAX_PACKET_LENGTH; | ||
1622 | 301 | int3store(buff, z_size); | ||
1623 | 302 | buff[3]= (unsigned char) net->pkt_nr++; | ||
1624 | 303 | if (net_write_buff(net, buff, NET_HEADER_SIZE) || | ||
1625 | 304 | net_write_buff(net, packet, z_size)) | ||
1626 | 305 | return 1; | ||
1627 | 306 | packet += z_size; | ||
1628 | 307 | len-= z_size; | ||
1629 | 308 | } | ||
1630 | 309 | /* Write last packet */ | ||
1631 | 310 | int3store(buff,len); | ||
1632 | 311 | buff[3]= (unsigned char) net->pkt_nr++; | ||
1633 | 312 | if (net_write_buff(net, buff, NET_HEADER_SIZE)) | ||
1634 | 313 | return 1; | ||
1635 | 314 | return net_write_buff(net,packet,len) ? 1 : 0; | ||
1636 | 315 | } | ||
1637 | 316 | |||
1638 | 317 | /** | ||
1639 | 318 | Send a command to the server. | ||
1640 | 319 | |||
1641 | 320 | The reason for having both header and packet is so that libdrizzle | ||
1642 | 321 | can easy add a header to a special command (like prepared statements) | ||
1643 | 322 | without having to re-alloc the string. | ||
1644 | 323 | |||
1645 | 324 | As the command is part of the first data packet, we have to do some data | ||
1646 | 325 | juggling to put the command in there, without having to create a new | ||
1647 | 326 | packet. | ||
1648 | 327 | |||
1649 | 328 | This function will split big packets into sub-packets if needed. | ||
1650 | 329 | (Each sub packet can only be 2^24 bytes) | ||
1651 | 330 | |||
1652 | 331 | @param net NET handler | ||
1653 | 332 | @param command Command in MySQL server (enum enum_server_command) | ||
1654 | 333 | @param header Header to write after command | ||
1655 | 334 | @param head_len Length of header | ||
1656 | 335 | @param packet Query or parameter to query | ||
1657 | 336 | @param len Length of packet | ||
1658 | 337 | |||
1659 | 338 | @retval | ||
1660 | 339 | 0 ok | ||
1661 | 340 | @retval | ||
1662 | 341 | 1 error | ||
1663 | 342 | */ | ||
1664 | 343 | |||
1665 | 344 | bool | ||
1666 | 345 | drizzleclient_net_write_command(NET *net,unsigned char command, | ||
1667 | 346 | const unsigned char *header, size_t head_len, | ||
1668 | 347 | const unsigned char *packet, size_t len) | ||
1669 | 348 | { | ||
1670 | 349 | uint32_t length=len+1+head_len; /* 1 extra byte for command */ | ||
1671 | 350 | unsigned char buff[NET_HEADER_SIZE+1]; | ||
1672 | 351 | uint32_t header_size=NET_HEADER_SIZE+1; | ||
1673 | 352 | |||
1674 | 353 | buff[4]=command; /* For first packet */ | ||
1675 | 354 | |||
1676 | 355 | if (length >= MAX_PACKET_LENGTH) | ||
1677 | 356 | { | ||
1678 | 357 | /* Take into account that we have the command in the first header */ | ||
1679 | 358 | len= MAX_PACKET_LENGTH - 1 - head_len; | ||
1680 | 359 | do | ||
1681 | 360 | { | ||
1682 | 361 | int3store(buff, MAX_PACKET_LENGTH); | ||
1683 | 362 | buff[3]= (unsigned char) net->pkt_nr++; | ||
1684 | 363 | if (net_write_buff(net, buff, header_size) || | ||
1685 | 364 | net_write_buff(net, header, head_len) || | ||
1686 | 365 | net_write_buff(net, packet, len)) | ||
1687 | 366 | return(1); | ||
1688 | 367 | packet+= len; | ||
1689 | 368 | length-= MAX_PACKET_LENGTH; | ||
1690 | 369 | len= MAX_PACKET_LENGTH; | ||
1691 | 370 | head_len= 0; | ||
1692 | 371 | header_size= NET_HEADER_SIZE; | ||
1693 | 372 | } while (length >= MAX_PACKET_LENGTH); | ||
1694 | 373 | len=length; /* Data left to be written */ | ||
1695 | 374 | } | ||
1696 | 375 | int3store(buff,length); | ||
1697 | 376 | buff[3]= (unsigned char) net->pkt_nr++; | ||
1698 | 377 | return((net_write_buff(net, buff, header_size) || | ||
1699 | 378 | (head_len && net_write_buff(net, header, head_len)) || | ||
1700 | 379 | net_write_buff(net, packet, len) || drizzleclient_net_flush(net)) ? 1 : 0 ); | ||
1701 | 380 | } | ||
1702 | 381 | |||
1703 | 382 | /** | ||
1704 | 383 | Caching the data in a local buffer before sending it. | ||
1705 | 384 | |||
1706 | 385 | Fill up net->buffer and send it to the client when full. | ||
1707 | 386 | |||
1708 | 387 | If the rest of the to-be-sent-packet is bigger than buffer, | ||
1709 | 388 | send it in one big block (to avoid copying to internal buffer). | ||
1710 | 389 | If not, copy the rest of the data to the buffer and return without | ||
1711 | 390 | sending data. | ||
1712 | 391 | |||
1713 | 392 | @param net Network handler | ||
1714 | 393 | @param packet Packet to send | ||
1715 | 394 | @param len Length of packet | ||
1716 | 395 | |||
1717 | 396 | @note | ||
1718 | 397 | The cached buffer can be sent as it is with 'drizzleclient_net_flush()'. | ||
1719 | 398 | In this code we have to be careful to not send a packet longer than | ||
1720 | 399 | MAX_PACKET_LENGTH to drizzleclient_net_real_write() if we are using the compressed | ||
1721 | 400 | protocol as we store the length of the compressed packet in 3 bytes. | ||
1722 | 401 | |||
1723 | 402 | @retval | ||
1724 | 403 | 0 ok | ||
1725 | 404 | @retval | ||
1726 | 405 | 1 | ||
1727 | 406 | */ | ||
1728 | 407 | |||
1729 | 408 | static bool | ||
1730 | 409 | net_write_buff(NET *net, const unsigned char *packet, uint32_t len) | ||
1731 | 410 | { | ||
1732 | 411 | uint32_t left_length; | ||
1733 | 412 | if (net->compress && net->max_packet > MAX_PACKET_LENGTH) | ||
1734 | 413 | left_length= MAX_PACKET_LENGTH - (net->write_pos - net->buff); | ||
1735 | 414 | else | ||
1736 | 415 | left_length= (uint32_t) (net->buff_end - net->write_pos); | ||
1737 | 416 | |||
1738 | 417 | if (len > left_length) | ||
1739 | 418 | { | ||
1740 | 419 | if (net->write_pos != net->buff) | ||
1741 | 420 | { | ||
1742 | 421 | /* Fill up already used packet and write it */ | ||
1743 | 422 | memcpy(net->write_pos,packet,left_length); | ||
1744 | 423 | if (drizzleclient_net_real_write(net, net->buff, | ||
1745 | 424 | (size_t) (net->write_pos - net->buff) + left_length)) | ||
1746 | 425 | return 1; | ||
1747 | 426 | net->write_pos= net->buff; | ||
1748 | 427 | packet+= left_length; | ||
1749 | 428 | len-= left_length; | ||
1750 | 429 | } | ||
1751 | 430 | if (net->compress) | ||
1752 | 431 | { | ||
1753 | 432 | /* | ||
1754 | 433 | We can't have bigger packets than 16M with compression | ||
1755 | 434 | Because the uncompressed length is stored in 3 bytes | ||
1756 | 435 | */ | ||
1757 | 436 | left_length= MAX_PACKET_LENGTH; | ||
1758 | 437 | while (len > left_length) | ||
1759 | 438 | { | ||
1760 | 439 | if (drizzleclient_net_real_write(net, packet, left_length)) | ||
1761 | 440 | return 1; | ||
1762 | 441 | packet+= left_length; | ||
1763 | 442 | len-= left_length; | ||
1764 | 443 | } | ||
1765 | 444 | } | ||
1766 | 445 | if (len > net->max_packet) | ||
1767 | 446 | return drizzleclient_net_real_write(net, packet, len) ? 1 : 0; | ||
1768 | 447 | /* Send out rest of the blocks as full sized blocks */ | ||
1769 | 448 | } | ||
1770 | 449 | memcpy(net->write_pos,packet,len); | ||
1771 | 450 | net->write_pos+= len; | ||
1772 | 451 | return 0; | ||
1773 | 452 | } | ||
1774 | 453 | |||
1775 | 454 | |||
1776 | 455 | /** | ||
1777 | 456 | Read and write one packet using timeouts. | ||
1778 | 457 | If needed, the packet is compressed before sending. | ||
1779 | 458 | |||
1780 | 459 | @todo | ||
1781 | 460 | - TODO is it needed to set this variable if we have no socket | ||
1782 | 461 | */ | ||
1783 | 462 | |||
1784 | 463 | /* | ||
1785 | 464 | TODO: rewrite this in a manner to do non-block writes. If a write can not be made, and we are | ||
1786 | 465 | in the server, yield to another process and come back later. | ||
1787 | 466 | */ | ||
1788 | 467 | static int | ||
1789 | 468 | drizzleclient_net_real_write(NET *net, const unsigned char *packet, size_t len) | ||
1790 | 469 | { | ||
1791 | 470 | size_t length; | ||
1792 | 471 | const unsigned char *pos, *end; | ||
1793 | 472 | uint32_t retry_count= 0; | ||
1794 | 473 | |||
1795 | 474 | /* Backup of the original SO_RCVTIMEO timeout */ | ||
1796 | 475 | |||
1797 | 476 | if (net->error == 2) | ||
1798 | 477 | return(-1); /* socket can't be used */ | ||
1799 | 478 | |||
1800 | 479 | net->reading_or_writing=2; | ||
1801 | 480 | if (net->compress) | ||
1802 | 481 | { | ||
1803 | 482 | size_t complen; | ||
1804 | 483 | unsigned char *b; | ||
1805 | 484 | const uint32_t header_length=NET_HEADER_SIZE+COMP_HEADER_SIZE; | ||
1806 | 485 | if (!(b= (unsigned char*) malloc(len + NET_HEADER_SIZE + | ||
1807 | 486 | COMP_HEADER_SIZE))) | ||
1808 | 487 | { | ||
1809 | 488 | net->error= 2; | ||
1810 | 489 | net->last_errno= CR_OUT_OF_MEMORY; | ||
1811 | 490 | /* In the server, the error is reported by MY_WME flag. */ | ||
1812 | 491 | net->reading_or_writing= 0; | ||
1813 | 492 | return(1); | ||
1814 | 493 | } | ||
1815 | 494 | memcpy(b+header_length,packet,len); | ||
1816 | 495 | |||
1817 | 496 | complen= len * 120 / 100 + 12; | ||
1818 | 497 | unsigned char * compbuf= (unsigned char *) malloc(complen); | ||
1819 | 498 | if (compbuf != NULL) | ||
1820 | 499 | { | ||
1821 | 500 | uLongf tmp_complen= complen; | ||
1822 | 501 | int res= compress((Bytef*) compbuf, &tmp_complen, | ||
1823 | 502 | (Bytef*) (b+header_length), | ||
1824 | 503 | len); | ||
1825 | 504 | complen= tmp_complen; | ||
1826 | 505 | |||
1827 | 506 | free(compbuf); | ||
1828 | 507 | |||
1829 | 508 | if ((res != Z_OK) || (complen >= len)) | ||
1830 | 509 | complen= 0; | ||
1831 | 510 | else | ||
1832 | 511 | { | ||
1833 | 512 | size_t tmplen= complen; | ||
1834 | 513 | complen= len; | ||
1835 | 514 | len= tmplen; | ||
1836 | 515 | } | ||
1837 | 516 | } | ||
1838 | 517 | else | ||
1839 | 518 | { | ||
1840 | 519 | complen=0; | ||
1841 | 520 | } | ||
1842 | 521 | int3store(&b[NET_HEADER_SIZE],complen); | ||
1843 | 522 | int3store(b,len); | ||
1844 | 523 | b[3]=(unsigned char) (net->compress_pkt_nr++); | ||
1845 | 524 | len+= header_length; | ||
1846 | 525 | packet= b; | ||
1847 | 526 | } | ||
1848 | 527 | |||
1849 | 528 | pos= packet; | ||
1850 | 529 | end=pos+len; | ||
1851 | 530 | /* Loop until we have read everything */ | ||
1852 | 531 | while (pos != end) | ||
1853 | 532 | { | ||
1854 | 533 | assert(pos); | ||
1855 | 534 | if ((long) (length= drizzleclient_vio_write(net->vio, pos, (size_t) (end-pos))) <= 0) | ||
1856 | 535 | { | ||
1857 | 536 | /* | ||
1858 | 537 | * We could end up here with net->vio == NULL | ||
1859 | 538 | * See LP bug#436685 | ||
1860 | 539 | * If that is the case, we exit the while loop | ||
1861 | 540 | */ | ||
1862 | 541 | if (net->vio == NULL) | ||
1863 | 542 | break; | ||
1864 | 543 | |||
1865 | 544 | const bool interrupted= drizzleclient_vio_should_retry(net->vio); | ||
1866 | 545 | /* | ||
1867 | 546 | If we read 0, or we were interrupted this means that | ||
1868 | 547 | we need to switch to blocking mode and wait until the timeout | ||
1869 | 548 | on the socket kicks in. | ||
1870 | 549 | */ | ||
1871 | 550 | if ((interrupted || length == 0)) | ||
1872 | 551 | { | ||
1873 | 552 | bool old_mode; | ||
1874 | 553 | |||
1875 | 554 | while (drizzleclient_vio_blocking(net->vio, true, &old_mode) < 0) | ||
1876 | 555 | { | ||
1877 | 556 | if (drizzleclient_vio_should_retry(net->vio) && retry_count++ < net->retry_count) | ||
1878 | 557 | continue; | ||
1879 | 558 | net->error= 2; /* Close socket */ | ||
1880 | 559 | net->last_errno= CR_NET_PACKET_TOO_LARGE; | ||
1881 | 560 | goto end; | ||
1882 | 561 | } | ||
1883 | 562 | retry_count=0; | ||
1884 | 563 | continue; | ||
1885 | 564 | } | ||
1886 | 565 | else | ||
1887 | 566 | { | ||
1888 | 567 | if (retry_count++ < net->retry_count) | ||
1889 | 568 | continue; | ||
1890 | 569 | } | ||
1891 | 570 | |||
1892 | 571 | if (drizzleclient_vio_errno(net->vio) == EINTR) | ||
1893 | 572 | { | ||
1894 | 573 | continue; | ||
1895 | 574 | } | ||
1896 | 575 | net->error= 2; /* Close socket */ | ||
1897 | 576 | net->last_errno= (interrupted ? CR_NET_WRITE_INTERRUPTED : | ||
1898 | 577 | CR_NET_ERROR_ON_WRITE); | ||
1899 | 578 | break; | ||
1900 | 579 | } | ||
1901 | 580 | pos+=length; | ||
1902 | 581 | current_session->status_var.bytes_sent+= length; | ||
1903 | 582 | } | ||
1904 | 583 | end: | ||
1905 | 584 | if ((net->compress) && (packet != NULL)) | ||
1906 | 585 | free((char*) packet); | ||
1907 | 586 | net->reading_or_writing=0; | ||
1908 | 587 | |||
1909 | 588 | return(((int) (pos != end))); | ||
1910 | 589 | } | ||
1911 | 590 | |||
1912 | 591 | |||
1913 | 592 | /** | ||
1914 | 593 | Reads one packet to net->buff + net->where_b. | ||
1915 | 594 | Long packets are handled by drizzleclient_net_read(). | ||
1916 | 595 | This function reallocates the net->buff buffer if necessary. | ||
1917 | 596 | |||
1918 | 597 | @return | ||
1919 | 598 | Returns length of packet. | ||
1920 | 599 | */ | ||
1921 | 600 | |||
1922 | 601 | static uint32_t | ||
1923 | 602 | my_real_read(NET *net, size_t *complen) | ||
1924 | 603 | { | ||
1925 | 604 | unsigned char *pos; | ||
1926 | 605 | size_t length; | ||
1927 | 606 | uint32_t i,retry_count=0; | ||
1928 | 607 | size_t len=packet_error; | ||
1929 | 608 | uint32_t remain= (net->compress ? NET_HEADER_SIZE+COMP_HEADER_SIZE : | ||
1930 | 609 | NET_HEADER_SIZE); | ||
1931 | 610 | |||
1932 | 611 | *complen = 0; | ||
1933 | 612 | |||
1934 | 613 | net->reading_or_writing= 1; | ||
1935 | 614 | /* Read timeout is set in drizzleclient_net_set_read_timeout */ | ||
1936 | 615 | |||
1937 | 616 | pos = net->buff + net->where_b; /* net->packet -4 */ | ||
1938 | 617 | |||
1939 | 618 | for (i= 0; i < 2 ; i++) | ||
1940 | 619 | { | ||
1941 | 620 | while (remain > 0) | ||
1942 | 621 | { | ||
1943 | 622 | /* First read is done with non blocking mode */ | ||
1944 | 623 | if ((long) (length= drizzleclient_vio_read(net->vio, pos, remain)) <= 0L) | ||
1945 | 624 | { | ||
1946 | 625 | if (net->vio == NULL) | ||
1947 | 626 | goto end; | ||
1948 | 627 | |||
1949 | 628 | const bool interrupted = drizzleclient_vio_should_retry(net->vio); | ||
1950 | 629 | |||
1951 | 630 | if (interrupted) | ||
1952 | 631 | { /* Probably in MIT threads */ | ||
1953 | 632 | if (retry_count++ < net->retry_count) | ||
1954 | 633 | continue; | ||
1955 | 634 | } | ||
1956 | 635 | if (drizzleclient_vio_errno(net->vio) == EINTR) | ||
1957 | 636 | { | ||
1958 | 637 | continue; | ||
1959 | 638 | } | ||
1960 | 639 | len= packet_error; | ||
1961 | 640 | net->error= 2; /* Close socket */ | ||
1962 | 641 | net->last_errno= (drizzleclient_vio_was_interrupted(net->vio) ? | ||
1963 | 642 | CR_NET_READ_INTERRUPTED : | ||
1964 | 643 | CR_NET_READ_ERROR); | ||
1965 | 644 | ER(net->last_errno); | ||
1966 | 645 | goto end; | ||
1967 | 646 | } | ||
1968 | 647 | remain -= (uint32_t) length; | ||
1969 | 648 | pos+= length; | ||
1970 | 649 | current_session->status_var.bytes_received+= length; | ||
1971 | 650 | } | ||
1972 | 651 | if (i == 0) | ||
1973 | 652 | { /* First parts is packet length */ | ||
1974 | 653 | uint32_t helping; | ||
1975 | 654 | |||
1976 | 655 | if (net->buff[net->where_b + 3] != (unsigned char) net->pkt_nr) | ||
1977 | 656 | { | ||
1978 | 657 | len= packet_error; | ||
1979 | 658 | /* Not a NET error on the client. XXX: why? */ | ||
1980 | 659 | goto end; | ||
1981 | 660 | } | ||
1982 | 661 | net->compress_pkt_nr= ++net->pkt_nr; | ||
1983 | 662 | if (net->compress) | ||
1984 | 663 | { | ||
1985 | 664 | /* | ||
1986 | 665 | If the packet is compressed then complen > 0 and contains the | ||
1987 | 666 | number of bytes in the uncompressed packet | ||
1988 | 667 | */ | ||
1989 | 668 | *complen=uint3korr(&(net->buff[net->where_b + NET_HEADER_SIZE])); | ||
1990 | 669 | } | ||
1991 | 670 | |||
1992 | 671 | len=uint3korr(net->buff+net->where_b); | ||
1993 | 672 | if (!len) /* End of big multi-packet */ | ||
1994 | 673 | goto end; | ||
1995 | 674 | helping = max(len,*complen) + net->where_b; | ||
1996 | 675 | /* The necessary size of net->buff */ | ||
1997 | 676 | if (helping >= net->max_packet) | ||
1998 | 677 | { | ||
1999 | 678 | if (drizzleclient_net_realloc(net,helping)) | ||
2000 | 679 | { | ||
2001 | 680 | len= packet_error; /* Return error and close connection */ | ||
2002 | 681 | goto end; | ||
2003 | 682 | } | ||
2004 | 683 | } | ||
2005 | 684 | pos=net->buff + net->where_b; | ||
2006 | 685 | remain = (uint32_t) len; | ||
2007 | 686 | } | ||
2008 | 687 | } | ||
2009 | 688 | |||
2010 | 689 | end: | ||
2011 | 690 | net->reading_or_writing= 0; | ||
2012 | 691 | |||
2013 | 692 | return(len); | ||
2014 | 693 | } | ||
2015 | 694 | |||
2016 | 695 | |||
2017 | 696 | /** | ||
2018 | 697 | Read a packet from the client/server and return it without the internal | ||
2019 | 698 | package header. | ||
2020 | 699 | |||
2021 | 700 | If the packet is the first packet of a multi-packet packet | ||
2022 | 701 | (which is indicated by the length of the packet = 0xffffff) then | ||
2023 | 702 | all sub packets are read and concatenated. | ||
2024 | 703 | |||
2025 | 704 | If the packet was compressed, its uncompressed and the length of the | ||
2026 | 705 | uncompressed packet is returned. | ||
2027 | 706 | |||
2028 | 707 | @return | ||
2029 | 708 | The function returns the length of the found packet or packet_error. | ||
2030 | 709 | net->read_pos points to the read data. | ||
2031 | 710 | */ | ||
2032 | 711 | |||
2033 | 712 | uint32_t | ||
2034 | 713 | drizzleclient_net_read(NET *net) | ||
2035 | 714 | { | ||
2036 | 715 | size_t len, complen; | ||
2037 | 716 | |||
2038 | 717 | if (!net->compress) | ||
2039 | 718 | { | ||
2040 | 719 | len = my_real_read(net,&complen); | ||
2041 | 720 | if (len == MAX_PACKET_LENGTH) | ||
2042 | 721 | { | ||
2043 | 722 | /* First packet of a multi-packet. Concatenate the packets */ | ||
2044 | 723 | uint32_t save_pos = net->where_b; | ||
2045 | 724 | size_t total_length= 0; | ||
2046 | 725 | do | ||
2047 | 726 | { | ||
2048 | 727 | net->where_b += len; | ||
2049 | 728 | total_length += len; | ||
2050 | 729 | len = my_real_read(net,&complen); | ||
2051 | 730 | } while (len == MAX_PACKET_LENGTH); | ||
2052 | 731 | if (len != packet_error) | ||
2053 | 732 | len+= total_length; | ||
2054 | 733 | net->where_b = save_pos; | ||
2055 | 734 | } | ||
2056 | 735 | net->read_pos = net->buff + net->where_b; | ||
2057 | 736 | if (len != packet_error) | ||
2058 | 737 | net->read_pos[len]=0; /* Safeguard for drizzleclient_use_result */ | ||
2059 | 738 | return len; | ||
2060 | 739 | } | ||
2061 | 740 | else | ||
2062 | 741 | { | ||
2063 | 742 | /* We are using the compressed protocol */ | ||
2064 | 743 | |||
2065 | 744 | uint32_t buf_length; | ||
2066 | 745 | uint32_t start_of_packet; | ||
2067 | 746 | uint32_t first_packet_offset; | ||
2068 | 747 | uint32_t read_length, multi_byte_packet=0; | ||
2069 | 748 | |||
2070 | 749 | if (net->remain_in_buf) | ||
2071 | 750 | { | ||
2072 | 751 | buf_length= net->buf_length; /* Data left in old packet */ | ||
2073 | 752 | first_packet_offset= start_of_packet= (net->buf_length - | ||
2074 | 753 | net->remain_in_buf); | ||
2075 | 754 | /* Restore the character that was overwritten by the end 0 */ | ||
2076 | 755 | net->buff[start_of_packet]= net->save_char; | ||
2077 | 756 | } | ||
2078 | 757 | else | ||
2079 | 758 | { | ||
2080 | 759 | /* reuse buffer, as there is nothing in it that we need */ | ||
2081 | 760 | buf_length= start_of_packet= first_packet_offset= 0; | ||
2082 | 761 | } | ||
2083 | 762 | for (;;) | ||
2084 | 763 | { | ||
2085 | 764 | uint32_t packet_len; | ||
2086 | 765 | |||
2087 | 766 | if (buf_length - start_of_packet >= NET_HEADER_SIZE) | ||
2088 | 767 | { | ||
2089 | 768 | read_length = uint3korr(net->buff+start_of_packet); | ||
2090 | 769 | if (!read_length) | ||
2091 | 770 | { | ||
2092 | 771 | /* End of multi-byte packet */ | ||
2093 | 772 | start_of_packet += NET_HEADER_SIZE; | ||
2094 | 773 | break; | ||
2095 | 774 | } | ||
2096 | 775 | if (read_length + NET_HEADER_SIZE <= buf_length - start_of_packet) | ||
2097 | 776 | { | ||
2098 | 777 | if (multi_byte_packet) | ||
2099 | 778 | { | ||
2100 | 779 | /* Remove packet header for second packet */ | ||
2101 | 780 | memmove(net->buff + first_packet_offset + start_of_packet, | ||
2102 | 781 | net->buff + first_packet_offset + start_of_packet + | ||
2103 | 782 | NET_HEADER_SIZE, | ||
2104 | 783 | buf_length - start_of_packet); | ||
2105 | 784 | start_of_packet += read_length; | ||
2106 | 785 | buf_length -= NET_HEADER_SIZE; | ||
2107 | 786 | } | ||
2108 | 787 | else | ||
2109 | 788 | start_of_packet+= read_length + NET_HEADER_SIZE; | ||
2110 | 789 | |||
2111 | 790 | if (read_length != MAX_PACKET_LENGTH) /* last package */ | ||
2112 | 791 | { | ||
2113 | 792 | multi_byte_packet= 0; /* No last zero len packet */ | ||
2114 | 793 | break; | ||
2115 | 794 | } | ||
2116 | 795 | multi_byte_packet= NET_HEADER_SIZE; | ||
2117 | 796 | /* Move data down to read next data packet after current one */ | ||
2118 | 797 | if (first_packet_offset) | ||
2119 | 798 | { | ||
2120 | 799 | memmove(net->buff,net->buff+first_packet_offset, | ||
2121 | 800 | buf_length-first_packet_offset); | ||
2122 | 801 | buf_length-=first_packet_offset; | ||
2123 | 802 | start_of_packet -= first_packet_offset; | ||
2124 | 803 | first_packet_offset=0; | ||
2125 | 804 | } | ||
2126 | 805 | continue; | ||
2127 | 806 | } | ||
2128 | 807 | } | ||
2129 | 808 | /* Move data down to read next data packet after current one */ | ||
2130 | 809 | if (first_packet_offset) | ||
2131 | 810 | { | ||
2132 | 811 | memmove(net->buff,net->buff+first_packet_offset, | ||
2133 | 812 | buf_length-first_packet_offset); | ||
2134 | 813 | buf_length-=first_packet_offset; | ||
2135 | 814 | start_of_packet -= first_packet_offset; | ||
2136 | 815 | first_packet_offset=0; | ||
2137 | 816 | } | ||
2138 | 817 | |||
2139 | 818 | net->where_b=buf_length; | ||
2140 | 819 | if ((packet_len = my_real_read(net,&complen)) == packet_error) | ||
2141 | 820 | return packet_error; | ||
2142 | 821 | |||
2143 | 822 | if (complen) | ||
2144 | 823 | { | ||
2145 | 824 | unsigned char * compbuf= (unsigned char *) malloc(complen); | ||
2146 | 825 | if (compbuf != NULL) | ||
2147 | 826 | { | ||
2148 | 827 | uLongf tmp_complen= complen; | ||
2149 | 828 | int error= uncompress((Bytef*) compbuf, &tmp_complen, | ||
2150 | 829 | (Bytef*) (net->buff + net->where_b), | ||
2151 | 830 | (uLong)packet_len); | ||
2152 | 831 | complen= tmp_complen; | ||
2153 | 832 | |||
2154 | 833 | if (error != Z_OK) | ||
2155 | 834 | { | ||
2156 | 835 | net->error= 2; /* caller will close socket */ | ||
2157 | 836 | net->last_errno= CR_NET_UNCOMPRESS_ERROR; | ||
2158 | 837 | } | ||
2159 | 838 | else | ||
2160 | 839 | { | ||
2161 | 840 | memcpy((net->buff + net->where_b), compbuf, complen); | ||
2162 | 841 | } | ||
2163 | 842 | free(compbuf); | ||
2164 | 843 | } | ||
2165 | 844 | } | ||
2166 | 845 | else | ||
2167 | 846 | complen= packet_len; | ||
2168 | 847 | |||
2169 | 848 | } | ||
2170 | 849 | buf_length+= complen; | ||
2171 | 850 | |||
2172 | 851 | net->read_pos= net->buff+ first_packet_offset + NET_HEADER_SIZE; | ||
2173 | 852 | net->buf_length= buf_length; | ||
2174 | 853 | net->remain_in_buf= (uint32_t) (buf_length - start_of_packet); | ||
2175 | 854 | len = ((uint32_t) (start_of_packet - first_packet_offset) - NET_HEADER_SIZE - | ||
2176 | 855 | multi_byte_packet); | ||
2177 | 856 | net->save_char= net->read_pos[len]; /* Must be saved */ | ||
2178 | 857 | net->read_pos[len]=0; /* Safeguard for drizzleclient_use_result */ | ||
2179 | 858 | } | ||
2180 | 859 | return len; | ||
2181 | 860 | } | ||
2182 | 861 | |||
2183 | 862 | |||
2184 | 863 | void drizzleclient_net_set_read_timeout(NET *net, uint32_t timeout) | ||
2185 | 864 | { | ||
2186 | 865 | net->read_timeout= timeout; | ||
2187 | 866 | #ifndef __sun | ||
2188 | 867 | if (net->vio) | ||
2189 | 868 | drizzleclient_vio_timeout(net->vio, 0, timeout); | ||
2190 | 869 | #endif | ||
2191 | 870 | return; | ||
2192 | 871 | } | ||
2193 | 872 | |||
2194 | 873 | |||
2195 | 874 | void drizzleclient_net_set_write_timeout(NET *net, uint32_t timeout) | ||
2196 | 875 | { | ||
2197 | 876 | net->write_timeout= timeout; | ||
2198 | 877 | #ifndef __sun | ||
2199 | 878 | if (net->vio) | ||
2200 | 879 | drizzleclient_vio_timeout(net->vio, 1, timeout); | ||
2201 | 880 | #endif | ||
2202 | 881 | return; | ||
2203 | 882 | } | ||
2204 | 883 | /** | ||
2205 | 884 | Clear possible error state of struct NET | ||
2206 | 885 | |||
2207 | 886 | @param net clear the state of the argument | ||
2208 | 887 | */ | ||
2209 | 888 | |||
2210 | 889 | void drizzleclient_drizzleclient_net_clear_error(NET *net) | ||
2211 | 890 | { | ||
2212 | 891 | net->last_errno= 0; | ||
2213 | 892 | net->last_error[0]= '\0'; | ||
2214 | 893 | strcpy(net->sqlstate, not_error_sqlstate); | ||
2215 | 894 | } | ||
2216 | 895 | |||
2217 | 896 | } /* namespace drizzle_protocol */ | ||
2218 | 897 | 0 | ||
2219 | === removed file 'plugin/drizzle_protocol/net_serv.h' | |||
2220 | --- plugin/drizzle_protocol/net_serv.h 2010-03-04 18:06:27 +0000 | |||
2221 | +++ plugin/drizzle_protocol/net_serv.h 1970-01-01 00:00:00 +0000 | |||
2222 | @@ -1,94 +0,0 @@ | |||
2223 | 1 | /* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*- | ||
2224 | 2 | * vim:expandtab:shiftwidth=2:tabstop=2:smarttab: | ||
2225 | 3 | * | ||
2226 | 4 | * Copyright (C) 2008 Sun Microsystems, Inc. | ||
2227 | 5 | * | ||
2228 | 6 | * This program is free software; you can redistribute it and/or modify | ||
2229 | 7 | * it under the terms of the GNU General Public License as published by | ||
2230 | 8 | * the Free Software Foundation; version 2 of the License. | ||
2231 | 9 | * | ||
2232 | 10 | * This program is distributed in the hope that it will be useful, | ||
2233 | 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
2234 | 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
2235 | 13 | * GNU General Public License for more details. | ||
2236 | 14 | * | ||
2237 | 15 | * You should have received a copy of the GNU General Public License | ||
2238 | 16 | * along with this program; if not, write to the Free Software | ||
2239 | 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
2240 | 18 | */ | ||
2241 | 19 | |||
2242 | 20 | |||
2243 | 21 | #ifndef PLUGIN_DRIZZLE_PROTOCOL_NET_SERV_H | ||
2244 | 22 | #define PLUGIN_DRIZZLE_PROTOCOL_NET_SERV_H | ||
2245 | 23 | |||
2246 | 24 | #include "vio.h" | ||
2247 | 25 | |||
2248 | 26 | #include <stdint.h> | ||
2249 | 27 | |||
2250 | 28 | namespace drizzle_protocol | ||
2251 | 29 | { | ||
2252 | 30 | |||
2253 | 31 | #define LIBDRIZZLE_ERRMSG_SIZE 512 | ||
2254 | 32 | #define LIBDRIZZLE_SQLSTATE_LENGTH 5 | ||
2255 | 33 | |||
2256 | 34 | typedef struct st_net { | ||
2257 | 35 | Vio *vio; | ||
2258 | 36 | unsigned char *buff,*buff_end,*write_pos,*read_pos; | ||
2259 | 37 | int fd; /* For Perl DBI/dbd */ | ||
2260 | 38 | /* | ||
2261 | 39 | The following variable is set if we are doing several queries in one | ||
2262 | 40 | command ( as in LOAD TABLE ... FROM MASTER ), | ||
2263 | 41 | and do not want to confuse the client with OK at the wrong time | ||
2264 | 42 | */ | ||
2265 | 43 | unsigned long remain_in_buf,length, buf_length, where_b; | ||
2266 | 44 | unsigned long max_packet,max_packet_size; | ||
2267 | 45 | unsigned int pkt_nr,compress_pkt_nr; | ||
2268 | 46 | unsigned int write_timeout; | ||
2269 | 47 | unsigned int read_timeout; | ||
2270 | 48 | unsigned int retry_count; | ||
2271 | 49 | int fcntl; | ||
2272 | 50 | unsigned int *return_status; | ||
2273 | 51 | unsigned char reading_or_writing; | ||
2274 | 52 | char save_char; | ||
2275 | 53 | bool compress; | ||
2276 | 54 | /* | ||
2277 | 55 | Pointer to query object in query cache, do not equal NULL (0) for | ||
2278 | 56 | queries in cache that have not stored its results yet | ||
2279 | 57 | */ | ||
2280 | 58 | /* | ||
2281 | 59 | Unused, please remove with the next incompatible ABI change. | ||
2282 | 60 | */ | ||
2283 | 61 | unsigned char *unused; | ||
2284 | 62 | unsigned int last_errno; | ||
2285 | 63 | unsigned char error; | ||
2286 | 64 | /** Client library error message buffer. Actually belongs to struct MYSQL. */ | ||
2287 | 65 | char last_error[LIBDRIZZLE_ERRMSG_SIZE]; | ||
2288 | 66 | /** Client library sqlstate buffer. Set along with the error message. */ | ||
2289 | 67 | char sqlstate[LIBDRIZZLE_SQLSTATE_LENGTH+1]; | ||
2290 | 68 | void *extension; | ||
2291 | 69 | } NET; | ||
2292 | 70 | |||
2293 | 71 | bool drizzleclient_net_init(NET *net, Vio* vio, uint32_t buffer_length); | ||
2294 | 72 | void drizzleclient_net_end(NET *net); | ||
2295 | 73 | void drizzleclient_net_clear(NET *net, bool clear_buffer); | ||
2296 | 74 | bool drizzleclient_net_flush(NET *net); | ||
2297 | 75 | bool drizzleclient_net_write(NET *net,const unsigned char *packet, size_t len); | ||
2298 | 76 | bool drizzleclient_net_write_command(NET *net,unsigned char command, | ||
2299 | 77 | const unsigned char *header, size_t head_len, | ||
2300 | 78 | const unsigned char *packet, size_t len); | ||
2301 | 79 | uint32_t drizzleclient_net_read(NET *net); | ||
2302 | 80 | void drizzleclient_net_close(NET *net); | ||
2303 | 81 | bool drizzleclient_net_init_sock(NET * net, int sock, int flags, | ||
2304 | 82 | uint32_t buffer_length); | ||
2305 | 83 | bool drizzleclient_net_peer_addr(NET *net, char *buf, uint16_t *port, size_t buflen); | ||
2306 | 84 | void drizzleclient_net_keepalive(NET *net, bool flag); | ||
2307 | 85 | int drizzleclient_net_get_sd(NET *net); | ||
2308 | 86 | bool drizzleclient_net_more_data(NET *net); | ||
2309 | 87 | |||
2310 | 88 | void drizzleclient_net_set_write_timeout(NET *net, uint32_t timeout); | ||
2311 | 89 | void drizzleclient_net_set_read_timeout(NET *net, uint32_t timeout); | ||
2312 | 90 | void drizzleclient_drizzleclient_net_clear_error(NET *net); | ||
2313 | 91 | |||
2314 | 92 | } /* namespace drizzle_protocol */ | ||
2315 | 93 | |||
2316 | 94 | #endif /* PLUGIN_DRIZZLE_PROTOCOL_NET_SERV_H */ | ||
2317 | 95 | 0 | ||
2318 | === removed file 'plugin/drizzle_protocol/options.h' | |||
2319 | --- plugin/drizzle_protocol/options.h 2010-03-04 18:06:27 +0000 | |||
2320 | +++ plugin/drizzle_protocol/options.h 1970-01-01 00:00:00 +0000 | |||
2321 | @@ -1,125 +0,0 @@ | |||
2322 | 1 | /* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*- | ||
2323 | 2 | * vim:expandtab:shiftwidth=2:tabstop=2:smarttab: | ||
2324 | 3 | * | ||
2325 | 4 | * Copyright (C) 2008 Sun Microsystems, Inc. | ||
2326 | 5 | * | ||
2327 | 6 | * This program is free software; you can redistribute it and/or modify | ||
2328 | 7 | * it under the terms of the GNU General Public License as published by | ||
2329 | 8 | * the Free Software Foundation; version 2 of the License. | ||
2330 | 9 | * | ||
2331 | 10 | * This program is distributed in the hope that it will be useful, | ||
2332 | 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
2333 | 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
2334 | 13 | * GNU General Public License for more details. | ||
2335 | 14 | * | ||
2336 | 15 | * You should have received a copy of the GNU General Public License | ||
2337 | 16 | * along with this program; if not, write to the Free Software | ||
2338 | 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
2339 | 18 | */ | ||
2340 | 19 | |||
2341 | 20 | #ifndef PLUGIN_DRIZZLE_PROTOCOL_OPTIONS_H | ||
2342 | 21 | #define PLUGIN_DRIZZLE_PROTOCOL_OPTIONS_H | ||
2343 | 22 | |||
2344 | 23 | namespace drizzle_protocol | ||
2345 | 24 | { | ||
2346 | 25 | |||
2347 | 26 | enum drizzle_option | ||
2348 | 27 | { | ||
2349 | 28 | DRIZZLE_OPT_CONNECT_TIMEOUT, DRIZZLE_OPT_COMPRESS, DRIZZLE_OPT_NAMED_PIPE, | ||
2350 | 29 | DRIZZLE_INIT_COMMAND, DRIZZLE_READ_DEFAULT_FILE, DRIZZLE_READ_DEFAULT_GROUP, | ||
2351 | 30 | DRIZZLE_OPT_PROTOCOL, DRIZZLE_SHARED_MEMORY_BASE_NAME, DRIZZLE_OPT_READ_TIMEOUT, | ||
2352 | 31 | DRIZZLE_OPT_WRITE_TIMEOUT, DRIZZLE_OPT_USE_RESULT, | ||
2353 | 32 | DRIZZLE_OPT_USE_REMOTE_CONNECTION, | ||
2354 | 33 | DRIZZLE_OPT_GUESS_CONNECTION, DRIZZLE_SET_CLIENT_IP, DRIZZLE_SECURE_AUTH, | ||
2355 | 34 | DRIZZLE_REPORT_DATA_TRUNCATION, DRIZZLE_OPT_RECONNECT, | ||
2356 | 35 | DRIZZLE_OPT_SSL_VERIFY_SERVER_CERT | ||
2357 | 36 | }; | ||
2358 | 37 | |||
2359 | 38 | struct st_drizzleclient_options { | ||
2360 | 39 | unsigned int connect_timeout, read_timeout, write_timeout; | ||
2361 | 40 | unsigned int port; | ||
2362 | 41 | unsigned long client_flag; | ||
2363 | 42 | char *host,*user,*password,*db; | ||
2364 | 43 | char *my_cnf_file,*my_cnf_group; | ||
2365 | 44 | char *ssl_key; /* PEM key file */ | ||
2366 | 45 | char *ssl_cert; /* PEM cert file */ | ||
2367 | 46 | char *ssl_ca; /* PEM CA file */ | ||
2368 | 47 | char *ssl_capath; /* PEM directory of CA-s? */ | ||
2369 | 48 | char *ssl_cipher; /* cipher to use */ | ||
2370 | 49 | char *shared_memory_base_name; | ||
2371 | 50 | unsigned long max_allowed_packet; | ||
2372 | 51 | bool use_ssl; /* if to use SSL or not */ | ||
2373 | 52 | bool compress,named_pipe; | ||
2374 | 53 | bool unused1; | ||
2375 | 54 | bool unused2; | ||
2376 | 55 | bool unused3; | ||
2377 | 56 | bool unused4; | ||
2378 | 57 | enum drizzle_option methods_to_use; | ||
2379 | 58 | char *client_ip; | ||
2380 | 59 | /* Refuse client connecting to server if it uses old (pre-4.1.1) protocol */ | ||
2381 | 60 | bool secure_auth; | ||
2382 | 61 | /* 0 - never report, 1 - always report (default) */ | ||
2383 | 62 | bool report_data_truncation; | ||
2384 | 63 | |||
2385 | 64 | /* function pointers for local infile support */ | ||
2386 | 65 | int (*local_infile_init)(void **, const char *, void *); | ||
2387 | 66 | int (*local_infile_read)(void *, char *, unsigned int); | ||
2388 | 67 | void (*local_infile_end)(void *); | ||
2389 | 68 | int (*local_infile_error)(void *, char *, unsigned int); | ||
2390 | 69 | void *local_infile_userdata; | ||
2391 | 70 | void *extension; | ||
2392 | 71 | }; | ||
2393 | 72 | |||
2394 | 73 | |||
2395 | 74 | #define CLIENT_NET_READ_TIMEOUT 365*24*3600 /* Timeout on read */ | ||
2396 | 75 | #define CLIENT_NET_WRITE_TIMEOUT 365*24*3600 /* Timeout on write */ | ||
2397 | 76 | |||
2398 | 77 | #define CLIENT_LONG_PASSWORD 1 /* new more secure passwords */ | ||
2399 | 78 | #define CLIENT_FOUND_ROWS 2 /* Found instead of affected rows */ | ||
2400 | 79 | #define CLIENT_LONG_FLAG 4 /* Get all column flags */ | ||
2401 | 80 | #define CLIENT_CONNECT_WITH_DB 8 /* One can specify db on connect */ | ||
2402 | 81 | #define CLIENT_NO_SCHEMA 16 /* Don't allow database.table.column */ | ||
2403 | 82 | #define CLIENT_COMPRESS 32 /* Can use compression protocol */ | ||
2404 | 83 | #define CLIENT_ODBC 64 /* Odbc client */ | ||
2405 | 84 | #define CLIENT_IGNORE_SPACE 256 /* Ignore spaces before '(' */ | ||
2406 | 85 | #define CLIENT_PROTOCOL_MYSQL41 512 /* New 4.1 protocol */ | ||
2407 | 86 | #define CLIENT_SSL 2048 /* Switch to SSL after handshake */ | ||
2408 | 87 | #define CLIENT_IGNORE_SIGPIPE 4096 /* IGNORE sigpipes */ | ||
2409 | 88 | #define CLIENT_RESERVED 16384 /* Old flag for 4.1 protocol */ | ||
2410 | 89 | #define CLIENT_SECURE_CONNECTION 32768 /* New 4.1 authentication */ | ||
2411 | 90 | #define CLIENT_MULTI_STATEMENTS (1UL << 16) /* Enable/disable multi-stmt support */ | ||
2412 | 91 | #define CLIENT_MULTI_RESULTS (1UL << 17) /* Enable/disable multi-results */ | ||
2413 | 92 | |||
2414 | 93 | #define CLIENT_SSL_VERIFY_SERVER_CERT (1UL << 30) | ||
2415 | 94 | #define CLIENT_REMEMBER_OPTIONS (1UL << 31) | ||
2416 | 95 | |||
2417 | 96 | /* Gather all possible capabilites (flags) supported by the server */ | ||
2418 | 97 | #define CLIENT_ALL_FLAGS (CLIENT_LONG_PASSWORD | \ | ||
2419 | 98 | CLIENT_FOUND_ROWS | \ | ||
2420 | 99 | CLIENT_LONG_FLAG | \ | ||
2421 | 100 | CLIENT_CONNECT_WITH_DB | \ | ||
2422 | 101 | CLIENT_NO_SCHEMA | \ | ||
2423 | 102 | CLIENT_COMPRESS | \ | ||
2424 | 103 | CLIENT_ODBC | \ | ||
2425 | 104 | CLIENT_IGNORE_SPACE | \ | ||
2426 | 105 | CLIENT_SSL | \ | ||
2427 | 106 | CLIENT_IGNORE_SIGPIPE | \ | ||
2428 | 107 | CLIENT_RESERVED | \ | ||
2429 | 108 | CLIENT_SECURE_CONNECTION | \ | ||
2430 | 109 | CLIENT_MULTI_STATEMENTS | \ | ||
2431 | 110 | CLIENT_MULTI_RESULTS | \ | ||
2432 | 111 | CLIENT_SSL_VERIFY_SERVER_CERT | \ | ||
2433 | 112 | CLIENT_REMEMBER_OPTIONS) | ||
2434 | 113 | |||
2435 | 114 | /* | ||
2436 | 115 | Switch off the flags that are optional and depending on build flags | ||
2437 | 116 | If any of the optional flags is supported by the build it will be switched | ||
2438 | 117 | on before sending to the client during the connection handshake. | ||
2439 | 118 | */ | ||
2440 | 119 | #define CLIENT_BASIC_FLAGS (((CLIENT_ALL_FLAGS & ~CLIENT_SSL) \ | ||
2441 | 120 | & ~CLIENT_COMPRESS) \ | ||
2442 | 121 | & ~CLIENT_SSL_VERIFY_SERVER_CERT) | ||
2443 | 122 | |||
2444 | 123 | } /* namespace drizzle_protocol */ | ||
2445 | 124 | |||
2446 | 125 | #endif /* PLUGIN_DRIZZLE_PROTOCOL_OPTIONS_H */ | ||
2447 | 126 | 0 | ||
2448 | === removed file 'plugin/drizzle_protocol/pack.cc' | |||
2449 | --- plugin/drizzle_protocol/pack.cc 2010-03-04 18:06:27 +0000 | |||
2450 | +++ plugin/drizzle_protocol/pack.cc 1970-01-01 00:00:00 +0000 | |||
2451 | @@ -1,132 +0,0 @@ | |||
2452 | 1 | /* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*- | ||
2453 | 2 | * vim:expandtab:shiftwidth=2:tabstop=2:smarttab: | ||
2454 | 3 | * | ||
2455 | 4 | * Copyright (C) 2008 Sun Microsystems, Inc. | ||
2456 | 5 | * | ||
2457 | 6 | * This program is free software; you can redistribute it and/or modify | ||
2458 | 7 | * it under the terms of the GNU General Public License as published by | ||
2459 | 8 | * the Free Software Foundation; version 2 of the License. | ||
2460 | 9 | * | ||
2461 | 10 | * This program is distributed in the hope that it will be useful, | ||
2462 | 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
2463 | 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
2464 | 13 | * GNU General Public License for more details. | ||
2465 | 14 | * | ||
2466 | 15 | * You should have received a copy of the GNU General Public License | ||
2467 | 16 | * along with this program; if not, write to the Free Software | ||
2468 | 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
2469 | 18 | */ | ||
2470 | 19 | |||
2471 | 20 | #include "config.h" | ||
2472 | 21 | #include <drizzled/korr.h> | ||
2473 | 22 | |||
2474 | 23 | #include <stdint.h> | ||
2475 | 24 | |||
2476 | 25 | #include "pack.h" | ||
2477 | 26 | |||
2478 | 27 | namespace drizzle_protocol | ||
2479 | 28 | { | ||
2480 | 29 | |||
2481 | 30 | /* Get the length of next field. Change parameter to point at fieldstart */ | ||
2482 | 31 | uint32_t drizzleclient_net_field_length(unsigned char **packet) | ||
2483 | 32 | { | ||
2484 | 33 | register unsigned char *pos= (unsigned char *)*packet; | ||
2485 | 34 | if (*pos < 251) | ||
2486 | 35 | { | ||
2487 | 36 | (*packet)++; | ||
2488 | 37 | return (uint32_t) *pos; | ||
2489 | 38 | } | ||
2490 | 39 | if (*pos == 251) | ||
2491 | 40 | { | ||
2492 | 41 | (*packet)++; | ||
2493 | 42 | return NULL_LENGTH; | ||
2494 | 43 | } | ||
2495 | 44 | if (*pos == 252) | ||
2496 | 45 | { | ||
2497 | 46 | (*packet)+=3; | ||
2498 | 47 | return (uint32_t) uint2korr(pos+1); | ||
2499 | 48 | } | ||
2500 | 49 | if (*pos == 253) | ||
2501 | 50 | { | ||
2502 | 51 | (*packet)+=4; | ||
2503 | 52 | return (uint32_t) uint3korr(pos+1); | ||
2504 | 53 | } | ||
2505 | 54 | (*packet)+=9; /* Must be 254 when here */ | ||
2506 | 55 | return (uint32_t) uint4korr(pos+1); | ||
2507 | 56 | } | ||
2508 | 57 | |||
2509 | 58 | /* The same as above but returns int64_t */ | ||
2510 | 59 | uint64_t drizzleclient_drizzleclient_net_field_length_ll(unsigned char **packet) | ||
2511 | 60 | { | ||
2512 | 61 | register unsigned char *pos= *packet; | ||
2513 | 62 | if (*pos < 251) | ||
2514 | 63 | { | ||
2515 | 64 | (*packet)++; | ||
2516 | 65 | return (uint64_t) *pos; | ||
2517 | 66 | } | ||
2518 | 67 | if (*pos == 251) | ||
2519 | 68 | { | ||
2520 | 69 | (*packet)++; | ||
2521 | 70 | return (uint64_t) NULL_LENGTH; | ||
2522 | 71 | } | ||
2523 | 72 | if (*pos == 252) | ||
2524 | 73 | { | ||
2525 | 74 | (*packet)+=3; | ||
2526 | 75 | return (uint64_t) uint2korr(pos+1); | ||
2527 | 76 | } | ||
2528 | 77 | if (*pos == 253) | ||
2529 | 78 | { | ||
2530 | 79 | (*packet)+=4; | ||
2531 | 80 | return (uint64_t) uint3korr(pos+1); | ||
2532 | 81 | } | ||
2533 | 82 | (*packet)+=9; /* Must be 254 when here */ | ||
2534 | 83 | #ifdef NO_CLIENT_LONGLONG | ||
2535 | 84 | return (uint64_t) uint4korr(pos+1); | ||
2536 | 85 | #else | ||
2537 | 86 | return (uint64_t) uint8korr(pos+1); | ||
2538 | 87 | #endif | ||
2539 | 88 | } | ||
2540 | 89 | |||
2541 | 90 | /* | ||
2542 | 91 | Store an integer with simple packing into a output package | ||
2543 | 92 | |||
2544 | 93 | SYNOPSIS | ||
2545 | 94 | drizzleclient_net_store_length() | ||
2546 | 95 | pkg Store the packed integer here | ||
2547 | 96 | length integers to store | ||
2548 | 97 | |||
2549 | 98 | NOTES | ||
2550 | 99 | This is mostly used to store lengths of strings. | ||
2551 | 100 | We have to cast the result for the LL() becasue of a bug in Forte CC | ||
2552 | 101 | compiler. | ||
2553 | 102 | |||
2554 | 103 | RETURN | ||
2555 | 104 | Position in 'pkg' after the packed length | ||
2556 | 105 | */ | ||
2557 | 106 | |||
2558 | 107 | unsigned char *drizzleclient_net_store_length(unsigned char *packet, uint64_t length) | ||
2559 | 108 | { | ||
2560 | 109 | if (length < (uint64_t) 251LL) | ||
2561 | 110 | { | ||
2562 | 111 | *packet=(unsigned char) length; | ||
2563 | 112 | return packet+1; | ||
2564 | 113 | } | ||
2565 | 114 | /* 251 is reserved for NULL */ | ||
2566 | 115 | if (length < (uint64_t) 65536LL) | ||
2567 | 116 | { | ||
2568 | 117 | *packet++=252; | ||
2569 | 118 | int2store(packet,(uint32_t) length); | ||
2570 | 119 | return packet+2; | ||
2571 | 120 | } | ||
2572 | 121 | if (length < (uint64_t) 16777216LL) | ||
2573 | 122 | { | ||
2574 | 123 | *packet++=253; | ||
2575 | 124 | int3store(packet,(uint32_t) length); | ||
2576 | 125 | return packet+3; | ||
2577 | 126 | } | ||
2578 | 127 | *packet++=254; | ||
2579 | 128 | int8store(packet,length); | ||
2580 | 129 | return packet+8; | ||
2581 | 130 | } | ||
2582 | 131 | |||
2583 | 132 | } /* namespace drizzle_protocol */ | ||
2584 | 133 | 0 | ||
2585 | === removed file 'plugin/drizzle_protocol/pack.h' | |||
2586 | --- plugin/drizzle_protocol/pack.h 2010-03-04 18:06:27 +0000 | |||
2587 | +++ plugin/drizzle_protocol/pack.h 1970-01-01 00:00:00 +0000 | |||
2588 | @@ -1,34 +0,0 @@ | |||
2589 | 1 | /* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*- | ||
2590 | 2 | * vim:expandtab:shiftwidth=2:tabstop=2:smarttab: | ||
2591 | 3 | * | ||
2592 | 4 | * Copyright (C) 2008 Sun Microsystems | ||
2593 | 5 | * | ||
2594 | 6 | * This program is free software; you can redistribute it and/or modify | ||
2595 | 7 | * it under the terms of the GNU General Public License as published by | ||
2596 | 8 | * the Free Software Foundation; version 2 of the License. | ||
2597 | 9 | * | ||
2598 | 10 | * This program is distributed in the hope that it will be useful, | ||
2599 | 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
2600 | 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
2601 | 13 | * GNU General Public License for more details. | ||
2602 | 14 | * | ||
2603 | 15 | * You should have received a copy of the GNU General Public License | ||
2604 | 16 | * along with this program; if not, write to the Free Software | ||
2605 | 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
2606 | 18 | */ | ||
2607 | 19 | |||
2608 | 20 | #ifndef PLUGIN_DRIZZLE_PROTOCOL_PACK_H | ||
2609 | 21 | #define PLUGIN_DRIZZLE_PROTOCOL_PACK_H | ||
2610 | 22 | |||
2611 | 23 | namespace drizzle_protocol | ||
2612 | 24 | { | ||
2613 | 25 | |||
2614 | 26 | #define NULL_LENGTH UINT32_MAX | ||
2615 | 27 | |||
2616 | 28 | uint32_t drizzleclient_net_field_length(unsigned char **packet); | ||
2617 | 29 | uint64_t drizzleclient_drizzleclient_net_field_length_ll(unsigned char **packet); | ||
2618 | 30 | unsigned char *drizzleclient_net_store_length(unsigned char *pkg, uint64_t length); | ||
2619 | 31 | |||
2620 | 32 | } /* namespace drizzle_protocol */ | ||
2621 | 33 | |||
2622 | 34 | #endif /* PLUGIN_DRIZZLE_PROTOCOL_PACK_H */ | ||
2623 | 35 | 0 | ||
2624 | === modified file 'plugin/drizzle_protocol/plugin.ini' | |||
2625 | --- plugin/drizzle_protocol/plugin.ini 2010-09-01 19:17:03 +0000 | |||
2626 | +++ plugin/drizzle_protocol/plugin.ini 2010-10-06 01:14:00 +0000 | |||
2627 | @@ -1,12 +1,17 @@ | |||
2628 | 1 | [plugin] | 1 | [plugin] |
2629 | 2 | title=Drizzle Protocol Module | 2 | title=Drizzle Protocol Module |
2633 | 3 | description=Drizzle protocol module that uses the old libdrizzle library (previously libmysql). | 3 | description=Drizzle protocol module. |
2634 | 4 | version=0.2 | 4 | version=0.3 |
2635 | 5 | author=Eric Day | 5 | author=Brian Aker |
2636 | 6 | license=PLUGIN_LICENSE_GPL | 6 | license=PLUGIN_LICENSE_GPL |
2637 | 7 | libs=drizzled/algorithm/libhash.la | 7 | libs=drizzled/algorithm/libhash.la |
2638 | 8 | load_by_default=yes | 8 | load_by_default=yes |
2639 | 9 | ldlfags=$(LIBZ) | 9 | ldlfags=$(LIBZ) |
2642 | 10 | headers=drizzle_protocol.h errmsg.h net_serv.h options.h pack.h vio.h table_function.h | 10 | headers= |
2643 | 11 | sources=drizzle_protocol.cc errmsg.cc net_serv.cc pack.cc vio.cc viosocket.cc | 11 | drizzle_protocol.h |
2644 | 12 | errmsg.h | ||
2645 | 13 | status_table.h | ||
2646 | 14 | sources= | ||
2647 | 15 | drizzle_protocol.cc | ||
2648 | 16 | errmsg.h | ||
2649 | 12 | static=yes | 17 | static=yes |
2650 | 13 | 18 | ||
2651 | === renamed file 'plugin/drizzle_protocol/table_function.h' => 'plugin/drizzle_protocol/status_table.h' | |||
2652 | --- plugin/drizzle_protocol/table_function.h 2010-09-08 22:20:35 +0000 | |||
2653 | +++ plugin/drizzle_protocol/status_table.h 2010-10-06 01:14:00 +0000 | |||
2654 | @@ -18,18 +18,18 @@ | |||
2655 | 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
2656 | 19 | */ | 19 | */ |
2657 | 20 | 20 | ||
2660 | 21 | #ifndef PLUGIN_DRIZZLE_PROTOCOL_TABLE_FUNCTION_H | 21 | #ifndef PLUGIN_DRIZZLE_PROTOCOL_STATUS_TABLE_H |
2661 | 22 | #define PLUGIN_DRIZZLE_PROTOCOL_TABLE_FUNCTION_H | 22 | #define PLUGIN_DRIZZLE_PROTOCOL_STATUS_TABLE_H |
2662 | 23 | 23 | ||
2663 | 24 | #include "drizzled/plugin/table_function.h" | 24 | #include "drizzled/plugin/table_function.h" |
2664 | 25 | namespace drizzle_protocol | 25 | namespace drizzle_protocol |
2665 | 26 | { | 26 | { |
2666 | 27 | 27 | ||
2667 | 28 | 28 | ||
2669 | 29 | class DrizzleProtocolStatus : public drizzled::plugin::TableFunction | 29 | class StatusTable : public drizzled::plugin::TableFunction |
2670 | 30 | { | 30 | { |
2671 | 31 | public: | 31 | public: |
2673 | 32 | DrizzleProtocolStatus() : | 32 | StatusTable() : |
2674 | 33 | drizzled::plugin::TableFunction("DATA_DICTIONARY","DRIZZLE_PROTOCOL_STATUS") | 33 | drizzled::plugin::TableFunction("DATA_DICTIONARY","DRIZZLE_PROTOCOL_STATUS") |
2675 | 34 | { | 34 | { |
2676 | 35 | add_field("VARIABLE_NAME"); | 35 | add_field("VARIABLE_NAME"); |
2677 | @@ -38,12 +38,17 @@ | |||
2678 | 38 | 38 | ||
2679 | 39 | class Generator : public drizzled::plugin::TableFunction::Generator | 39 | class Generator : public drizzled::plugin::TableFunction::Generator |
2680 | 40 | { | 40 | { |
2681 | 41 | drizzled::drizzle_show_var *status_var_ptr; | ||
2682 | 42 | 41 | ||
2683 | 43 | public: | 42 | public: |
2685 | 44 | Generator(drizzled::Field **fields); | 43 | Generator(drizzled::Field **fields) : |
2686 | 44 | drizzled::plugin::TableFunction::Generator(fields) | ||
2687 | 45 | { | ||
2688 | 46 | } | ||
2689 | 45 | 47 | ||
2691 | 46 | bool populate(); | 48 | bool populate() |
2692 | 49 | { | ||
2693 | 50 | return false; | ||
2694 | 51 | } | ||
2695 | 47 | }; | 52 | }; |
2696 | 48 | 53 | ||
2697 | 49 | Generator *generator(drizzled::Field **arg) | 54 | Generator *generator(drizzled::Field **arg) |
2698 | @@ -54,4 +59,4 @@ | |||
2699 | 54 | 59 | ||
2700 | 55 | } | 60 | } |
2701 | 56 | 61 | ||
2703 | 57 | #endif /* PLUGIN_DRIZZLE_PROTOCOL_TABLE_FUNCTION_H */ | 62 | #endif /* PLUGIN_DRIZZLE_PROTOCOL_STATUS_TABLE_H */ |
2704 | 58 | 63 | ||
2705 | === renamed file 'plugin/drizzle_protocol/vio.cc' => 'plugin/drizzle_protocol/vio.cc.THIS' | |||
2706 | === renamed file 'plugin/drizzle_protocol/vio.h' => 'plugin/drizzle_protocol/vio.h.THIS' | |||
2707 | === renamed file 'plugin/drizzle_protocol/viosocket.cc' => 'plugin/drizzle_protocol/viosocket.cc.THIS' | |||
2708 | === modified file 'plugin/information_schema_dictionary/key_column_usage.cc' | |||
2709 | --- plugin/information_schema_dictionary/key_column_usage.cc 2010-07-11 15:57:03 +0000 | |||
2710 | +++ plugin/information_schema_dictionary/key_column_usage.cc 2010-10-06 01:14:00 +0000 | |||
2711 | @@ -41,7 +41,9 @@ | |||
2712 | 41 | InformationSchema::Generator(arg), | 41 | InformationSchema::Generator(arg), |
2713 | 42 | generator(getSession()), | 42 | generator(getSession()), |
2714 | 43 | index_iterator(0), | 43 | index_iterator(0), |
2716 | 44 | index_part_iterator(0) | 44 | index_part_iterator(0), |
2717 | 45 | fk_constraint_iterator(0), | ||
2718 | 46 | fk_constraint_column_name_iterator(0) | ||
2719 | 45 | { | 47 | { |
2720 | 46 | while (not (table_message= generator)) | 48 | while (not (table_message= generator)) |
2721 | 47 | { }; | 49 | { }; |
2722 | @@ -84,7 +86,7 @@ | |||
2723 | 84 | push(table_message->field(fieldnr).name()); | 86 | push(table_message->field(fieldnr).name()); |
2724 | 85 | 87 | ||
2725 | 86 | /* ORDINAL_POSITION */ | 88 | /* ORDINAL_POSITION */ |
2727 | 87 | push(static_cast<int64_t>(index_part_iterator)); | 89 | push(static_cast<int64_t>((index_part_iterator +1))); |
2728 | 88 | 90 | ||
2729 | 89 | if (index_part_iterator == index.index_part_size() -1) | 91 | if (index_part_iterator == index.index_part_size() -1) |
2730 | 90 | { | 92 | { |
2731 | @@ -100,9 +102,56 @@ | |||
2732 | 100 | } | 102 | } |
2733 | 101 | } | 103 | } |
2734 | 102 | 104 | ||
2735 | 105 | if (fk_constraint_iterator != table_message->fk_constraint_size()) | ||
2736 | 106 | { | ||
2737 | 107 | drizzled::message::Table::ForeignKeyConstraint foreign_key= table_message->fk_constraint(fk_constraint_iterator); | ||
2738 | 108 | |||
2739 | 109 | { | ||
2740 | 110 | /* Constraints live in the same catalog.schema as the table they refer too. */ | ||
2741 | 111 | /* CONSTRAINT_CATALOG */ | ||
2742 | 112 | push(table_message->catalog()); | ||
2743 | 113 | |||
2744 | 114 | /* CONSTRAINT_SCHEMA */ | ||
2745 | 115 | push(table_message->schema()); | ||
2746 | 116 | |||
2747 | 117 | /* CONSTRAINT_NAME */ | ||
2748 | 118 | push(foreign_key.name()); | ||
2749 | 119 | |||
2750 | 120 | /* TABLE_CATALOG */ | ||
2751 | 121 | push(table_message->catalog()); | ||
2752 | 122 | |||
2753 | 123 | /* TABLE_SCHEMA */ | ||
2754 | 124 | push(table_message->schema()); | ||
2755 | 125 | |||
2756 | 126 | /* TABLE_NAME */ | ||
2757 | 127 | push(table_message->name()); | ||
2758 | 128 | |||
2759 | 129 | /* COLUMN_NAME */ | ||
2760 | 130 | push(foreign_key.column_names(fk_constraint_column_name_iterator)); | ||
2761 | 131 | |||
2762 | 132 | /* ORDINAL_POSITION */ | ||
2763 | 133 | push(static_cast<int64_t>((fk_constraint_column_name_iterator + 1))); | ||
2764 | 134 | |||
2765 | 135 | if (fk_constraint_column_name_iterator == foreign_key.column_names_size() -1) | ||
2766 | 136 | { | ||
2767 | 137 | fk_constraint_iterator++; | ||
2768 | 138 | fk_constraint_column_name_iterator= 0; | ||
2769 | 139 | } | ||
2770 | 140 | else | ||
2771 | 141 | { | ||
2772 | 142 | fk_constraint_column_name_iterator++; | ||
2773 | 143 | } | ||
2774 | 144 | |||
2775 | 145 | return true; | ||
2776 | 146 | } | ||
2777 | 147 | } | ||
2778 | 148 | |||
2779 | 103 | index_iterator= 0; | 149 | index_iterator= 0; |
2780 | 104 | index_part_iterator= 0; | 150 | index_part_iterator= 0; |
2781 | 105 | 151 | ||
2782 | 152 | fk_constraint_iterator= 0; | ||
2783 | 153 | fk_constraint_column_name_iterator= 0; | ||
2784 | 154 | |||
2785 | 106 | } while ((table_message= generator)); | 155 | } while ((table_message= generator)); |
2786 | 107 | 156 | ||
2787 | 108 | return false; | 157 | return false; |
2788 | 109 | 158 | ||
2789 | === modified file 'plugin/information_schema_dictionary/key_column_usage.h' | |||
2790 | --- plugin/information_schema_dictionary/key_column_usage.h 2010-07-09 21:52:18 +0000 | |||
2791 | +++ plugin/information_schema_dictionary/key_column_usage.h 2010-10-06 01:14:00 +0000 | |||
2792 | @@ -34,6 +34,9 @@ | |||
2793 | 34 | int32_t index_iterator; | 34 | int32_t index_iterator; |
2794 | 35 | int32_t index_part_iterator; | 35 | int32_t index_part_iterator; |
2795 | 36 | 36 | ||
2796 | 37 | int32_t fk_constraint_iterator; | ||
2797 | 38 | int32_t fk_constraint_column_name_iterator; | ||
2798 | 39 | |||
2799 | 37 | public: | 40 | public: |
2800 | 38 | Generator(drizzled::Field **arg); | 41 | Generator(drizzled::Field **arg); |
2801 | 39 | 42 | ||
2802 | 40 | 43 | ||
2803 | === modified file 'plugin/information_schema_dictionary/tests/r/key_column_usage.result' | |||
2804 | --- plugin/information_schema_dictionary/tests/r/key_column_usage.result 2010-07-09 21:52:18 +0000 | |||
2805 | +++ plugin/information_schema_dictionary/tests/r/key_column_usage.result 2010-10-06 01:14:00 +0000 | |||
2806 | @@ -336,40 +336,40 @@ | |||
2807 | 336 | ) ; | 336 | ) ; |
2808 | 337 | select * from information_schema.key_column_usage WHERE table_schema="everything" ORDER BY TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME; | 337 | select * from information_schema.key_column_usage WHERE table_schema="everything" ORDER BY TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME; |
2809 | 338 | CONSTRAINT_CATALOG CONSTRAINT_SCHEMA CONSTRAINT_NAME TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION | 338 | CONSTRAINT_CATALOG CONSTRAINT_SCHEMA CONSTRAINT_NAME TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION |
2846 | 339 | everything PRIMARY everything branch branch_id 0 | 339 | everything PRIMARY everything branch branch_id 1 |
2847 | 340 | everything PRIMARY everything container container_id 0 | 340 | everything PRIMARY everything container container_id 1 |
2848 | 341 | everything PRIMARY everything document document_id 0 | 341 | everything PRIMARY everything document document_id 1 |
2849 | 342 | everything PRIMARY everything genstats_attributes genstats_attributes_id 0 | 342 | everything PRIMARY everything genstats_attributes genstats_attributes_id 1 |
2850 | 343 | everything PRIMARY everything htmlcode htmlcode_id 0 | 343 | everything PRIMARY everything htmlcode htmlcode_id 1 |
2851 | 344 | everything PRIMARY everything htmlpage htmlpage_id 0 | 344 | everything PRIMARY everything htmlpage htmlpage_id 1 |
2852 | 345 | everything PRIMARY everything image image_id 0 | 345 | everything PRIMARY everything image image_id 1 |
2853 | 346 | everything PRIMARY everything javascript javascript_id 0 | 346 | everything PRIMARY everything javascript javascript_id 1 |
2854 | 347 | everything PRIMARY everything knowledge_item knowledge_item_id 0 | 347 | everything PRIMARY everything knowledge_item knowledge_item_id 1 |
2855 | 348 | everything PRIMARY everything links from_node 0 | 348 | everything PRIMARY everything links from_node 1 |
2856 | 349 | everything PRIMARY everything links linktype 2 | 349 | everything PRIMARY everything links linktype 3 |
2857 | 350 | everything PRIMARY everything links to_node 1 | 350 | everything PRIMARY everything links to_node 2 |
2858 | 351 | everything PRIMARY everything mail mail_id 0 | 351 | everything PRIMARY everything mail mail_id 1 |
2859 | 352 | everything PRIMARY everything node node_id 0 | 352 | everything PRIMARY everything node node_id 1 |
2860 | 353 | everything PRIMARY everything nodegroup nodegroup_id 0 | 353 | everything PRIMARY everything nodegroup nodegroup_id 1 |
2861 | 354 | everything PRIMARY everything nodegroup rank 1 | 354 | everything PRIMARY everything nodegroup rank 2 |
2862 | 355 | everything PRIMARY everything nodelet nodelet_id 0 | 355 | everything PRIMARY everything nodelet nodelet_id 1 |
2863 | 356 | everything PRIMARY everything nodemethod nodemethod_id 0 | 356 | everything PRIMARY everything nodemethod nodemethod_id 1 |
2864 | 357 | everything PRIMARY everything nodetype nodetype_id 0 | 357 | everything PRIMARY everything nodetype nodetype_id 1 |
2865 | 358 | everything PRIMARY everything project project_id 0 | 358 | everything PRIMARY everything project project_id 1 |
2866 | 359 | everything PRIMARY everything project_document project_document_id 0 | 359 | everything PRIMARY everything project_document project_document_id 1 |
2867 | 360 | everything PRIMARY everything question question_id 0 | 360 | everything PRIMARY everything question question_id 1 |
2868 | 361 | everything PRIMARY everything question rank 1 | 361 | everything PRIMARY everything question rank 2 |
2869 | 362 | everything PRIMARY everything redirects redirects_id 0 | 362 | everything PRIMARY everything redirects redirects_id 1 |
2870 | 363 | everything PRIMARY everything releases releases_id 0 | 363 | everything PRIMARY everything releases releases_id 1 |
2871 | 364 | everything PRIMARY everything revision inside_workspace 1 | 364 | everything PRIMARY everything revision inside_workspace 2 |
2872 | 365 | everything PRIMARY everything revision node_id 0 | 365 | everything PRIMARY everything revision node_id 1 |
2873 | 366 | everything PRIMARY everything revision revision_id 2 | 366 | everything PRIMARY everything revision revision_id 3 |
2874 | 367 | everything PRIMARY everything setting setting_id 0 | 367 | everything PRIMARY everything setting setting_id 1 |
2875 | 368 | everything PRIMARY everything symlink symlink_id 0 | 368 | everything PRIMARY everything symlink symlink_id 1 |
2876 | 369 | everything PRIMARY everything themesetting themesetting_id 0 | 369 | everything PRIMARY everything themesetting themesetting_id 1 |
2877 | 370 | everything PRIMARY everything typeversion typeversion_id 0 | 370 | everything PRIMARY everything typeversion typeversion_id 1 |
2878 | 371 | everything PRIMARY everything user user_id 0 | 371 | everything PRIMARY everything user user_id 1 |
2879 | 372 | everything PRIMARY everything version version_id 0 | 372 | everything PRIMARY everything version version_id 1 |
2880 | 373 | everything PRIMARY everything weblog entry_id 0 | 373 | everything PRIMARY everything weblog entry_id 1 |
2881 | 374 | everything PRIMARY everything workspace workspace_id 0 | 374 | everything PRIMARY everything workspace workspace_id 1 |
2882 | 375 | drop schema everything; | 375 | drop schema everything; |
2883 | 376 | 376 | ||
2884 | === modified file 'tests/include.am' | |||
2885 | --- tests/include.am 2010-10-02 21:15:42 +0000 | |||
2886 | +++ tests/include.am 2010-10-06 01:14:00 +0000 | |||
2887 | @@ -22,8 +22,8 @@ | |||
2888 | 22 | GENSCRIPTS = tests/dtr tests/mtr tests/test-run | 22 | GENSCRIPTS = tests/dtr tests/mtr tests/test-run |
2889 | 23 | PRESCRIPTS = tests/test-run.pl tests/stress-test.pl | 23 | PRESCRIPTS = tests/test-run.pl tests/stress-test.pl |
2890 | 24 | PLUGIN_TESTS = $(pandora_plugin_test_list) | 24 | PLUGIN_TESTS = $(pandora_plugin_test_list) |
2893 | 25 | NORMAL_TESTS = main,jp,tamil,$(PLUGIN_TESTS) | 25 | NORMAL_TESTS = main,jp,tamil,regression,$(PLUGIN_TESTS) |
2894 | 26 | ALL_TESTS = main,big,jp,tamil,$(PLUGIN_TESTS) | 26 | ALL_TESTS = main,big,jp,tamil,regression,$(PLUGIN_TESTS) |
2895 | 27 | noinst_SCRIPTS = $(GENSCRIPTS) $(PRESCRIPTS) | 27 | noinst_SCRIPTS = $(GENSCRIPTS) $(PRESCRIPTS) |
2896 | 28 | CLEANFILES += $(GENSCRIPTS) tests/mtr | 28 | CLEANFILES += $(GENSCRIPTS) tests/mtr |
2897 | 29 | 29 | ||
2898 | 30 | 30 | ||
2899 | === added directory 'tests/suite/regression' | |||
2900 | === added directory 'tests/suite/regression/r' | |||
2901 | === added file 'tests/suite/regression/r/654219.result' | |||
2902 | --- tests/suite/regression/r/654219.result 1970-01-01 00:00:00 +0000 | |||
2903 | +++ tests/suite/regression/r/654219.result 2010-10-06 01:14:00 +0000 | |||
2904 | @@ -0,0 +1,63 @@ | |||
2905 | 1 | CREATE TABLE `prim_key` ( | ||
2906 | 2 | `id` INT NOT NULL, | ||
2907 | 3 | `val` VARCHAR(20) COLLATE utf8_general_ci DEFAULT NULL, | ||
2908 | 4 | PRIMARY KEY (`id`) | ||
2909 | 5 | ); | ||
2910 | 6 | CREATE TABLE `fore_key0` ( | ||
2911 | 7 | `id` INT NOT NULL, | ||
2912 | 8 | `id_ref0` INT DEFAULT NULL, | ||
2913 | 9 | PRIMARY KEY (`id`), | ||
2914 | 10 | KEY `id_ref0` (`id_ref0`), | ||
2915 | 11 | CONSTRAINT `fore_key0_ibfk_1` FOREIGN KEY (`id_ref0`) REFERENCES | ||
2916 | 12 | `prim_key` (`id`) | ||
2917 | 13 | ); | ||
2918 | 14 | CREATE TABLE `fore_key1` ( | ||
2919 | 15 | `id` INT NOT NULL, | ||
2920 | 16 | `id_ref1` INT DEFAULT NULL, | ||
2921 | 17 | PRIMARY KEY (`id`), | ||
2922 | 18 | KEY `id_ref1` (`id_ref1`), | ||
2923 | 19 | CONSTRAINT `fore_key1_ibfk_1` FOREIGN KEY (`id_ref1`) REFERENCES | ||
2924 | 20 | `prim_key` (`id`) ON UPDATE CASCADE | ||
2925 | 21 | ); | ||
2926 | 22 | SELECT CONSTRAINT_NAME,TABLE_NAME,COLUMN_NAME,ORDINAL_POSITION FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE; | ||
2927 | 23 | CONSTRAINT_NAME TABLE_NAME COLUMN_NAME ORDINAL_POSITION | ||
2928 | 24 | PRIMARY prim_key id 1 | ||
2929 | 25 | PRIMARY fore_key1 id 1 | ||
2930 | 26 | fore_key1_ibfk_1 fore_key1 id_ref1 1 | ||
2931 | 27 | PRIMARY fore_key0 id 1 | ||
2932 | 28 | fore_key0_ibfk_1 fore_key0 id_ref0 1 | ||
2933 | 29 | DROP TABLE fore_key1; | ||
2934 | 30 | DROP TABLE fore_key0; | ||
2935 | 31 | DROP TABLE prim_key; | ||
2936 | 32 | CREATE TABLE t1 | ||
2937 | 33 | ( | ||
2938 | 34 | s1 INT, | ||
2939 | 35 | s2 INT, | ||
2940 | 36 | s3 INT, | ||
2941 | 37 | PRIMARY KEY(s3) | ||
2942 | 38 | ); | ||
2943 | 39 | CREATE TABLE t3 | ||
2944 | 40 | ( | ||
2945 | 41 | s1 INT, | ||
2946 | 42 | s2 INT, | ||
2947 | 43 | s3 INT, | ||
2948 | 44 | KEY(s1), | ||
2949 | 45 | CONSTRAINT CO FOREIGN KEY (s2) | ||
2950 | 46 | REFERENCES t1(s3) | ||
2951 | 47 | ); | ||
2952 | 48 | SELECT CONSTRAINT_NAME,TABLE_NAME,COLUMN_NAME,ORDINAL_POSITION FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE; | ||
2953 | 49 | CONSTRAINT_NAME TABLE_NAME COLUMN_NAME ORDINAL_POSITION | ||
2954 | 50 | CO t3 s2 1 | ||
2955 | 51 | PRIMARY t1 s3 1 | ||
2956 | 52 | DROP TABLE t3; | ||
2957 | 53 | DROP TABLE t1; | ||
2958 | 54 | CREATE TABLE t1 (c1 INT NOT NULL, c2 INT NOT NULL, c3 CHAR(5), c4 INT, c5 INT, constraint pk_t1 PRIMARY KEY (c5,c4)); | ||
2959 | 55 | CREATE TABLE T2 (tc1 INT NOT NULL, c1 INT NOT NULL, c2 INT NOT NULL, c5 CHAR(5), constraint fk_t2 FOREIGN KEY (c1,c2) REFERENCES t1 (c5,c4)); | ||
2960 | 56 | SELECT CONSTRAINT_NAME, TABLE_NAME, COLUMN_NAME, ORDINAL_POSITION FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE TABLE_NAME IN ('t1', 't2'); | ||
2961 | 57 | CONSTRAINT_NAME TABLE_NAME COLUMN_NAME ORDINAL_POSITION | ||
2962 | 58 | PRIMARY t1 c5 1 | ||
2963 | 59 | PRIMARY t1 c4 2 | ||
2964 | 60 | fk_t2 t2 c1 1 | ||
2965 | 61 | fk_t2 t2 c2 2 | ||
2966 | 62 | DROP TABLE t2; | ||
2967 | 63 | DROP TABLE t1; | ||
2968 | 0 | 64 | ||
2969 | === added directory 'tests/suite/regression/t' | |||
2970 | === added file 'tests/suite/regression/t/654219.test' | |||
2971 | --- tests/suite/regression/t/654219.test 1970-01-01 00:00:00 +0000 | |||
2972 | +++ tests/suite/regression/t/654219.test 2010-10-06 01:14:00 +0000 | |||
2973 | @@ -0,0 +1,64 @@ | |||
2974 | 1 | CREATE TABLE `prim_key` ( | ||
2975 | 2 | `id` INT NOT NULL, | ||
2976 | 3 | `val` VARCHAR(20) COLLATE utf8_general_ci DEFAULT NULL, | ||
2977 | 4 | PRIMARY KEY (`id`) | ||
2978 | 5 | ); | ||
2979 | 6 | |||
2980 | 7 | CREATE TABLE `fore_key0` ( | ||
2981 | 8 | `id` INT NOT NULL, | ||
2982 | 9 | `id_ref0` INT DEFAULT NULL, | ||
2983 | 10 | PRIMARY KEY (`id`), | ||
2984 | 11 | KEY `id_ref0` (`id_ref0`), | ||
2985 | 12 | CONSTRAINT `fore_key0_ibfk_1` FOREIGN KEY (`id_ref0`) REFERENCES | ||
2986 | 13 | `prim_key` (`id`) | ||
2987 | 14 | ); | ||
2988 | 15 | |||
2989 | 16 | CREATE TABLE `fore_key1` ( | ||
2990 | 17 | `id` INT NOT NULL, | ||
2991 | 18 | `id_ref1` INT DEFAULT NULL, | ||
2992 | 19 | PRIMARY KEY (`id`), | ||
2993 | 20 | KEY `id_ref1` (`id_ref1`), | ||
2994 | 21 | CONSTRAINT `fore_key1_ibfk_1` FOREIGN KEY (`id_ref1`) REFERENCES | ||
2995 | 22 | `prim_key` (`id`) ON UPDATE CASCADE | ||
2996 | 23 | ); | ||
2997 | 24 | |||
2998 | 25 | SELECT CONSTRAINT_NAME,TABLE_NAME,COLUMN_NAME,ORDINAL_POSITION FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE; | ||
2999 | 26 | |||
3000 | 27 | DROP TABLE fore_key1; | ||
3001 | 28 | DROP TABLE fore_key0; | ||
3002 | 29 | DROP TABLE prim_key; | ||
3003 | 30 | |||
3004 | 31 | # Taken from MySQL example | ||
3005 | 32 | CREATE TABLE t1 | ||
3006 | 33 | ( | ||
3007 | 34 | s1 INT, | ||
3008 | 35 | s2 INT, | ||
3009 | 36 | s3 INT, | ||
3010 | 37 | PRIMARY KEY(s3) | ||
3011 | 38 | ); | ||
3012 | 39 | |||
3013 | 40 | CREATE TABLE t3 | ||
3014 | 41 | ( | ||
3015 | 42 | s1 INT, | ||
3016 | 43 | s2 INT, | ||
3017 | 44 | s3 INT, | ||
3018 | 45 | KEY(s1), | ||
3019 | 46 | CONSTRAINT CO FOREIGN KEY (s2) | ||
3020 | 47 | REFERENCES t1(s3) | ||
3021 | 48 | ); | ||
3022 | 49 | |||
3023 | 50 | SELECT CONSTRAINT_NAME,TABLE_NAME,COLUMN_NAME,ORDINAL_POSITION FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE; | ||
3024 | 51 | |||
3025 | 52 | DROP TABLE t3; | ||
3026 | 53 | DROP TABLE t1; | ||
3027 | 54 | |||
3028 | 55 | # Taken from SQL Server example | ||
3029 | 56 | CREATE TABLE t1 (c1 INT NOT NULL, c2 INT NOT NULL, c3 CHAR(5), c4 INT, c5 INT, constraint pk_t1 PRIMARY KEY (c5,c4)); | ||
3030 | 57 | |||
3031 | 58 | CREATE TABLE T2 (tc1 INT NOT NULL, c1 INT NOT NULL, c2 INT NOT NULL, c5 CHAR(5), constraint fk_t2 FOREIGN KEY (c1,c2) REFERENCES t1 (c5,c4)); | ||
3032 | 59 | |||
3033 | 60 | SELECT CONSTRAINT_NAME, TABLE_NAME, COLUMN_NAME, ORDINAL_POSITION FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE TABLE_NAME IN ('t1', 't2'); | ||
3034 | 61 | |||
3035 | 62 | DROP TABLE t2; | ||
3036 | 63 | DROP TABLE t1; | ||
3037 | 64 |
Need to re-merge with trunk getting conflicts.