381
by Monty Taylor
Reformatted slap and test. |
1 |
/* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*-
|
2 |
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
|
|
3 |
*
|
|
4 |
* Copyright (C) 2008 MySQL
|
|
5 |
*
|
|
6 |
* This program is free software; you can redistribute it and/or modify
|
|
7 |
* it under the terms of the GNU General Public License as published by
|
|
8 |
* the Free Software Foundation; either version 2 of the License, or
|
|
9 |
* (at your option) any later version.
|
|
10 |
*
|
|
11 |
* This program is distributed in the hope that it will be useful,
|
|
12 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
14 |
* GNU General Public License for more details.
|
|
15 |
*
|
|
16 |
* You should have received a copy of the GNU General Public License
|
|
17 |
* along with this program; if not, write to the Free Software
|
|
18 |
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
19 |
*/
|
|
1
by brian
clean slate |
20 |
|
21 |
/*
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
22 |
drizzletest
|
1
by brian
clean slate |
23 |
|
24 |
Tool used for executing a .test file
|
|
25 |
||
206.3.1
by Patrick Galbraith
Most everything working with client rename |
26 |
See the "DRIZZLE Test framework manual" for more information
|
27 |
http://dev.mysql.com/doc/drizzletest/en/index.html
|
|
1
by brian
clean slate |
28 |
|
29 |
Please keep the test framework tools identical in all versions!
|
|
30 |
||
31 |
Written by:
|
|
32 |
Sasha Pachev <sasha@mysql.com>
|
|
33 |
Matt Wagner <matt@mysql.com>
|
|
34 |
Monty
|
|
35 |
Jani
|
|
36 |
Holyfoot
|
|
37 |
*/
|
|
38 |
||
39 |
#define MTEST_VERSION "3.3"
|
|
373.1.6
by Monty Taylor
Moved q_lines to vector. |
40 |
|
549
by Monty Taylor
Took gettext.h out of header files. |
41 |
#include <config.h> |
481.1.9
by Monty Taylor
Added autoconf tests for location of cstdint and cinttypes. Use those in C++ programs now, so that we don't have to define _STDC_LIMIT_MACROS, etc by hand. Stop, in fact, defining those by hand. |
42 |
#include "client_priv.h" |
139.1.16
by Trond Norbye
Include config.h first to aviod redefining macro warning |
43 |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
44 |
#include <queue> |
373.1.6
by Monty Taylor
Moved q_lines to vector. |
45 |
#include <map> |
46 |
#include <string> |
|
496.1.6
by Paul McCullagh
Fixed the --sorted_result command and changed to sorting accending |
47 |
#include <vector> |
373.1.6
by Monty Taylor
Moved q_lines to vector. |
48 |
|
77.1.31
by Monty Taylor
Replaced regex lib with pcre. Reworked mysqltest to use it. |
49 |
#include <pcrecpp.h> |
1
by brian
clean slate |
50 |
|
212.5.17
by Monty Taylor
Moved queues and hash. |
51 |
#include <mysys/hash.h> |
1
by brian
clean slate |
52 |
#include <stdarg.h> |
15
by brian
Fix for stat, NETWARE removal |
53 |
|
212.5.42
by Monty Taylor
Ding dong include is dead. |
54 |
#include "errname.h" |
1
by brian
clean slate |
55 |
|
373.1.6
by Monty Taylor
Moved q_lines to vector. |
56 |
using namespace std; |
57 |
||
1
by brian
clean slate |
58 |
#define MAX_VAR_NAME_LENGTH 256
|
59 |
#define MAX_COLUMNS 256
|
|
60 |
#define MAX_EMBEDDED_SERVER_ARGS 64
|
|
61 |
#define MAX_DELIMITER_LENGTH 16
|
|
62 |
||
63 |
/* Flags controlling send and reap */
|
|
64 |
#define QUERY_SEND_FLAG 1
|
|
65 |
#define QUERY_REAP_FLAG 2
|
|
66 |
||
67 |
enum { |
|
68 |
OPT_PS_PROTOCOL, OPT_SP_PROTOCOL, OPT_CURSOR_PROTOCOL, OPT_VIEW_PROTOCOL, |
|
69 |
OPT_MAX_CONNECT_RETRIES, OPT_MARK_PROGRESS, OPT_LOG_DIR, OPT_TAIL_LINES |
|
70 |
};
|
|
71 |
||
72 |
static int record= 0, opt_sleep= -1; |
|
73 |
static char *opt_db= 0, *opt_pass= 0; |
|
74 |
const char *opt_user= 0, *opt_host= 0, *unix_sock= 0, *opt_basedir= "./"; |
|
75 |
const char *opt_logdir= ""; |
|
76 |
const char *opt_include= 0, *opt_charsets_dir; |
|
77 |
static int opt_port= 0; |
|
78 |
static int opt_max_connect_retries; |
|
143
by Brian Aker
Bool cleanup. |
79 |
static bool opt_compress= 0, silent= 0, verbose= 0; |
80 |
static bool debug_info_flag= 0, debug_check_flag= 0; |
|
81 |
static bool tty_password= 0; |
|
82 |
static bool opt_mark_progress= 0; |
|
83 |
static bool parsing_disabled= 0; |
|
163
by Brian Aker
Merge Monty's code. |
84 |
static bool display_result_vertically= false, |
85 |
display_metadata= false, display_result_sorted= false; |
|
143
by Brian Aker
Bool cleanup. |
86 |
static bool disable_query_log= 0, disable_result_log= 0; |
87 |
static bool disable_warnings= 0; |
|
88 |
static bool disable_info= 1; |
|
89 |
static bool abort_on_error= 1; |
|
90 |
static bool server_initialized= 0; |
|
91 |
static bool is_windows= 0; |
|
1
by brian
clean slate |
92 |
static char **default_argv; |
206.3.1
by Patrick Galbraith
Most everything working with client rename |
93 |
static const char *load_default_groups[]= { "drizzletest", "client", 0 }; |
1
by brian
clean slate |
94 |
static char line_buffer[MAX_DELIMITER_LENGTH], *line_buffer_pos= line_buffer; |
95 |
||
96 |
static uint start_lineno= 0; /* Start line of current command */ |
|
97 |
static uint my_end_arg= 0; |
|
98 |
||
99 |
/* Number of lines of the result to include in failure report */
|
|
100 |
static uint opt_tail_lines= 0; |
|
101 |
||
102 |
static char delimiter[MAX_DELIMITER_LENGTH]= ";"; |
|
103 |
static uint delimiter_length= 1; |
|
104 |
||
105 |
static char TMPDIR[FN_REFLEN]; |
|
106 |
||
107 |
/* Block stack */
|
|
108 |
enum block_cmd { |
|
109 |
cmd_none, |
|
110 |
cmd_if, |
|
111 |
cmd_while
|
|
112 |
};
|
|
113 |
||
114 |
struct st_block |
|
115 |
{
|
|
116 |
int line; /* Start line of block */ |
|
143
by Brian Aker
Bool cleanup. |
117 |
bool ok; /* Should block be executed */ |
1
by brian
clean slate |
118 |
enum block_cmd cmd; /* Command owning the block */ |
119 |
};
|
|
120 |
||
121 |
static struct st_block block_stack[32]; |
|
122 |
static struct st_block *cur_block, *block_stack_end; |
|
123 |
||
124 |
/* Open file stack */
|
|
125 |
struct st_test_file |
|
126 |
{
|
|
127 |
FILE* file; |
|
128 |
const char *file_name; |
|
129 |
uint lineno; /* Current line in file */ |
|
130 |
};
|
|
131 |
||
132 |
static struct st_test_file file_stack[16]; |
|
133 |
static struct st_test_file* cur_file; |
|
134 |
static struct st_test_file* file_stack_end; |
|
135 |
||
136 |
||
383.1.12
by Brian Aker
Much closer toward UTF8 being around all the time... |
137 |
static const CHARSET_INFO *charset_info= &my_charset_utf8_general_ci; /* Default charset */ |
1
by brian
clean slate |
138 |
|
139 |
static int embedded_server_arg_count=0; |
|
140 |
static char *embedded_server_args[MAX_EMBEDDED_SERVER_ARGS]; |
|
141 |
||
142 |
/*
|
|
143 |
Timer related variables
|
|
144 |
See the timer_output() definition for details
|
|
145 |
*/
|
|
146 |
static char *timer_file = NULL; |
|
151
by Brian Aker
Ulonglong to uint64_t |
147 |
static uint64_t timer_start; |
1
by brian
clean slate |
148 |
static void timer_output(void); |
151
by Brian Aker
Ulonglong to uint64_t |
149 |
static uint64_t timer_now(void); |
1
by brian
clean slate |
150 |
|
151
by Brian Aker
Ulonglong to uint64_t |
151 |
static uint64_t progress_start= 0; |
1
by brian
clean slate |
152 |
|
373.1.6
by Monty Taylor
Moved q_lines to vector. |
153 |
vector<struct st_command*> q_lines; |
1
by brian
clean slate |
154 |
|
77.1.31
by Monty Taylor
Replaced regex lib with pcre. Reworked mysqltest to use it. |
155 |
typedef struct { |
1
by brian
clean slate |
156 |
int read_lines,current_line; |
77.1.31
by Monty Taylor
Replaced regex lib with pcre. Reworked mysqltest to use it. |
157 |
} parser_st; |
158 |
parser_st parser; |
|
1
by brian
clean slate |
159 |
|
77.1.31
by Monty Taylor
Replaced regex lib with pcre. Reworked mysqltest to use it. |
160 |
typedef struct |
1
by brian
clean slate |
161 |
{
|
162 |
char file[FN_REFLEN]; |
|
297
by Brian Aker
Final ulong cleanup in clients |
163 |
uint32_t pos; |
77.1.31
by Monty Taylor
Replaced regex lib with pcre. Reworked mysqltest to use it. |
164 |
} master_pos_st; |
165 |
||
166 |
master_pos_st master_pos; |
|
1
by brian
clean slate |
167 |
|
168 |
/* if set, all results are concated and compared against this file */
|
|
169 |
const char *result_file_name= 0; |
|
170 |
||
171 |
typedef struct st_var |
|
172 |
{
|
|
173 |
char *name; |
|
174 |
int name_len; |
|
175 |
char *str_val; |
|
176 |
int str_val_len; |
|
177 |
int int_val; |
|
178 |
int alloced_len; |
|
179 |
int int_dirty; /* do not update string if int is updated until first read */ |
|
180 |
int alloced; |
|
181 |
char *env_s; |
|
182 |
} VAR; |
|
183 |
||
184 |
/*Perl/shell-like variable registers */
|
|
185 |
VAR var_reg[10]; |
|
186 |
||
187 |
HASH var_hash; |
|
188 |
||
189 |
struct st_connection |
|
190 |
{
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
191 |
DRIZZLE drizzle; |
1
by brian
clean slate |
192 |
/* Used when creating views and sp, to avoid implicit commit */
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
193 |
DRIZZLE *util_drizzle; |
1
by brian
clean slate |
194 |
char *name; |
195 |
};
|
|
196 |
struct st_connection connections[128]; |
|
197 |
struct st_connection* cur_con= NULL, *next_con, *connections_end; |
|
198 |
||
199 |
/*
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
200 |
List of commands in drizzletest
|
1
by brian
clean slate |
201 |
Must match the "command_names" array
|
202 |
Add new commands before Q_UNKNOWN!
|
|
203 |
*/
|
|
204 |
enum enum_commands { |
|
205 |
Q_CONNECTION=1, Q_QUERY, |
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
206 |
Q_CONNECT, Q_SLEEP, Q_REAL_SLEEP, |
207 |
Q_INC, Q_DEC, |
|
208 |
Q_SOURCE, Q_DISCONNECT, |
|
209 |
Q_LET, Q_ECHO, |
|
210 |
Q_WHILE, Q_END_BLOCK, |
|
211 |
Q_SYSTEM, Q_RESULT, |
|
212 |
Q_REQUIRE, Q_SAVE_MASTER_POS, |
|
1
by brian
clean slate |
213 |
Q_SYNC_WITH_MASTER, |
214 |
Q_SYNC_SLAVE_WITH_MASTER, |
|
215 |
Q_ERROR, |
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
216 |
Q_SEND, Q_REAP, |
217 |
Q_DIRTY_CLOSE, Q_REPLACE, Q_REPLACE_COLUMN, |
|
218 |
Q_PING, Q_EVAL, |
|
1
by brian
clean slate |
219 |
Q_EVAL_RESULT, |
220 |
Q_ENABLE_QUERY_LOG, Q_DISABLE_QUERY_LOG, |
|
221 |
Q_ENABLE_RESULT_LOG, Q_DISABLE_RESULT_LOG, |
|
222 |
Q_WAIT_FOR_SLAVE_TO_STOP, |
|
223 |
Q_ENABLE_WARNINGS, Q_DISABLE_WARNINGS, |
|
224 |
Q_ENABLE_INFO, Q_DISABLE_INFO, |
|
225 |
Q_ENABLE_METADATA, Q_DISABLE_METADATA, |
|
226 |
Q_EXEC, Q_DELIMITER, |
|
227 |
Q_DISABLE_ABORT_ON_ERROR, Q_ENABLE_ABORT_ON_ERROR, |
|
228 |
Q_DISPLAY_VERTICAL_RESULTS, Q_DISPLAY_HORIZONTAL_RESULTS, |
|
229 |
Q_QUERY_VERTICAL, Q_QUERY_HORIZONTAL, Q_SORTED_RESULT, |
|
230 |
Q_START_TIMER, Q_END_TIMER, |
|
496.1.7
by Paul McCullagh
Fixed the --replace_regex command |
231 |
Q_CHARACTER_SET, |
1
by brian
clean slate |
232 |
Q_DISABLE_RECONNECT, Q_ENABLE_RECONNECT, |
233 |
Q_IF, |
|
234 |
Q_DISABLE_PARSING, Q_ENABLE_PARSING, |
|
235 |
Q_REPLACE_REGEX, Q_REMOVE_FILE, Q_FILE_EXIST, |
|
236 |
Q_WRITE_FILE, Q_COPY_FILE, Q_PERL, Q_DIE, Q_EXIT, Q_SKIP, |
|
237 |
Q_CHMOD_FILE, Q_APPEND_FILE, Q_CAT_FILE, Q_DIFF_FILES, |
|
238 |
Q_SEND_QUIT, Q_CHANGE_USER, Q_MKDIR, Q_RMDIR, |
|
239 |
||
206.3.1
by Patrick Galbraith
Most everything working with client rename |
240 |
Q_UNKNOWN, /* Unknown command. */ |
241 |
Q_COMMENT, /* Comments, ignored. */ |
|
1
by brian
clean slate |
242 |
Q_COMMENT_WITH_COMMAND
|
243 |
};
|
|
244 |
||
245 |
||
246 |
const char *command_names[]= |
|
247 |
{
|
|
248 |
"connection", |
|
249 |
"query", |
|
250 |
"connect", |
|
251 |
"sleep", |
|
252 |
"real_sleep", |
|
253 |
"inc", |
|
254 |
"dec", |
|
255 |
"source", |
|
256 |
"disconnect", |
|
257 |
"let", |
|
258 |
"echo", |
|
259 |
"while", |
|
260 |
"end", |
|
261 |
"system", |
|
262 |
"result", |
|
263 |
"require", |
|
264 |
"save_master_pos", |
|
265 |
"sync_with_master", |
|
266 |
"sync_slave_with_master", |
|
267 |
"error", |
|
268 |
"send", |
|
269 |
"reap", |
|
270 |
"dirty_close", |
|
271 |
"replace_result", |
|
272 |
"replace_column", |
|
273 |
"ping", |
|
274 |
"eval", |
|
275 |
"eval_result", |
|
276 |
/* Enable/disable that the _query_ is logged to result file */
|
|
277 |
"enable_query_log", |
|
278 |
"disable_query_log", |
|
279 |
/* Enable/disable that the _result_ from a query is logged to result file */
|
|
280 |
"enable_result_log", |
|
281 |
"disable_result_log", |
|
282 |
"wait_for_slave_to_stop", |
|
283 |
"enable_warnings", |
|
284 |
"disable_warnings", |
|
285 |
"enable_info", |
|
286 |
"disable_info", |
|
287 |
"enable_metadata", |
|
288 |
"disable_metadata", |
|
289 |
"exec", |
|
290 |
"delimiter", |
|
291 |
"disable_abort_on_error", |
|
292 |
"enable_abort_on_error", |
|
293 |
"vertical_results", |
|
294 |
"horizontal_results", |
|
295 |
"query_vertical", |
|
296 |
"query_horizontal", |
|
297 |
"sorted_result", |
|
298 |
"start_timer", |
|
299 |
"end_timer", |
|
300 |
"character_set", |
|
301 |
"disable_reconnect", |
|
302 |
"enable_reconnect", |
|
303 |
"if", |
|
304 |
"disable_parsing", |
|
305 |
"enable_parsing", |
|
306 |
"replace_regex", |
|
307 |
"remove_file", |
|
308 |
"file_exists", |
|
309 |
"write_file", |
|
310 |
"copy_file", |
|
311 |
"perl", |
|
312 |
"die", |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
313 |
|
1
by brian
clean slate |
314 |
/* Don't execute any more commands, compare result */
|
315 |
"exit", |
|
316 |
"skip", |
|
317 |
"chmod", |
|
318 |
"append_file", |
|
319 |
"cat_file", |
|
320 |
"diff_files", |
|
321 |
"send_quit", |
|
322 |
"change_user", |
|
323 |
"mkdir", |
|
324 |
"rmdir", |
|
325 |
||
326 |
0
|
|
327 |
};
|
|
328 |
||
329 |
||
330 |
/*
|
|
331 |
The list of error codes to --error are stored in an internal array of
|
|
332 |
structs. This struct can hold numeric SQL error codes, error names or
|
|
333 |
SQLSTATE codes as strings. The element next to the last active element
|
|
334 |
in the list is set to type ERR_EMPTY. When an SQL statement returns an
|
|
335 |
error, we use this list to check if this is an expected error.
|
|
336 |
*/
|
|
337 |
enum match_err_type |
|
338 |
{
|
|
339 |
ERR_EMPTY= 0, |
|
340 |
ERR_ERRNO, |
|
341 |
ERR_SQLSTATE
|
|
342 |
};
|
|
343 |
||
344 |
struct st_match_err |
|
345 |
{
|
|
346 |
enum match_err_type type; |
|
347 |
union
|
|
348 |
{
|
|
349 |
uint errnum; |
|
350 |
char sqlstate[SQLSTATE_LENGTH+1]; /* \0 terminated string */ |
|
351 |
} code; |
|
352 |
};
|
|
353 |
||
354 |
struct st_expected_errors |
|
355 |
{
|
|
356 |
struct st_match_err err[10]; |
|
357 |
uint count; |
|
358 |
};
|
|
359 |
static struct st_expected_errors saved_expected_errors; |
|
360 |
||
361 |
struct st_command |
|
362 |
{
|
|
363 |
char *query, *query_buf,*first_argument,*last_argument,*end; |
|
364 |
int first_word_len, query_len; |
|
143
by Brian Aker
Bool cleanup. |
365 |
bool abort_on_error; |
1
by brian
clean slate |
366 |
struct st_expected_errors expected_errors; |
367 |
char require_file[FN_REFLEN]; |
|
368 |
enum enum_commands type; |
|
369 |
};
|
|
370 |
||
371 |
TYPELIB command_typelib= {array_elements(command_names),"", |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
372 |
command_names, 0}; |
1
by brian
clean slate |
373 |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
374 |
string ds_res, ds_progress, ds_warning_messages; |
1
by brian
clean slate |
375 |
|
376 |
char builtin_echo[FN_REFLEN]; |
|
377 |
||
378 |
void die(const char *fmt, ...) |
|
212.5.26
by Monty Taylor
Removed my_attribute. Renaming __attribute__((format(x,y,z))) to ATTRIBUTE_FORMAT(x,y,z) is retarded. So we don't do it anymore. |
379 |
__attribute__((format(printf, 1, 2))); |
1
by brian
clean slate |
380 |
void abort_not_supported_test(const char *fmt, ...) |
212.5.26
by Monty Taylor
Removed my_attribute. Renaming __attribute__((format(x,y,z))) to ATTRIBUTE_FORMAT(x,y,z) is retarded. So we don't do it anymore. |
381 |
__attribute__((format(printf, 1, 2))); |
1
by brian
clean slate |
382 |
void verbose_msg(const char *fmt, ...) |
212.5.26
by Monty Taylor
Removed my_attribute. Renaming __attribute__((format(x,y,z))) to ATTRIBUTE_FORMAT(x,y,z) is retarded. So we don't do it anymore. |
383 |
__attribute__((format(printf, 1, 2))); |
1
by brian
clean slate |
384 |
void warning_msg(const char *fmt, ...) |
212.5.26
by Monty Taylor
Removed my_attribute. Renaming __attribute__((format(x,y,z))) to ATTRIBUTE_FORMAT(x,y,z) is retarded. So we don't do it anymore. |
385 |
__attribute__((format(printf, 1, 2))); |
1
by brian
clean slate |
386 |
void log_msg(const char *fmt, ...) |
212.5.26
by Monty Taylor
Removed my_attribute. Renaming __attribute__((format(x,y,z))) to ATTRIBUTE_FORMAT(x,y,z) is retarded. So we don't do it anymore. |
387 |
__attribute__((format(printf, 1, 2))); |
1
by brian
clean slate |
388 |
|
389 |
VAR* var_from_env(const char *, const char *); |
|
390 |
VAR* var_init(VAR* v, const char *name, int name_len, const char *val, |
|
391 |
int val_len); |
|
392 |
void var_free(void* v); |
|
393 |
VAR* var_get(const char *var_name, const char** var_name_end, |
|
143
by Brian Aker
Bool cleanup. |
394 |
bool raw, bool ignore_not_existing); |
1
by brian
clean slate |
395 |
void eval_expr(VAR* v, const char *p, const char** p_end); |
143
by Brian Aker
Bool cleanup. |
396 |
bool match_delimiter(int c, const char *delim, uint length); |
1
by brian
clean slate |
397 |
void dump_result_to_reject_file(char *buf, int size); |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
398 |
void dump_result_to_log_file(const char *buf, int size); |
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
399 |
void dump_warning_messages(void); |
400 |
void dump_progress(void); |
|
1
by brian
clean slate |
401 |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
402 |
void do_eval(string *query_eval, const char *query, |
143
by Brian Aker
Bool cleanup. |
403 |
const char *query_end, bool pass_through_escape_chars); |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
404 |
void str_to_file(const char *fname, const char *str, int size); |
405 |
void str_to_file2(const char *fname, const char *str, int size, bool append); |
|
1
by brian
clean slate |
406 |
|
407 |
/* For replace_column */
|
|
408 |
static char *replace_column[MAX_COLUMNS]; |
|
409 |
static uint max_replace_column= 0; |
|
410 |
void do_get_replace_column(struct st_command*); |
|
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
411 |
void free_replace_column(void); |
1
by brian
clean slate |
412 |
|
413 |
/* For replace */
|
|
414 |
void do_get_replace(struct st_command *command); |
|
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
415 |
void free_replace(void); |
1
by brian
clean slate |
416 |
|
417 |
/* For replace_regex */
|
|
418 |
void do_get_replace_regex(struct st_command *command); |
|
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
419 |
void free_replace_regex(void); |
420 |
||
421 |
||
422 |
void free_all_replace(void); |
|
423 |
||
424 |
||
425 |
void free_all_replace(void){ |
|
1
by brian
clean slate |
426 |
free_replace(); |
427 |
free_replace_regex(); |
|
428 |
free_replace_column(); |
|
429 |
}
|
|
430 |
||
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
431 |
void replace_append_mem(string *ds, const char *val, |
432 |
int len); |
|
433 |
void replace_append(string *ds, const char *val); |
|
434 |
void replace_append_uint(string *ds, uint val); |
|
435 |
void append_sorted(string* ds, string* ds_input); |
|
1
by brian
clean slate |
436 |
|
437 |
void handle_error(struct st_command*, |
|
438 |
unsigned int err_errno, const char *err_error, |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
439 |
const char *err_sqlstate, string *ds); |
1
by brian
clean slate |
440 |
void handle_no_error(struct st_command*); |
441 |
||
442 |
||
206.3.1
by Patrick Galbraith
Most everything working with client rename |
443 |
#define do_send_query(cn,q,q_len,flags) drizzle_send_query(&cn->drizzle, q, q_len)
|
1
by brian
clean slate |
444 |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
445 |
void do_eval(string *query_eval, const char *query, |
143
by Brian Aker
Bool cleanup. |
446 |
const char *query_end, bool pass_through_escape_chars) |
1
by brian
clean slate |
447 |
{
|
448 |
const char *p; |
|
449 |
register char c, next_c; |
|
450 |
register int escaped = 0; |
|
451 |
VAR *v; |
|
142.1.1
by Patrick
Removing DBUG from client |
452 |
|
1
by brian
clean slate |
453 |
|
454 |
for (p= query; (c= *p) && p < query_end; ++p) |
|
455 |
{
|
|
456 |
switch(c) { |
|
457 |
case '$': |
|
458 |
if (escaped) |
|
459 |
{
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
460 |
escaped= 0; |
461 |
query_eval->append(p, 1); |
|
1
by brian
clean slate |
462 |
}
|
463 |
else
|
|
464 |
{
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
465 |
if (!(v= var_get(p, &p, 0, 0))) |
466 |
die("Bad variable in eval"); |
|
467 |
query_eval->append(v->str_val, v->str_val_len); |
|
1
by brian
clean slate |
468 |
}
|
469 |
break; |
|
470 |
case '\\': |
|
471 |
next_c= *(p+1); |
|
472 |
if (escaped) |
|
473 |
{
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
474 |
escaped= 0; |
475 |
query_eval->append(p, 1); |
|
1
by brian
clean slate |
476 |
}
|
477 |
else if (next_c == '\\' || next_c == '$' || next_c == '"') |
|
478 |
{
|
|
479 |
/* Set escaped only if next char is \, " or $ */
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
480 |
escaped= 1; |
1
by brian
clean slate |
481 |
|
482 |
if (pass_through_escape_chars) |
|
483 |
{
|
|
484 |
/* The escape char should be added to the output string. */
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
485 |
query_eval->append(p, 1); |
1
by brian
clean slate |
486 |
}
|
487 |
}
|
|
488 |
else
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
489 |
query_eval->append(p, 1); |
1
by brian
clean slate |
490 |
break; |
491 |
default: |
|
492 |
escaped= 0; |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
493 |
query_eval->append(p, 1); |
1
by brian
clean slate |
494 |
break; |
495 |
}
|
|
496 |
}
|
|
142.1.1
by Patrick
Removing DBUG from client |
497 |
return; |
1
by brian
clean slate |
498 |
}
|
499 |
||
500 |
||
501 |
/*
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
502 |
Concatenates any number of strings, escapes any OS quote in the result then
|
503 |
surround the whole affair in another set of quotes which is finally appended
|
|
504 |
to specified string. This function is especially useful when
|
|
505 |
building strings to be executed with the system() function.
|
|
506 |
||
507 |
@param str string which will have addtional strings appended.
|
|
508 |
@param append string to be appended.
|
|
509 |
@param ... Optional. Additional string(s) to be appended.
|
|
510 |
||
461
by Monty Taylor
Removed NullS. bu-bye. |
511 |
@note The final argument in the list must be NULL even if no additional
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
512 |
options are passed.
|
513 |
*/
|
|
514 |
||
515 |
void append_os_quoted(string *str, const char *append, ...) |
|
516 |
{
|
|
517 |
const char *quote_str= "\'"; |
|
518 |
const uint quote_len= 1; |
|
519 |
||
520 |
va_list dirty_text; |
|
521 |
||
522 |
str->append(quote_str, quote_len); /* Leading quote */ |
|
523 |
va_start(dirty_text, append); |
|
461
by Monty Taylor
Removed NullS. bu-bye. |
524 |
while (append != NULL) |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
525 |
{
|
526 |
const char *cur_pos= append; |
|
527 |
const char *next_pos= cur_pos; |
|
528 |
||
529 |
/* Search for quote in each string and replace with escaped quote */
|
|
530 |
while((next_pos= strrchr(cur_pos, quote_str[0])) != NULL) |
|
531 |
{
|
|
532 |
str->append(cur_pos, next_pos - cur_pos); |
|
533 |
str->append("\\", 1); |
|
534 |
str->append(quote_str, quote_len); |
|
535 |
cur_pos= next_pos + 1; |
|
536 |
}
|
|
482.1.1
by Monty Taylor
Fix for drizzletest crash from Paul McCullagh. (Fixes #279304) |
537 |
str->append(cur_pos); |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
538 |
append= va_arg(dirty_text, char *); |
539 |
}
|
|
540 |
va_end(dirty_text); |
|
541 |
str->append(quote_str, quote_len); /* Trailing quote */ |
|
542 |
}
|
|
543 |
||
544 |
||
545 |
/*
|
|
1
by brian
clean slate |
546 |
Run query and dump the result to stdout in vertical format
|
547 |
||
548 |
NOTE! This function should be safe to call when an error
|
|
549 |
has occured and thus any further errors will be ignored(although logged)
|
|
550 |
||
551 |
SYNOPSIS
|
|
552 |
show_query
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
553 |
drizzle - connection to use
|
1
by brian
clean slate |
554 |
query - query to run
|
555 |
||
556 |
*/
|
|
557 |
||
206.3.1
by Patrick Galbraith
Most everything working with client rename |
558 |
static void show_query(DRIZZLE *drizzle, const char* query) |
1
by brian
clean slate |
559 |
{
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
560 |
DRIZZLE_RES* res; |
561 |
||
562 |
||
563 |
if (!drizzle) |
|
142.1.1
by Patrick
Removing DBUG from client |
564 |
return; |
1
by brian
clean slate |
565 |
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
566 |
if (drizzle_query(drizzle, query)) |
1
by brian
clean slate |
567 |
{
|
568 |
log_msg("Error running query '%s': %d %s", |
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
569 |
query, drizzle_errno(drizzle), drizzle_error(drizzle)); |
142.1.1
by Patrick
Removing DBUG from client |
570 |
return; |
1
by brian
clean slate |
571 |
}
|
572 |
||
206.3.1
by Patrick Galbraith
Most everything working with client rename |
573 |
if ((res= drizzle_store_result(drizzle)) == NULL) |
1
by brian
clean slate |
574 |
{
|
575 |
/* No result set returned */
|
|
142.1.1
by Patrick
Removing DBUG from client |
576 |
return; |
1
by brian
clean slate |
577 |
}
|
578 |
||
579 |
{
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
580 |
DRIZZLE_ROW row; |
1
by brian
clean slate |
581 |
unsigned int i; |
582 |
unsigned int row_num= 0; |
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
583 |
unsigned int num_fields= drizzle_num_fields(res); |
236.3.5
by Andrey Hristov
Constify libdrizzle functions |
584 |
const DRIZZLE_FIELD *fields= drizzle_fetch_fields(res); |
1
by brian
clean slate |
585 |
|
586 |
fprintf(stderr, "=== %s ===\n", query); |
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
587 |
while ((row= drizzle_fetch_row(res))) |
1
by brian
clean slate |
588 |
{
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
589 |
uint32_t *lengths= drizzle_fetch_lengths(res); |
1
by brian
clean slate |
590 |
row_num++; |
591 |
||
592 |
fprintf(stderr, "---- %d. ----\n", row_num); |
|
593 |
for(i= 0; i < num_fields; i++) |
|
594 |
{
|
|
595 |
fprintf(stderr, "%s\t%.*s\n", |
|
596 |
fields[i].name, |
|
597 |
(int)lengths[i], row[i] ? row[i] : "NULL"); |
|
598 |
}
|
|
599 |
}
|
|
600 |
for (i= 0; i < strlen(query)+8; i++) |
|
601 |
fprintf(stderr, "="); |
|
602 |
fprintf(stderr, "\n\n"); |
|
603 |
}
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
604 |
drizzle_free_result(res); |
1
by brian
clean slate |
605 |
|
142.1.1
by Patrick
Removing DBUG from client |
606 |
return; |
1
by brian
clean slate |
607 |
}
|
608 |
||
609 |
||
610 |
/*
|
|
611 |
Show any warnings just before the error. Since the last error
|
|
612 |
is added to the warning stack, only print @@warning_count-1 warnings.
|
|
613 |
||
614 |
NOTE! This function should be safe to call when an error
|
|
615 |
has occured and this any further errors will be ignored(although logged)
|
|
616 |
||
617 |
SYNOPSIS
|
|
618 |
show_warnings_before_error
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
619 |
drizzle - connection to use
|
1
by brian
clean slate |
620 |
|
621 |
*/
|
|
622 |
||
206.3.1
by Patrick Galbraith
Most everything working with client rename |
623 |
static void show_warnings_before_error(DRIZZLE *drizzle) |
1
by brian
clean slate |
624 |
{
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
625 |
DRIZZLE_RES* res; |
1
by brian
clean slate |
626 |
const char* query= "SHOW WARNINGS"; |
142.1.1
by Patrick
Removing DBUG from client |
627 |
|
1
by brian
clean slate |
628 |
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
629 |
if (!drizzle) |
142.1.1
by Patrick
Removing DBUG from client |
630 |
return; |
1
by brian
clean slate |
631 |
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
632 |
if (drizzle_query(drizzle, query)) |
1
by brian
clean slate |
633 |
{
|
634 |
log_msg("Error running query '%s': %d %s", |
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
635 |
query, drizzle_errno(drizzle), drizzle_error(drizzle)); |
142.1.1
by Patrick
Removing DBUG from client |
636 |
return; |
1
by brian
clean slate |
637 |
}
|
638 |
||
206.3.1
by Patrick Galbraith
Most everything working with client rename |
639 |
if ((res= drizzle_store_result(drizzle)) == NULL) |
1
by brian
clean slate |
640 |
{
|
641 |
/* No result set returned */
|
|
142.1.1
by Patrick
Removing DBUG from client |
642 |
return; |
1
by brian
clean slate |
643 |
}
|
644 |
||
206.3.1
by Patrick Galbraith
Most everything working with client rename |
645 |
if (drizzle_num_rows(res) <= 1) |
1
by brian
clean slate |
646 |
{
|
647 |
/* Don't display the last row, it's "last error" */
|
|
648 |
}
|
|
649 |
else
|
|
650 |
{
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
651 |
DRIZZLE_ROW row; |
1
by brian
clean slate |
652 |
unsigned int row_num= 0; |
206.3.1
by Patrick Galbraith
Most everything working with client rename |
653 |
unsigned int num_fields= drizzle_num_fields(res); |
1
by brian
clean slate |
654 |
|
655 |
fprintf(stderr, "\nWarnings from just before the error:\n"); |
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
656 |
while ((row= drizzle_fetch_row(res))) |
1
by brian
clean slate |
657 |
{
|
164
by Brian Aker
Commit cleanup of export types. |
658 |
uint32_t i; |
206.3.1
by Patrick Galbraith
Most everything working with client rename |
659 |
uint32_t *lengths= drizzle_fetch_lengths(res); |
1
by brian
clean slate |
660 |
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
661 |
if (++row_num >= drizzle_num_rows(res)) |
1
by brian
clean slate |
662 |
{
|
663 |
/* Don't display the last row, it's "last error" */
|
|
664 |
break; |
|
665 |
}
|
|
666 |
||
667 |
for(i= 0; i < num_fields; i++) |
|
668 |
{
|
|
669 |
fprintf(stderr, "%.*s ", (int)lengths[i], |
|
670 |
row[i] ? row[i] : "NULL"); |
|
671 |
}
|
|
672 |
fprintf(stderr, "\n"); |
|
673 |
}
|
|
674 |
}
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
675 |
drizzle_free_result(res); |
1
by brian
clean slate |
676 |
|
142.1.1
by Patrick
Removing DBUG from client |
677 |
return; |
1
by brian
clean slate |
678 |
}
|
679 |
||
680 |
||
681 |
enum arg_type |
|
682 |
{
|
|
683 |
ARG_STRING, |
|
684 |
ARG_REST
|
|
685 |
};
|
|
686 |
||
687 |
struct command_arg { |
|
688 |
const char *argname; /* Name of argument */ |
|
689 |
enum arg_type type; /* Type of argument */ |
|
143
by Brian Aker
Bool cleanup. |
690 |
bool required; /* Argument required */ |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
691 |
string *ds; /* Storage for argument */ |
1
by brian
clean slate |
692 |
const char *description; /* Description of the argument */ |
693 |
};
|
|
694 |
||
695 |
||
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
696 |
static void check_command_args(struct st_command *command, |
697 |
const char *arguments, |
|
698 |
const struct command_arg *args, |
|
699 |
int num_args, const char delimiter_arg) |
|
1
by brian
clean slate |
700 |
{
|
701 |
int i; |
|
702 |
const char *ptr= arguments; |
|
703 |
const char *start; |
|
704 |
||
705 |
for (i= 0; i < num_args; i++) |
|
706 |
{
|
|
707 |
const struct command_arg *arg= &args[i]; |
|
708 |
||
709 |
switch (arg->type) { |
|
710 |
/* A string */
|
|
711 |
case ARG_STRING: |
|
712 |
/* Skip leading spaces */
|
|
713 |
while (*ptr && *ptr == ' ') |
|
714 |
ptr++; |
|
715 |
start= ptr; |
|
716 |
/* Find end of arg, terminated by "delimiter_arg" */
|
|
717 |
while (*ptr && *ptr != delimiter_arg) |
|
718 |
ptr++; |
|
719 |
if (ptr > start) |
|
720 |
{
|
|
163
by Brian Aker
Merge Monty's code. |
721 |
do_eval(arg->ds, start, ptr, false); |
1
by brian
clean slate |
722 |
}
|
723 |
else
|
|
724 |
{
|
|
725 |
/* Empty string */
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
726 |
arg->ds->erase(); |
1
by brian
clean slate |
727 |
}
|
728 |
command->last_argument= (char*)ptr; |
|
729 |
||
730 |
/* Step past the delimiter */
|
|
731 |
if (*ptr && *ptr == delimiter_arg) |
|
732 |
ptr++; |
|
733 |
break; |
|
734 |
||
735 |
/* Rest of line */
|
|
736 |
case ARG_REST: |
|
737 |
start= ptr; |
|
163
by Brian Aker
Merge Monty's code. |
738 |
do_eval(arg->ds, start, command->end, false); |
1
by brian
clean slate |
739 |
command->last_argument= command->end; |
740 |
break; |
|
741 |
||
742 |
default: |
|
142.1.2
by Patrick
All DBUG_x removed from client/ |
743 |
assert("Unknown argument type"); |
1
by brian
clean slate |
744 |
break; |
745 |
}
|
|
746 |
||
747 |
/* Check required arg */
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
748 |
if (arg->ds->length() == 0 && arg->required) |
1
by brian
clean slate |
749 |
die("Missing required argument '%s' to command '%.*s'", arg->argname, |
750 |
command->first_word_len, command->query); |
|
751 |
||
752 |
}
|
|
753 |
/* Check for too many arguments passed */
|
|
754 |
ptr= command->last_argument; |
|
755 |
while(ptr <= command->end) |
|
756 |
{
|
|
757 |
if (*ptr && *ptr != ' ') |
|
758 |
die("Extra argument '%s' passed to '%.*s'", |
|
759 |
ptr, command->first_word_len, command->query); |
|
760 |
ptr++; |
|
761 |
}
|
|
142.1.1
by Patrick
Removing DBUG from client |
762 |
return; |
1
by brian
clean slate |
763 |
}
|
764 |
||
765 |
||
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
766 |
static void handle_command_error(struct st_command *command, uint error) |
1
by brian
clean slate |
767 |
{
|
142.1.1
by Patrick
Removing DBUG from client |
768 |
|
1
by brian
clean slate |
769 |
if (error != 0) |
770 |
{
|
|
771 |
uint i; |
|
772 |
||
773 |
if (command->abort_on_error) |
|
774 |
die("command \"%.*s\" failed with error %d", |
|
775 |
command->first_word_len, command->query, error); |
|
776 |
for (i= 0; i < command->expected_errors.count; i++) |
|
777 |
{
|
|
778 |
if ((command->expected_errors.err[i].type == ERR_ERRNO) && |
|
779 |
(command->expected_errors.err[i].code.errnum == error)) |
|
780 |
{
|
|
142.1.1
by Patrick
Removing DBUG from client |
781 |
return; |
1
by brian
clean slate |
782 |
}
|
783 |
}
|
|
784 |
die("command \"%.*s\" failed with wrong error: %d", |
|
785 |
command->first_word_len, command->query, error); |
|
786 |
}
|
|
787 |
else if (command->expected_errors.err[0].type == ERR_ERRNO && |
|
788 |
command->expected_errors.err[0].code.errnum != 0) |
|
789 |
{
|
|
790 |
/* Error code we wanted was != 0, i.e. not an expected success */
|
|
791 |
die("command \"%.*s\" succeeded - should have failed with errno %d...", |
|
792 |
command->first_word_len, command->query, |
|
793 |
command->expected_errors.err[0].code.errnum); |
|
794 |
}
|
|
142.1.1
by Patrick
Removing DBUG from client |
795 |
return; |
1
by brian
clean slate |
796 |
}
|
797 |
||
798 |
||
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
799 |
static void close_connections(void) |
1
by brian
clean slate |
800 |
{
|
142.1.1
by Patrick
Removing DBUG from client |
801 |
|
1
by brian
clean slate |
802 |
for (--next_con; next_con >= connections; --next_con) |
803 |
{
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
804 |
drizzle_close(&next_con->drizzle); |
805 |
if (next_con->util_drizzle) |
|
806 |
drizzle_close(next_con->util_drizzle); |
|
477
by Monty Taylor
Removed my_free(). It turns out that it had been def'd to ignore the flags passed to it in the second arg anyway. Gotta love that. |
807 |
free(next_con->name); |
1
by brian
clean slate |
808 |
}
|
142.1.1
by Patrick
Removing DBUG from client |
809 |
return; |
1
by brian
clean slate |
810 |
}
|
811 |
||
812 |
||
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
813 |
static void close_files(void) |
1
by brian
clean slate |
814 |
{
|
142.1.1
by Patrick
Removing DBUG from client |
815 |
|
1
by brian
clean slate |
816 |
for (; cur_file >= file_stack; cur_file--) |
817 |
{
|
|
818 |
if (cur_file->file && cur_file->file != stdin) |
|
819 |
{
|
|
820 |
my_fclose(cur_file->file, MYF(0)); |
|
821 |
}
|
|
481
by Brian Aker
Remove all of uchar. |
822 |
free((unsigned char*) cur_file->file_name); |
1
by brian
clean slate |
823 |
cur_file->file_name= 0; |
824 |
}
|
|
142.1.1
by Patrick
Removing DBUG from client |
825 |
return; |
1
by brian
clean slate |
826 |
}
|
827 |
||
828 |
||
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
829 |
static void free_used_memory(void) |
1
by brian
clean slate |
830 |
{
|
831 |
uint i; |
|
142.1.1
by Patrick
Removing DBUG from client |
832 |
|
1
by brian
clean slate |
833 |
|
834 |
close_connections(); |
|
835 |
close_files(); |
|
836 |
hash_free(&var_hash); |
|
837 |
||
373.1.6
by Monty Taylor
Moved q_lines to vector. |
838 |
vector<struct st_command *>::iterator iter; |
839 |
for (iter= q_lines.begin() ; iter < q_lines.end() ; iter++) |
|
1
by brian
clean slate |
840 |
{
|
373.1.6
by Monty Taylor
Moved q_lines to vector. |
841 |
struct st_command * q_line= *(iter.base()); |
842 |
if (q_line->query_buf != NULL) |
|
843 |
{
|
|
844 |
free(q_line->query_buf); |
|
845 |
}
|
|
846 |
free(q_line); |
|
1
by brian
clean slate |
847 |
}
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
848 |
|
1
by brian
clean slate |
849 |
for (i= 0; i < 10; i++) |
850 |
{
|
|
851 |
if (var_reg[i].alloced_len) |
|
477
by Monty Taylor
Removed my_free(). It turns out that it had been def'd to ignore the flags passed to it in the second arg anyway. Gotta love that. |
852 |
free(var_reg[i].str_val); |
1
by brian
clean slate |
853 |
}
|
854 |
while (embedded_server_arg_count > 1) |
|
477
by Monty Taylor
Removed my_free(). It turns out that it had been def'd to ignore the flags passed to it in the second arg anyway. Gotta love that. |
855 |
free(embedded_server_args[--embedded_server_arg_count]); |
373.1.6
by Monty Taylor
Moved q_lines to vector. |
856 |
|
1
by brian
clean slate |
857 |
free_all_replace(); |
477
by Monty Taylor
Removed my_free(). It turns out that it had been def'd to ignore the flags passed to it in the second arg anyway. Gotta love that. |
858 |
free(opt_pass); |
1
by brian
clean slate |
859 |
free_defaults(default_argv); |
860 |
||
861 |
return; |
|
862 |
}
|
|
863 |
||
864 |
||
865 |
static void cleanup_and_exit(int exit_code) |
|
866 |
{
|
|
867 |
free_used_memory(); |
|
868 |
my_end(my_end_arg); |
|
869 |
||
870 |
if (!silent) { |
|
871 |
switch (exit_code) { |
|
872 |
case 1: |
|
873 |
printf("not ok\n"); |
|
874 |
break; |
|
875 |
case 0: |
|
876 |
printf("ok\n"); |
|
877 |
break; |
|
878 |
case 62: |
|
879 |
printf("skipped\n"); |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
880 |
break; |
1
by brian
clean slate |
881 |
default: |
882 |
printf("unknown exit code: %d\n", exit_code); |
|
142.1.2
by Patrick
All DBUG_x removed from client/ |
883 |
assert(0); |
1
by brian
clean slate |
884 |
}
|
885 |
}
|
|
886 |
||
887 |
exit(exit_code); |
|
888 |
}
|
|
889 |
||
890 |
void die(const char *fmt, ...) |
|
891 |
{
|
|
892 |
static int dying= 0; |
|
893 |
va_list args; |
|
894 |
||
895 |
/*
|
|
896 |
Protect against dying twice
|
|
897 |
first time 'die' is called, try to write log files
|
|
898 |
second time, just exit
|
|
899 |
*/
|
|
900 |
if (dying) |
|
901 |
cleanup_and_exit(1); |
|
902 |
dying= 1; |
|
903 |
||
904 |
/* Print the error message */
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
905 |
fprintf(stderr, "drizzletest: "); |
1
by brian
clean slate |
906 |
if (cur_file && cur_file != file_stack) |
907 |
fprintf(stderr, "In included file \"%s\": ", |
|
908 |
cur_file->file_name); |
|
909 |
if (start_lineno > 0) |
|
910 |
fprintf(stderr, "At line %u: ", start_lineno); |
|
911 |
if (fmt) |
|
912 |
{
|
|
913 |
va_start(args, fmt); |
|
914 |
vfprintf(stderr, fmt, args); |
|
915 |
va_end(args); |
|
916 |
}
|
|
917 |
else
|
|
918 |
fprintf(stderr, "unknown error"); |
|
919 |
fprintf(stderr, "\n"); |
|
920 |
fflush(stderr); |
|
921 |
||
922 |
/* Show results from queries just before failure */
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
923 |
if (ds_res.length() && opt_tail_lines) |
1
by brian
clean slate |
924 |
{
|
925 |
int tail_lines= opt_tail_lines; |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
926 |
const char* show_from= ds_res.c_str() + ds_res.length() - 1; |
927 |
while(show_from > ds_res.c_str() && tail_lines > 0 ) |
|
1
by brian
clean slate |
928 |
{
|
929 |
show_from--; |
|
930 |
if (*show_from == '\n') |
|
931 |
tail_lines--; |
|
932 |
}
|
|
933 |
fprintf(stderr, "\nThe result from queries just before the failure was:\n"); |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
934 |
if (show_from > ds_res.c_str()) |
1
by brian
clean slate |
935 |
fprintf(stderr, "< snip >"); |
936 |
fprintf(stderr, "%s", show_from); |
|
937 |
fflush(stderr); |
|
938 |
}
|
|
939 |
||
940 |
/* Dump the result that has been accumulated so far to .log file */
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
941 |
if (result_file_name && ds_res.length()) |
942 |
dump_result_to_log_file(ds_res.c_str(), ds_res.length()); |
|
1
by brian
clean slate |
943 |
|
944 |
/* Dump warning messages */
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
945 |
if (result_file_name && ds_warning_messages.length()) |
1
by brian
clean slate |
946 |
dump_warning_messages(); |
947 |
||
948 |
/*
|
|
949 |
Help debugging by displaying any warnings that might have
|
|
950 |
been produced prior to the error
|
|
951 |
*/
|
|
952 |
if (cur_con) |
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
953 |
show_warnings_before_error(&cur_con->drizzle); |
1
by brian
clean slate |
954 |
|
955 |
cleanup_and_exit(1); |
|
956 |
}
|
|
957 |
||
958 |
||
959 |
void abort_not_supported_test(const char *fmt, ...) |
|
960 |
{
|
|
961 |
va_list args; |
|
962 |
struct st_test_file* err_file= cur_file; |
|
142.1.1
by Patrick
Removing DBUG from client |
963 |
|
1
by brian
clean slate |
964 |
|
965 |
/* Print include filestack */
|
|
966 |
fprintf(stderr, "The test '%s' is not supported by this installation\n", |
|
967 |
file_stack->file_name); |
|
968 |
fprintf(stderr, "Detected in file %s at line %d\n", |
|
969 |
err_file->file_name, err_file->lineno); |
|
970 |
while (err_file != file_stack) |
|
971 |
{
|
|
972 |
err_file--; |
|
973 |
fprintf(stderr, "included from %s at line %d\n", |
|
974 |
err_file->file_name, err_file->lineno); |
|
975 |
}
|
|
976 |
||
977 |
/* Print error message */
|
|
978 |
va_start(args, fmt); |
|
979 |
if (fmt) |
|
980 |
{
|
|
981 |
fprintf(stderr, "reason: "); |
|
982 |
vfprintf(stderr, fmt, args); |
|
983 |
fprintf(stderr, "\n"); |
|
984 |
fflush(stderr); |
|
985 |
}
|
|
986 |
va_end(args); |
|
987 |
||
988 |
cleanup_and_exit(62); |
|
989 |
}
|
|
990 |
||
991 |
||
992 |
void verbose_msg(const char *fmt, ...) |
|
993 |
{
|
|
994 |
va_list args; |
|
142.1.1
by Patrick
Removing DBUG from client |
995 |
|
1
by brian
clean slate |
996 |
if (!verbose) |
142.1.1
by Patrick
Removing DBUG from client |
997 |
return; |
1
by brian
clean slate |
998 |
|
999 |
va_start(args, fmt); |
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
1000 |
fprintf(stderr, "drizzletest: "); |
1
by brian
clean slate |
1001 |
if (cur_file && cur_file != file_stack) |
1002 |
fprintf(stderr, "In included file \"%s\": ", |
|
1003 |
cur_file->file_name); |
|
1004 |
if (start_lineno != 0) |
|
1005 |
fprintf(stderr, "At line %u: ", start_lineno); |
|
1006 |
vfprintf(stderr, fmt, args); |
|
1007 |
fprintf(stderr, "\n"); |
|
1008 |
va_end(args); |
|
1009 |
||
142.1.1
by Patrick
Removing DBUG from client |
1010 |
return; |
1
by brian
clean slate |
1011 |
}
|
1012 |
||
1013 |
||
1014 |
void warning_msg(const char *fmt, ...) |
|
1015 |
{
|
|
1016 |
va_list args; |
|
1017 |
char buff[512]; |
|
1018 |
size_t len; |
|
142.1.1
by Patrick
Removing DBUG from client |
1019 |
|
1
by brian
clean slate |
1020 |
|
1021 |
va_start(args, fmt); |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
1022 |
ds_warning_messages.append("drizzletest: "); |
1
by brian
clean slate |
1023 |
if (start_lineno != 0) |
1024 |
{
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
1025 |
ds_warning_messages.append("Warning detected "); |
1
by brian
clean slate |
1026 |
if (cur_file && cur_file != file_stack) |
1027 |
{
|
|
77.1.18
by Monty Taylor
Removed my_vsnprintf and my_snprintf. |
1028 |
len= snprintf(buff, sizeof(buff), "in included file %s ", |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
1029 |
cur_file->file_name); |
1030 |
ds_warning_messages.append(buff, len); |
|
1
by brian
clean slate |
1031 |
}
|
77.1.18
by Monty Taylor
Removed my_vsnprintf and my_snprintf. |
1032 |
len= snprintf(buff, sizeof(buff), "at line %d: ", |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
1033 |
start_lineno); |
1034 |
ds_warning_messages.append(buff, len); |
|
1
by brian
clean slate |
1035 |
}
|
1036 |
||
77.1.18
by Monty Taylor
Removed my_vsnprintf and my_snprintf. |
1037 |
len= vsnprintf(buff, sizeof(buff), fmt, args); |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
1038 |
ds_warning_messages.append(buff, len); |
1
by brian
clean slate |
1039 |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
1040 |
ds_warning_messages.append("\n"); |
1
by brian
clean slate |
1041 |
va_end(args); |
1042 |
||
142.1.1
by Patrick
Removing DBUG from client |
1043 |
return; |
1
by brian
clean slate |
1044 |
}
|
1045 |
||
1046 |
||
1047 |
void log_msg(const char *fmt, ...) |
|
1048 |
{
|
|
1049 |
va_list args; |
|
1050 |
char buff[1024]; |
|
1051 |
size_t len; |
|
142.1.1
by Patrick
Removing DBUG from client |
1052 |
|
1
by brian
clean slate |
1053 |
|
1054 |
va_start(args, fmt); |
|
77.1.18
by Monty Taylor
Removed my_vsnprintf and my_snprintf. |
1055 |
len= vsnprintf(buff, sizeof(buff)-1, fmt, args); |
1
by brian
clean slate |
1056 |
va_end(args); |
1057 |
||
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
1058 |
ds_res.append(buff, len); |
1059 |
ds_res.append("\n"); |
|
1
by brian
clean slate |
1060 |
|
142.1.1
by Patrick
Removing DBUG from client |
1061 |
return; |
1
by brian
clean slate |
1062 |
}
|
1063 |
||
1064 |
||
1065 |
/*
|
|
1066 |
Read a file and append it to ds
|
|
1067 |
||
1068 |
SYNOPSIS
|
|
1069 |
cat_file
|
|
1070 |
ds - pointer to dynamic string where to add the files content
|
|
1071 |
filename - name of the file to read
|
|
1072 |
||
1073 |
*/
|
|
1074 |
||
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
1075 |
static void cat_file(string* ds, const char* filename) |
1
by brian
clean slate |
1076 |
{
|
1077 |
int fd; |
|
1078 |
uint len; |
|
1079 |
char buff[512]; |
|
1080 |
||
1081 |
if ((fd= my_open(filename, O_RDONLY, MYF(0))) < 0) |
|
1082 |
die("Failed to open file '%s'", filename); |
|
481
by Brian Aker
Remove all of uchar. |
1083 |
while((len= my_read(fd, (unsigned char*)&buff, |
1
by brian
clean slate |
1084 |
sizeof(buff), MYF(0))) > 0) |
1085 |
{
|
|
1086 |
char *p= buff, *start= buff; |
|
1087 |
while (p < buff+len) |
|
1088 |
{
|
|
1089 |
/* Convert cr/lf to lf */
|
|
1090 |
if (*p == '\r' && *(p+1) && *(p+1)== '\n') |
|
1091 |
{
|
|
1092 |
/* Add fake newline instead of cr and output the line */
|
|
1093 |
*p= '\n'; |
|
1094 |
p++; /* Step past the "fake" newline */ |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
1095 |
ds->append(start, p-start); |
1
by brian
clean slate |
1096 |
p++; /* Step past the "fake" newline */ |
1097 |
start= p; |
|
1098 |
}
|
|
1099 |
else
|
|
1100 |
p++; |
|
1101 |
}
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
1102 |
/* Output any chars that might be left */
|
1103 |
ds->append(start, p-start); |
|
1
by brian
clean slate |
1104 |
}
|
1105 |
my_close(fd, MYF(0)); |
|
1106 |
}
|
|
1107 |
||
1108 |
||
1109 |
/*
|
|
1110 |
Run the specified command with popen
|
|
1111 |
||
1112 |
SYNOPSIS
|
|
1113 |
run_command
|
|
1114 |
cmd - command to execute(should be properly quoted
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
1115 |
result - pointer to string where to store the result
|
1
by brian
clean slate |
1116 |
|
1117 |
*/
|
|
1118 |
||
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
1119 |
static int run_command(const char * cmd, string * result) |
1
by brian
clean slate |
1120 |
{
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
1121 |
assert(result!=NULL); |
1
by brian
clean slate |
1122 |
char buf[512]= {0}; |
1123 |
FILE *res_file; |
|
1124 |
int error; |
|
1125 |
||
1126 |
if (!(res_file= popen(cmd, "r"))) |
|
1127 |
die("popen(\"%s\", \"r\") failed", cmd); |
|
1128 |
||
1129 |
while (fgets(buf, sizeof(buf), res_file)) |
|
1130 |
{
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
1131 |
/* Save the output of this command in the supplied string */
|
1132 |
result->append(buf); |
|
1
by brian
clean slate |
1133 |
}
|
1134 |
||
1135 |
error= pclose(res_file); |
|
1136 |
return WEXITSTATUS(error); |
|
1137 |
}
|
|
1138 |
||
1139 |
||
1140 |
/*
|
|
1141 |
Run the specified tool with variable number of arguments
|
|
1142 |
||
1143 |
SYNOPSIS
|
|
1144 |
run_tool
|
|
1145 |
tool_path - the name of the tool to run
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
1146 |
result - pointer to dynamic string where to store the result
|
1
by brian
clean slate |
1147 |
... - variable number of arguments that will be properly
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
1148 |
quoted and appended after the tool's name
|
1
by brian
clean slate |
1149 |
|
1150 |
*/
|
|
1151 |
||
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
1152 |
static int run_tool(const char *tool_path, string * result, ...) |
1
by brian
clean slate |
1153 |
{
|
1154 |
int ret; |
|
1155 |
const char* arg; |
|
1156 |
va_list args; |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
1157 |
string ds_cmdline; |
1158 |
||
1159 |
||
482.1.1
by Monty Taylor
Fix for drizzletest crash from Paul McCullagh. (Fixes #279304) |
1160 |
append_os_quoted(&ds_cmdline, tool_path, NULL); |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
1161 |
ds_cmdline.append(" "); |
1162 |
||
1163 |
va_start(args, result); |
|
1
by brian
clean slate |
1164 |
|
1165 |
while ((arg= va_arg(args, char *))) |
|
1166 |
{
|
|
1167 |
/* Options should be os quoted */
|
|
1168 |
if (strncmp(arg, "--", 2) == 0) |
|
461
by Monty Taylor
Removed NullS. bu-bye. |
1169 |
append_os_quoted(&ds_cmdline, arg, NULL); |
1
by brian
clean slate |
1170 |
else
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
1171 |
ds_cmdline.append(arg); |
1172 |
ds_cmdline.append(" "); |
|
1
by brian
clean slate |
1173 |
}
|
1174 |
||
1175 |
va_end(args); |
|
1176 |
||
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
1177 |
ret= run_command(ds_cmdline.c_str(), result); |
142.1.1
by Patrick
Removing DBUG from client |
1178 |
return(ret); |
1
by brian
clean slate |
1179 |
}
|
1180 |
||
1181 |
||
1182 |
/*
|
|
1183 |
Show the diff of two files using the systems builtin diff
|
|
1184 |
command. If no such diff command exist, just dump the content
|
|
1185 |
of the two files and inform about how to get "diff"
|
|
1186 |
||
1187 |
SYNOPSIS
|
|
1188 |
show_diff
|
|
1189 |
ds - pointer to dynamic string where to add the diff(may be NULL)
|
|
1190 |
filename1 - name of first file
|
|
1191 |
filename2 - name of second file
|
|
1192 |
||
1193 |
*/
|
|
1194 |
||
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
1195 |
static void show_diff(string* ds, |
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
1196 |
const char* filename1, const char* filename2) |
1
by brian
clean slate |
1197 |
{
|
1198 |
||
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
1199 |
string ds_tmp; |
1
by brian
clean slate |
1200 |
|
1201 |
/* First try with unified diff */
|
|
1202 |
if (run_tool("diff", |
|
1203 |
&ds_tmp, /* Get output from diff in ds_tmp */ |
|
1204 |
"-u", |
|
1205 |
filename1, |
|
1206 |
filename2, |
|
1207 |
"2>&1", |
|
1208 |
NULL) > 1) /* Most "diff" tools return >1 if error */ |
|
1209 |
{
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
1210 |
ds_tmp= ""; |
1
by brian
clean slate |
1211 |
|
1212 |
/* Fallback to context diff with "diff -c" */
|
|
1213 |
if (run_tool("diff", |
|
1214 |
&ds_tmp, /* Get output from diff in ds_tmp */ |
|
1215 |
"-c", |
|
1216 |
filename1, |
|
1217 |
filename2, |
|
1218 |
"2>&1", |
|
1219 |
NULL) > 1) /* Most "diff" tools return >1 if error */ |
|
1220 |
{
|
|
1221 |
/*
|
|
1222 |
Fallback to dump both files to result file and inform
|
|
1223 |
about installing "diff"
|
|
1224 |
*/
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
1225 |
ds_tmp= ""; |
1226 |
||
1227 |
ds_tmp.append( |
|
1228 |
"\n" |
|
1229 |
"The two files differ but it was not possible to execute 'diff' in\n" |
|
1230 |
"order to show only the difference, tried both 'diff -u' or 'diff -c'.\n" |
|
1231 |
"Instead the whole content of the two files was shown for you to diff manually. ;)\n\n" |
|
1232 |
"To get a better report you should install 'diff' on your system, which you\n" |
|
1233 |
"for example can get from http://www.gnu.org/software/diffutils/diffutils.html\n" |
|
1234 |
"\n"); |
|
1235 |
||
1236 |
ds_tmp.append(" --- "); |
|
1237 |
ds_tmp.append(filename1); |
|
1238 |
ds_tmp.append(" >>>\n"); |
|
1
by brian
clean slate |
1239 |
cat_file(&ds_tmp, filename1); |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
1240 |
ds_tmp.append("<<<\n --- "); |
1241 |
ds_tmp.append(filename1); |
|
1242 |
ds_tmp.append(" >>>\n"); |
|
1
by brian
clean slate |
1243 |
cat_file(&ds_tmp, filename2); |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
1244 |
ds_tmp.append("<<<<\n"); |
1
by brian
clean slate |
1245 |
}
|
1246 |
}
|
|
1247 |
||
1248 |
if (ds) |
|
1249 |
{
|
|
1250 |
/* Add the diff to output */
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
1251 |
ds->append(ds_tmp.c_str(), ds_tmp.length()); |
1
by brian
clean slate |
1252 |
}
|
1253 |
else
|
|
1254 |
{
|
|
1255 |
/* Print diff directly to stdout */
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
1256 |
fprintf(stderr, "%s\n", ds_tmp.c_str()); |
1
by brian
clean slate |
1257 |
}
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
1258 |
|
1
by brian
clean slate |
1259 |
}
|
1260 |
||
1261 |
||
1262 |
enum compare_files_result_enum { |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
1263 |
RESULT_OK= 0, |
1264 |
RESULT_CONTENT_MISMATCH= 1, |
|
1265 |
RESULT_LENGTH_MISMATCH= 2 |
|
1
by brian
clean slate |
1266 |
};
|
1267 |
||
1268 |
/*
|
|
1269 |
Compare two files, given a fd to the first file and
|
|
1270 |
name of the second file
|
|
1271 |
||
1272 |
SYNOPSIS
|
|
1273 |
compare_files2
|
|
1274 |
fd - Open file descriptor of the first file
|
|
1275 |
filename2 - Name of second file
|
|
1276 |
||
1277 |
RETURN VALUES
|
|
1278 |
According to the values in "compare_files_result_enum"
|
|
1279 |
||
1280 |
*/
|
|
1281 |
||
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
1282 |
static int compare_files2(File fd, const char* filename2) |
1
by brian
clean slate |
1283 |
{
|
1284 |
int error= RESULT_OK; |
|
1285 |
File fd2; |
|
1286 |
uint len, len2; |
|
1287 |
char buff[512], buff2[512]; |
|
1288 |
||
1289 |
if ((fd2= my_open(filename2, O_RDONLY, MYF(0))) < 0) |
|
1290 |
{
|
|
1291 |
my_close(fd, MYF(0)); |
|
1292 |
die("Failed to open second file: '%s'", filename2); |
|
1293 |
}
|
|
481
by Brian Aker
Remove all of uchar. |
1294 |
while((len= my_read(fd, (unsigned char*)&buff, |
1
by brian
clean slate |
1295 |
sizeof(buff), MYF(0))) > 0) |
1296 |
{
|
|
481
by Brian Aker
Remove all of uchar. |
1297 |
if ((len2= my_read(fd2, (unsigned char*)&buff2, |
1
by brian
clean slate |
1298 |
sizeof(buff2), MYF(0))) < len) |
1299 |
{
|
|
1300 |
/* File 2 was smaller */
|
|
1301 |
error= RESULT_LENGTH_MISMATCH; |
|
1302 |
break; |
|
1303 |
}
|
|
1304 |
if (len2 > len) |
|
1305 |
{
|
|
1306 |
/* File 1 was smaller */
|
|
1307 |
error= RESULT_LENGTH_MISMATCH; |
|
1308 |
break; |
|
1309 |
}
|
|
1310 |
if ((memcmp(buff, buff2, len))) |
|
1311 |
{
|
|
1312 |
/* Content of this part differed */
|
|
1313 |
error= RESULT_CONTENT_MISMATCH; |
|
1314 |
break; |
|
1315 |
}
|
|
1316 |
}
|
|
481
by Brian Aker
Remove all of uchar. |
1317 |
if (!error && my_read(fd2, (unsigned char*)&buff2, |
1
by brian
clean slate |
1318 |
sizeof(buff2), MYF(0)) > 0) |
1319 |
{
|
|
1320 |
/* File 1 was smaller */
|
|
1321 |
error= RESULT_LENGTH_MISMATCH; |
|
1322 |
}
|
|
1323 |
||
1324 |
my_close(fd2, MYF(0)); |
|
1325 |
||
1326 |
return error; |
|
1327 |
}
|
|
1328 |
||
1329 |
||
1330 |
/*
|
|
1331 |
Compare two files, given their filenames
|
|
1332 |
||
1333 |
SYNOPSIS
|
|
1334 |
compare_files
|
|
1335 |
filename1 - Name of first file
|
|
1336 |
filename2 - Name of second file
|
|
1337 |
||
1338 |
RETURN VALUES
|
|
1339 |
See 'compare_files2'
|
|
1340 |
||
1341 |
*/
|
|
1342 |
||
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
1343 |
static int compare_files(const char* filename1, const char* filename2) |
1
by brian
clean slate |
1344 |
{
|
1345 |
File fd; |
|
1346 |
int error; |
|
1347 |
||
1348 |
if ((fd= my_open(filename1, O_RDONLY, MYF(0))) < 0) |
|
1349 |
die("Failed to open first file: '%s'", filename1); |
|
1350 |
||
1351 |
error= compare_files2(fd, filename2); |
|
1352 |
||
1353 |
my_close(fd, MYF(0)); |
|
1354 |
||
1355 |
return error; |
|
1356 |
}
|
|
1357 |
||
1358 |
||
1359 |
/*
|
|
1360 |
Compare content of the string in ds to content of file fname
|
|
1361 |
||
1362 |
SYNOPSIS
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
1363 |
string_cmp
|
1
by brian
clean slate |
1364 |
ds - Dynamic string containing the string o be compared
|
1365 |
fname - Name of file to compare with
|
|
1366 |
||
1367 |
RETURN VALUES
|
|
1368 |
See 'compare_files2'
|
|
1369 |
*/
|
|
1370 |
||
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
1371 |
static int string_cmp(string* ds, const char *fname) |
1
by brian
clean slate |
1372 |
{
|
1373 |
int error; |
|
1374 |
File fd; |
|
1375 |
char temp_file_path[FN_REFLEN]; |
|
1376 |
||
1377 |
if ((fd= create_temp_file(temp_file_path, NULL, |
|
492.1.13
by Monty Taylor
Removed O_SHARE. I think it was only for OS/2. |
1378 |
"tmp", O_CREAT | O_RDWR, |
1
by brian
clean slate |
1379 |
MYF(MY_WME))) < 0) |
1380 |
die("Failed to create temporary file for ds"); |
|
1381 |
||
1382 |
/* Write ds to temporary file and set file pos to beginning*/
|
|
481
by Brian Aker
Remove all of uchar. |
1383 |
if (my_write(fd, (unsigned char *) ds->c_str(), ds->length(), |
1
by brian
clean slate |
1384 |
MYF(MY_FNABP | MY_WME)) || |
1385 |
my_seek(fd, 0, SEEK_SET, MYF(0)) == MY_FILEPOS_ERROR) |
|
1386 |
{
|
|
1387 |
my_close(fd, MYF(0)); |
|
1388 |
/* Remove the temporary file */
|
|
1389 |
my_delete(temp_file_path, MYF(0)); |
|
1390 |
die("Failed to write file '%s'", temp_file_path); |
|
1391 |
}
|
|
1392 |
||
1393 |
error= compare_files2(fd, fname); |
|
1394 |
||
1395 |
my_close(fd, MYF(0)); |
|
1396 |
/* Remove the temporary file */
|
|
1397 |
my_delete(temp_file_path, MYF(0)); |
|
1398 |
||
142.1.1
by Patrick
Removing DBUG from client |
1399 |
return(error); |
1
by brian
clean slate |
1400 |
}
|
1401 |
||
1402 |
||
1403 |
/*
|
|
1404 |
Check the content of ds against result file
|
|
1405 |
||
1406 |
SYNOPSIS
|
|
1407 |
check_result
|
|
1408 |
ds - content to be checked
|
|
1409 |
||
1410 |
RETURN VALUES
|
|
1411 |
error - the function will not return
|
|
1412 |
||
1413 |
*/
|
|
1414 |
||
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
1415 |
static void check_result(string* ds) |
1
by brian
clean slate |
1416 |
{
|
1417 |
const char* mess= "Result content mismatch\n"; |
|
1418 |
||
142.1.1
by Patrick
Removing DBUG from client |
1419 |
|
142.1.2
by Patrick
All DBUG_x removed from client/ |
1420 |
assert(result_file_name); |
1
by brian
clean slate |
1421 |
|
1422 |
if (access(result_file_name, F_OK) != 0) |
|
1423 |
die("The specified result file does not exist: '%s'", result_file_name); |
|
1424 |
||
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
1425 |
switch (string_cmp(ds, result_file_name)) { |
1
by brian
clean slate |
1426 |
case RESULT_OK: |
1427 |
break; /* ok */ |
|
1428 |
case RESULT_LENGTH_MISMATCH: |
|
1429 |
mess= "Result length mismatch\n"; |
|
1430 |
/* Fallthrough */
|
|
1431 |
case RESULT_CONTENT_MISMATCH: |
|
1432 |
{
|
|
1433 |
/*
|
|
1434 |
Result mismatched, dump results to .reject file
|
|
1435 |
and then show the diff
|
|
1436 |
*/
|
|
1437 |
char reject_file[FN_REFLEN]; |
|
1438 |
size_t reject_length; |
|
1439 |
dirname_part(reject_file, result_file_name, &reject_length); |
|
1440 |
||
1441 |
if (access(reject_file, W_OK) == 0) |
|
1442 |
{
|
|
1443 |
/* Result file directory is writable, save reject file there */
|
|
1444 |
fn_format(reject_file, result_file_name, NULL, |
|
1445 |
".reject", MY_REPLACE_EXT); |
|
1446 |
}
|
|
1447 |
else
|
|
1448 |
{
|
|
1449 |
/* Put reject file in opt_logdir */
|
|
1450 |
fn_format(reject_file, result_file_name, opt_logdir, |
|
1451 |
".reject", MY_REPLACE_DIR | MY_REPLACE_EXT); |
|
1452 |
}
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
1453 |
str_to_file(reject_file, ds->c_str(), ds->length()); |
1
by brian
clean slate |
1454 |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
1455 |
ds->erase(); /* Don't create a .log file */ |
1
by brian
clean slate |
1456 |
|
1457 |
show_diff(NULL, result_file_name, reject_file); |
|
512.1.1
by Stewart Smith
a few warnings that show up on ubuntu 8.10: unchecked return codes, not fromat string |
1458 |
die("%s",mess); |
1
by brian
clean slate |
1459 |
break; |
1460 |
}
|
|
1461 |
default: /* impossible */ |
|
1462 |
die("Unknown error code from dyn_string_cmp()"); |
|
1463 |
}
|
|
1464 |
||
142.1.1
by Patrick
Removing DBUG from client |
1465 |
return; |
1
by brian
clean slate |
1466 |
}
|
1467 |
||
1468 |
||
1469 |
/*
|
|
1470 |
Check the content of ds against a require file
|
|
1471 |
If match fails, abort the test with special error code
|
|
1472 |
indicating that test is not supported
|
|
1473 |
||
1474 |
SYNOPSIS
|
|
1475 |
check_require
|
|
1476 |
ds - content to be checked
|
|
1477 |
fname - name of file to check against
|
|
1478 |
||
1479 |
RETURN VALUES
|
|
1480 |
error - the function will not return
|
|
1481 |
||
1482 |
*/
|
|
1483 |
||
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
1484 |
static void check_require(string* ds, const char *fname) |
1
by brian
clean slate |
1485 |
{
|
142.1.1
by Patrick
Removing DBUG from client |
1486 |
|
1
by brian
clean slate |
1487 |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
1488 |
if (string_cmp(ds, fname)) |
1
by brian
clean slate |
1489 |
{
|
1490 |
char reason[FN_REFLEN]; |
|
1491 |
fn_format(reason, fname, "", "", MY_REPLACE_EXT | MY_REPLACE_DIR); |
|
1492 |
abort_not_supported_test("Test requires: '%s'", reason); |
|
1493 |
}
|
|
142.1.1
by Patrick
Removing DBUG from client |
1494 |
return; |
1
by brian
clean slate |
1495 |
}
|
1496 |
||
1497 |
||
1498 |
/*
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
1499 |
Remove surrounding chars from string
|
1
by brian
clean slate |
1500 |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
1501 |
Return 1 if first character is found but not last
|
1
by brian
clean slate |
1502 |
*/
|
1503 |
static int strip_surrounding(char* str, char c1, char c2) |
|
1504 |
{
|
|
1505 |
char* ptr= str; |
|
1506 |
||
1507 |
/* Check if the first non space character is c1 */
|
|
1508 |
while(*ptr && my_isspace(charset_info, *ptr)) |
|
1509 |
ptr++; |
|
1510 |
if (*ptr == c1) |
|
1511 |
{
|
|
1512 |
/* Replace it with a space */
|
|
1513 |
*ptr= ' '; |
|
1514 |
||
1515 |
/* Last non space charecter should be c2 */
|
|
376
by Brian Aker
strend remove |
1516 |
ptr= strchr(str, '\0')-1; |
1
by brian
clean slate |
1517 |
while(*ptr && my_isspace(charset_info, *ptr)) |
1518 |
ptr--; |
|
1519 |
if (*ptr == c2) |
|
1520 |
{
|
|
1521 |
/* Replace it with \0 */
|
|
1522 |
*ptr= 0; |
|
1523 |
}
|
|
1524 |
else
|
|
1525 |
{
|
|
1526 |
/* Mismatch detected */
|
|
1527 |
return 1; |
|
1528 |
}
|
|
1529 |
}
|
|
1530 |
return 0; |
|
1531 |
}
|
|
1532 |
||
1533 |
||
1534 |
static void strip_parentheses(struct st_command *command) |
|
1535 |
{
|
|
1536 |
if (strip_surrounding(command->first_argument, '(', ')')) |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
1537 |
die("%.*s - argument list started with '%c' must be ended with '%c'", |
1538 |
command->first_word_len, command->query, '(', ')'); |
|
1
by brian
clean slate |
1539 |
}
|
1540 |
||
1541 |
||
481
by Brian Aker
Remove all of uchar. |
1542 |
static unsigned char *get_var_key(const unsigned char* var, size_t *len, |
146
by Brian Aker
my_bool cleanup. |
1543 |
bool __attribute__((unused)) t) |
1
by brian
clean slate |
1544 |
{
|
1545 |
register char* key; |
|
1546 |
key = ((VAR*)var)->name; |
|
1547 |
*len = ((VAR*)var)->name_len; |
|
481
by Brian Aker
Remove all of uchar. |
1548 |
return (unsigned char*)key; |
1
by brian
clean slate |
1549 |
}
|
1550 |
||
1551 |
||
1552 |
VAR *var_init(VAR *v, const char *name, int name_len, const char *val, |
|
1553 |
int val_len) |
|
1554 |
{
|
|
1555 |
int val_alloc_len; |
|
1556 |
VAR *tmp_var; |
|
1557 |
if (!name_len && name) |
|
1558 |
name_len = strlen(name); |
|
1559 |
if (!val_len && val) |
|
1560 |
val_len = strlen(val) ; |
|
1561 |
val_alloc_len = val_len + 16; /* room to grow */ |
|
1562 |
if (!(tmp_var=v) && !(tmp_var = (VAR*)my_malloc(sizeof(*tmp_var) |
|
1563 |
+ name_len+1, MYF(MY_WME)))) |
|
1564 |
die("Out of memory"); |
|
1565 |
||
1566 |
tmp_var->name = (name) ? (char*) tmp_var + sizeof(*tmp_var) : 0; |
|
1567 |
tmp_var->alloced = (v == 0); |
|
1568 |
||
77.1.31
by Monty Taylor
Replaced regex lib with pcre. Reworked mysqltest to use it. |
1569 |
if (!(tmp_var->str_val = (char *)my_malloc(val_alloc_len+1, MYF(MY_WME)))) |
1
by brian
clean slate |
1570 |
die("Out of memory"); |
1571 |
||
1572 |
memcpy(tmp_var->name, name, name_len); |
|
1573 |
if (val) |
|
1574 |
{
|
|
1575 |
memcpy(tmp_var->str_val, val, val_len); |
|
1576 |
tmp_var->str_val[val_len]= 0; |
|
1577 |
}
|
|
1578 |
tmp_var->name_len = name_len; |
|
1579 |
tmp_var->str_val_len = val_len; |
|
1580 |
tmp_var->alloced_len = val_alloc_len; |
|
1581 |
tmp_var->int_val = (val) ? atoi(val) : 0; |
|
1582 |
tmp_var->int_dirty = 0; |
|
1583 |
tmp_var->env_s = 0; |
|
1584 |
return tmp_var; |
|
1585 |
}
|
|
1586 |
||
1587 |
||
1588 |
void var_free(void *v) |
|
1589 |
{
|
|
477
by Monty Taylor
Removed my_free(). It turns out that it had been def'd to ignore the flags passed to it in the second arg anyway. Gotta love that. |
1590 |
free(((VAR*) v)->str_val); |
1591 |
free(((VAR*) v)->env_s); |
|
1
by brian
clean slate |
1592 |
if (((VAR*)v)->alloced) |
477
by Monty Taylor
Removed my_free(). It turns out that it had been def'd to ignore the flags passed to it in the second arg anyway. Gotta love that. |
1593 |
free(v); |
1
by brian
clean slate |
1594 |
}
|
1595 |
||
1596 |
||
1597 |
VAR* var_from_env(const char *name, const char *def_val) |
|
1598 |
{
|
|
1599 |
const char *tmp; |
|
1600 |
VAR *v; |
|
1601 |
if (!(tmp = getenv(name))) |
|
1602 |
tmp = def_val; |
|
1603 |
||
1604 |
v = var_init(0, name, strlen(name), tmp, strlen(tmp)); |
|
481
by Brian Aker
Remove all of uchar. |
1605 |
my_hash_insert(&var_hash, (unsigned char*)v); |
1
by brian
clean slate |
1606 |
return v; |
1607 |
}
|
|
1608 |
||
1609 |
||
143
by Brian Aker
Bool cleanup. |
1610 |
VAR* var_get(const char *var_name, const char **var_name_end, bool raw, |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
1611 |
bool ignore_not_existing) |
1
by brian
clean slate |
1612 |
{
|
1613 |
int digit; |
|
1614 |
VAR *v; |
|
1615 |
||
1616 |
if (*var_name != '$') |
|
1617 |
goto err; |
|
1618 |
digit = *++var_name - '0'; |
|
1619 |
if (digit < 0 || digit >= 10) |
|
1620 |
{
|
|
1621 |
const char *save_var_name = var_name, *end; |
|
1622 |
uint length; |
|
1623 |
end = (var_name_end) ? *var_name_end : 0; |
|
1624 |
while (my_isvar(charset_info,*var_name) && var_name != end) |
|
1625 |
var_name++; |
|
1626 |
if (var_name == save_var_name) |
|
1627 |
{
|
|
1628 |
if (ignore_not_existing) |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
1629 |
return(0); |
1
by brian
clean slate |
1630 |
die("Empty variable"); |
1631 |
}
|
|
1632 |
length= (uint) (var_name - save_var_name); |
|
1633 |
if (length >= MAX_VAR_NAME_LENGTH) |
|
1634 |
die("Too long variable name: %s", save_var_name); |
|
1635 |
||
481
by Brian Aker
Remove all of uchar. |
1636 |
if (!(v = (VAR*) hash_search(&var_hash, (const unsigned char*) save_var_name, |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
1637 |
length))) |
1
by brian
clean slate |
1638 |
{
|
1639 |
char buff[MAX_VAR_NAME_LENGTH+1]; |
|
1640 |
strmake(buff, save_var_name, length); |
|
1641 |
v= var_from_env(buff, ""); |
|
1642 |
}
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
1643 |
var_name--; /* Point at last character */ |
1
by brian
clean slate |
1644 |
}
|
1645 |
else
|
|
1646 |
v = var_reg + digit; |
|
1647 |
||
1648 |
if (!raw && v->int_dirty) |
|
1649 |
{
|
|
1650 |
sprintf(v->str_val, "%d", v->int_val); |
|
1651 |
v->int_dirty = 0; |
|
1652 |
v->str_val_len = strlen(v->str_val); |
|
1653 |
}
|
|
1654 |
if (var_name_end) |
|
1655 |
*var_name_end = var_name ; |
|
142.1.1
by Patrick
Removing DBUG from client |
1656 |
return(v); |
1
by brian
clean slate |
1657 |
err: |
1658 |
if (var_name_end) |
|
1659 |
*var_name_end = 0; |
|
1660 |
die("Unsupported variable name: %s", var_name); |
|
142.1.1
by Patrick
Removing DBUG from client |
1661 |
return(0); |
1
by brian
clean slate |
1662 |
}
|
1663 |
||
1664 |
||
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
1665 |
static VAR *var_obtain(const char *name, int len) |
1
by brian
clean slate |
1666 |
{
|
1667 |
VAR* v; |
|
481
by Brian Aker
Remove all of uchar. |
1668 |
if ((v = (VAR*)hash_search(&var_hash, (const unsigned char *) name, len))) |
1
by brian
clean slate |
1669 |
return v; |
1670 |
v = var_init(0, name, len, "", 0); |
|
481
by Brian Aker
Remove all of uchar. |
1671 |
my_hash_insert(&var_hash, (unsigned char*)v); |
1
by brian
clean slate |
1672 |
return v; |
1673 |
}
|
|
1674 |
||
1675 |
||
1676 |
/*
|
|
1677 |
- if variable starts with a $ it is regarded as a local test varable
|
|
1678 |
- if not it is treated as a environment variable, and the corresponding
|
|
1679 |
environment variable will be updated
|
|
1680 |
*/
|
|
1681 |
||
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
1682 |
static void var_set(const char *var_name, const char *var_name_end, |
1683 |
const char *var_val, const char *var_val_end) |
|
1
by brian
clean slate |
1684 |
{
|
1685 |
int digit, env_var= 0; |
|
1686 |
VAR *v; |
|
1687 |
||
1688 |
if (*var_name != '$') |
|
1689 |
env_var= 1; |
|
1690 |
else
|
|
1691 |
var_name++; |
|
1692 |
||
1693 |
digit= *var_name - '0'; |
|
1694 |
if (!(digit < 10 && digit >= 0)) |
|
1695 |
{
|
|
1696 |
v= var_obtain(var_name, (uint) (var_name_end - var_name)); |
|
1697 |
}
|
|
1698 |
else
|
|
1699 |
v= var_reg + digit; |
|
1700 |
||
1701 |
eval_expr(v, var_val, (const char**) &var_val_end); |
|
1702 |
||
1703 |
if (env_var) |
|
1704 |
{
|
|
1705 |
char buf[1024], *old_env_s= v->env_s; |
|
1706 |
if (v->int_dirty) |
|
1707 |
{
|
|
1708 |
sprintf(v->str_val, "%d", v->int_val); |
|
1709 |
v->int_dirty= 0; |
|
1710 |
v->str_val_len= strlen(v->str_val); |
|
1711 |
}
|
|
77.1.18
by Monty Taylor
Removed my_vsnprintf and my_snprintf. |
1712 |
snprintf(buf, sizeof(buf), "%.*s=%.*s", |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
1713 |
v->name_len, v->name, |
1714 |
v->str_val_len, v->str_val); |
|
1
by brian
clean slate |
1715 |
if (!(v->env_s= my_strdup(buf, MYF(MY_WME)))) |
1716 |
die("Out of memory"); |
|
1717 |
putenv(v->env_s); |
|
477
by Monty Taylor
Removed my_free(). It turns out that it had been def'd to ignore the flags passed to it in the second arg anyway. Gotta love that. |
1718 |
free(old_env_s); |
1
by brian
clean slate |
1719 |
}
|
142.1.1
by Patrick
Removing DBUG from client |
1720 |
return; |
1
by brian
clean slate |
1721 |
}
|
1722 |
||
1723 |
||
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
1724 |
static void var_set_string(const char* name, const char* value) |
1
by brian
clean slate |
1725 |
{
|
1726 |
var_set(name, name + strlen(name), value, value + strlen(value)); |
|
1727 |
}
|
|
1728 |
||
1729 |
||
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
1730 |
static void var_set_int(const char* name, int value) |
1
by brian
clean slate |
1731 |
{
|
1732 |
char buf[21]; |
|
77.1.18
by Monty Taylor
Removed my_vsnprintf and my_snprintf. |
1733 |
snprintf(buf, sizeof(buf), "%d", value); |
1
by brian
clean slate |
1734 |
var_set_string(name, buf); |
1735 |
}
|
|
1736 |
||
1737 |
||
1738 |
/*
|
|
1739 |
Store an integer (typically the returncode of the last SQL)
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
1740 |
statement in the drizzletest builtin variable $drizzle_errno
|
1
by brian
clean slate |
1741 |
*/
|
1742 |
||
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
1743 |
static void var_set_errno(int sql_errno) |
1
by brian
clean slate |
1744 |
{
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
1745 |
var_set_int("$drizzle_errno", sql_errno); |
1
by brian
clean slate |
1746 |
}
|
1747 |
||
1748 |
||
1749 |
/*
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
1750 |
Update $drizzle_get_server_version variable with version
|
1
by brian
clean slate |
1751 |
of the currently connected server
|
1752 |
*/
|
|
1753 |
||
206.3.1
by Patrick Galbraith
Most everything working with client rename |
1754 |
static void var_set_drizzle_get_server_version(DRIZZLE *drizzle) |
1
by brian
clean slate |
1755 |
{
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
1756 |
var_set_int("$drizzle_get_server_version", drizzle_get_server_version(drizzle)); |
1
by brian
clean slate |
1757 |
}
|
1758 |
||
1759 |
||
1760 |
/*
|
|
1761 |
Set variable from the result of a query
|
|
1762 |
||
1763 |
SYNOPSIS
|
|
1764 |
var_query_set()
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
1765 |
var variable to set from query
|
1
by brian
clean slate |
1766 |
query start of query string to execute
|
1767 |
query_end end of the query string to execute
|
|
1768 |
||
1769 |
||
1770 |
DESCRIPTION
|
|
1771 |
let @<var_name> = `<query>`
|
|
1772 |
||
1773 |
Execute the query and assign the first row of result to var as
|
|
1774 |
a tab separated strings
|
|
1775 |
||
1776 |
Also assign each column of the result set to
|
|
1777 |
variable "$<var_name>_<column_name>"
|
|
1778 |
Thus the tab separated output can be read from $<var_name> and
|
|
1779 |
and each individual column can be read as $<var_name>_<col_name>
|
|
1780 |
||
1781 |
*/
|
|
1782 |
||
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
1783 |
static void var_query_set(VAR *var, const char *query, const char** query_end) |
1
by brian
clean slate |
1784 |
{
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
1785 |
const char *end = (char*)((query_end && *query_end) ? |
1786 |
*query_end : query + strlen(query)); |
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
1787 |
DRIZZLE_RES *res; |
1788 |
DRIZZLE_ROW row; |
|
1789 |
DRIZZLE *drizzle= &cur_con->drizzle; |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
1790 |
string ds_query; |
142.1.1
by Patrick
Removing DBUG from client |
1791 |
|
1
by brian
clean slate |
1792 |
|
1793 |
while (end > query && *end != '`') |
|
1794 |
--end; |
|
1795 |
if (query == end) |
|
1796 |
die("Syntax error in query, missing '`'"); |
|
1797 |
++query; |
|
1798 |
||
1799 |
/* Eval the query, thus replacing all environment variables */
|
|
163
by Brian Aker
Merge Monty's code. |
1800 |
do_eval(&ds_query, query, end, false); |
1
by brian
clean slate |
1801 |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
1802 |
if (drizzle_real_query(drizzle, ds_query.c_str(), ds_query.length())) |
1803 |
die("Error running query '%s': %d %s", ds_query.c_str(), |
|
1804 |
drizzle_errno(drizzle), drizzle_error(drizzle)); |
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
1805 |
if (!(res= drizzle_store_result(drizzle))) |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
1806 |
die("Query '%s' didn't return a result set", ds_query.c_str()); |
1
by brian
clean slate |
1807 |
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
1808 |
if ((row= drizzle_fetch_row(res)) && row[0]) |
1
by brian
clean slate |
1809 |
{
|
1810 |
/*
|
|
1811 |
Concatenate all fields in the first row with tab in between
|
|
1812 |
and assign that string to the $variable
|
|
1813 |
*/
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
1814 |
string result; |
164
by Brian Aker
Commit cleanup of export types. |
1815 |
uint32_t i; |
1816 |
uint32_t *lengths; |
|
1
by brian
clean slate |
1817 |
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
1818 |
lengths= drizzle_fetch_lengths(res); |
1819 |
for (i= 0; i < drizzle_num_fields(res); i++) |
|
1
by brian
clean slate |
1820 |
{
|
1821 |
if (row[i]) |
|
1822 |
{
|
|
1823 |
/* Add column to tab separated string */
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
1824 |
result.append(row[i], lengths[i]); |
1
by brian
clean slate |
1825 |
}
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
1826 |
result.append("\t", 1); |
1
by brian
clean slate |
1827 |
}
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
1828 |
end= result.c_str() + result.length()-1; |
1829 |
eval_expr(var, result.c_str(), (const char**) &end); |
|
1
by brian
clean slate |
1830 |
}
|
1831 |
else
|
|
1832 |
eval_expr(var, "", 0); |
|
1833 |
||
206.3.1
by Patrick Galbraith
Most everything working with client rename |
1834 |
drizzle_free_result(res); |
142.1.1
by Patrick
Removing DBUG from client |
1835 |
return; |
1
by brian
clean slate |
1836 |
}
|
1837 |
||
1838 |
||
1839 |
/*
|
|
1840 |
Set variable from the result of a field in a query
|
|
1841 |
||
1842 |
This function is useful when checking for a certain value
|
|
1843 |
in the output from a query that can't be restricted to only
|
|
1844 |
return some values. A very good example of that is most SHOW
|
|
1845 |
commands.
|
|
1846 |
||
1847 |
SYNOPSIS
|
|
1848 |
var_set_query_get_value()
|
|
1849 |
||
1850 |
DESCRIPTION
|
|
1851 |
let $variable= query_get_value(<query to run>,<column name>,<row no>);
|
|
1852 |
||
1853 |
<query to run> - The query that should be sent to the server
|
|
1854 |
<column name> - Name of the column that holds the field be compared
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
1855 |
against the expected value
|
1
by brian
clean slate |
1856 |
<row no> - Number of the row that holds the field to be
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
1857 |
compared against the expected value
|
1
by brian
clean slate |
1858 |
|
1859 |
*/
|
|
1860 |
||
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
1861 |
static void var_set_query_get_value(struct st_command *command, VAR *var) |
1
by brian
clean slate |
1862 |
{
|
1863 |
long row_no; |
|
1864 |
int col_no= -1; |
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
1865 |
DRIZZLE_RES* res; |
1866 |
DRIZZLE *drizzle= &cur_con->drizzle; |
|
1
by brian
clean slate |
1867 |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
1868 |
string ds_query; |
1869 |
string ds_col; |
|
1870 |
string ds_row; |
|
1
by brian
clean slate |
1871 |
const struct command_arg query_get_value_args[] = { |
163
by Brian Aker
Merge Monty's code. |
1872 |
{"query", ARG_STRING, true, &ds_query, "Query to run"}, |
1873 |
{"column name", ARG_STRING, true, &ds_col, "Name of column"}, |
|
1874 |
{"row number", ARG_STRING, true, &ds_row, "Number for row"} |
|
1
by brian
clean slate |
1875 |
};
|
1876 |
||
142.1.1
by Patrick
Removing DBUG from client |
1877 |
|
1
by brian
clean slate |
1878 |
|
1879 |
strip_parentheses(command); |
|
1880 |
check_command_args(command, command->first_argument, query_get_value_args, |
|
1881 |
sizeof(query_get_value_args)/sizeof(struct command_arg), |
|
1882 |
','); |
|
1883 |
||
1884 |
/* Convert row number to int */
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
1885 |
if (!str2int(ds_row.c_str(), 10, (long) 0, (long) INT_MAX, &row_no)) |
1886 |
die("Invalid row number: '%s'", ds_row.c_str()); |
|
1
by brian
clean slate |
1887 |
|
1888 |
/* Remove any surrounding "'s from the query - if there is any */
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
1889 |
// (Don't get me started on this)
|
1890 |
char * unstripped_query= strdup(ds_query.c_str()); |
|
1891 |
if (strip_surrounding(unstripped_query, '"', '"')) |
|
1892 |
die("Mismatched \"'s around query '%s'", ds_query.c_str()); |
|
1893 |
ds_query= unstripped_query; |
|
1
by brian
clean slate |
1894 |
|
1895 |
/* Run the query */
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
1896 |
if (drizzle_real_query(drizzle, ds_query.c_str(), ds_query.length())) |
1897 |
die("Error running query '%s': %d %s", ds_query.c_str(), |
|
1898 |
drizzle_errno(drizzle), drizzle_error(drizzle)); |
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
1899 |
if (!(res= drizzle_store_result(drizzle))) |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
1900 |
die("Query '%s' didn't return a result set", ds_query.c_str()); |
1
by brian
clean slate |
1901 |
|
1902 |
{
|
|
1903 |
/* Find column number from the given column name */
|
|
1904 |
uint i; |
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
1905 |
uint num_fields= drizzle_num_fields(res); |
236.3.5
by Andrey Hristov
Constify libdrizzle functions |
1906 |
const DRIZZLE_FIELD *fields= drizzle_fetch_fields(res); |
1
by brian
clean slate |
1907 |
|
1908 |
for (i= 0; i < num_fields; i++) |
|
1909 |
{
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
1910 |
if (strcmp(fields[i].name, ds_col.c_str()) == 0 && |
1911 |
strlen(fields[i].name) == ds_col.length()) |
|
1
by brian
clean slate |
1912 |
{
|
1913 |
col_no= i; |
|
1914 |
break; |
|
1915 |
}
|
|
1916 |
}
|
|
1917 |
if (col_no == -1) |
|
1918 |
{
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
1919 |
drizzle_free_result(res); |
1
by brian
clean slate |
1920 |
die("Could not find column '%s' in the result of '%s'", |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
1921 |
ds_col.c_str(), ds_query.c_str()); |
1
by brian
clean slate |
1922 |
}
|
1923 |
}
|
|
1924 |
||
1925 |
{
|
|
1926 |
/* Get the value */
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
1927 |
DRIZZLE_ROW row; |
1
by brian
clean slate |
1928 |
long rows= 0; |
1929 |
const char* value= "No such row"; |
|
1930 |
||
206.3.1
by Patrick Galbraith
Most everything working with client rename |
1931 |
while ((row= drizzle_fetch_row(res))) |
1
by brian
clean slate |
1932 |
{
|
1933 |
if (++rows == row_no) |
|
1934 |
{
|
|
1935 |
||
1936 |
/* Found the row to get */
|
|
1937 |
if (row[col_no]) |
|
1938 |
value= row[col_no]; |
|
1939 |
else
|
|
1940 |
value= "NULL"; |
|
1941 |
||
1942 |
break; |
|
1943 |
}
|
|
1944 |
}
|
|
1945 |
eval_expr(var, value, 0); |
|
1946 |
}
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
1947 |
drizzle_free_result(res); |
1
by brian
clean slate |
1948 |
|
142.1.1
by Patrick
Removing DBUG from client |
1949 |
return; |
1
by brian
clean slate |
1950 |
}
|
1951 |
||
1952 |
||
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
1953 |
static void var_copy(VAR *dest, VAR *src) |
1
by brian
clean slate |
1954 |
{
|
1955 |
dest->int_val= src->int_val; |
|
1956 |
dest->int_dirty= src->int_dirty; |
|
1957 |
||
1958 |
/* Alloc/realloc data for str_val in dest */
|
|
1959 |
if (dest->alloced_len < src->alloced_len && |
|
1960 |
!(dest->str_val= dest->str_val |
|
77.1.31
by Monty Taylor
Replaced regex lib with pcre. Reworked mysqltest to use it. |
1961 |
? (char *)my_realloc(dest->str_val, src->alloced_len, MYF(MY_WME)) |
1962 |
: (char *)my_malloc(src->alloced_len, MYF(MY_WME)))) |
|
1
by brian
clean slate |
1963 |
die("Out of memory"); |
1964 |
else
|
|
1965 |
dest->alloced_len= src->alloced_len; |
|
1966 |
||
1967 |
/* Copy str_val data to dest */
|
|
1968 |
dest->str_val_len= src->str_val_len; |
|
1969 |
if (src->str_val_len) |
|
1970 |
memcpy(dest->str_val, src->str_val, src->str_val_len); |
|
1971 |
}
|
|
1972 |
||
1973 |
||
1974 |
void eval_expr(VAR *v, const char *p, const char **p_end) |
|
1975 |
{
|
|
1976 |
if (*p == '$') |
|
1977 |
{
|
|
1978 |
VAR *vp; |
|
1979 |
if ((vp= var_get(p, p_end, 0, 0))) |
|
1980 |
var_copy(v, vp); |
|
142.1.1
by Patrick
Removing DBUG from client |
1981 |
return; |
1
by brian
clean slate |
1982 |
}
|
1983 |
||
1984 |
if (*p == '`') |
|
1985 |
{
|
|
1986 |
var_query_set(v, p, p_end); |
|
142.1.1
by Patrick
Removing DBUG from client |
1987 |
return; |
1
by brian
clean slate |
1988 |
}
|
1989 |
||
1990 |
{
|
|
1991 |
/* Check if this is a "let $var= query_get_value()" */
|
|
1992 |
const char* get_value_str= "query_get_value"; |
|
1993 |
const size_t len= strlen(get_value_str); |
|
1994 |
if (strncmp(p, get_value_str, len)==0) |
|
1995 |
{
|
|
1996 |
struct st_command command; |
|
1997 |
memset(&command, 0, sizeof(command)); |
|
1998 |
command.query= (char*)p; |
|
1999 |
command.first_word_len= len; |
|
2000 |
command.first_argument= command.query + len; |
|
2001 |
command.end= (char*)*p_end; |
|
2002 |
var_set_query_get_value(&command, v); |
|
142.1.1
by Patrick
Removing DBUG from client |
2003 |
return; |
1
by brian
clean slate |
2004 |
}
|
2005 |
}
|
|
2006 |
||
2007 |
{
|
|
2008 |
int new_val_len = (p_end && *p_end) ? |
|
2009 |
(int) (*p_end - p) : (int) strlen(p); |
|
2010 |
if (new_val_len + 1 >= v->alloced_len) |
|
2011 |
{
|
|
2012 |
static int MIN_VAR_ALLOC= 32; |
|
2013 |
v->alloced_len = (new_val_len < MIN_VAR_ALLOC - 1) ? |
|
2014 |
MIN_VAR_ALLOC : new_val_len + 1; |
|
2015 |
if (!(v->str_val = |
|
77.1.31
by Monty Taylor
Replaced regex lib with pcre. Reworked mysqltest to use it. |
2016 |
v->str_val ? (char *)my_realloc(v->str_val, v->alloced_len+1, |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
2017 |
MYF(MY_WME)) : |
77.1.31
by Monty Taylor
Replaced regex lib with pcre. Reworked mysqltest to use it. |
2018 |
(char *)my_malloc(v->alloced_len+1, MYF(MY_WME)))) |
1
by brian
clean slate |
2019 |
die("Out of memory"); |
2020 |
}
|
|
2021 |
v->str_val_len = new_val_len; |
|
2022 |
memcpy(v->str_val, p, new_val_len); |
|
2023 |
v->str_val[new_val_len] = 0; |
|
2024 |
v->int_val=atoi(p); |
|
2025 |
v->int_dirty=0; |
|
2026 |
}
|
|
142.1.1
by Patrick
Removing DBUG from client |
2027 |
return; |
1
by brian
clean slate |
2028 |
}
|
2029 |
||
2030 |
||
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
2031 |
static int open_file(const char *name) |
1
by brian
clean slate |
2032 |
{
|
2033 |
char buff[FN_REFLEN]; |
|
142.1.1
by Patrick
Removing DBUG from client |
2034 |
|
1
by brian
clean slate |
2035 |
if (!test_if_hard_path(name)) |
2036 |
{
|
|
461
by Monty Taylor
Removed NullS. bu-bye. |
2037 |
strxmov(buff, opt_basedir, name, NULL); |
1
by brian
clean slate |
2038 |
name=buff; |
2039 |
}
|
|
2040 |
fn_format(buff, name, "", "", MY_UNPACK_FILENAME); |
|
2041 |
||
2042 |
if (cur_file == file_stack_end) |
|
2043 |
die("Source directives are nesting too deep"); |
|
2044 |
cur_file++; |
|
492.1.15
by Monty Taylor
Missed a FILE_BINARY |
2045 |
if (!(cur_file->file = my_fopen(buff, O_RDONLY, MYF(0)))) |
1
by brian
clean slate |
2046 |
{
|
2047 |
cur_file--; |
|
2048 |
die("Could not open '%s' for reading", buff); |
|
2049 |
}
|
|
2050 |
cur_file->file_name= my_strdup(buff, MYF(MY_FAE)); |
|
2051 |
cur_file->lineno=1; |
|
142.1.1
by Patrick
Removing DBUG from client |
2052 |
return(0); |
1
by brian
clean slate |
2053 |
}
|
2054 |
||
2055 |
||
2056 |
/*
|
|
2057 |
Source and execute the given file
|
|
2058 |
||
2059 |
SYNOPSIS
|
|
2060 |
do_source()
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
2061 |
query called command
|
1
by brian
clean slate |
2062 |
|
2063 |
DESCRIPTION
|
|
2064 |
source <file_name>
|
|
2065 |
||
2066 |
Open the file <file_name> and execute it
|
|
2067 |
||
2068 |
*/
|
|
2069 |
||
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
2070 |
static void do_source(struct st_command *command) |
1
by brian
clean slate |
2071 |
{
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
2072 |
string ds_filename; |
1
by brian
clean slate |
2073 |
const struct command_arg source_args[] = { |
163
by Brian Aker
Merge Monty's code. |
2074 |
{ "filename", ARG_STRING, true, &ds_filename, "File to source" } |
1
by brian
clean slate |
2075 |
};
|
142.1.1
by Patrick
Removing DBUG from client |
2076 |
|
1
by brian
clean slate |
2077 |
|
2078 |
check_command_args(command, command->first_argument, source_args, |
|
2079 |
sizeof(source_args)/sizeof(struct command_arg), |
|
2080 |
' '); |
|
2081 |
||
2082 |
/*
|
|
2083 |
If this file has already been sourced, don't source it again.
|
|
2084 |
It's already available in the q_lines cache.
|
|
2085 |
*/
|
|
2086 |
if (parser.current_line < (parser.read_lines - 1)) |
|
2087 |
; /* Do nothing */ |
|
2088 |
else
|
|
2089 |
{
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
2090 |
open_file(ds_filename.c_str()); |
1
by brian
clean slate |
2091 |
}
|
2092 |
||
2093 |
return; |
|
2094 |
}
|
|
2095 |
||
2096 |
||
2097 |
static void init_builtin_echo(void) |
|
2098 |
{
|
|
2099 |
builtin_echo[0]= 0; |
|
2100 |
return; |
|
2101 |
}
|
|
2102 |
||
2103 |
||
2104 |
/*
|
|
2105 |
Replace a substring
|
|
2106 |
||
2107 |
SYNOPSIS
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
2108 |
replace
|
2109 |
ds_str The string to search and perform the replace in
|
|
2110 |
search_str The string to search for
|
|
2111 |
search_len Length of the string to search for
|
|
2112 |
replace_str The string to replace with
|
|
2113 |
replace_len Length of the string to replace with
|
|
1
by brian
clean slate |
2114 |
|
2115 |
RETURN
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
2116 |
0 String replaced
|
2117 |
1 Could not find search_str in str
|
|
1
by brian
clean slate |
2118 |
*/
|
2119 |
||
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
2120 |
static int replace(string *ds_str, |
297
by Brian Aker
Final ulong cleanup in clients |
2121 |
const char *search_str, uint32_t search_len, |
2122 |
const char *replace_str, uint32_t replace_len) |
|
1
by brian
clean slate |
2123 |
{
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
2124 |
string ds_tmp; |
2125 |
const char *start= strstr(ds_str->c_str(), search_str); |
|
1
by brian
clean slate |
2126 |
if (!start) |
2127 |
return 1; |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
2128 |
ds_tmp.append(ds_str->c_str(), start - ds_str->c_str()); |
2129 |
ds_tmp.append(replace_str, replace_len); |
|
2130 |
ds_tmp.append(start + search_len); |
|
2131 |
*ds_str= ds_tmp; |
|
1
by brian
clean slate |
2132 |
return 0; |
2133 |
}
|
|
2134 |
||
2135 |
||
2136 |
/*
|
|
2137 |
Execute given command.
|
|
2138 |
||
2139 |
SYNOPSIS
|
|
2140 |
do_exec()
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
2141 |
query called command
|
1
by brian
clean slate |
2142 |
|
2143 |
DESCRIPTION
|
|
2144 |
exec <command>
|
|
2145 |
||
2146 |
Execute the text between exec and end of line in a subprocess.
|
|
2147 |
The error code returned from the subprocess is checked against the
|
|
2148 |
expected error array, previously set with the --error command.
|
|
2149 |
It can thus be used to execute a command that shall fail.
|
|
2150 |
||
2151 |
NOTE
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
2152 |
Although drizzletest is executed from cygwin shell, the command will be
|
1
by brian
clean slate |
2153 |
executed in "cmd.exe". Thus commands like "rm" etc can NOT be used, use
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
2154 |
drizzletest commmand(s) like "remove_file" for that
|
1
by brian
clean slate |
2155 |
*/
|
2156 |
||
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
2157 |
static void do_exec(struct st_command *command) |
1
by brian
clean slate |
2158 |
{
|
2159 |
int error; |
|
2160 |
char buf[512]; |
|
2161 |
FILE *res_file; |
|
2162 |
char *cmd= command->first_argument; |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
2163 |
string ds_cmd; |
1
by brian
clean slate |
2164 |
|
2165 |
/* Skip leading space */
|
|
2166 |
while (*cmd && my_isspace(charset_info, *cmd)) |
|
2167 |
cmd++; |
|
2168 |
if (!*cmd) |
|
2169 |
die("Missing argument in exec"); |
|
2170 |
command->last_argument= command->end; |
|
2171 |
||
2172 |
/* Eval the command, thus replacing all environment variables */
|
|
2173 |
do_eval(&ds_cmd, cmd, command->end, !is_windows); |
|
2174 |
||
2175 |
/* Check if echo should be replaced with "builtin" echo */
|
|
2176 |
if (builtin_echo[0] && strncmp(cmd, "echo", 4) == 0) |
|
2177 |
{
|
|
2178 |
/* Replace echo with our "builtin" echo */
|
|
2179 |
replace(&ds_cmd, "echo", 4, builtin_echo, strlen(builtin_echo)); |
|
2180 |
}
|
|
2181 |
||
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
2182 |
if (!(res_file= popen(ds_cmd.c_str(), "r")) && command->abort_on_error) |
1
by brian
clean slate |
2183 |
{
|
2184 |
die("popen(\"%s\", \"r\") failed", command->first_argument); |
|
2185 |
}
|
|
2186 |
||
2187 |
while (fgets(buf, sizeof(buf), res_file)) |
|
2188 |
{
|
|
2189 |
if (disable_result_log) |
|
2190 |
{
|
|
2191 |
buf[strlen(buf)-1]=0; |
|
2192 |
}
|
|
2193 |
else
|
|
2194 |
{
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
2195 |
replace_append(&ds_res, buf); |
1
by brian
clean slate |
2196 |
}
|
2197 |
}
|
|
2198 |
error= pclose(res_file); |
|
2199 |
if (error > 0) |
|
2200 |
{
|
|
2201 |
uint status= WEXITSTATUS(error), i; |
|
143
by Brian Aker
Bool cleanup. |
2202 |
bool ok= 0; |
1
by brian
clean slate |
2203 |
|
2204 |
if (command->abort_on_error) |
|
2205 |
{
|
|
2206 |
log_msg("exec of '%s' failed, error: %d, status: %d, errno: %d", |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
2207 |
ds_cmd.c_str(), error, status, errno); |
1
by brian
clean slate |
2208 |
die("command \"%s\" failed", command->first_argument); |
2209 |
}
|
|
2210 |
||
2211 |
for (i= 0; i < command->expected_errors.count; i++) |
|
2212 |
{
|
|
2213 |
if ((command->expected_errors.err[i].type == ERR_ERRNO) && |
|
2214 |
(command->expected_errors.err[i].code.errnum == status)) |
|
2215 |
{
|
|
2216 |
ok= 1; |
|
2217 |
}
|
|
2218 |
}
|
|
2219 |
if (!ok) |
|
2220 |
{
|
|
2221 |
die("command \"%s\" failed with wrong error: %d", |
|
2222 |
command->first_argument, status); |
|
2223 |
}
|
|
2224 |
}
|
|
2225 |
else if (command->expected_errors.err[0].type == ERR_ERRNO && |
|
2226 |
command->expected_errors.err[0].code.errnum != 0) |
|
2227 |
{
|
|
2228 |
/* Error code we wanted was != 0, i.e. not an expected success */
|
|
2229 |
log_msg("exec of '%s failed, error: %d, errno: %d", |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
2230 |
ds_cmd.c_str(), error, errno); |
1
by brian
clean slate |
2231 |
die("command \"%s\" succeeded - should have failed with errno %d...", |
2232 |
command->first_argument, command->expected_errors.err[0].code.errnum); |
|
2233 |
}
|
|
2234 |
||
142.1.1
by Patrick
Removing DBUG from client |
2235 |
return; |
1
by brian
clean slate |
2236 |
}
|
2237 |
||
2238 |
enum enum_operator |
|
2239 |
{
|
|
2240 |
DO_DEC, |
|
2241 |
DO_INC
|
|
2242 |
};
|
|
2243 |
||
2244 |
||
2245 |
/*
|
|
2246 |
Decrease or increase the value of a variable
|
|
2247 |
||
2248 |
SYNOPSIS
|
|
2249 |
do_modify_var()
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
2250 |
query called command
|
1
by brian
clean slate |
2251 |
operator operation to perform on the var
|
2252 |
||
2253 |
DESCRIPTION
|
|
2254 |
dec $var_name
|
|
2255 |
inc $var_name
|
|
2256 |
||
2257 |
*/
|
|
2258 |
||
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
2259 |
static int do_modify_var(struct st_command *command, |
77.1.31
by Monty Taylor
Replaced regex lib with pcre. Reworked mysqltest to use it. |
2260 |
enum enum_operator op) |
1
by brian
clean slate |
2261 |
{
|
2262 |
const char *p= command->first_argument; |
|
2263 |
VAR* v; |
|
2264 |
if (!*p) |
|
2265 |
die("Missing argument to %.*s", command->first_word_len, command->query); |
|
2266 |
if (*p != '$') |
|
2267 |
die("The argument to %.*s must be a variable (start with $)", |
|
2268 |
command->first_word_len, command->query); |
|
2269 |
v= var_get(p, &p, 1, 0); |
|
77.1.31
by Monty Taylor
Replaced regex lib with pcre. Reworked mysqltest to use it. |
2270 |
switch (op) { |
1
by brian
clean slate |
2271 |
case DO_DEC: |
2272 |
v->int_val--; |
|
2273 |
break; |
|
2274 |
case DO_INC: |
|
2275 |
v->int_val++; |
|
2276 |
break; |
|
2277 |
default: |
|
2278 |
die("Invalid operator to do_modify_var"); |
|
2279 |
break; |
|
2280 |
}
|
|
2281 |
v->int_dirty= 1; |
|
2282 |
command->last_argument= (char*)++p; |
|
2283 |
return 0; |
|
2284 |
}
|
|
2285 |
||
2286 |
||
2287 |
/*
|
|
2288 |
SYNOPSIS
|
|
2289 |
do_system
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
2290 |
command called command
|
1
by brian
clean slate |
2291 |
|
2292 |
DESCRIPTION
|
|
2293 |
system <command>
|
|
2294 |
||
2295 |
Eval the query to expand any $variables in the command.
|
|
2296 |
Execute the command with the "system" command.
|
|
2297 |
||
2298 |
*/
|
|
2299 |
||
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
2300 |
static void do_system(struct st_command *command) |
1
by brian
clean slate |
2301 |
{
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
2302 |
string ds_cmd; |
142.1.1
by Patrick
Removing DBUG from client |
2303 |
|
1
by brian
clean slate |
2304 |
|
2305 |
if (strlen(command->first_argument) == 0) |
|
2306 |
die("Missing arguments to system, nothing to do!"); |
|
2307 |
||
2308 |
/* Eval the system command, thus replacing all environment variables */
|
|
2309 |
do_eval(&ds_cmd, command->first_argument, command->end, !is_windows); |
|
2310 |
||
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
2311 |
if (system(ds_cmd.c_str())) |
1
by brian
clean slate |
2312 |
{
|
2313 |
if (command->abort_on_error) |
|
2314 |
die("system command '%s' failed", command->first_argument); |
|
2315 |
||
2316 |
/* If ! abort_on_error, log message and continue */
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
2317 |
ds_res.append("system command '"); |
2318 |
replace_append(&ds_res, command->first_argument); |
|
2319 |
ds_res.append("' failed\n"); |
|
1
by brian
clean slate |
2320 |
}
|
2321 |
||
2322 |
command->last_argument= command->end; |
|
142.1.1
by Patrick
Removing DBUG from client |
2323 |
return; |
1
by brian
clean slate |
2324 |
}
|
2325 |
||
2326 |
||
2327 |
/*
|
|
2328 |
SYNOPSIS
|
|
2329 |
do_remove_file
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
2330 |
command called command
|
1
by brian
clean slate |
2331 |
|
2332 |
DESCRIPTION
|
|
2333 |
remove_file <file_name>
|
|
2334 |
Remove the file <file_name>
|
|
2335 |
*/
|
|
2336 |
||
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
2337 |
static void do_remove_file(struct st_command *command) |
1
by brian
clean slate |
2338 |
{
|
2339 |
int error; |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
2340 |
string ds_filename; |
1
by brian
clean slate |
2341 |
const struct command_arg rm_args[] = { |
163
by Brian Aker
Merge Monty's code. |
2342 |
{ "filename", ARG_STRING, true, &ds_filename, "File to delete" } |
1
by brian
clean slate |
2343 |
};
|
142.1.1
by Patrick
Removing DBUG from client |
2344 |
|
1
by brian
clean slate |
2345 |
|
2346 |
check_command_args(command, command->first_argument, |
|
2347 |
rm_args, sizeof(rm_args)/sizeof(struct command_arg), |
|
2348 |
' '); |
|
2349 |
||
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
2350 |
error= my_delete(ds_filename.c_str(), MYF(0)) != 0; |
1
by brian
clean slate |
2351 |
handle_command_error(command, error); |
142.1.1
by Patrick
Removing DBUG from client |
2352 |
return; |
1
by brian
clean slate |
2353 |
}
|
2354 |
||
2355 |
||
2356 |
/*
|
|
2357 |
SYNOPSIS
|
|
2358 |
do_copy_file
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
2359 |
command command handle
|
1
by brian
clean slate |
2360 |
|
2361 |
DESCRIPTION
|
|
2362 |
copy_file <from_file> <to_file>
|
|
2363 |
Copy <from_file> to <to_file>
|
|
2364 |
||
2365 |
NOTE! Will fail if <to_file> exists
|
|
2366 |
*/
|
|
2367 |
||
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
2368 |
static void do_copy_file(struct st_command *command) |
1
by brian
clean slate |
2369 |
{
|
2370 |
int error; |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
2371 |
string ds_from_file; |
2372 |
string ds_to_file; |
|
1
by brian
clean slate |
2373 |
const struct command_arg copy_file_args[] = { |
163
by Brian Aker
Merge Monty's code. |
2374 |
{ "from_file", ARG_STRING, true, &ds_from_file, "Filename to copy from" }, |
2375 |
{ "to_file", ARG_STRING, true, &ds_to_file, "Filename to copy to" } |
|
1
by brian
clean slate |
2376 |
};
|
142.1.1
by Patrick
Removing DBUG from client |
2377 |
|
1
by brian
clean slate |
2378 |
|
2379 |
check_command_args(command, command->first_argument, |
|
2380 |
copy_file_args, |
|
2381 |
sizeof(copy_file_args)/sizeof(struct command_arg), |
|
2382 |
' '); |
|
2383 |
||
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
2384 |
error= (my_copy(ds_from_file.c_str(), ds_to_file.c_str(), |
1
by brian
clean slate |
2385 |
MYF(MY_DONT_OVERWRITE_FILE)) != 0); |
2386 |
handle_command_error(command, error); |
|
142.1.1
by Patrick
Removing DBUG from client |
2387 |
return; |
1
by brian
clean slate |
2388 |
}
|
2389 |
||
2390 |
||
2391 |
/*
|
|
2392 |
SYNOPSIS
|
|
2393 |
do_chmod_file
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
2394 |
command command handle
|
1
by brian
clean slate |
2395 |
|
2396 |
DESCRIPTION
|
|
2397 |
chmod <octal> <file_name>
|
|
2398 |
Change file permission of <file_name>
|
|
2399 |
||
2400 |
*/
|
|
2401 |
||
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
2402 |
static void do_chmod_file(struct st_command *command) |
1
by brian
clean slate |
2403 |
{
|
2404 |
long mode= 0; |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
2405 |
string ds_mode; |
2406 |
string ds_file; |
|
1
by brian
clean slate |
2407 |
const struct command_arg chmod_file_args[] = { |
206.3.1
by Patrick Galbraith
Most everything working with client rename |
2408 |
{ "mode", ARG_STRING, true, &ds_mode, "Mode of file(octal) ex. 0660"}, |
163
by Brian Aker
Merge Monty's code. |
2409 |
{ "filename", ARG_STRING, true, &ds_file, "Filename of file to modify" } |
1
by brian
clean slate |
2410 |
};
|
142.1.1
by Patrick
Removing DBUG from client |
2411 |
|
1
by brian
clean slate |
2412 |
|
2413 |
check_command_args(command, command->first_argument, |
|
2414 |
chmod_file_args, |
|
2415 |
sizeof(chmod_file_args)/sizeof(struct command_arg), |
|
2416 |
' '); |
|
2417 |
||
2418 |
/* Parse what mode to set */
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
2419 |
if (ds_mode.length() != 4 || |
461
by Monty Taylor
Removed NullS. bu-bye. |
2420 |
str2int(ds_mode.c_str(), 8, 0, INT_MAX, &mode) == NULL) |
1
by brian
clean slate |
2421 |
die("You must write a 4 digit octal number for mode"); |
2422 |
||
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
2423 |
handle_command_error(command, chmod(ds_file.c_str(), mode)); |
142.1.1
by Patrick
Removing DBUG from client |
2424 |
return; |
1
by brian
clean slate |
2425 |
}
|
2426 |
||
2427 |
||
2428 |
/*
|
|
2429 |
SYNOPSIS
|
|
2430 |
do_file_exists
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
2431 |
command called command
|
1
by brian
clean slate |
2432 |
|
2433 |
DESCRIPTION
|
|
2434 |
fiile_exist <file_name>
|
|
2435 |
Check if file <file_name> exists
|
|
2436 |
*/
|
|
2437 |
||
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
2438 |
static void do_file_exist(struct st_command *command) |
1
by brian
clean slate |
2439 |
{
|
2440 |
int error; |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
2441 |
string ds_filename; |
1
by brian
clean slate |
2442 |
const struct command_arg file_exist_args[] = { |
163
by Brian Aker
Merge Monty's code. |
2443 |
{ "filename", ARG_STRING, true, &ds_filename, "File to check if it exist" } |
1
by brian
clean slate |
2444 |
};
|
142.1.1
by Patrick
Removing DBUG from client |
2445 |
|
1
by brian
clean slate |
2446 |
|
2447 |
check_command_args(command, command->first_argument, |
|
2448 |
file_exist_args, |
|
2449 |
sizeof(file_exist_args)/sizeof(struct command_arg), |
|
2450 |
' '); |
|
2451 |
||
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
2452 |
error= (access(ds_filename.c_str(), F_OK) != 0); |
1
by brian
clean slate |
2453 |
handle_command_error(command, error); |
142.1.1
by Patrick
Removing DBUG from client |
2454 |
return; |
1
by brian
clean slate |
2455 |
}
|
2456 |
||
2457 |
||
2458 |
/*
|
|
2459 |
SYNOPSIS
|
|
2460 |
do_mkdir
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
2461 |
command called command
|
1
by brian
clean slate |
2462 |
|
2463 |
DESCRIPTION
|
|
2464 |
mkdir <dir_name>
|
|
2465 |
Create the directory <dir_name>
|
|
2466 |
*/
|
|
2467 |
||
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
2468 |
static void do_mkdir(struct st_command *command) |
1
by brian
clean slate |
2469 |
{
|
2470 |
int error; |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
2471 |
string ds_dirname; |
1
by brian
clean slate |
2472 |
const struct command_arg mkdir_args[] = { |
163
by Brian Aker
Merge Monty's code. |
2473 |
{"dirname", ARG_STRING, true, &ds_dirname, "Directory to create"} |
1
by brian
clean slate |
2474 |
};
|
142.1.1
by Patrick
Removing DBUG from client |
2475 |
|
1
by brian
clean slate |
2476 |
|
2477 |
check_command_args(command, command->first_argument, |
|
2478 |
mkdir_args, sizeof(mkdir_args)/sizeof(struct command_arg), |
|
2479 |
' '); |
|
2480 |
||
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
2481 |
error= my_mkdir(ds_dirname.c_str(), 0777, MYF(0)) != 0; |
1
by brian
clean slate |
2482 |
handle_command_error(command, error); |
142.1.1
by Patrick
Removing DBUG from client |
2483 |
return; |
1
by brian
clean slate |
2484 |
}
|
2485 |
||
2486 |
/*
|
|
2487 |
SYNOPSIS
|
|
2488 |
do_rmdir
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
2489 |
command called command
|
1
by brian
clean slate |
2490 |
|
2491 |
DESCRIPTION
|
|
2492 |
rmdir <dir_name>
|
|
2493 |
Remove the empty directory <dir_name>
|
|
2494 |
*/
|
|
2495 |
||
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
2496 |
static void do_rmdir(struct st_command *command) |
1
by brian
clean slate |
2497 |
{
|
2498 |
int error; |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
2499 |
string ds_dirname; |
1
by brian
clean slate |
2500 |
const struct command_arg rmdir_args[] = { |
163
by Brian Aker
Merge Monty's code. |
2501 |
{"dirname", ARG_STRING, true, &ds_dirname, "Directory to remove"} |
1
by brian
clean slate |
2502 |
};
|
142.1.1
by Patrick
Removing DBUG from client |
2503 |
|
1
by brian
clean slate |
2504 |
|
2505 |
check_command_args(command, command->first_argument, |
|
2506 |
rmdir_args, sizeof(rmdir_args)/sizeof(struct command_arg), |
|
2507 |
' '); |
|
2508 |
||
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
2509 |
error= rmdir(ds_dirname.c_str()) != 0; |
1
by brian
clean slate |
2510 |
handle_command_error(command, error); |
142.1.1
by Patrick
Removing DBUG from client |
2511 |
return; |
1
by brian
clean slate |
2512 |
}
|
2513 |
||
2514 |
||
2515 |
/*
|
|
2516 |
Read characters from line buffer or file. This is needed to allow
|
|
2517 |
my_ungetc() to buffer MAX_DELIMITER_LENGTH characters for a file
|
|
2518 |
||
2519 |
NOTE:
|
|
2520 |
This works as long as one doesn't change files (with 'source file_name')
|
|
2521 |
when there is things pushed into the buffer. This should however not
|
|
2522 |
happen for any tests in the test suite.
|
|
2523 |
*/
|
|
2524 |
||
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
2525 |
static int my_getc(FILE *file) |
1
by brian
clean slate |
2526 |
{
|
2527 |
if (line_buffer_pos == line_buffer) |
|
2528 |
return fgetc(file); |
|
2529 |
return *--line_buffer_pos; |
|
2530 |
}
|
|
2531 |
||
2532 |
||
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
2533 |
static void my_ungetc(int c) |
1
by brian
clean slate |
2534 |
{
|
2535 |
*line_buffer_pos++= (char) c; |
|
2536 |
}
|
|
2537 |
||
2538 |
||
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
2539 |
static void read_until_delimiter(string *ds, |
2540 |
string *ds_delimiter) |
|
1
by brian
clean slate |
2541 |
{
|
2542 |
char c; |
|
2543 |
||
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
2544 |
if (ds_delimiter->length() > MAX_DELIMITER_LENGTH) |
1
by brian
clean slate |
2545 |
die("Max delimiter length(%d) exceeded", MAX_DELIMITER_LENGTH); |
2546 |
||
2547 |
/* Read from file until delimiter is found */
|
|
2548 |
while (1) |
|
2549 |
{
|
|
2550 |
c= my_getc(cur_file->file); |
|
2551 |
||
2552 |
if (c == '\n') |
|
2553 |
{
|
|
2554 |
cur_file->lineno++; |
|
2555 |
||
2556 |
/* Skip newline from the same line as the command */
|
|
2557 |
if (start_lineno == (cur_file->lineno - 1)) |
|
2558 |
continue; |
|
2559 |
}
|
|
2560 |
else if (start_lineno == cur_file->lineno) |
|
2561 |
{
|
|
2562 |
/*
|
|
2563 |
No characters except \n are allowed on
|
|
2564 |
the same line as the command
|
|
2565 |
*/
|
|
2566 |
die("Trailing characters found after command"); |
|
2567 |
}
|
|
2568 |
||
2569 |
if (feof(cur_file->file)) |
|
2570 |
die("End of file encountered before '%s' delimiter was found", |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
2571 |
ds_delimiter->c_str()); |
1
by brian
clean slate |
2572 |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
2573 |
if (match_delimiter(c, ds_delimiter->c_str(), ds_delimiter->length())) |
1
by brian
clean slate |
2574 |
break; |
142.1.1
by Patrick
Removing DBUG from client |
2575 |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
2576 |
ds->push_back(c); |
1
by brian
clean slate |
2577 |
}
|
142.1.1
by Patrick
Removing DBUG from client |
2578 |
return; |
1
by brian
clean slate |
2579 |
}
|
2580 |
||
2581 |
||
143
by Brian Aker
Bool cleanup. |
2582 |
static void do_write_file_command(struct st_command *command, bool append) |
1
by brian
clean slate |
2583 |
{
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
2584 |
string ds_content; |
2585 |
string ds_filename; |
|
2586 |
string ds_delimiter; |
|
1
by brian
clean slate |
2587 |
const struct command_arg write_file_args[] = { |
163
by Brian Aker
Merge Monty's code. |
2588 |
{ "filename", ARG_STRING, true, &ds_filename, "File to write to" }, |
2589 |
{ "delimiter", ARG_STRING, false, &ds_delimiter, "Delimiter to read until" } |
|
1
by brian
clean slate |
2590 |
};
|
142.1.1
by Patrick
Removing DBUG from client |
2591 |
|
1
by brian
clean slate |
2592 |
|
2593 |
check_command_args(command, |
|
2594 |
command->first_argument, |
|
2595 |
write_file_args, |
|
2596 |
sizeof(write_file_args)/sizeof(struct command_arg), |
|
2597 |
' '); |
|
2598 |
||
2599 |
/* If no delimiter was provided, use EOF */
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
2600 |
if (ds_delimiter.length() == 0) |
2601 |
ds_delimiter= "EOF"; |
|
1
by brian
clean slate |
2602 |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
2603 |
if (!append && access(ds_filename.c_str(), F_OK) == 0) |
1
by brian
clean slate |
2604 |
{
|
2605 |
/* The file should not be overwritten */
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
2606 |
die("File already exist: '%s'", ds_filename.c_str()); |
1
by brian
clean slate |
2607 |
}
|
2608 |
||
2609 |
read_until_delimiter(&ds_content, &ds_delimiter); |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
2610 |
str_to_file2(ds_filename.c_str(), ds_content.c_str(), |
2611 |
ds_content.length(), append); |
|
142.1.1
by Patrick
Removing DBUG from client |
2612 |
return; |
1
by brian
clean slate |
2613 |
}
|
2614 |
||
2615 |
||
2616 |
/*
|
|
2617 |
SYNOPSIS
|
|
2618 |
do_write_file
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
2619 |
command called command
|
1
by brian
clean slate |
2620 |
|
2621 |
DESCRIPTION
|
|
2622 |
write_file <file_name> [<delimiter>];
|
|
2623 |
<what to write line 1>
|
|
2624 |
<...>
|
|
2625 |
< what to write line n>
|
|
2626 |
EOF
|
|
2627 |
||
2628 |
--write_file <file_name>;
|
|
2629 |
<what to write line 1>
|
|
2630 |
<...>
|
|
2631 |
< what to write line n>
|
|
2632 |
EOF
|
|
2633 |
||
2634 |
Write everything between the "write_file" command and 'delimiter'
|
|
2635 |
to "file_name"
|
|
2636 |
||
2637 |
NOTE! Will fail if <file_name> exists
|
|
2638 |
||
2639 |
Default <delimiter> is EOF
|
|
2640 |
||
2641 |
*/
|
|
2642 |
||
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
2643 |
static void do_write_file(struct st_command *command) |
1
by brian
clean slate |
2644 |
{
|
163
by Brian Aker
Merge Monty's code. |
2645 |
do_write_file_command(command, false); |
1
by brian
clean slate |
2646 |
}
|
2647 |
||
2648 |
||
2649 |
/*
|
|
2650 |
SYNOPSIS
|
|
2651 |
do_append_file
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
2652 |
command called command
|
1
by brian
clean slate |
2653 |
|
2654 |
DESCRIPTION
|
|
2655 |
append_file <file_name> [<delimiter>];
|
|
2656 |
<what to write line 1>
|
|
2657 |
<...>
|
|
2658 |
< what to write line n>
|
|
2659 |
EOF
|
|
2660 |
||
2661 |
--append_file <file_name>;
|
|
2662 |
<what to write line 1>
|
|
2663 |
<...>
|
|
2664 |
< what to write line n>
|
|
2665 |
EOF
|
|
2666 |
||
2667 |
Append everything between the "append_file" command
|
|
2668 |
and 'delimiter' to "file_name"
|
|
2669 |
||
2670 |
Default <delimiter> is EOF
|
|
2671 |
||
2672 |
*/
|
|
2673 |
||
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
2674 |
static void do_append_file(struct st_command *command) |
1
by brian
clean slate |
2675 |
{
|
163
by Brian Aker
Merge Monty's code. |
2676 |
do_write_file_command(command, true); |
1
by brian
clean slate |
2677 |
}
|
2678 |
||
2679 |
||
2680 |
/*
|
|
2681 |
SYNOPSIS
|
|
2682 |
do_cat_file
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
2683 |
command called command
|
1
by brian
clean slate |
2684 |
|
2685 |
DESCRIPTION
|
|
2686 |
cat_file <file_name>;
|
|
2687 |
||
2688 |
Print the given file to result log
|
|
2689 |
||
2690 |
*/
|
|
2691 |
||
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
2692 |
static void do_cat_file(struct st_command *command) |
1
by brian
clean slate |
2693 |
{
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
2694 |
static string ds_filename; |
1
by brian
clean slate |
2695 |
const struct command_arg cat_file_args[] = { |
163
by Brian Aker
Merge Monty's code. |
2696 |
{ "filename", ARG_STRING, true, &ds_filename, "File to read from" } |
1
by brian
clean slate |
2697 |
};
|
142.1.1
by Patrick
Removing DBUG from client |
2698 |
|
1
by brian
clean slate |
2699 |
|
2700 |
check_command_args(command, |
|
2701 |
command->first_argument, |
|
2702 |
cat_file_args, |
|
2703 |
sizeof(cat_file_args)/sizeof(struct command_arg), |
|
2704 |
' '); |
|
2705 |
||
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
2706 |
cat_file(&ds_res, ds_filename.c_str()); |
1
by brian
clean slate |
2707 |
|
142.1.1
by Patrick
Removing DBUG from client |
2708 |
return; |
1
by brian
clean slate |
2709 |
}
|
2710 |
||
2711 |
||
2712 |
/*
|
|
2713 |
SYNOPSIS
|
|
2714 |
do_diff_files
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
2715 |
command called command
|
1
by brian
clean slate |
2716 |
|
2717 |
DESCRIPTION
|
|
2718 |
diff_files <file1> <file2>;
|
|
2719 |
||
2720 |
Fails if the two files differ.
|
|
2721 |
||
2722 |
*/
|
|
2723 |
||
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
2724 |
static void do_diff_files(struct st_command *command) |
1
by brian
clean slate |
2725 |
{
|
2726 |
int error= 0; |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
2727 |
string ds_filename; |
2728 |
string ds_filename2; |
|
1
by brian
clean slate |
2729 |
const struct command_arg diff_file_args[] = { |
163
by Brian Aker
Merge Monty's code. |
2730 |
{ "file1", ARG_STRING, true, &ds_filename, "First file to diff" }, |
2731 |
{ "file2", ARG_STRING, true, &ds_filename2, "Second file to diff" } |
|
1
by brian
clean slate |
2732 |
};
|
142.1.1
by Patrick
Removing DBUG from client |
2733 |
|
1
by brian
clean slate |
2734 |
|
2735 |
check_command_args(command, |
|
2736 |
command->first_argument, |
|
2737 |
diff_file_args, |
|
2738 |
sizeof(diff_file_args)/sizeof(struct command_arg), |
|
2739 |
' '); |
|
2740 |
||
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
2741 |
if ((error= compare_files(ds_filename.c_str(), ds_filename2.c_str()))) |
1
by brian
clean slate |
2742 |
{
|
2743 |
/* Compare of the two files failed, append them to output
|
|
2744 |
so the failure can be analyzed
|
|
2745 |
*/
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
2746 |
show_diff(&ds_res, ds_filename.c_str(), ds_filename2.c_str()); |
1
by brian
clean slate |
2747 |
}
|
2748 |
||
2749 |
handle_command_error(command, error); |
|
142.1.1
by Patrick
Removing DBUG from client |
2750 |
return; |
1
by brian
clean slate |
2751 |
}
|
2752 |
||
2753 |
||
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
2754 |
static struct st_connection * find_connection_by_name(const char *name) |
1
by brian
clean slate |
2755 |
{
|
2756 |
struct st_connection *con; |
|
2757 |
for (con= connections; con < next_con; con++) |
|
2758 |
{
|
|
2759 |
if (!strcmp(con->name, name)) |
|
2760 |
{
|
|
2761 |
return con; |
|
2762 |
}
|
|
2763 |
}
|
|
2764 |
return 0; /* Connection not found */ |
|
2765 |
}
|
|
2766 |
||
2767 |
||
2768 |
/*
|
|
2769 |
SYNOPSIS
|
|
2770 |
do_send_quit
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
2771 |
command called command
|
1
by brian
clean slate |
2772 |
|
2773 |
DESCRIPTION
|
|
2774 |
Sends a simple quit command to the server for the named connection.
|
|
2775 |
||
2776 |
*/
|
|
2777 |
||
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
2778 |
static void do_send_quit(struct st_command *command) |
1
by brian
clean slate |
2779 |
{
|
2780 |
char *p= command->first_argument, *name; |
|
2781 |
struct st_connection *con; |
|
2782 |
||
2783 |
if (!*p) |
|
2784 |
die("Missing connection name in send_quit"); |
|
2785 |
name= p; |
|
2786 |
while (*p && !my_isspace(charset_info,*p)) |
|
2787 |
p++; |
|
2788 |
||
2789 |
if (*p) |
|
2790 |
*p++= 0; |
|
2791 |
command->last_argument= p; |
|
2792 |
||
2793 |
if (!(con= find_connection_by_name(name))) |
|
2794 |
die("connection '%s' not found in connection pool", name); |
|
2795 |
||
206.3.1
by Patrick Galbraith
Most everything working with client rename |
2796 |
simple_command(&con->drizzle,COM_QUIT,0,0,1); |
1
by brian
clean slate |
2797 |
|
142.1.1
by Patrick
Removing DBUG from client |
2798 |
return; |
1
by brian
clean slate |
2799 |
}
|
2800 |
||
2801 |
||
2802 |
/*
|
|
2803 |
SYNOPSIS
|
|
2804 |
do_change_user
|
|
2805 |
command called command
|
|
2806 |
||
2807 |
DESCRIPTION
|
|
2808 |
change_user [<user>], [<passwd>], [<db>]
|
|
2809 |
<user> - user to change to
|
|
2810 |
<passwd> - user password
|
|
2811 |
<db> - default database
|
|
2812 |
||
2813 |
Changes the user and causes the database specified by db to become
|
|
2814 |
the default (current) database for the the current connection.
|
|
2815 |
||
2816 |
*/
|
|
2817 |
||
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
2818 |
static void do_change_user(struct st_command *command) |
1
by brian
clean slate |
2819 |
{
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
2820 |
DRIZZLE *drizzle= &cur_con->drizzle; |
1
by brian
clean slate |
2821 |
/* static keyword to make the NetWare compiler happy. */
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
2822 |
string ds_user, ds_passwd, ds_db; |
1
by brian
clean slate |
2823 |
const struct command_arg change_user_args[] = { |
163
by Brian Aker
Merge Monty's code. |
2824 |
{ "user", ARG_STRING, false, &ds_user, "User to connect as" }, |
2825 |
{ "password", ARG_STRING, false, &ds_passwd, "Password used when connecting" }, |
|
2826 |
{ "database", ARG_STRING, false, &ds_db, "Database to select after connect" }, |
|
1
by brian
clean slate |
2827 |
};
|
2828 |
||
142.1.1
by Patrick
Removing DBUG from client |
2829 |
|
1
by brian
clean slate |
2830 |
|
2831 |
check_command_args(command, command->first_argument, |
|
2832 |
change_user_args, |
|
2833 |
sizeof(change_user_args)/sizeof(struct command_arg), |
|
2834 |
','); |
|
2835 |
||
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
2836 |
if (!ds_user.length()) |
2837 |
ds_user= drizzle->user; |
|
2838 |
||
2839 |
if (!ds_passwd.length()) |
|
2840 |
ds_passwd= drizzle->passwd; |
|
2841 |
||
2842 |
if (!ds_db.length()) |
|
2843 |
ds_db= drizzle->db; |
|
2844 |
||
2845 |
if (drizzle_change_user(drizzle, ds_user.c_str(), |
|
2846 |
ds_passwd.c_str(), ds_db.c_str())) |
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
2847 |
die("change user failed: %s", drizzle_error(drizzle)); |
1
by brian
clean slate |
2848 |
|
2849 |
||
142.1.1
by Patrick
Removing DBUG from client |
2850 |
return; |
1
by brian
clean slate |
2851 |
}
|
2852 |
||
2853 |
||
2854 |
/*
|
|
2855 |
SYNOPSIS
|
|
2856 |
do_perl
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
2857 |
command command handle
|
1
by brian
clean slate |
2858 |
|
2859 |
DESCRIPTION
|
|
2860 |
perl [<delimiter>];
|
|
2861 |
<perlscript line 1>
|
|
2862 |
<...>
|
|
2863 |
<perlscript line n>
|
|
2864 |
EOF
|
|
2865 |
||
2866 |
Execute everything after "perl" until <delimiter> as perl.
|
|
2867 |
Useful for doing more advanced things
|
|
2868 |
but still being able to execute it on all platforms.
|
|
2869 |
||
2870 |
Default <delimiter> is EOF
|
|
2871 |
*/
|
|
2872 |
||
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
2873 |
static void do_perl(struct st_command *command) |
1
by brian
clean slate |
2874 |
{
|
2875 |
int error; |
|
2876 |
File fd; |
|
2877 |
FILE *res_file; |
|
2878 |
char buf[FN_REFLEN]; |
|
2879 |
char temp_file_path[FN_REFLEN]; |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
2880 |
string ds_script; |
2881 |
string ds_delimiter; |
|
1
by brian
clean slate |
2882 |
const struct command_arg perl_args[] = { |
163
by Brian Aker
Merge Monty's code. |
2883 |
{ "delimiter", ARG_STRING, false, &ds_delimiter, "Delimiter to read until" } |
1
by brian
clean slate |
2884 |
};
|
142.1.1
by Patrick
Removing DBUG from client |
2885 |
|
1
by brian
clean slate |
2886 |
|
2887 |
check_command_args(command, |
|
2888 |
command->first_argument, |
|
2889 |
perl_args, |
|
2890 |
sizeof(perl_args)/sizeof(struct command_arg), |
|
2891 |
' '); |
|
2892 |
||
2893 |
/* If no delimiter was provided, use EOF */
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
2894 |
if (ds_delimiter.length() == 0) |
2895 |
ds_delimiter= "EOF"; |
|
1
by brian
clean slate |
2896 |
|
2897 |
read_until_delimiter(&ds_script, &ds_delimiter); |
|
2898 |
||
2899 |
/* Create temporary file name */
|
|
2900 |
if ((fd= create_temp_file(temp_file_path, getenv("MYSQLTEST_VARDIR"), |
|
492.1.13
by Monty Taylor
Removed O_SHARE. I think it was only for OS/2. |
2901 |
"tmp", O_CREAT | O_RDWR, |
1
by brian
clean slate |
2902 |
MYF(MY_WME))) < 0) |
2903 |
die("Failed to create temporary file for perl command"); |
|
2904 |
my_close(fd, MYF(0)); |
|
2905 |
||
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
2906 |
str_to_file(temp_file_path, ds_script.c_str(), ds_script.length()); |
1
by brian
clean slate |
2907 |
|
2908 |
/* Format the "perl <filename>" command */
|
|
77.1.18
by Monty Taylor
Removed my_vsnprintf and my_snprintf. |
2909 |
snprintf(buf, sizeof(buf), "perl %s", temp_file_path); |
1
by brian
clean slate |
2910 |
|
2911 |
if (!(res_file= popen(buf, "r")) && command->abort_on_error) |
|
2912 |
die("popen(\"%s\", \"r\") failed", buf); |
|
2913 |
||
2914 |
while (fgets(buf, sizeof(buf), res_file)) |
|
2915 |
{
|
|
2916 |
if (disable_result_log) |
|
2917 |
buf[strlen(buf)-1]=0; |
|
2918 |
else
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
2919 |
replace_append(&ds_res, buf); |
1
by brian
clean slate |
2920 |
}
|
2921 |
error= pclose(res_file); |
|
2922 |
||
2923 |
/* Remove the temporary file */
|
|
2924 |
my_delete(temp_file_path, MYF(0)); |
|
2925 |
||
2926 |
handle_command_error(command, WEXITSTATUS(error)); |
|
142.1.1
by Patrick
Removing DBUG from client |
2927 |
return; |
1
by brian
clean slate |
2928 |
}
|
2929 |
||
2930 |
||
2931 |
/*
|
|
2932 |
Print the content between echo and <delimiter> to result file.
|
|
2933 |
Evaluate all variables in the string before printing, allow
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
2934 |
for variable names to be escaped using \
|
1
by brian
clean slate |
2935 |
|
2936 |
SYNOPSIS
|
|
2937 |
do_echo()
|
|
2938 |
command called command
|
|
2939 |
||
2940 |
DESCRIPTION
|
|
2941 |
echo text
|
|
2942 |
Print the text after echo until end of command to result file
|
|
2943 |
||
2944 |
echo $<var_name>
|
|
2945 |
Print the content of the variable <var_name> to result file
|
|
2946 |
||
2947 |
echo Some text $<var_name>
|
|
2948 |
Print "Some text" plus the content of the variable <var_name> to
|
|
2949 |
result file
|
|
2950 |
||
2951 |
echo Some text \$<var_name>
|
|
2952 |
Print "Some text" plus $<var_name> to result file
|
|
2953 |
*/
|
|
2954 |
||
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
2955 |
static int do_echo(struct st_command *command) |
1
by brian
clean slate |
2956 |
{
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
2957 |
string ds_echo; |
2958 |
||
2959 |
||
163
by Brian Aker
Merge Monty's code. |
2960 |
do_eval(&ds_echo, command->first_argument, command->end, false); |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
2961 |
ds_res.append(ds_echo.c_str(), ds_echo.length()); |
2962 |
ds_res.append("\n"); |
|
1
by brian
clean slate |
2963 |
command->last_argument= command->end; |
142.1.1
by Patrick
Removing DBUG from client |
2964 |
return(0); |
1
by brian
clean slate |
2965 |
}
|
2966 |
||
2967 |
||
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
2968 |
static void |
2969 |
do_wait_for_slave_to_stop(struct st_command *c __attribute__((unused))) |
|
1
by brian
clean slate |
2970 |
{
|
2971 |
static int SLAVE_POLL_INTERVAL= 300000; |
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
2972 |
DRIZZLE *drizzle= &cur_con->drizzle; |
1
by brian
clean slate |
2973 |
for (;;) |
2974 |
{
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
2975 |
DRIZZLE_RES *res= NULL; |
2976 |
DRIZZLE_ROW row; |
|
1
by brian
clean slate |
2977 |
int done; |
2978 |
||
206.3.1
by Patrick Galbraith
Most everything working with client rename |
2979 |
if (drizzle_query(drizzle,"show status like 'Slave_running'") || |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
2980 |
!(res=drizzle_store_result(drizzle))) |
1
by brian
clean slate |
2981 |
die("Query failed while probing slave for stop: %s", |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
2982 |
drizzle_error(drizzle)); |
206.3.1
by Patrick Galbraith
Most everything working with client rename |
2983 |
if (!(row=drizzle_fetch_row(res)) || !row[1]) |
1
by brian
clean slate |
2984 |
{
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
2985 |
drizzle_free_result(res); |
1
by brian
clean slate |
2986 |
die("Strange result from query while probing slave for stop"); |
2987 |
}
|
|
2988 |
done = !strcmp(row[1],"OFF"); |
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
2989 |
drizzle_free_result(res); |
1
by brian
clean slate |
2990 |
if (done) |
2991 |
break; |
|
2992 |
my_sleep(SLAVE_POLL_INTERVAL); |
|
2993 |
}
|
|
2994 |
return; |
|
2995 |
}
|
|
2996 |
||
2997 |
||
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
2998 |
static void do_sync_with_master2(long offset) |
1
by brian
clean slate |
2999 |
{
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
3000 |
DRIZZLE_RES *res; |
3001 |
DRIZZLE_ROW row; |
|
3002 |
DRIZZLE *drizzle= &cur_con->drizzle; |
|
1
by brian
clean slate |
3003 |
char query_buf[FN_REFLEN+128]; |
3004 |
int tries= 0; |
|
3005 |
||
3006 |
if (!master_pos.file[0]) |
|
3007 |
die("Calling 'sync_with_master' without calling 'save_master_pos'"); |
|
3008 |
||
3009 |
sprintf(query_buf, "select master_pos_wait('%s', %ld)", master_pos.file, |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
3010 |
master_pos.pos + offset); |
1
by brian
clean slate |
3011 |
|
3012 |
wait_for_position: |
|
3013 |
||
206.3.1
by Patrick Galbraith
Most everything working with client rename |
3014 |
if (drizzle_query(drizzle, query_buf)) |
3015 |
die("failed in '%s': %d: %s", query_buf, drizzle_errno(drizzle), |
|
3016 |
drizzle_error(drizzle)); |
|
1
by brian
clean slate |
3017 |
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
3018 |
if (!(res= drizzle_store_result(drizzle))) |
3019 |
die("drizzle_store_result() returned NULL for '%s'", query_buf); |
|
3020 |
if (!(row= drizzle_fetch_row(res))) |
|
1
by brian
clean slate |
3021 |
{
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
3022 |
drizzle_free_result(res); |
1
by brian
clean slate |
3023 |
die("empty result in %s", query_buf); |
3024 |
}
|
|
3025 |
if (!row[0]) |
|
3026 |
{
|
|
3027 |
/*
|
|
3028 |
It may be that the slave SQL thread has not started yet, though START
|
|
3029 |
SLAVE has been issued ?
|
|
3030 |
*/
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
3031 |
drizzle_free_result(res); |
1
by brian
clean slate |
3032 |
if (tries++ == 30) |
3033 |
{
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
3034 |
show_query(drizzle, "SHOW MASTER STATUS"); |
3035 |
show_query(drizzle, "SHOW SLAVE STATUS"); |
|
1
by brian
clean slate |
3036 |
die("could not sync with master ('%s' returned NULL)", query_buf); |
3037 |
}
|
|
3038 |
sleep(1); /* So at most we will wait 30 seconds and make 31 tries */ |
|
3039 |
goto wait_for_position; |
|
3040 |
}
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
3041 |
drizzle_free_result(res); |
1
by brian
clean slate |
3042 |
return; |
3043 |
}
|
|
3044 |
||
3045 |
||
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
3046 |
static void do_sync_with_master(struct st_command *command) |
1
by brian
clean slate |
3047 |
{
|
3048 |
long offset= 0; |
|
3049 |
char *p= command->first_argument; |
|
3050 |
const char *offset_start= p; |
|
3051 |
if (*offset_start) |
|
3052 |
{
|
|
3053 |
for (; my_isdigit(charset_info, *p); p++) |
|
3054 |
offset = offset * 10 + *p - '0'; |
|
3055 |
||
3056 |
if(*p && !my_isspace(charset_info, *p)) |
|
3057 |
die("Invalid integer argument \"%s\"", offset_start); |
|
3058 |
command->last_argument= p; |
|
3059 |
}
|
|
3060 |
do_sync_with_master2(offset); |
|
3061 |
return; |
|
3062 |
}
|
|
3063 |
||
3064 |
||
3065 |
/*
|
|
3066 |
when ndb binlog is on, this call will wait until last updated epoch
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
3067 |
(locally in the drizzled) has been received into the binlog
|
1
by brian
clean slate |
3068 |
*/
|
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
3069 |
static int do_save_master_pos(void) |
1
by brian
clean slate |
3070 |
{
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
3071 |
DRIZZLE_RES *res; |
3072 |
DRIZZLE_ROW row; |
|
3073 |
DRIZZLE *drizzle= &cur_con->drizzle; |
|
1
by brian
clean slate |
3074 |
const char *query; |
142.1.1
by Patrick
Removing DBUG from client |
3075 |
|
1
by brian
clean slate |
3076 |
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
3077 |
if (drizzle_query(drizzle, query= "show master status")) |
1
by brian
clean slate |
3078 |
die("failed in 'show master status': %d %s", |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
3079 |
drizzle_errno(drizzle), drizzle_error(drizzle)); |
1
by brian
clean slate |
3080 |
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
3081 |
if (!(res = drizzle_store_result(drizzle))) |
3082 |
die("drizzle_store_result() retuned NULL for '%s'", query); |
|
3083 |
if (!(row = drizzle_fetch_row(res))) |
|
1
by brian
clean slate |
3084 |
die("empty result in show master status"); |
411.1.1
by Brian Aker
Work on removing GNU specific calls. |
3085 |
my_stpncpy(master_pos.file, row[0], sizeof(master_pos.file)-1); |
1
by brian
clean slate |
3086 |
master_pos.pos = strtoul(row[1], (char**) 0, 10); |
206.3.1
by Patrick Galbraith
Most everything working with client rename |
3087 |
drizzle_free_result(res); |
142.1.1
by Patrick
Removing DBUG from client |
3088 |
return(0); |
1
by brian
clean slate |
3089 |
}
|
3090 |
||
3091 |
||
3092 |
/*
|
|
3093 |
Assign the variable <var_name> with <var_val>
|
|
3094 |
||
3095 |
SYNOPSIS
|
|
3096 |
do_let()
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
3097 |
query called command
|
1
by brian
clean slate |
3098 |
|
3099 |
DESCRIPTION
|
|
3100 |
let $<var_name>=<var_val><delimiter>
|
|
3101 |
||
3102 |
<var_name> - is the string string found between the $ and =
|
|
3103 |
<var_val> - is the content between the = and <delimiter>, it may span
|
|
3104 |
multiple line and contain any characters except <delimiter>
|
|
3105 |
<delimiter> - is a string containing of one or more chars, default is ;
|
|
3106 |
||
3107 |
RETURN VALUES
|
|
3108 |
Program will die if error detected
|
|
3109 |
*/
|
|
3110 |
||
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
3111 |
static void do_let(struct st_command *command) |
1
by brian
clean slate |
3112 |
{
|
3113 |
char *p= command->first_argument; |
|
3114 |
char *var_name, *var_name_end; |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
3115 |
string let_rhs_expr; |
3116 |
||
1
by brian
clean slate |
3117 |
|
3118 |
/* Find <var_name> */
|
|
3119 |
if (!*p) |
|
3120 |
die("Missing arguments to let"); |
|
3121 |
var_name= p; |
|
3122 |
while (*p && (*p != '=') && !my_isspace(charset_info,*p)) |
|
3123 |
p++; |
|
3124 |
var_name_end= p; |
|
3125 |
if (var_name == var_name_end || |
|
3126 |
(var_name+1 == var_name_end && *var_name == '$')) |
|
3127 |
die("Missing variable name in let"); |
|
3128 |
while (my_isspace(charset_info,*p)) |
|
3129 |
p++; |
|
3130 |
if (*p++ != '=') |
|
3131 |
die("Missing assignment operator in let"); |
|
3132 |
||
3133 |
/* Find start of <var_val> */
|
|
3134 |
while (*p && my_isspace(charset_info,*p)) |
|
3135 |
p++; |
|
3136 |
||
163
by Brian Aker
Merge Monty's code. |
3137 |
do_eval(&let_rhs_expr, p, command->end, false); |
1
by brian
clean slate |
3138 |
|
3139 |
command->last_argument= command->end; |
|
3140 |
/* Assign var_val to var_name */
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
3141 |
var_set(var_name, var_name_end, let_rhs_expr.c_str(), |
3142 |
(let_rhs_expr.c_str() + let_rhs_expr.length())); |
|
142.1.1
by Patrick
Removing DBUG from client |
3143 |
return; |
1
by brian
clean slate |
3144 |
}
|
3145 |
||
3146 |
||
3147 |
/*
|
|
3148 |
Sleep the number of specified seconds
|
|
3149 |
||
3150 |
SYNOPSIS
|
|
3151 |
do_sleep()
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
3152 |
q called command
|
1
by brian
clean slate |
3153 |
real_sleep use the value from opt_sleep as number of seconds to sleep
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
3154 |
if real_sleep is false
|
1
by brian
clean slate |
3155 |
|
3156 |
DESCRIPTION
|
|
3157 |
sleep <seconds>
|
|
3158 |
real_sleep <seconds>
|
|
3159 |
||
3160 |
The difference between the sleep and real_sleep commands is that sleep
|
|
3161 |
uses the delay from the --sleep command-line option if there is one.
|
|
3162 |
(If the --sleep option is not given, the sleep command uses the delay
|
|
3163 |
specified by its argument.) The real_sleep command always uses the
|
|
3164 |
delay specified by its argument. The logic is that sometimes delays are
|
|
3165 |
cpu-dependent, and --sleep can be used to set this delay. real_sleep is
|
|
3166 |
used for cpu-independent delays.
|
|
3167 |
*/
|
|
3168 |
||
143
by Brian Aker
Bool cleanup. |
3169 |
static int do_sleep(struct st_command *command, bool real_sleep) |
1
by brian
clean slate |
3170 |
{
|
3171 |
int error= 0; |
|
3172 |
char *p= command->first_argument; |
|
3173 |
char *sleep_start, *sleep_end= command->end; |
|
3174 |
double sleep_val; |
|
3175 |
||
3176 |
while (my_isspace(charset_info, *p)) |
|
3177 |
p++; |
|
3178 |
if (!*p) |
|
3179 |
die("Missing argument to %.*s", command->first_word_len, command->query); |
|
3180 |
sleep_start= p; |
|
3181 |
/* Check that arg starts with a digit, not handled by my_strtod */
|
|
3182 |
if (!my_isdigit(charset_info, *sleep_start)) |
|
3183 |
die("Invalid argument to %.*s \"%s\"", command->first_word_len, |
|
3184 |
command->query,command->first_argument); |
|
3185 |
sleep_val= my_strtod(sleep_start, &sleep_end, &error); |
|
3186 |
if (error) |
|
3187 |
die("Invalid argument to %.*s \"%s\"", command->first_word_len, |
|
3188 |
command->query, command->first_argument); |
|
3189 |
||
3190 |
/* Fixed sleep time selected by --sleep option */
|
|
3191 |
if (opt_sleep >= 0 && !real_sleep) |
|
3192 |
sleep_val= opt_sleep; |
|
3193 |
||
3194 |
if (sleep_val) |
|
297
by Brian Aker
Final ulong cleanup in clients |
3195 |
my_sleep((uint32_t) (sleep_val * 1000000L)); |
1
by brian
clean slate |
3196 |
command->last_argument= sleep_end; |
3197 |
return 0; |
|
3198 |
}
|
|
3199 |
||
3200 |
||
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
3201 |
static void do_get_file_name(struct st_command *command, |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
3202 |
char* dest, uint dest_max_len) |
1
by brian
clean slate |
3203 |
{
|
3204 |
char *p= command->first_argument, *name; |
|
3205 |
if (!*p) |
|
3206 |
die("Missing file name argument"); |
|
3207 |
name= p; |
|
3208 |
while (*p && !my_isspace(charset_info,*p)) |
|
3209 |
p++; |
|
3210 |
if (*p) |
|
3211 |
*p++= 0; |
|
3212 |
command->last_argument= p; |
|
3213 |
strmake(dest, name, dest_max_len - 1); |
|
3214 |
}
|
|
3215 |
||
3216 |
||
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
3217 |
static void do_set_charset(struct st_command *command) |
1
by brian
clean slate |
3218 |
{
|
3219 |
char *charset_name= command->first_argument; |
|
3220 |
char *p; |
|
3221 |
||
3222 |
if (!charset_name || !*charset_name) |
|
3223 |
die("Missing charset name in 'character_set'"); |
|
3224 |
/* Remove end space */
|
|
3225 |
p= charset_name; |
|
3226 |
while (*p && !my_isspace(charset_info,*p)) |
|
3227 |
p++; |
|
3228 |
if(*p) |
|
3229 |
*p++= 0; |
|
3230 |
command->last_argument= p; |
|
3231 |
charset_info= get_charset_by_csname(charset_name,MY_CS_PRIMARY,MYF(MY_WME)); |
|
3232 |
if (!charset_info) |
|
3233 |
abort_not_supported_test("Test requires charset '%s'", charset_name); |
|
3234 |
}
|
|
3235 |
||
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
3236 |
static uint get_errcode_from_name(char *error_name, char *error_end) |
1
by brian
clean slate |
3237 |
{
|
3238 |
/* SQL error as string */
|
|
3239 |
st_error *e= global_error_names; |
|
3240 |
||
3241 |
/* Loop through the array of known error names */
|
|
3242 |
for (; e->name; e++) |
|
3243 |
{
|
|
3244 |
/*
|
|
3245 |
If we get a match, we need to check the length of the name we
|
|
3246 |
matched against in case it was longer than what we are checking
|
|
3247 |
(as in ER_WRONG_VALUE vs. ER_WRONG_VALUE_COUNT).
|
|
3248 |
*/
|
|
3249 |
if (!strncmp(error_name, e->name, (int) (error_end - error_name)) && |
|
3250 |
(uint) strlen(e->name) == (uint) (error_end - error_name)) |
|
3251 |
{
|
|
142.1.1
by Patrick
Removing DBUG from client |
3252 |
return(e->code); |
1
by brian
clean slate |
3253 |
}
|
3254 |
}
|
|
3255 |
if (!e->name) |
|
3256 |
die("Unknown SQL error name '%s'", error_name); |
|
142.1.1
by Patrick
Removing DBUG from client |
3257 |
return(0); |
1
by brian
clean slate |
3258 |
}
|
3259 |
||
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
3260 |
static void do_get_errcodes(struct st_command *command) |
1
by brian
clean slate |
3261 |
{
|
3262 |
struct st_match_err *to= saved_expected_errors.err; |
|
3263 |
char *p= command->first_argument; |
|
3264 |
uint count= 0; |
|
3265 |
||
142.1.1
by Patrick
Removing DBUG from client |
3266 |
|
1
by brian
clean slate |
3267 |
|
3268 |
if (!*p) |
|
3269 |
die("Missing argument(s) to 'error'"); |
|
3270 |
||
3271 |
do
|
|
3272 |
{
|
|
3273 |
char *end; |
|
3274 |
||
3275 |
/* Skip leading spaces */
|
|
3276 |
while (*p && *p == ' ') |
|
3277 |
p++; |
|
3278 |
||
3279 |
/* Find end */
|
|
3280 |
end= p; |
|
3281 |
while (*end && *end != ',' && *end != ' ') |
|
3282 |
end++; |
|
3283 |
||
3284 |
if (*p == 'S') |
|
3285 |
{
|
|
3286 |
char *to_ptr= to->code.sqlstate; |
|
3287 |
||
3288 |
/*
|
|
3289 |
SQLSTATE string
|
|
3290 |
- Must be SQLSTATE_LENGTH long
|
|
3291 |
- May contain only digits[0-9] and _uppercase_ letters
|
|
3292 |
*/
|
|
3293 |
p++; /* Step past the S */ |
|
3294 |
if ((end - p) != SQLSTATE_LENGTH) |
|
3295 |
die("The sqlstate must be exactly %d chars long", SQLSTATE_LENGTH); |
|
3296 |
||
3297 |
/* Check sqlstate string validity */
|
|
3298 |
while (*p && p < end) |
|
3299 |
{
|
|
3300 |
if (my_isdigit(charset_info, *p) || my_isupper(charset_info, *p)) |
|
3301 |
*to_ptr++= *p++; |
|
3302 |
else
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
3303 |
die("The sqlstate may only consist of digits[0-9] " \ |
1
by brian
clean slate |
3304 |
"and _uppercase_ letters"); |
3305 |
}
|
|
3306 |
||
3307 |
*to_ptr= 0; |
|
3308 |
to->type= ERR_SQLSTATE; |
|
3309 |
}
|
|
3310 |
else if (*p == 's') |
|
3311 |
{
|
|
3312 |
die("The sqlstate definition must start with an uppercase S"); |
|
3313 |
}
|
|
3314 |
else if (*p == 'E') |
|
3315 |
{
|
|
3316 |
/* Error name string */
|
|
3317 |
||
3318 |
to->code.errnum= get_errcode_from_name(p, end); |
|
3319 |
to->type= ERR_ERRNO; |
|
3320 |
}
|
|
3321 |
else if (*p == 'e') |
|
3322 |
{
|
|
3323 |
die("The error name definition must start with an uppercase E"); |
|
3324 |
}
|
|
3325 |
else
|
|
3326 |
{
|
|
3327 |
long val; |
|
3328 |
char *start= p; |
|
3329 |
/* Check that the string passed to str2int only contain digits */
|
|
3330 |
while (*p && p != end) |
|
3331 |
{
|
|
3332 |
if (!my_isdigit(charset_info, *p)) |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
3333 |
die("Invalid argument to error: '%s' - " \ |
1
by brian
clean slate |
3334 |
"the errno may only consist of digits[0-9]", |
3335 |
command->first_argument); |
|
3336 |
p++; |
|
3337 |
}
|
|
3338 |
||
3339 |
/* Convert the sting to int */
|
|
3340 |
if (!str2int(start, 10, (long) INT_MIN, (long) INT_MAX, &val)) |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
3341 |
die("Invalid argument to error: '%s'", command->first_argument); |
1
by brian
clean slate |
3342 |
|
3343 |
to->code.errnum= (uint) val; |
|
3344 |
to->type= ERR_ERRNO; |
|
3345 |
}
|
|
3346 |
to++; |
|
3347 |
count++; |
|
3348 |
||
3349 |
if (count >= (sizeof(saved_expected_errors.err) / |
|
3350 |
sizeof(struct st_match_err))) |
|
3351 |
die("Too many errorcodes specified"); |
|
3352 |
||
3353 |
/* Set pointer to the end of the last error code */
|
|
3354 |
p= end; |
|
3355 |
||
3356 |
/* Find next ',' */
|
|
3357 |
while (*p && *p != ',') |
|
3358 |
p++; |
|
3359 |
||
3360 |
if (*p) |
|
3361 |
p++; /* Step past ',' */ |
|
3362 |
||
3363 |
} while (*p); |
|
3364 |
||
3365 |
command->last_argument= p; |
|
3366 |
to->type= ERR_EMPTY; /* End of data */ |
|
3367 |
||
3368 |
saved_expected_errors.count= count; |
|
142.1.1
by Patrick
Removing DBUG from client |
3369 |
return; |
1
by brian
clean slate |
3370 |
}
|
3371 |
||
3372 |
||
3373 |
/*
|
|
3374 |
Get a string; Return ptr to end of string
|
|
3375 |
Strings may be surrounded by " or '
|
|
3376 |
||
3377 |
If string is a '$variable', return the value of the variable.
|
|
3378 |
*/
|
|
3379 |
||
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
3380 |
static char *get_string(char **to_ptr, char **from_ptr, |
3381 |
struct st_command *command) |
|
1
by brian
clean slate |
3382 |
{
|
3383 |
char c, sep; |
|
3384 |
char *to= *to_ptr, *from= *from_ptr, *start=to; |
|
142.1.1
by Patrick
Removing DBUG from client |
3385 |
|
1
by brian
clean slate |
3386 |
|
3387 |
/* Find separator */
|
|
3388 |
if (*from == '"' || *from == '\'') |
|
3389 |
sep= *from++; |
|
3390 |
else
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
3391 |
sep=' '; /* Separated with space */ |
1
by brian
clean slate |
3392 |
|
3393 |
for ( ; (c=*from) ; from++) |
|
3394 |
{
|
|
3395 |
if (c == '\\' && from[1]) |
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
3396 |
{ /* Escaped character */ |
1
by brian
clean slate |
3397 |
/* We can't translate \0 -> ASCII 0 as replace can't handle ASCII 0 */
|
3398 |
switch (*++from) { |
|
3399 |
case 'n': |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
3400 |
*to++= '\n'; |
3401 |
break; |
|
1
by brian
clean slate |
3402 |
case 't': |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
3403 |
*to++= '\t'; |
3404 |
break; |
|
1
by brian
clean slate |
3405 |
case 'r': |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
3406 |
*to++ = '\r'; |
3407 |
break; |
|
1
by brian
clean slate |
3408 |
case 'b': |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
3409 |
*to++ = '\b'; |
3410 |
break; |
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
3411 |
case 'Z': /* ^Z must be escaped on Win32 */ |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
3412 |
*to++='\032'; |
3413 |
break; |
|
1
by brian
clean slate |
3414 |
default: |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
3415 |
*to++ = *from; |
3416 |
break; |
|
1
by brian
clean slate |
3417 |
}
|
3418 |
}
|
|
3419 |
else if (c == sep) |
|
3420 |
{
|
|
3421 |
if (c == ' ' || c != *++from) |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
3422 |
break; /* Found end of string */ |
206.3.1
by Patrick Galbraith
Most everything working with client rename |
3423 |
*to++=c; /* Copy duplicated separator */ |
1
by brian
clean slate |
3424 |
}
|
3425 |
else
|
|
3426 |
*to++=c; |
|
3427 |
}
|
|
3428 |
if (*from != ' ' && *from) |
|
3429 |
die("Wrong string argument in %s", command->query); |
|
3430 |
||
206.3.1
by Patrick Galbraith
Most everything working with client rename |
3431 |
while (my_isspace(charset_info,*from)) /* Point to next string */ |
1
by brian
clean slate |
3432 |
from++; |
3433 |
||
206.3.1
by Patrick Galbraith
Most everything working with client rename |
3434 |
*to =0; /* End of string marker */ |
3435 |
*to_ptr= to+1; /* Store pointer to end */ |
|
1
by brian
clean slate |
3436 |
*from_ptr= from; |
3437 |
||
3438 |
/* Check if this was a variable */
|
|
3439 |
if (*start == '$') |
|
3440 |
{
|
|
3441 |
const char *end= to; |
|
3442 |
VAR *var=var_get(start, &end, 0, 1); |
|
3443 |
if (var && to == (char*) end+1) |
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
3444 |
return(var->str_val); /* return found variable value */ |
1
by brian
clean slate |
3445 |
}
|
142.1.1
by Patrick
Removing DBUG from client |
3446 |
return(start); |
1
by brian
clean slate |
3447 |
}
|
3448 |
||
3449 |
||
206.3.1
by Patrick Galbraith
Most everything working with client rename |
3450 |
static void set_reconnect(DRIZZLE *drizzle, int val) |
1
by brian
clean slate |
3451 |
{
|
143
by Brian Aker
Bool cleanup. |
3452 |
bool reconnect= val; |
142.1.1
by Patrick
Removing DBUG from client |
3453 |
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
3454 |
drizzle_options(drizzle, DRIZZLE_OPT_RECONNECT, (char *)&reconnect); |
144
by Brian Aker
Merging in Patrick's work. |
3455 |
|
142.1.1
by Patrick
Removing DBUG from client |
3456 |
return; |
1
by brian
clean slate |
3457 |
}
|
3458 |
||
3459 |
||
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
3460 |
static int select_connection_name(const char *name) |
1
by brian
clean slate |
3461 |
{
|
3462 |
if (!(cur_con= find_connection_by_name(name))) |
|
3463 |
die("connection '%s' not found in connection pool", name); |
|
3464 |
||
206.3.1
by Patrick Galbraith
Most everything working with client rename |
3465 |
/* Update $drizzle_get_server_version to that of current connection */
|
3466 |
var_set_drizzle_get_server_version(&cur_con->drizzle); |
|
1
by brian
clean slate |
3467 |
|
142.1.1
by Patrick
Removing DBUG from client |
3468 |
return(0); |
1
by brian
clean slate |
3469 |
}
|
3470 |
||
3471 |
||
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
3472 |
static int select_connection(struct st_command *command) |
1
by brian
clean slate |
3473 |
{
|
3474 |
char *name; |
|
3475 |
char *p= command->first_argument; |
|
142.1.1
by Patrick
Removing DBUG from client |
3476 |
|
1
by brian
clean slate |
3477 |
|
3478 |
if (!*p) |
|
3479 |
die("Missing connection name in connect"); |
|
3480 |
name= p; |
|
3481 |
while (*p && !my_isspace(charset_info,*p)) |
|
3482 |
p++; |
|
3483 |
if (*p) |
|
3484 |
*p++= 0; |
|
3485 |
command->last_argument= p; |
|
142.1.1
by Patrick
Removing DBUG from client |
3486 |
return(select_connection_name(name)); |
1
by brian
clean slate |
3487 |
}
|
3488 |
||
3489 |
||
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
3490 |
static void do_close_connection(struct st_command *command) |
1
by brian
clean slate |
3491 |
{
|
3492 |
char *p= command->first_argument, *name; |
|
3493 |
struct st_connection *con; |
|
3494 |
||
3495 |
if (!*p) |
|
3496 |
die("Missing connection name in disconnect"); |
|
3497 |
name= p; |
|
3498 |
while (*p && !my_isspace(charset_info,*p)) |
|
3499 |
p++; |
|
3500 |
||
3501 |
if (*p) |
|
3502 |
*p++= 0; |
|
3503 |
command->last_argument= p; |
|
3504 |
||
3505 |
if (!(con= find_connection_by_name(name))) |
|
3506 |
die("connection '%s' not found in connection pool", name); |
|
3507 |
||
3508 |
if (command->type == Q_DIRTY_CLOSE) |
|
3509 |
{
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
3510 |
if (con->drizzle.net.vio) |
1
by brian
clean slate |
3511 |
{
|
383.1.53
by Monty Taylor
Removed more direct use of vio. |
3512 |
net_close(&(con->drizzle.net)); |
1
by brian
clean slate |
3513 |
}
|
3514 |
}
|
|
3515 |
||
206.3.1
by Patrick Galbraith
Most everything working with client rename |
3516 |
drizzle_close(&con->drizzle); |
1
by brian
clean slate |
3517 |
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
3518 |
if (con->util_drizzle) |
3519 |
drizzle_close(con->util_drizzle); |
|
3520 |
con->util_drizzle= 0; |
|
1
by brian
clean slate |
3521 |
|
477
by Monty Taylor
Removed my_free(). It turns out that it had been def'd to ignore the flags passed to it in the second arg anyway. Gotta love that. |
3522 |
free(con->name); |
1
by brian
clean slate |
3523 |
|
3524 |
/*
|
|
3525 |
When the connection is closed set name to "-closed_connection-"
|
|
3526 |
to make it possible to reuse the connection name.
|
|
3527 |
*/
|
|
3528 |
if (!(con->name = my_strdup("-closed_connection-", MYF(MY_WME)))) |
|
3529 |
die("Out of memory"); |
|
3530 |
||
142.1.1
by Patrick
Removing DBUG from client |
3531 |
return; |
1
by brian
clean slate |
3532 |
}
|
3533 |
||
3534 |
||
3535 |
/*
|
|
3536 |
Connect to a server doing several retries if needed.
|
|
3537 |
||
3538 |
SYNOPSIS
|
|
3539 |
safe_connect()
|
|
3540 |
con - connection structure to be used
|
|
3541 |
host, user, pass, - connection parameters
|
|
3542 |
db, port, sock
|
|
3543 |
||
3544 |
NOTE
|
|
3545 |
||
3546 |
Sometimes in a test the client starts before
|
|
3547 |
the server - to solve the problem, we try again
|
|
3548 |
after some sleep if connection fails the first
|
|
3549 |
time
|
|
3550 |
||
3551 |
This function will try to connect to the given server
|
|
3552 |
"opt_max_connect_retries" times and sleep "connection_retry_sleep"
|
|
3553 |
seconds between attempts before finally giving up.
|
|
3554 |
This helps in situation when the client starts
|
|
3555 |
before the server (which happens sometimes).
|
|
3556 |
It will only ignore connection errors during these retries.
|
|
3557 |
||
3558 |
*/
|
|
3559 |
||
206.3.1
by Patrick Galbraith
Most everything working with client rename |
3560 |
static void safe_connect(DRIZZLE *drizzle, const char *name, const char *host, |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
3561 |
const char *user, const char *pass, const char *db, |
3562 |
int port) |
|
1
by brian
clean slate |
3563 |
{
|
3564 |
int failed_attempts= 0; |
|
297
by Brian Aker
Final ulong cleanup in clients |
3565 |
static uint32_t connection_retry_sleep= 100000; /* Microseconds */ |
1
by brian
clean slate |
3566 |
|
142.1.1
by Patrick
Removing DBUG from client |
3567 |
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
3568 |
while(!drizzle_connect(drizzle, host, user, pass, db, port, NULL, |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
3569 |
CLIENT_MULTI_STATEMENTS | CLIENT_REMEMBER_OPTIONS)) |
1
by brian
clean slate |
3570 |
{
|
3571 |
/*
|
|
3572 |
Connect failed
|
|
3573 |
||
3574 |
Only allow retry if this was an error indicating the server
|
|
3575 |
could not be contacted. Error code differs depending
|
|
3576 |
on protocol/connection type
|
|
3577 |
*/
|
|
3578 |
||
206.3.1
by Patrick Galbraith
Most everything working with client rename |
3579 |
if ((drizzle_errno(drizzle) == CR_CONN_HOST_ERROR || |
3580 |
drizzle_errno(drizzle) == CR_CONNECTION_ERROR) && |
|
1
by brian
clean slate |
3581 |
failed_attempts < opt_max_connect_retries) |
3582 |
{
|
|
3583 |
verbose_msg("Connect attempt %d/%d failed: %d: %s", failed_attempts, |
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
3584 |
opt_max_connect_retries, drizzle_errno(drizzle), |
3585 |
drizzle_error(drizzle)); |
|
1
by brian
clean slate |
3586 |
my_sleep(connection_retry_sleep); |
3587 |
}
|
|
3588 |
else
|
|
3589 |
{
|
|
3590 |
if (failed_attempts > 0) |
|
3591 |
die("Could not open connection '%s' after %d attempts: %d %s", name, |
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
3592 |
failed_attempts, drizzle_errno(drizzle), drizzle_error(drizzle)); |
1
by brian
clean slate |
3593 |
else
|
3594 |
die("Could not open connection '%s': %d %s", name, |
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
3595 |
drizzle_errno(drizzle), drizzle_error(drizzle)); |
1
by brian
clean slate |
3596 |
}
|
3597 |
failed_attempts++; |
|
3598 |
}
|
|
142.1.1
by Patrick
Removing DBUG from client |
3599 |
return; |
1
by brian
clean slate |
3600 |
}
|
3601 |
||
3602 |
||
3603 |
/*
|
|
3604 |
Connect to a server and handle connection errors in case they occur.
|
|
3605 |
||
3606 |
SYNOPSIS
|
|
3607 |
connect_n_handle_errors()
|
|
3608 |
q - context of connect "query" (command)
|
|
3609 |
con - connection structure to be used
|
|
3610 |
host, user, pass, - connection parameters
|
|
3611 |
db, port, sock
|
|
3612 |
||
3613 |
DESCRIPTION
|
|
3614 |
This function will try to establish a connection to server and handle
|
|
3615 |
possible errors in the same manner as if "connect" was usual SQL-statement
|
|
3616 |
(If error is expected it will ignore it once it occurs and log the
|
|
3617 |
"statement" to the query log).
|
|
3618 |
Unlike safe_connect() it won't do several attempts.
|
|
3619 |
||
3620 |
RETURN VALUES
|
|
3621 |
1 - Connected
|
|
3622 |
0 - Not connected
|
|
3623 |
||
3624 |
*/
|
|
3625 |
||
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
3626 |
static int connect_n_handle_errors(struct st_command *command, |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
3627 |
DRIZZLE *con, const char* host, |
3628 |
const char* user, const char* pass, |
|
3629 |
const char* db, int port, const char* sock) |
|
1
by brian
clean slate |
3630 |
{
|
3631 |
||
3632 |
/* Only log if an error is expected */
|
|
3633 |
if (!command->abort_on_error && |
|
3634 |
!disable_query_log) |
|
3635 |
{
|
|
3636 |
/*
|
|
3637 |
Log the connect to result log
|
|
3638 |
*/
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
3639 |
ds_res.append("connect("); |
3640 |
replace_append(&ds_res, host); |
|
3641 |
ds_res.append(","); |
|
3642 |
replace_append(&ds_res, user); |
|
3643 |
ds_res.append(","); |
|
3644 |
replace_append(&ds_res, pass); |
|
3645 |
ds_res.append(","); |
|
1
by brian
clean slate |
3646 |
if (db) |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
3647 |
replace_append(&ds_res, db); |
3648 |
ds_res.append(","); |
|
3649 |
replace_append_uint(&ds_res, port); |
|
3650 |
ds_res.append(","); |
|
1
by brian
clean slate |
3651 |
if (sock) |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
3652 |
replace_append(&ds_res, sock); |
3653 |
ds_res.append(")"); |
|
3654 |
ds_res.append(delimiter); |
|
3655 |
ds_res.append("\n"); |
|
1
by brian
clean slate |
3656 |
}
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
3657 |
if (!drizzle_connect(con, host, user, pass, db, port, 0, |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
3658 |
CLIENT_MULTI_STATEMENTS)) |
1
by brian
clean slate |
3659 |
{
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
3660 |
var_set_errno(drizzle_errno(con)); |
3661 |
handle_error(command, drizzle_errno(con), drizzle_error(con), |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
3662 |
drizzle_sqlstate(con), &ds_res); |
1
by brian
clean slate |
3663 |
return 0; /* Not connected */ |
3664 |
}
|
|
3665 |
||
3666 |
var_set_errno(0); |
|
3667 |
handle_no_error(command); |
|
3668 |
return 1; /* Connected */ |
|
3669 |
}
|
|
3670 |
||
3671 |
||
3672 |
/*
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
3673 |
Open a new connection to DRIZZLE Server with the parameters
|
1
by brian
clean slate |
3674 |
specified. Make the new connection the current connection.
|
3675 |
||
3676 |
SYNOPSIS
|
|
3677 |
do_connect()
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
3678 |
q called command
|
1
by brian
clean slate |
3679 |
|
3680 |
DESCRIPTION
|
|
3681 |
connect(<name>,<host>,<user>,[<pass>,[<db>,[<port>,<sock>[<opts>]]]]);
|
|
3682 |
connect <name>,<host>,<user>,[<pass>,[<db>,[<port>,<sock>[<opts>]]]];
|
|
3683 |
||
3684 |
<name> - name of the new connection
|
|
3685 |
<host> - hostname of server
|
|
3686 |
<user> - user to connect as
|
|
3687 |
<pass> - password used when connecting
|
|
3688 |
<db> - initial db when connected
|
|
3689 |
<port> - server port
|
|
3690 |
<sock> - server socket
|
|
3691 |
<opts> - options to use for the connection
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
3692 |
* SSL - use SSL if available
|
3693 |
* COMPRESS - use compression if available
|
|
1
by brian
clean slate |
3694 |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
3695 |
*/
|
1
by brian
clean slate |
3696 |
|
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
3697 |
static void do_connect(struct st_command *command) |
1
by brian
clean slate |
3698 |
{
|
3699 |
int con_port= opt_port; |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
3700 |
const char *con_options; |
143
by Brian Aker
Bool cleanup. |
3701 |
bool con_ssl= 0, con_compress= 0; |
1
by brian
clean slate |
3702 |
struct st_connection* con_slot; |
3703 |
||
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
3704 |
string ds_connection_name; |
3705 |
string ds_host; |
|
3706 |
string ds_user; |
|
3707 |
string ds_password; |
|
3708 |
string ds_database; |
|
3709 |
string ds_port; |
|
3710 |
string ds_sock; |
|
3711 |
string ds_options; |
|
1
by brian
clean slate |
3712 |
const struct command_arg connect_args[] = { |
163
by Brian Aker
Merge Monty's code. |
3713 |
{ "connection name", ARG_STRING, true, &ds_connection_name, "Name of the connection" }, |
3714 |
{ "host", ARG_STRING, true, &ds_host, "Host to connect to" }, |
|
3715 |
{ "user", ARG_STRING, false, &ds_user, "User to connect as" }, |
|
3716 |
{ "passsword", ARG_STRING, false, &ds_password, "Password used when connecting" }, |
|
3717 |
{ "database", ARG_STRING, false, &ds_database, "Database to select after connect" }, |
|
3718 |
{ "port", ARG_STRING, false, &ds_port, "Port to connect to" }, |
|
3719 |
{ "socket", ARG_STRING, false, &ds_sock, "Socket to connect with" }, |
|
3720 |
{ "options", ARG_STRING, false, &ds_options, "Options to use while connecting" } |
|
1
by brian
clean slate |
3721 |
};
|
3722 |
||
3723 |
||
3724 |
strip_parentheses(command); |
|
3725 |
check_command_args(command, command->first_argument, connect_args, |
|
3726 |
sizeof(connect_args)/sizeof(struct command_arg), |
|
3727 |
','); |
|
3728 |
||
3729 |
/* Port */
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
3730 |
if (ds_port.length()) |
1
by brian
clean slate |
3731 |
{
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
3732 |
con_port= atoi(ds_port.c_str()); |
1
by brian
clean slate |
3733 |
if (con_port == 0) |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
3734 |
die("Illegal argument for port: '%s'", ds_port.c_str()); |
1
by brian
clean slate |
3735 |
}
|
3736 |
||
3737 |
/* Sock */
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
3738 |
if (!ds_sock.empty()) |
1
by brian
clean slate |
3739 |
{
|
3740 |
/*
|
|
3741 |
If the socket is specified just as a name without path
|
|
3742 |
append tmpdir in front
|
|
3743 |
*/
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
3744 |
if (*ds_sock.c_str() != FN_LIBCHAR) |
1
by brian
clean slate |
3745 |
{
|
3746 |
char buff[FN_REFLEN]; |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
3747 |
fn_format(buff, ds_sock.c_str(), TMPDIR, "", 0); |
3748 |
ds_sock= buff; |
|
1
by brian
clean slate |
3749 |
}
|
3750 |
}
|
|
3751 |
||
3752 |
/* Options */
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
3753 |
con_options= ds_options.c_str(); |
1
by brian
clean slate |
3754 |
while (*con_options) |
3755 |
{
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
3756 |
const char* end; |
1
by brian
clean slate |
3757 |
/* Step past any spaces in beginning of option*/
|
3758 |
while (*con_options && my_isspace(charset_info, *con_options)) |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
3759 |
con_options++; |
1
by brian
clean slate |
3760 |
/* Find end of this option */
|
3761 |
end= con_options; |
|
3762 |
while (*end && !my_isspace(charset_info, *end)) |
|
3763 |
end++; |
|
3764 |
if (!strncmp(con_options, "SSL", 3)) |
|
3765 |
con_ssl= 1; |
|
3766 |
else if (!strncmp(con_options, "COMPRESS", 8)) |
|
3767 |
con_compress= 1; |
|
3768 |
else
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
3769 |
die("Illegal option to connect: %.*s", |
1
by brian
clean slate |
3770 |
(int) (end - con_options), con_options); |
3771 |
/* Process next option */
|
|
3772 |
con_options= end; |
|
3773 |
}
|
|
3774 |
||
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
3775 |
if (find_connection_by_name(ds_connection_name.c_str())) |
3776 |
die("Connection %s already exists", ds_connection_name.c_str()); |
|
3777 |
||
1
by brian
clean slate |
3778 |
if (next_con != connections_end) |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
3779 |
{
|
1
by brian
clean slate |
3780 |
con_slot= next_con; |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
3781 |
}
|
1
by brian
clean slate |
3782 |
else
|
3783 |
{
|
|
3784 |
if (!(con_slot= find_connection_by_name("-closed_connection-"))) |
|
3785 |
die("Connection limit exhausted, you can have max %d connections", |
|
3786 |
(int) (sizeof(connections)/sizeof(struct st_connection))); |
|
3787 |
}
|
|
3788 |
||
202.2.4
by Monty Taylor
Merged from Patrick. |
3789 |
if (!drizzle_create(&con_slot->drizzle)) |
202.2.1
by Monty Taylor
Renamed mysql_init to drizzle_create. |
3790 |
die("Failed on drizzle_create()"); |
1
by brian
clean slate |
3791 |
if (opt_compress || con_compress) |
461
by Monty Taylor
Removed NullS. bu-bye. |
3792 |
drizzle_options(&con_slot->drizzle, DRIZZLE_OPT_COMPRESS, NULL); |
206.3.1
by Patrick Galbraith
Most everything working with client rename |
3793 |
drizzle_options(&con_slot->drizzle, DRIZZLE_OPT_LOCAL_INFILE, 0); |
1
by brian
clean slate |
3794 |
|
3795 |
/* Use default db name */
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
3796 |
if (ds_database.length() == 0) |
3797 |
ds_database= opt_db; |
|
1
by brian
clean slate |
3798 |
|
3799 |
/* Special database to allow one to connect without a database name */
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
3800 |
if (ds_database.length() && !strcmp(ds_database.c_str(),"*NO-ONE*")) |
3801 |
ds_database= ""; |
|
1
by brian
clean slate |
3802 |
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
3803 |
if (connect_n_handle_errors(command, &con_slot->drizzle, |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
3804 |
ds_host.c_str(),ds_user.c_str(), |
3805 |
ds_password.c_str(), ds_database.c_str(), |
|
3806 |
con_port, ds_sock.c_str())) |
|
1
by brian
clean slate |
3807 |
{
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
3808 |
if (!(con_slot->name= strdup(ds_connection_name.c_str()))) |
1
by brian
clean slate |
3809 |
die("Out of memory"); |
3810 |
cur_con= con_slot; |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
3811 |
|
1
by brian
clean slate |
3812 |
if (con_slot == next_con) |
3813 |
next_con++; /* if we used the next_con slot, advance the pointer */ |
|
3814 |
}
|
|
3815 |
||
206.3.1
by Patrick Galbraith
Most everything working with client rename |
3816 |
/* Update $drizzle_get_server_version to that of current connection */
|
3817 |
var_set_drizzle_get_server_version(&cur_con->drizzle); |
|
1
by brian
clean slate |
3818 |
|
142.1.1
by Patrick
Removing DBUG from client |
3819 |
return; |
1
by brian
clean slate |
3820 |
}
|
3821 |
||
3822 |
||
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
3823 |
static int do_done(struct st_command *command) |
1
by brian
clean slate |
3824 |
{
|
3825 |
/* Check if empty block stack */
|
|
3826 |
if (cur_block == block_stack) |
|
3827 |
{
|
|
3828 |
if (*command->query != '}') |
|
3829 |
die("Stray 'end' command - end of block before beginning"); |
|
3830 |
die("Stray '}' - end of block before beginning"); |
|
3831 |
}
|
|
3832 |
||
3833 |
/* Test if inner block has been executed */
|
|
3834 |
if (cur_block->ok && cur_block->cmd == cmd_while) |
|
3835 |
{
|
|
3836 |
/* Pop block from stack, re-execute outer block */
|
|
3837 |
cur_block--; |
|
3838 |
parser.current_line = cur_block->line; |
|
3839 |
}
|
|
3840 |
else
|
|
3841 |
{
|
|
3842 |
/* Pop block from stack, goto next line */
|
|
3843 |
cur_block--; |
|
3844 |
parser.current_line++; |
|
3845 |
}
|
|
3846 |
return 0; |
|
3847 |
}
|
|
3848 |
||
3849 |
||
3850 |
/*
|
|
3851 |
Process start of a "if" or "while" statement
|
|
3852 |
||
3853 |
SYNOPSIS
|
|
3854 |
do_block()
|
|
3855 |
cmd Type of block
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
3856 |
q called command
|
1
by brian
clean slate |
3857 |
|
3858 |
DESCRIPTION
|
|
3859 |
if ([!]<expr>)
|
|
3860 |
{
|
|
3861 |
<block statements>
|
|
3862 |
}
|
|
3863 |
||
3864 |
while ([!]<expr>)
|
|
3865 |
{
|
|
3866 |
<block statements>
|
|
3867 |
}
|
|
3868 |
||
3869 |
Evaluates the <expr> and if it evaluates to
|
|
3870 |
greater than zero executes the following code block.
|
|
3871 |
A '!' can be used before the <expr> to indicate it should
|
|
3872 |
be executed if it evaluates to zero.
|
|
3873 |
||
3874 |
*/
|
|
3875 |
||
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
3876 |
static void do_block(enum block_cmd cmd, struct st_command* command) |
1
by brian
clean slate |
3877 |
{
|
3878 |
char *p= command->first_argument; |
|
3879 |
const char *expr_start, *expr_end; |
|
3880 |
VAR v; |
|
3881 |
const char *cmd_name= (cmd == cmd_while ? "while" : "if"); |
|
144
by Brian Aker
Merging in Patrick's work. |
3882 |
bool not_expr= false; |
1
by brian
clean slate |
3883 |
|
3884 |
/* Check stack overflow */
|
|
3885 |
if (cur_block == block_stack_end) |
|
3886 |
die("Nesting too deeply"); |
|
3887 |
||
3888 |
/* Set way to find outer block again, increase line counter */
|
|
3889 |
cur_block->line= parser.current_line++; |
|
3890 |
||
3891 |
/* If this block is ignored */
|
|
3892 |
if (!cur_block->ok) |
|
3893 |
{
|
|
3894 |
/* Inner block should be ignored too */
|
|
3895 |
cur_block++; |
|
3896 |
cur_block->cmd= cmd; |
|
163
by Brian Aker
Merge Monty's code. |
3897 |
cur_block->ok= false; |
142.1.1
by Patrick
Removing DBUG from client |
3898 |
return; |
1
by brian
clean slate |
3899 |
}
|
3900 |
||
3901 |
/* Parse and evaluate test expression */
|
|
3902 |
expr_start= strchr(p, '('); |
|
3903 |
if (!expr_start++) |
|
3904 |
die("missing '(' in %s", cmd_name); |
|
3905 |
||
3906 |
/* Check for !<expr> */
|
|
3907 |
if (*expr_start == '!') |
|
3908 |
{
|
|
163
by Brian Aker
Merge Monty's code. |
3909 |
not_expr= true; |
1
by brian
clean slate |
3910 |
expr_start++; /* Step past the '!' */ |
3911 |
}
|
|
3912 |
/* Find ending ')' */
|
|
3913 |
expr_end= strrchr(expr_start, ')'); |
|
3914 |
if (!expr_end) |
|
3915 |
die("missing ')' in %s", cmd_name); |
|
3916 |
p= (char*)expr_end+1; |
|
3917 |
||
3918 |
while (*p && my_isspace(charset_info, *p)) |
|
3919 |
p++; |
|
3920 |
if (*p && *p != '{') |
|
3921 |
die("Missing '{' after %s. Found \"%s\"", cmd_name, p); |
|
3922 |
||
3923 |
var_init(&v,0,0,0,0); |
|
3924 |
eval_expr(&v, expr_start, &expr_end); |
|
3925 |
||
3926 |
/* Define inner block */
|
|
3927 |
cur_block++; |
|
3928 |
cur_block->cmd= cmd; |
|
163
by Brian Aker
Merge Monty's code. |
3929 |
cur_block->ok= (v.int_val ? true : false); |
1
by brian
clean slate |
3930 |
|
3931 |
if (not_expr) |
|
3932 |
cur_block->ok = !cur_block->ok; |
|
3933 |
||
3934 |
var_free(&v); |
|
142.1.1
by Patrick
Removing DBUG from client |
3935 |
return; |
1
by brian
clean slate |
3936 |
}
|
3937 |
||
3938 |
||
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
3939 |
static void do_delimiter(struct st_command* command) |
1
by brian
clean slate |
3940 |
{
|
3941 |
char* p= command->first_argument; |
|
3942 |
||
3943 |
while (*p && my_isspace(charset_info, *p)) |
|
3944 |
p++; |
|
3945 |
||
3946 |
if (!(*p)) |
|
3947 |
die("Can't set empty delimiter"); |
|
3948 |
||
3949 |
strmake(delimiter, p, sizeof(delimiter) - 1); |
|
3950 |
delimiter_length= strlen(delimiter); |
|
3951 |
||
3952 |
command->last_argument= p + delimiter_length; |
|
142.1.1
by Patrick
Removing DBUG from client |
3953 |
return; |
1
by brian
clean slate |
3954 |
}
|
3955 |
||
3956 |
||
143
by Brian Aker
Bool cleanup. |
3957 |
bool match_delimiter(int c, const char *delim, uint length) |
1
by brian
clean slate |
3958 |
{
|
3959 |
uint i; |
|
3960 |
char tmp[MAX_DELIMITER_LENGTH]; |
|
3961 |
||
3962 |
if (c != *delim) |
|
3963 |
return 0; |
|
3964 |
||
3965 |
for (i= 1; i < length && |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
3966 |
(c= my_getc(cur_file->file)) == *(delim + i); |
1
by brian
clean slate |
3967 |
i++) |
3968 |
tmp[i]= c; |
|
3969 |
||
3970 |
if (i == length) |
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
3971 |
return 1; /* Found delimiter */ |
1
by brian
clean slate |
3972 |
|
3973 |
/* didn't find delimiter, push back things that we read */
|
|
3974 |
my_ungetc(c); |
|
3975 |
while (i > 1) |
|
3976 |
my_ungetc(tmp[--i]); |
|
3977 |
return 0; |
|
3978 |
}
|
|
3979 |
||
3980 |
||
143
by Brian Aker
Bool cleanup. |
3981 |
static bool end_of_query(int c) |
1
by brian
clean slate |
3982 |
{
|
3983 |
return match_delimiter(c, delimiter, delimiter_length); |
|
3984 |
}
|
|
3985 |
||
3986 |
||
3987 |
/*
|
|
3988 |
Read one "line" from the file
|
|
3989 |
||
3990 |
SYNOPSIS
|
|
3991 |
read_line
|
|
3992 |
buf buffer for the read line
|
|
3993 |
size size of the buffer i.e max size to read
|
|
3994 |
||
3995 |
DESCRIPTION
|
|
3996 |
This function actually reads several lines and adds them to the
|
|
3997 |
buffer buf. It continues to read until it finds what it believes
|
|
3998 |
is a complete query.
|
|
3999 |
||
4000 |
Normally that means it will read lines until it reaches the
|
|
4001 |
"delimiter" that marks end of query. Default delimiter is ';'
|
|
4002 |
The function should be smart enough not to detect delimiter's
|
|
4003 |
found inside strings surrounded with '"' and '\'' escaped strings.
|
|
4004 |
||
4005 |
If the first line in a query starts with '#' or '-' this line is treated
|
|
4006 |
as a comment. A comment is always terminated when end of line '\n' is
|
|
4007 |
reached.
|
|
4008 |
||
4009 |
*/
|
|
4010 |
||
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
4011 |
static int read_line(char *buf, int size) |
1
by brian
clean slate |
4012 |
{
|
4013 |
char c, last_quote= 0; |
|
4014 |
char *p= buf, *buf_end= buf + size - 1; |
|
4015 |
int skip_char= 0; |
|
4016 |
enum {R_NORMAL, R_Q, R_SLASH_IN_Q, |
|
4017 |
R_COMMENT, R_LINE_START} state= R_LINE_START; |
|
142.1.1
by Patrick
Removing DBUG from client |
4018 |
|
1
by brian
clean slate |
4019 |
|
4020 |
start_lineno= cur_file->lineno; |
|
4021 |
for (; p < buf_end ;) |
|
4022 |
{
|
|
4023 |
skip_char= 0; |
|
4024 |
c= my_getc(cur_file->file); |
|
4025 |
if (feof(cur_file->file)) |
|
4026 |
{
|
|
4027 |
found_eof: |
|
4028 |
if (cur_file->file != stdin) |
|
4029 |
{
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
4030 |
my_fclose(cur_file->file, MYF(0)); |
1
by brian
clean slate |
4031 |
cur_file->file= 0; |
4032 |
}
|
|
481
by Brian Aker
Remove all of uchar. |
4033 |
free((unsigned char*) cur_file->file_name); |
1
by brian
clean slate |
4034 |
cur_file->file_name= 0; |
4035 |
if (cur_file == file_stack) |
|
4036 |
{
|
|
4037 |
/* We're back at the first file, check if
|
|
4038 |
all { have matching }
|
|
4039 |
*/
|
|
4040 |
if (cur_block != block_stack) |
|
4041 |
die("Missing end of block"); |
|
4042 |
||
4043 |
*p= 0; |
|
142.1.1
by Patrick
Removing DBUG from client |
4044 |
return(1); |
1
by brian
clean slate |
4045 |
}
|
4046 |
cur_file--; |
|
4047 |
start_lineno= cur_file->lineno; |
|
4048 |
continue; |
|
4049 |
}
|
|
4050 |
||
4051 |
if (c == '\n') |
|
4052 |
{
|
|
4053 |
/* Line counting is independent of state */
|
|
4054 |
cur_file->lineno++; |
|
4055 |
||
4056 |
/* Convert cr/lf to lf */
|
|
4057 |
if (p != buf && *(p-1) == '\r') |
|
4058 |
p--; |
|
4059 |
}
|
|
4060 |
||
4061 |
switch(state) { |
|
4062 |
case R_NORMAL: |
|
4063 |
if (end_of_query(c)) |
|
4064 |
{
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
4065 |
*p= 0; |
4066 |
return(0); |
|
1
by brian
clean slate |
4067 |
}
|
4068 |
else if ((c == '{' && |
|
481
by Brian Aker
Remove all of uchar. |
4069 |
(!my_strnncoll_simple(charset_info, (const unsigned char*) "while", 5, |
4070 |
(unsigned char*) buf, cmin((long)5, p - buf), 0) || |
|
4071 |
!my_strnncoll_simple(charset_info, (const unsigned char*) "if", 2, |
|
4072 |
(unsigned char*) buf, cmin((long)2, p - buf), 0)))) |
|
1
by brian
clean slate |
4073 |
{
|
4074 |
/* Only if and while commands can be terminated by { */
|
|
4075 |
*p++= c; |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
4076 |
*p= 0; |
4077 |
return(0); |
|
1
by brian
clean slate |
4078 |
}
|
4079 |
else if (c == '\'' || c == '"' || c == '`') |
|
4080 |
{
|
|
4081 |
last_quote= c; |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
4082 |
state= R_Q; |
1
by brian
clean slate |
4083 |
}
|
4084 |
break; |
|
4085 |
||
4086 |
case R_COMMENT: |
|
4087 |
if (c == '\n') |
|
4088 |
{
|
|
4089 |
/* Comments are terminated by newline */
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
4090 |
*p= 0; |
4091 |
return(0); |
|
1
by brian
clean slate |
4092 |
}
|
4093 |
break; |
|
4094 |
||
4095 |
case R_LINE_START: |
|
4096 |
if (c == '#' || c == '-') |
|
4097 |
{
|
|
4098 |
/* A # or - in the first position of the line - this is a comment */
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
4099 |
state = R_COMMENT; |
1
by brian
clean slate |
4100 |
}
|
4101 |
else if (my_isspace(charset_info, c)) |
|
4102 |
{
|
|
4103 |
/* Skip all space at begining of line */
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
4104 |
if (c == '\n') |
1
by brian
clean slate |
4105 |
{
|
4106 |
/* Query hasn't started yet */
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
4107 |
start_lineno= cur_file->lineno; |
1
by brian
clean slate |
4108 |
}
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
4109 |
skip_char= 1; |
1
by brian
clean slate |
4110 |
}
|
4111 |
else if (end_of_query(c)) |
|
4112 |
{
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
4113 |
*p= 0; |
4114 |
return(0); |
|
1
by brian
clean slate |
4115 |
}
|
4116 |
else if (c == '}') |
|
4117 |
{
|
|
4118 |
/* A "}" need to be by itself in the begining of a line to terminate */
|
|
4119 |
*p++= c; |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
4120 |
*p= 0; |
4121 |
return(0); |
|
1
by brian
clean slate |
4122 |
}
|
4123 |
else if (c == '\'' || c == '"' || c == '`') |
|
4124 |
{
|
|
4125 |
last_quote= c; |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
4126 |
state= R_Q; |
1
by brian
clean slate |
4127 |
}
|
4128 |
else
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
4129 |
state= R_NORMAL; |
1
by brian
clean slate |
4130 |
break; |
4131 |
||
4132 |
case R_Q: |
|
4133 |
if (c == last_quote) |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
4134 |
state= R_NORMAL; |
1
by brian
clean slate |
4135 |
else if (c == '\\') |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
4136 |
state= R_SLASH_IN_Q; |
1
by brian
clean slate |
4137 |
break; |
4138 |
||
4139 |
case R_SLASH_IN_Q: |
|
4140 |
state= R_Q; |
|
4141 |
break; |
|
4142 |
||
4143 |
}
|
|
4144 |
||
4145 |
if (!skip_char) |
|
4146 |
{
|
|
4147 |
/* Could be a multibyte character */
|
|
4148 |
/* This code is based on the code in "sql_load.cc" */
|
|
4149 |
#ifdef USE_MB
|
|
4150 |
int charlen = my_mbcharlen(charset_info, c); |
|
4151 |
/* We give up if multibyte character is started but not */
|
|
4152 |
/* completed before we pass buf_end */
|
|
4153 |
if ((charlen > 1) && (p + charlen) <= buf_end) |
|
4154 |
{
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
4155 |
int i; |
4156 |
char* mb_start = p; |
|
4157 |
||
4158 |
*p++ = c; |
|
4159 |
||
4160 |
for (i= 1; i < charlen; i++) |
|
4161 |
{
|
|
4162 |
if (feof(cur_file->file)) |
|
4163 |
goto found_eof; |
|
4164 |
c= my_getc(cur_file->file); |
|
4165 |
*p++ = c; |
|
4166 |
}
|
|
4167 |
if (! my_ismbchar(charset_info, mb_start, p)) |
|
4168 |
{
|
|
4169 |
/* It was not a multiline char, push back the characters */
|
|
4170 |
/* We leave first 'c', i.e. pretend it was a normal char */
|
|
4171 |
while (p > mb_start) |
|
4172 |
my_ungetc(*--p); |
|
4173 |
}
|
|
1
by brian
clean slate |
4174 |
}
|
4175 |
else
|
|
4176 |
#endif
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
4177 |
*p++= c; |
1
by brian
clean slate |
4178 |
}
|
4179 |
}
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
4180 |
die("The input buffer is too small for this query.x\n" \ |
1
by brian
clean slate |
4181 |
"check your query or increase MAX_QUERY and recompile"); |
142.1.1
by Patrick
Removing DBUG from client |
4182 |
return(0); |
1
by brian
clean slate |
4183 |
}
|
4184 |
||
4185 |
||
4186 |
/*
|
|
4187 |
Convert the read query to result format version 1
|
|
4188 |
||
4189 |
That is: After newline, all spaces need to be skipped
|
|
4190 |
unless the previous char was a quote
|
|
4191 |
||
4192 |
This is due to an old bug that has now been fixed, but the
|
|
4193 |
version 1 output format is preserved by using this function
|
|
4194 |
||
4195 |
*/
|
|
4196 |
||
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
4197 |
static void convert_to_format_v1(char* query) |
1
by brian
clean slate |
4198 |
{
|
4199 |
int last_c_was_quote= 0; |
|
4200 |
char *p= query, *to= query; |
|
376
by Brian Aker
strend remove |
4201 |
char *end= strchr(query, '\0'); |
1
by brian
clean slate |
4202 |
char last_c; |
4203 |
||
4204 |
while (p <= end) |
|
4205 |
{
|
|
4206 |
if (*p == '\n' && !last_c_was_quote) |
|
4207 |
{
|
|
4208 |
*to++ = *p++; /* Save the newline */ |
|
4209 |
||
4210 |
/* Skip any spaces on next line */
|
|
4211 |
while (*p && my_isspace(charset_info, *p)) |
|
4212 |
p++; |
|
4213 |
||
4214 |
last_c_was_quote= 0; |
|
4215 |
}
|
|
4216 |
else if (*p == '\'' || *p == '"' || *p == '`') |
|
4217 |
{
|
|
4218 |
last_c= *p; |
|
4219 |
*to++ = *p++; |
|
4220 |
||
4221 |
/* Copy anything until the next quote of same type */
|
|
4222 |
while (*p && *p != last_c) |
|
4223 |
*to++ = *p++; |
|
4224 |
||
4225 |
*to++ = *p++; |
|
4226 |
||
4227 |
last_c_was_quote= 1; |
|
4228 |
}
|
|
4229 |
else
|
|
4230 |
{
|
|
4231 |
*to++ = *p++; |
|
4232 |
last_c_was_quote= 0; |
|
4233 |
}
|
|
4234 |
}
|
|
4235 |
}
|
|
4236 |
||
4237 |
||
4238 |
/*
|
|
4239 |
Check a command that is about to be sent (or should have been
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
4240 |
sent if parsing was enabled) to DRIZZLE server for
|
1
by brian
clean slate |
4241 |
suspicious things and generate warnings.
|
4242 |
*/
|
|
4243 |
||
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
4244 |
static void scan_command_for_warnings(struct st_command *command) |
1
by brian
clean slate |
4245 |
{
|
4246 |
const char *ptr= command->query; |
|
4247 |
||
4248 |
while(*ptr) |
|
4249 |
{
|
|
4250 |
/*
|
|
4251 |
Look for query's that lines that start with a -- comment
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
4252 |
and has a drizzletest command
|
1
by brian
clean slate |
4253 |
*/
|
4254 |
if (ptr[0] == '\n' && |
|
4255 |
ptr[1] && ptr[1] == '-' && |
|
4256 |
ptr[2] && ptr[2] == '-' && |
|
4257 |
ptr[3]) |
|
4258 |
{
|
|
4259 |
uint type; |
|
4260 |
char save; |
|
4261 |
char *end, *start= (char*)ptr+3; |
|
4262 |
/* Skip leading spaces */
|
|
4263 |
while (*start && my_isspace(charset_info, *start)) |
|
4264 |
start++; |
|
4265 |
end= start; |
|
4266 |
/* Find end of command(next space) */
|
|
4267 |
while (*end && !my_isspace(charset_info, *end)) |
|
4268 |
end++; |
|
4269 |
save= *end; |
|
4270 |
*end= 0; |
|
4271 |
type= find_type(start, &command_typelib, 1+2); |
|
4272 |
if (type) |
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
4273 |
warning_msg("Embedded drizzletest command '--%s' detected in " |
1
by brian
clean slate |
4274 |
"query '%s' was this intentional? ", |
4275 |
start, command->query); |
|
4276 |
*end= save; |
|
4277 |
}
|
|
4278 |
||
4279 |
ptr++; |
|
4280 |
}
|
|
142.1.1
by Patrick
Removing DBUG from client |
4281 |
return; |
1
by brian
clean slate |
4282 |
}
|
4283 |
||
4284 |
/*
|
|
4285 |
Check for unexpected "junk" after the end of query
|
|
4286 |
This is normally caused by missing delimiters or when
|
|
4287 |
switching between different delimiters
|
|
4288 |
*/
|
|
4289 |
||
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
4290 |
static void check_eol_junk_line(const char *line) |
1
by brian
clean slate |
4291 |
{
|
4292 |
const char *p= line; |
|
4293 |
||
4294 |
/* Check for extra delimiter */
|
|
4295 |
if (*p && !strncmp(p, delimiter, delimiter_length)) |
|
4296 |
die("Extra delimiter \"%s\" found", delimiter); |
|
4297 |
||
4298 |
/* Allow trailing # comment */
|
|
4299 |
if (*p && *p != '#') |
|
4300 |
{
|
|
4301 |
if (*p == '\n') |
|
4302 |
die("Missing delimiter"); |
|
4303 |
die("End of line junk detected: \"%s\"", p); |
|
4304 |
}
|
|
142.1.1
by Patrick
Removing DBUG from client |
4305 |
return; |
1
by brian
clean slate |
4306 |
}
|
4307 |
||
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
4308 |
static void check_eol_junk(const char *eol) |
1
by brian
clean slate |
4309 |
{
|
4310 |
const char *p= eol; |
|
4311 |
||
4312 |
/* Skip past all spacing chars and comments */
|
|
4313 |
while (*p && (my_isspace(charset_info, *p) || *p == '#' || *p == '\n')) |
|
4314 |
{
|
|
4315 |
/* Skip past comments started with # and ended with newline */
|
|
4316 |
if (*p && *p == '#') |
|
4317 |
{
|
|
4318 |
p++; |
|
4319 |
while (*p && *p != '\n') |
|
4320 |
p++; |
|
4321 |
}
|
|
4322 |
||
4323 |
/* Check this line */
|
|
4324 |
if (*p && *p == '\n') |
|
4325 |
check_eol_junk_line(p); |
|
4326 |
||
4327 |
if (*p) |
|
4328 |
p++; |
|
4329 |
}
|
|
4330 |
||
4331 |
check_eol_junk_line(p); |
|
4332 |
||
142.1.1
by Patrick
Removing DBUG from client |
4333 |
return; |
1
by brian
clean slate |
4334 |
}
|
4335 |
||
4336 |
||
4337 |
||
4338 |
/*
|
|
4339 |
Create a command from a set of lines
|
|
4340 |
||
4341 |
SYNOPSIS
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
4342 |
read_command()
|
4343 |
command_ptr pointer where to return the new query
|
|
1
by brian
clean slate |
4344 |
|
4345 |
DESCRIPTION
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
4346 |
Converts lines returned by read_line into a command, this involves
|
4347 |
parsing the first word in the read line to find the command type.
|
|
1
by brian
clean slate |
4348 |
|
4349 |
A -- comment may contain a valid query as the first word after the
|
|
4350 |
comment start. Thus it's always checked to see if that is the case.
|
|
4351 |
The advantage with this approach is to be able to execute commands
|
|
4352 |
terminated by new line '\n' regardless how many "delimiter" it contain.
|
|
4353 |
*/
|
|
4354 |
||
4355 |
#define MAX_QUERY (256*1024*2) /* 256K -- a test in sp-big is >128K */ |
|
4356 |
static char read_command_buf[MAX_QUERY]; |
|
4357 |
||
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
4358 |
static int read_command(struct st_command** command_ptr) |
1
by brian
clean slate |
4359 |
{
|
4360 |
char *p= read_command_buf; |
|
4361 |
struct st_command* command; |
|
142.1.1
by Patrick
Removing DBUG from client |
4362 |
|
1
by brian
clean slate |
4363 |
|
4364 |
if (parser.current_line < parser.read_lines) |
|
4365 |
{
|
|
373.1.6
by Monty Taylor
Moved q_lines to vector. |
4366 |
*command_ptr= q_lines[parser.current_line]; |
142.1.1
by Patrick
Removing DBUG from client |
4367 |
return(0); |
1
by brian
clean slate |
4368 |
}
|
4369 |
if (!(*command_ptr= command= |
|
4370 |
(struct st_command*) my_malloc(sizeof(*command), |
|
373.1.6
by Monty Taylor
Moved q_lines to vector. |
4371 |
MYF(MY_WME|MY_ZEROFILL)))) |
461
by Monty Taylor
Removed NullS. bu-bye. |
4372 |
die(NULL); |
373.1.6
by Monty Taylor
Moved q_lines to vector. |
4373 |
q_lines.push_back(command); |
1
by brian
clean slate |
4374 |
command->type= Q_UNKNOWN; |
4375 |
||
4376 |
read_command_buf[0]= 0; |
|
4377 |
if (read_line(read_command_buf, sizeof(read_command_buf))) |
|
4378 |
{
|
|
4379 |
check_eol_junk(read_command_buf); |
|
142.1.1
by Patrick
Removing DBUG from client |
4380 |
return(1); |
1
by brian
clean slate |
4381 |
}
|
4382 |
||
4383 |
convert_to_format_v1(read_command_buf); |
|
4384 |
||
4385 |
if (*p == '#') |
|
4386 |
{
|
|
4387 |
command->type= Q_COMMENT; |
|
4388 |
}
|
|
4389 |
else if (p[0] == '-' && p[1] == '-') |
|
4390 |
{
|
|
4391 |
command->type= Q_COMMENT_WITH_COMMAND; |
|
4392 |
p+= 2; /* Skip past -- */ |
|
4393 |
}
|
|
4394 |
||
4395 |
/* Skip leading spaces */
|
|
4396 |
while (*p && my_isspace(charset_info, *p)) |
|
4397 |
p++; |
|
4398 |
||
4399 |
if (!(command->query_buf= command->query= my_strdup(p, MYF(MY_WME)))) |
|
4400 |
die("Out of memory"); |
|
4401 |
||
4402 |
/* Calculate first word length(the command), terminated by space or ( */
|
|
4403 |
p= command->query; |
|
4404 |
while (*p && !my_isspace(charset_info, *p) && *p != '(') |
|
4405 |
p++; |
|
4406 |
command->first_word_len= (uint) (p - command->query); |
|
4407 |
||
4408 |
/* Skip spaces between command and first argument */
|
|
4409 |
while (*p && my_isspace(charset_info, *p)) |
|
4410 |
p++; |
|
4411 |
command->first_argument= p; |
|
4412 |
||
376
by Brian Aker
strend remove |
4413 |
command->end= strchr(command->query, '\0'); |
1
by brian
clean slate |
4414 |
command->query_len= (command->end - command->query); |
4415 |
parser.read_lines++; |
|
142.1.1
by Patrick
Removing DBUG from client |
4416 |
return(0); |
1
by brian
clean slate |
4417 |
}
|
4418 |
||
4419 |
||
4420 |
static struct my_option my_long_options[] = |
|
4421 |
{
|
|
4422 |
{"help", '?', "Display this help and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, |
|
4423 |
0, 0, 0, 0, 0, 0}, |
|
77.1.77
by Monty Taylor
A crapton more warning cleanups (I turned on more warnings) |
4424 |
{"basedir", 'b', "Basedir for tests.", (char**) &opt_basedir, |
4425 |
(char**) &opt_basedir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, |
|
1
by brian
clean slate |
4426 |
{"character-sets-dir", OPT_CHARSETS_DIR, |
77.1.77
by Monty Taylor
A crapton more warning cleanups (I turned on more warnings) |
4427 |
"Directory where character sets are.", (char**) &opt_charsets_dir, |
4428 |
(char**) &opt_charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, |
|
1
by brian
clean slate |
4429 |
{"compress", 'C', "Use the compressed server/client protocol.", |
77.1.77
by Monty Taylor
A crapton more warning cleanups (I turned on more warnings) |
4430 |
(char**) &opt_compress, (char**) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0, |
1
by brian
clean slate |
4431 |
0, 0, 0}, |
77.1.77
by Monty Taylor
A crapton more warning cleanups (I turned on more warnings) |
4432 |
{"database", 'D', "Database to use.", (char**) &opt_db, (char**) &opt_db, 0, |
1
by brian
clean slate |
4433 |
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, |
4434 |
{"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit.", |
|
77.1.77
by Monty Taylor
A crapton more warning cleanups (I turned on more warnings) |
4435 |
(char**) &debug_check_flag, (char**) &debug_check_flag, 0, |
1
by brian
clean slate |
4436 |
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, |
4437 |
{"debug-info", OPT_DEBUG_INFO, "Print some debug info at exit.", |
|
77.1.77
by Monty Taylor
A crapton more warning cleanups (I turned on more warnings) |
4438 |
(char**) &debug_info_flag, (char**) &debug_info_flag, |
1
by brian
clean slate |
4439 |
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, |
77.1.77
by Monty Taylor
A crapton more warning cleanups (I turned on more warnings) |
4440 |
{"host", 'h', "Connect to host.", (char**) &opt_host, (char**) &opt_host, 0, |
1
by brian
clean slate |
4441 |
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, |
77.1.77
by Monty Taylor
A crapton more warning cleanups (I turned on more warnings) |
4442 |
{"include", 'i', "Include SQL before each test case.", (char**) &opt_include, |
4443 |
(char**) &opt_include, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, |
|
4444 |
{"logdir", OPT_LOG_DIR, "Directory for log files", (char**) &opt_logdir, |
|
4445 |
(char**) &opt_logdir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, |
|
1
by brian
clean slate |
4446 |
{"mark-progress", OPT_MARK_PROGRESS, |
4447 |
"Write linenumber and elapsed time to <testname>.progress ", |
|
77.1.77
by Monty Taylor
A crapton more warning cleanups (I turned on more warnings) |
4448 |
(char**) &opt_mark_progress, (char**) &opt_mark_progress, 0, |
1
by brian
clean slate |
4449 |
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, |
4450 |
{"max-connect-retries", OPT_MAX_CONNECT_RETRIES, |
|
4451 |
"Max number of connection attempts when connecting to server", |
|
77.1.77
by Monty Taylor
A crapton more warning cleanups (I turned on more warnings) |
4452 |
(char**) &opt_max_connect_retries, (char**) &opt_max_connect_retries, 0, |
1
by brian
clean slate |
4453 |
GET_INT, REQUIRED_ARG, 500, 1, 10000, 0, 0, 0}, |
4454 |
{"password", 'p', "Password to use when connecting to server.", |
|
4455 |
0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, |
|
4456 |
{"port", 'P', "Port number to use for connection or 0 for default to, in " |
|
301
by Brian Aker
Clean up port startup |
4457 |
"order of preference, my.cnf, $DRIZZLE_TCP_PORT, "
|
4458 |
"built-in default (" STRINGIFY_ARG(DRIZZLE_PORT) ").", |
|
77.1.77
by Monty Taylor
A crapton more warning cleanups (I turned on more warnings) |
4459 |
(char**) &opt_port, |
4460 |
(char**) &opt_port, 0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, |
|
4461 |
{"quiet", 's', "Suppress all normal output.", (char**) &silent, |
|
4462 |
(char**) &silent, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, |
|
1
by brian
clean slate |
4463 |
{"record", 'r', "Record output of test_file into result file.", |
4464 |
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, |
|
4465 |
{"result-file", 'R', "Read/Store result from/in this file.", |
|
77.1.77
by Monty Taylor
A crapton more warning cleanups (I turned on more warnings) |
4466 |
(char**) &result_file_name, (char**) &result_file_name, 0, |
1
by brian
clean slate |
4467 |
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, |
4468 |
{"server-arg", 'A', "Send option value to embedded server as a parameter.", |
|
4469 |
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, |
|
4470 |
{"server-file", 'F', "Read embedded server arguments from file.", |
|
4471 |
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, |
|
4472 |
{"silent", 's', "Suppress all normal output. Synonym for --quiet.", |
|
77.1.77
by Monty Taylor
A crapton more warning cleanups (I turned on more warnings) |
4473 |
(char**) &silent, (char**) &silent, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, |
1
by brian
clean slate |
4474 |
{"sleep", 'T', "Sleep always this many seconds on sleep commands.", |
77.1.77
by Monty Taylor
A crapton more warning cleanups (I turned on more warnings) |
4475 |
(char**) &opt_sleep, (char**) &opt_sleep, 0, GET_INT, REQUIRED_ARG, -1, -1, 0, |
1
by brian
clean slate |
4476 |
0, 0, 0}, |
4477 |
{"tail-lines", OPT_TAIL_LINES, |
|
4478 |
"Number of lines of the resul to include in a failure report", |
|
77.1.77
by Monty Taylor
A crapton more warning cleanups (I turned on more warnings) |
4479 |
(char**) &opt_tail_lines, (char**) &opt_tail_lines, 0, |
1
by brian
clean slate |
4480 |
GET_INT, REQUIRED_ARG, 0, 0, 10000, 0, 0, 0}, |
4481 |
{"test-file", 'x', "Read test from/in this file (default stdin).", |
|
4482 |
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, |
|
4483 |
{"timer-file", 'm', "File where the timing in micro seconds is stored.", |
|
4484 |
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, |
|
4485 |
{"tmpdir", 't', "Temporary directory where sockets are put.", |
|
4486 |
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, |
|
77.1.77
by Monty Taylor
A crapton more warning cleanups (I turned on more warnings) |
4487 |
{"user", 'u', "User for login.", (char**) &opt_user, (char**) &opt_user, 0, |
1
by brian
clean slate |
4488 |
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, |
77.1.77
by Monty Taylor
A crapton more warning cleanups (I turned on more warnings) |
4489 |
{"verbose", 'v', "Write more.", (char**) &verbose, (char**) &verbose, 0, |
1
by brian
clean slate |
4490 |
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, |
4491 |
{"version", 'V', "Output version information and exit.", |
|
4492 |
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, |
|
4493 |
{ 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} |
|
4494 |
};
|
|
4495 |
||
4496 |
||
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
4497 |
static void print_version(void) |
1
by brian
clean slate |
4498 |
{
|
4499 |
printf("%s Ver %s Distrib %s, for %s (%s)\n",my_progname,MTEST_VERSION, |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
4500 |
drizzle_get_client_info(),SYSTEM_TYPE,MACHINE_TYPE); |
1
by brian
clean slate |
4501 |
}
|
4502 |
||
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
4503 |
static void usage(void) |
1
by brian
clean slate |
4504 |
{
|
4505 |
print_version(); |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
4506 |
printf("MySQL AB, by Sasha, Matt, Monty & Jani\n"); |
1
by brian
clean slate |
4507 |
printf("This software comes with ABSOLUTELY NO WARRANTY\n\n"); |
206.3.1
by Patrick Galbraith
Most everything working with client rename |
4508 |
printf("Runs a test against the DRIZZLE server and compares output with a results file.\n\n"); |
1
by brian
clean slate |
4509 |
printf("Usage: %s [OPTIONS] [database] < test_file\n", my_progname); |
4510 |
my_print_help(my_long_options); |
|
4511 |
printf(" --no-defaults Don't read default options from any options file.\n"); |
|
4512 |
my_print_variables(my_long_options); |
|
4513 |
}
|
|
4514 |
||
4515 |
/*
|
|
4516 |
Read arguments for embedded server and put them into
|
|
4517 |
embedded_server_args[]
|
|
4518 |
*/
|
|
4519 |
||
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
4520 |
static void read_embedded_server_arguments(const char *name) |
1
by brian
clean slate |
4521 |
{
|
4522 |
char argument[1024],buff[FN_REFLEN], *str=0; |
|
4523 |
FILE *file; |
|
4524 |
||
4525 |
if (!test_if_hard_path(name)) |
|
4526 |
{
|
|
461
by Monty Taylor
Removed NullS. bu-bye. |
4527 |
strxmov(buff, opt_basedir, name, NULL); |
1
by brian
clean slate |
4528 |
name=buff; |
4529 |
}
|
|
4530 |
fn_format(buff, name, "", "", MY_UNPACK_FILENAME); |
|
4531 |
||
4532 |
if (!embedded_server_arg_count) |
|
4533 |
{
|
|
4534 |
embedded_server_arg_count=1; |
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
4535 |
embedded_server_args[0]= (char*) ""; /* Progname */ |
1
by brian
clean slate |
4536 |
}
|
492.1.14
by Monty Taylor
Removed O_BINARY and FILE_BINARY. |
4537 |
if (!(file=my_fopen(buff, O_RDONLY, MYF(MY_WME)))) |
1
by brian
clean slate |
4538 |
die("Failed to open file '%s'", buff); |
4539 |
||
4540 |
while (embedded_server_arg_count < MAX_EMBEDDED_SERVER_ARGS && |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
4541 |
(str=fgets(argument,sizeof(argument), file))) |
1
by brian
clean slate |
4542 |
{
|
376
by Brian Aker
strend remove |
4543 |
*(strchr(str, '\0')-1)=0; /* Remove end newline */ |
1
by brian
clean slate |
4544 |
if (!(embedded_server_args[embedded_server_arg_count]= |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
4545 |
(char*) my_strdup(str,MYF(MY_WME)))) |
1
by brian
clean slate |
4546 |
{
|
4547 |
my_fclose(file,MYF(0)); |
|
4548 |
die("Out of memory"); |
|
4549 |
||
4550 |
}
|
|
4551 |
embedded_server_arg_count++; |
|
4552 |
}
|
|
4553 |
my_fclose(file,MYF(0)); |
|
4554 |
if (str) |
|
4555 |
die("Too many arguments in option file: %s",name); |
|
4556 |
||
4557 |
return; |
|
4558 |
}
|
|
4559 |
||
4560 |
||
143
by Brian Aker
Bool cleanup. |
4561 |
static bool |
1
by brian
clean slate |
4562 |
get_one_option(int optid, const struct my_option *opt __attribute__((unused)), |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
4563 |
char *argument) |
1
by brian
clean slate |
4564 |
{
|
4565 |
switch(optid) { |
|
4566 |
case 'r': |
|
4567 |
record = 1; |
|
4568 |
break; |
|
4569 |
case 'x': |
|
4570 |
{
|
|
4571 |
char buff[FN_REFLEN]; |
|
4572 |
if (!test_if_hard_path(argument)) |
|
4573 |
{
|
|
461
by Monty Taylor
Removed NullS. bu-bye. |
4574 |
strxmov(buff, opt_basedir, argument, NULL); |
1
by brian
clean slate |
4575 |
argument= buff; |
4576 |
}
|
|
4577 |
fn_format(buff, argument, "", "", MY_UNPACK_FILENAME); |
|
142.1.2
by Patrick
All DBUG_x removed from client/ |
4578 |
assert(cur_file == file_stack && cur_file->file == 0); |
1
by brian
clean slate |
4579 |
if (!(cur_file->file= |
492.1.15
by Monty Taylor
Missed a FILE_BINARY |
4580 |
my_fopen(buff, O_RDONLY, MYF(0)))) |
1
by brian
clean slate |
4581 |
die("Could not open '%s' for reading: errno = %d", buff, errno); |
4582 |
cur_file->file_name= my_strdup(buff, MYF(MY_FAE)); |
|
4583 |
cur_file->lineno= 1; |
|
4584 |
break; |
|
4585 |
}
|
|
4586 |
case 'm': |
|
4587 |
{
|
|
4588 |
static char buff[FN_REFLEN]; |
|
4589 |
if (!test_if_hard_path(argument)) |
|
4590 |
{
|
|
461
by Monty Taylor
Removed NullS. bu-bye. |
4591 |
strxmov(buff, opt_basedir, argument, NULL); |
1
by brian
clean slate |
4592 |
argument= buff; |
4593 |
}
|
|
4594 |
fn_format(buff, argument, "", "", MY_UNPACK_FILENAME); |
|
4595 |
timer_file= buff; |
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
4596 |
unlink(timer_file); /* Ignore error, may not exist */ |
1
by brian
clean slate |
4597 |
break; |
4598 |
}
|
|
4599 |
case 'p': |
|
4600 |
if (argument) |
|
4601 |
{
|
|
477
by Monty Taylor
Removed my_free(). It turns out that it had been def'd to ignore the flags passed to it in the second arg anyway. Gotta love that. |
4602 |
free(opt_pass); |
1
by brian
clean slate |
4603 |
opt_pass= my_strdup(argument, MYF(MY_FAE)); |
206.3.1
by Patrick Galbraith
Most everything working with client rename |
4604 |
while (*argument) *argument++= 'x'; /* Destroy argument */ |
1
by brian
clean slate |
4605 |
tty_password= 0; |
4606 |
}
|
|
4607 |
else
|
|
4608 |
tty_password= 1; |
|
4609 |
break; |
|
4610 |
case 't': |
|
411.1.1
by Brian Aker
Work on removing GNU specific calls. |
4611 |
my_stpncpy(TMPDIR, argument, sizeof(TMPDIR)); |
1
by brian
clean slate |
4612 |
break; |
4613 |
case 'A': |
|
4614 |
if (!embedded_server_arg_count) |
|
4615 |
{
|
|
4616 |
embedded_server_arg_count=1; |
|
4617 |
embedded_server_args[0]= (char*) ""; |
|
4618 |
}
|
|
4619 |
if (embedded_server_arg_count == MAX_EMBEDDED_SERVER_ARGS-1 || |
|
4620 |
!(embedded_server_args[embedded_server_arg_count++]= |
|
4621 |
my_strdup(argument, MYF(MY_FAE)))) |
|
4622 |
{
|
|
4623 |
die("Can't use server argument"); |
|
4624 |
}
|
|
4625 |
break; |
|
4626 |
case 'F': |
|
4627 |
read_embedded_server_arguments(argument); |
|
4628 |
break; |
|
4629 |
case 'V': |
|
4630 |
print_version(); |
|
4631 |
exit(0); |
|
4632 |
case '?': |
|
4633 |
usage(); |
|
4634 |
exit(0); |
|
4635 |
}
|
|
4636 |
return 0; |
|
4637 |
}
|
|
4638 |
||
4639 |
||
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
4640 |
static int parse_args(int argc, char **argv) |
1
by brian
clean slate |
4641 |
{
|
4642 |
load_defaults("my",load_default_groups,&argc,&argv); |
|
4643 |
default_argv= argv; |
|
4644 |
||
4645 |
if ((handle_options(&argc, &argv, my_long_options, get_one_option))) |
|
4646 |
exit(1); |
|
4647 |
||
4648 |
if (argc > 1) |
|
4649 |
{
|
|
4650 |
usage(); |
|
4651 |
exit(1); |
|
4652 |
}
|
|
4653 |
if (argc == 1) |
|
4654 |
opt_db= *argv; |
|
4655 |
if (tty_password) |
|
461
by Monty Taylor
Removed NullS. bu-bye. |
4656 |
opt_pass= get_tty_password(NULL); /* purify tested */ |
1
by brian
clean slate |
4657 |
if (debug_info_flag) |
4658 |
my_end_arg= MY_CHECK_ERROR | MY_GIVE_INFO; |
|
4659 |
if (debug_check_flag) |
|
4660 |
my_end_arg= MY_CHECK_ERROR; |
|
4661 |
||
4662 |
return 0; |
|
4663 |
}
|
|
4664 |
||
4665 |
/*
|
|
4666 |
Write the content of str into file
|
|
4667 |
||
4668 |
SYNOPSIS
|
|
4669 |
str_to_file2
|
|
4670 |
fname - name of file to truncate/create and write to
|
|
4671 |
str - content to write to file
|
|
4672 |
size - size of content witten to file
|
|
4673 |
append - append to file instead of overwriting old file
|
|
4674 |
*/
|
|
4675 |
||
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
4676 |
void str_to_file2(const char *fname, const char *str, int size, bool append) |
1
by brian
clean slate |
4677 |
{
|
4678 |
int fd; |
|
4679 |
char buff[FN_REFLEN]; |
|
4680 |
int flags= O_WRONLY | O_CREAT; |
|
4681 |
if (!test_if_hard_path(fname)) |
|
4682 |
{
|
|
461
by Monty Taylor
Removed NullS. bu-bye. |
4683 |
strxmov(buff, opt_basedir, fname, NULL); |
1
by brian
clean slate |
4684 |
fname= buff; |
4685 |
}
|
|
4686 |
fn_format(buff, fname, "", "", MY_UNPACK_FILENAME); |
|
4687 |
||
4688 |
if (!append) |
|
4689 |
flags|= O_TRUNC; |
|
4690 |
if ((fd= my_open(buff, flags, |
|
4691 |
MYF(MY_WME | MY_FFNF))) < 0) |
|
4692 |
die("Could not open '%s' for writing: errno = %d", buff, errno); |
|
4693 |
if (append && my_seek(fd, 0, SEEK_END, MYF(0)) == MY_FILEPOS_ERROR) |
|
4694 |
die("Could not find end of file '%s': errno = %d", buff, errno); |
|
481
by Brian Aker
Remove all of uchar. |
4695 |
if (my_write(fd, (unsigned char*)str, size, MYF(MY_WME|MY_FNABP))) |
1
by brian
clean slate |
4696 |
die("write failed"); |
4697 |
my_close(fd, MYF(0)); |
|
4698 |
}
|
|
4699 |
||
4700 |
/*
|
|
4701 |
Write the content of str into file
|
|
4702 |
||
4703 |
SYNOPSIS
|
|
4704 |
str_to_file
|
|
4705 |
fname - name of file to truncate/create and write to
|
|
4706 |
str - content to write to file
|
|
4707 |
size - size of content witten to file
|
|
4708 |
*/
|
|
4709 |
||
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
4710 |
void str_to_file(const char *fname, const char *str, int size) |
1
by brian
clean slate |
4711 |
{
|
163
by Brian Aker
Merge Monty's code. |
4712 |
str_to_file2(fname, str, size, false); |
1
by brian
clean slate |
4713 |
}
|
4714 |
||
4715 |
||
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
4716 |
void dump_result_to_log_file(const char *buf, int size) |
1
by brian
clean slate |
4717 |
{
|
4718 |
char log_file[FN_REFLEN]; |
|
4719 |
str_to_file(fn_format(log_file, result_file_name, opt_logdir, ".log", |
|
4720 |
*opt_logdir ? MY_REPLACE_DIR | MY_REPLACE_EXT : |
|
4721 |
MY_REPLACE_EXT), |
|
4722 |
buf, size); |
|
4723 |
fprintf(stderr, "\nMore results from queries before failure can be found in %s\n", |
|
4724 |
log_file); |
|
4725 |
}
|
|
4726 |
||
4727 |
void dump_progress(void) |
|
4728 |
{
|
|
4729 |
char progress_file[FN_REFLEN]; |
|
4730 |
str_to_file(fn_format(progress_file, result_file_name, |
|
4731 |
opt_logdir, ".progress", |
|
4732 |
*opt_logdir ? MY_REPLACE_DIR | MY_REPLACE_EXT : |
|
4733 |
MY_REPLACE_EXT), |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
4734 |
ds_progress.c_str(), ds_progress.length()); |
1
by brian
clean slate |
4735 |
}
|
4736 |
||
4737 |
void dump_warning_messages(void) |
|
4738 |
{
|
|
4739 |
char warn_file[FN_REFLEN]; |
|
4740 |
||
4741 |
str_to_file(fn_format(warn_file, result_file_name, opt_logdir, ".warnings", |
|
4742 |
*opt_logdir ? MY_REPLACE_DIR | MY_REPLACE_EXT : |
|
4743 |
MY_REPLACE_EXT), |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
4744 |
ds_warning_messages.c_str(), ds_warning_messages.length()); |
1
by brian
clean slate |
4745 |
}
|
4746 |
||
4747 |
||
4748 |
/*
|
|
4749 |
Append the result for one field to the dynamic string ds
|
|
4750 |
*/
|
|
4751 |
||
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
4752 |
static void append_field(string *ds, uint col_idx, const DRIZZLE_FIELD* field, |
151
by Brian Aker
Ulonglong to uint64_t |
4753 |
const char* val, uint64_t len, bool is_null) |
1
by brian
clean slate |
4754 |
{
|
4755 |
if (col_idx < max_replace_column && replace_column[col_idx]) |
|
4756 |
{
|
|
4757 |
val= replace_column[col_idx]; |
|
4758 |
len= strlen(val); |
|
4759 |
}
|
|
4760 |
else if (is_null) |
|
4761 |
{
|
|
4762 |
val= "NULL"; |
|
4763 |
len= 4; |
|
4764 |
}
|
|
4765 |
||
4766 |
if (!display_result_vertically) |
|
4767 |
{
|
|
4768 |
if (col_idx) |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
4769 |
ds->append("\t"); |
4770 |
replace_append_mem(ds, val, (int)len); |
|
1
by brian
clean slate |
4771 |
}
|
4772 |
else
|
|
4773 |
{
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
4774 |
ds->append(field->name); |
4775 |
ds->append("\t"); |
|
4776 |
replace_append_mem(ds, val, (int)len); |
|
4777 |
ds->append("\n"); |
|
1
by brian
clean slate |
4778 |
}
|
4779 |
}
|
|
4780 |
||
4781 |
||
4782 |
/*
|
|
4783 |
Append all results to the dynamic string separated with '\t'
|
|
4784 |
Values may be converted with 'replace_column'
|
|
4785 |
*/
|
|
4786 |
||
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
4787 |
static void append_result(string *ds, DRIZZLE_RES *res) |
1
by brian
clean slate |
4788 |
{
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
4789 |
DRIZZLE_ROW row; |
4790 |
uint32_t num_fields= drizzle_num_fields(res); |
|
236.3.5
by Andrey Hristov
Constify libdrizzle functions |
4791 |
const DRIZZLE_FIELD *fields= drizzle_fetch_fields(res); |
164
by Brian Aker
Commit cleanup of export types. |
4792 |
uint32_t *lengths; |
1
by brian
clean slate |
4793 |
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
4794 |
while ((row = drizzle_fetch_row(res))) |
1
by brian
clean slate |
4795 |
{
|
164
by Brian Aker
Commit cleanup of export types. |
4796 |
uint32_t i; |
206.3.1
by Patrick Galbraith
Most everything working with client rename |
4797 |
lengths = drizzle_fetch_lengths(res); |
1
by brian
clean slate |
4798 |
for (i = 0; i < num_fields; i++) |
4799 |
append_field(ds, i, &fields[i], |
|
4800 |
(const char*)row[i], lengths[i], !row[i]); |
|
4801 |
if (!display_result_vertically) |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
4802 |
ds->append("\n"); |
4803 |
||
1
by brian
clean slate |
4804 |
}
|
4805 |
}
|
|
4806 |
||
4807 |
||
4808 |
/*
|
|
4809 |
Append metadata for fields to output
|
|
4810 |
*/
|
|
4811 |
||
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
4812 |
static void append_metadata(string *ds, |
236.3.5
by Andrey Hristov
Constify libdrizzle functions |
4813 |
const DRIZZLE_FIELD *field, |
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
4814 |
uint num_fields) |
1
by brian
clean slate |
4815 |
{
|
236.3.5
by Andrey Hristov
Constify libdrizzle functions |
4816 |
const DRIZZLE_FIELD *field_end; |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
4817 |
ds->append("Catalog\tDatabase\tTable\tTable_alias\tColumn\t" |
4818 |
"Column_alias\tType\tLength\tMax length\tIs_null\t" |
|
4819 |
"Flags\tDecimals\tCharsetnr\n"); |
|
1
by brian
clean slate |
4820 |
|
4821 |
for (field_end= field+num_fields ; |
|
4822 |
field < field_end ; |
|
4823 |
field++) |
|
4824 |
{
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
4825 |
ds->append(field->catalog, |
4826 |
field->catalog_length); |
|
4827 |
ds->append("\t", 1); |
|
4828 |
ds->append(field->db, field->db_length); |
|
4829 |
ds->append("\t", 1); |
|
4830 |
ds->append(field->org_table, |
|
4831 |
field->org_table_length); |
|
4832 |
ds->append("\t", 1); |
|
4833 |
ds->append(field->table, |
|
4834 |
field->table_length); |
|
4835 |
ds->append("\t", 1); |
|
4836 |
ds->append(field->org_name, |
|
4837 |
field->org_name_length); |
|
4838 |
ds->append("\t", 1); |
|
4839 |
ds->append(field->name, field->name_length); |
|
4840 |
ds->append("\t", 1); |
|
4841 |
replace_append_uint(ds, field->type); |
|
4842 |
ds->append("\t", 1); |
|
4843 |
replace_append_uint(ds, field->length); |
|
4844 |
ds->append("\t", 1); |
|
4845 |
replace_append_uint(ds, field->max_length); |
|
4846 |
ds->append("\t", 1); |
|
383.1.45
by Monty Taylor
libdrizzle.h cleanup. Removed some unused things. Started splitting header into |
4847 |
ds->append((char*) ((field->flags & NOT_NULL_FLAG) ? |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
4848 |
"N" : "Y"), 1); |
4849 |
ds->append("\t", 1); |
|
4850 |
replace_append_uint(ds, field->flags); |
|
4851 |
ds->append("\t", 1); |
|
4852 |
replace_append_uint(ds, field->decimals); |
|
4853 |
ds->append("\t", 1); |
|
4854 |
replace_append_uint(ds, field->charsetnr); |
|
4855 |
ds->append("\n", 1); |
|
1
by brian
clean slate |
4856 |
}
|
4857 |
}
|
|
4858 |
||
4859 |
||
4860 |
/*
|
|
4861 |
Append affected row count and other info to output
|
|
4862 |
*/
|
|
4863 |
||
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
4864 |
static void append_info(string *ds, uint64_t affected_rows, |
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
4865 |
const char *info) |
1
by brian
clean slate |
4866 |
{
|
4867 |
char buf[40], buff2[21]; |
|
4868 |
sprintf(buf,"affected rows: %s\n", llstr(affected_rows, buff2)); |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
4869 |
ds->append(buf); |
1
by brian
clean slate |
4870 |
if (info) |
4871 |
{
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
4872 |
ds->append("info: "); |
4873 |
ds->append(info); |
|
4874 |
ds->append("\n", 1); |
|
1
by brian
clean slate |
4875 |
}
|
4876 |
}
|
|
4877 |
||
4878 |
||
4879 |
/*
|
|
4880 |
Display the table headings with the names tab separated
|
|
4881 |
*/
|
|
4882 |
||
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
4883 |
static void append_table_headings(string *ds, |
236.3.5
by Andrey Hristov
Constify libdrizzle functions |
4884 |
const DRIZZLE_FIELD *field, |
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
4885 |
uint num_fields) |
1
by brian
clean slate |
4886 |
{
|
4887 |
uint col_idx; |
|
4888 |
for (col_idx= 0; col_idx < num_fields; col_idx++) |
|
4889 |
{
|
|
4890 |
if (col_idx) |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
4891 |
ds->append("\t", 1); |
4892 |
replace_append(ds, field[col_idx].name); |
|
1
by brian
clean slate |
4893 |
}
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
4894 |
ds->append("\n", 1); |
1
by brian
clean slate |
4895 |
}
|
4896 |
||
4897 |
/*
|
|
4898 |
Fetch warnings from server and append to ds
|
|
4899 |
||
4900 |
RETURN VALUE
|
|
4901 |
Number of warnings appended to ds
|
|
4902 |
*/
|
|
4903 |
||
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
4904 |
static int append_warnings(string *ds, DRIZZLE *drizzle) |
1
by brian
clean slate |
4905 |
{
|
4906 |
uint count; |
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
4907 |
DRIZZLE_RES *warn_res; |
4908 |
||
4909 |
||
4910 |
if (!(count= drizzle_warning_count(drizzle))) |
|
142.1.1
by Patrick
Removing DBUG from client |
4911 |
return(0); |
1
by brian
clean slate |
4912 |
|
4913 |
/*
|
|
4914 |
If one day we will support execution of multi-statements
|
|
4915 |
through PS API we should not issue SHOW WARNINGS until
|
|
4916 |
we have not read all results...
|
|
4917 |
*/
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
4918 |
assert(!drizzle_more_results(drizzle)); |
4919 |
||
4920 |
if (drizzle_real_query(drizzle, "SHOW WARNINGS", 13)) |
|
4921 |
die("Error running query \"SHOW WARNINGS\": %s", drizzle_error(drizzle)); |
|
4922 |
||
4923 |
if (!(warn_res= drizzle_store_result(drizzle))) |
|
1
by brian
clean slate |
4924 |
die("Warning count is %u but didn't get any warnings", |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
4925 |
count); |
1
by brian
clean slate |
4926 |
|
4927 |
append_result(ds, warn_res); |
|
4928 |
||
142.1.1
by Patrick
Removing DBUG from client |
4929 |
return(count); |
1
by brian
clean slate |
4930 |
}
|
4931 |
||
4932 |
||
4933 |
/*
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
4934 |
Run query using DRIZZLE C API
|
1
by brian
clean slate |
4935 |
|
4936 |
SYNOPSIS
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
4937 |
run_query_normal()
|
4938 |
drizzle DRIZZLE handle
|
|
4939 |
command current command pointer
|
|
4940 |
flags flags indicating if we should SEND and/or REAP
|
|
4941 |
query query string to execute
|
|
4942 |
query_len length query string to execute
|
|
4943 |
ds output buffer where to store result form query
|
|
1
by brian
clean slate |
4944 |
*/
|
4945 |
||
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
4946 |
static void run_query_normal(struct st_connection *cn, |
4947 |
struct st_command *command, |
|
4948 |
int flags, char *query, int query_len, |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
4949 |
string *ds, string *ds_warnings) |
1
by brian
clean slate |
4950 |
{
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
4951 |
DRIZZLE_RES *res= 0; |
4952 |
DRIZZLE *drizzle= &cn->drizzle; |
|
1
by brian
clean slate |
4953 |
int err= 0, counter= 0; |
4954 |
||
4955 |
if (flags & QUERY_SEND_FLAG) |
|
4956 |
{
|
|
4957 |
/*
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
4958 |
* Send the query
|
4959 |
*/
|
|
1
by brian
clean slate |
4960 |
if (do_send_query(cn, query, query_len, flags)) |
4961 |
{
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
4962 |
handle_error(command, drizzle_errno(drizzle), drizzle_error(drizzle), |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
4963 |
drizzle_sqlstate(drizzle), ds); |
1
by brian
clean slate |
4964 |
goto end; |
4965 |
}
|
|
4966 |
}
|
|
4967 |
if (!(flags & QUERY_REAP_FLAG)) |
|
142.1.1
by Patrick
Removing DBUG from client |
4968 |
return; |
1
by brian
clean slate |
4969 |
|
4970 |
do
|
|
4971 |
{
|
|
4972 |
/*
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
4973 |
When on first result set, call drizzle_read_query_result to retrieve
|
1
by brian
clean slate |
4974 |
answer to the query sent earlier
|
4975 |
*/
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
4976 |
if ((counter==0) && drizzle_read_query_result(drizzle)) |
1
by brian
clean slate |
4977 |
{
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
4978 |
handle_error(command, drizzle_errno(drizzle), drizzle_error(drizzle), |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
4979 |
drizzle_sqlstate(drizzle), ds); |
1
by brian
clean slate |
4980 |
goto end; |
4981 |
||
4982 |
}
|
|
4983 |
||
4984 |
/*
|
|
4985 |
Store the result of the query if it will return any fields
|
|
4986 |
*/
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
4987 |
if (drizzle_field_count(drizzle) && ((res= drizzle_store_result(drizzle)) == 0)) |
1
by brian
clean slate |
4988 |
{
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
4989 |
handle_error(command, drizzle_errno(drizzle), drizzle_error(drizzle), |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
4990 |
drizzle_sqlstate(drizzle), ds); |
1
by brian
clean slate |
4991 |
goto end; |
4992 |
}
|
|
4993 |
||
4994 |
if (!disable_result_log) |
|
4995 |
{
|
|
151
by Brian Aker
Ulonglong to uint64_t |
4996 |
uint64_t affected_rows= 0; /* Ok to be undef if 'disable_info' is set */ |
1
by brian
clean slate |
4997 |
|
4998 |
if (res) |
|
4999 |
{
|
|
236.3.5
by Andrey Hristov
Constify libdrizzle functions |
5000 |
const DRIZZLE_FIELD *fields= drizzle_fetch_fields(res); |
5001 |
uint num_fields= drizzle_num_fields(res); |
|
1
by brian
clean slate |
5002 |
|
236.3.5
by Andrey Hristov
Constify libdrizzle functions |
5003 |
if (display_metadata) |
1
by brian
clean slate |
5004 |
append_metadata(ds, fields, num_fields); |
5005 |
||
236.3.5
by Andrey Hristov
Constify libdrizzle functions |
5006 |
if (!display_result_vertically) |
5007 |
append_table_headings(ds, fields, num_fields); |
|
1
by brian
clean slate |
5008 |
|
236.3.5
by Andrey Hristov
Constify libdrizzle functions |
5009 |
append_result(ds, res); |
1
by brian
clean slate |
5010 |
}
|
5011 |
||
5012 |
/*
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
5013 |
Need to call drizzle_affected_rows() before the "new"
|
1
by brian
clean slate |
5014 |
query to find the warnings
|
5015 |
*/
|
|
5016 |
if (!disable_info) |
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
5017 |
affected_rows= drizzle_affected_rows(drizzle); |
1
by brian
clean slate |
5018 |
|
5019 |
/*
|
|
5020 |
Add all warnings to the result. We can't do this if we are in
|
|
5021 |
the middle of processing results from multi-statement, because
|
|
5022 |
this will break protocol.
|
|
5023 |
*/
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
5024 |
if (!disable_warnings && !drizzle_more_results(drizzle)) |
1
by brian
clean slate |
5025 |
{
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
5026 |
if (append_warnings(ds_warnings, drizzle) || ds_warnings->length()) |
5027 |
{
|
|
5028 |
ds->append("Warnings:\n", 10); |
|
5029 |
ds->append(ds_warnings->c_str(), ds_warnings->length()); |
|
5030 |
}
|
|
1
by brian
clean slate |
5031 |
}
|
5032 |
||
5033 |
if (!disable_info) |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
5034 |
append_info(ds, affected_rows, drizzle_info(drizzle)); |
1
by brian
clean slate |
5035 |
}
|
5036 |
||
5037 |
if (res) |
|
5038 |
{
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
5039 |
drizzle_free_result(res); |
1
by brian
clean slate |
5040 |
res= 0; |
5041 |
}
|
|
5042 |
counter++; |
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
5043 |
} while (!(err= drizzle_next_result(drizzle))); |
1
by brian
clean slate |
5044 |
if (err > 0) |
5045 |
{
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
5046 |
/* We got an error from drizzle_next_result, maybe expected */
|
5047 |
handle_error(command, drizzle_errno(drizzle), drizzle_error(drizzle), |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
5048 |
drizzle_sqlstate(drizzle), ds); |
1
by brian
clean slate |
5049 |
goto end; |
5050 |
}
|
|
142.1.2
by Patrick
All DBUG_x removed from client/ |
5051 |
assert(err == -1); /* Successful and there are no more results */ |
1
by brian
clean slate |
5052 |
|
5053 |
/* If we come here the query is both executed and read successfully */
|
|
5054 |
handle_no_error(command); |
|
5055 |
||
5056 |
end: |
|
5057 |
||
5058 |
/*
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
5059 |
We save the return code (drizzle_errno(drizzle)) from the last call sent
|
5060 |
to the server into the drizzletest builtin variable $drizzle_errno. This
|
|
1
by brian
clean slate |
5061 |
variable then can be used from the test case itself.
|
5062 |
*/
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
5063 |
var_set_errno(drizzle_errno(drizzle)); |
142.1.1
by Patrick
Removing DBUG from client |
5064 |
return; |
1
by brian
clean slate |
5065 |
}
|
5066 |
||
5067 |
||
5068 |
/*
|
|
5069 |
Handle errors which occurred during execution
|
|
5070 |
||
5071 |
SYNOPSIS
|
|
5072 |
handle_error()
|
|
5073 |
q - query context
|
|
5074 |
err_errno - error number
|
|
5075 |
err_error - error message
|
|
5076 |
err_sqlstate - sql state
|
|
5077 |
ds - dynamic string which is used for output buffer
|
|
5078 |
||
5079 |
NOTE
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
5080 |
If there is an unexpected error this function will abort drizzletest
|
5081 |
immediately.
|
|
1
by brian
clean slate |
5082 |
*/
|
5083 |
||
5084 |
void handle_error(struct st_command *command, |
|
5085 |
unsigned int err_errno, const char *err_error, |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
5086 |
const char *err_sqlstate, string *ds) |
1
by brian
clean slate |
5087 |
{
|
5088 |
uint i; |
|
5089 |
||
142.1.1
by Patrick
Removing DBUG from client |
5090 |
|
1
by brian
clean slate |
5091 |
if (command->require_file[0]) |
5092 |
{
|
|
5093 |
/*
|
|
5094 |
The query after a "--require" failed. This is fine as long the server
|
|
5095 |
returned a valid reponse. Don't allow 2013 or 2006 to trigger an
|
|
5096 |
abort_not_supported_test
|
|
5097 |
*/
|
|
5098 |
if (err_errno == CR_SERVER_LOST || |
|
5099 |
err_errno == CR_SERVER_GONE_ERROR) |
|
5100 |
die("require query '%s' failed: %d: %s", command->query, |
|
5101 |
err_errno, err_error); |
|
5102 |
||
5103 |
/* Abort the run of this test, pass the failed query as reason */
|
|
5104 |
abort_not_supported_test("Query '%s' failed, required functionality " \ |
|
5105 |
"not supported", command->query); |
|
5106 |
}
|
|
5107 |
||
5108 |
if (command->abort_on_error) |
|
5109 |
die("query '%s' failed: %d: %s", command->query, err_errno, err_error); |
|
5110 |
||
5111 |
for (i= 0 ; (uint) i < command->expected_errors.count ; i++) |
|
5112 |
{
|
|
5113 |
if (((command->expected_errors.err[i].type == ERR_ERRNO) && |
|
5114 |
(command->expected_errors.err[i].code.errnum == err_errno)) || |
|
5115 |
((command->expected_errors.err[i].type == ERR_SQLSTATE) && |
|
5116 |
(strncmp(command->expected_errors.err[i].code.sqlstate, |
|
5117 |
err_sqlstate, SQLSTATE_LENGTH) == 0))) |
|
5118 |
{
|
|
5119 |
if (!disable_result_log) |
|
5120 |
{
|
|
5121 |
if (command->expected_errors.count == 1) |
|
5122 |
{
|
|
5123 |
/* Only log error if there is one possible error */
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
5124 |
ds->append("ERROR ", 6); |
5125 |
replace_append(ds, err_sqlstate); |
|
5126 |
ds->append(": ", 2); |
|
5127 |
replace_append(ds, err_error); |
|
5128 |
ds->append("\n",1); |
|
1
by brian
clean slate |
5129 |
}
|
5130 |
/* Don't log error if we may not get an error */
|
|
5131 |
else if (command->expected_errors.err[0].type == ERR_SQLSTATE || |
|
5132 |
(command->expected_errors.err[0].type == ERR_ERRNO && |
|
5133 |
command->expected_errors.err[0].code.errnum != 0)) |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
5134 |
ds->append("Got one of the listed errors\n"); |
1
by brian
clean slate |
5135 |
}
|
5136 |
/* OK */
|
|
142.1.1
by Patrick
Removing DBUG from client |
5137 |
return; |
1
by brian
clean slate |
5138 |
}
|
5139 |
}
|
|
5140 |
||
5141 |
if (!disable_result_log) |
|
5142 |
{
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
5143 |
ds->append("ERROR ",6); |
5144 |
replace_append(ds, err_sqlstate); |
|
5145 |
ds->append(": ", 2); |
|
5146 |
replace_append(ds, err_error); |
|
5147 |
ds->append("\n", 1); |
|
1
by brian
clean slate |
5148 |
}
|
5149 |
||
5150 |
if (i) |
|
5151 |
{
|
|
5152 |
if (command->expected_errors.err[0].type == ERR_ERRNO) |
|
5153 |
die("query '%s' failed with wrong errno %d: '%s', instead of %d...", |
|
5154 |
command->query, err_errno, err_error, |
|
5155 |
command->expected_errors.err[0].code.errnum); |
|
5156 |
else
|
|
5157 |
die("query '%s' failed with wrong sqlstate %s: '%s', instead of %s...", |
|
5158 |
command->query, err_sqlstate, err_error, |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
5159 |
command->expected_errors.err[0].code.sqlstate); |
1
by brian
clean slate |
5160 |
}
|
5161 |
||
142.1.1
by Patrick
Removing DBUG from client |
5162 |
return; |
1
by brian
clean slate |
5163 |
}
|
5164 |
||
5165 |
||
5166 |
/*
|
|
5167 |
Handle absence of errors after execution
|
|
5168 |
||
5169 |
SYNOPSIS
|
|
5170 |
handle_no_error()
|
|
5171 |
q - context of query
|
|
5172 |
||
5173 |
RETURN VALUE
|
|
5174 |
error - function will not return
|
|
5175 |
*/
|
|
5176 |
||
5177 |
void handle_no_error(struct st_command *command) |
|
5178 |
{
|
|
142.1.1
by Patrick
Removing DBUG from client |
5179 |
|
1
by brian
clean slate |
5180 |
|
5181 |
if (command->expected_errors.err[0].type == ERR_ERRNO && |
|
5182 |
command->expected_errors.err[0].code.errnum != 0) |
|
5183 |
{
|
|
5184 |
/* Error code we wanted was != 0, i.e. not an expected success */
|
|
5185 |
die("query '%s' succeeded - should have failed with errno %d...", |
|
5186 |
command->query, command->expected_errors.err[0].code.errnum); |
|
5187 |
}
|
|
5188 |
else if (command->expected_errors.err[0].type == ERR_SQLSTATE && |
|
5189 |
strcmp(command->expected_errors.err[0].code.sqlstate,"00000") != 0) |
|
5190 |
{
|
|
5191 |
/* SQLSTATE we wanted was != "00000", i.e. not an expected success */
|
|
5192 |
die("query '%s' succeeded - should have failed with sqlstate %s...", |
|
5193 |
command->query, command->expected_errors.err[0].code.sqlstate); |
|
5194 |
}
|
|
5195 |
||
142.1.1
by Patrick
Removing DBUG from client |
5196 |
return; |
1
by brian
clean slate |
5197 |
}
|
5198 |
||
5199 |
||
5200 |
/*
|
|
5201 |
Run query
|
|
5202 |
||
5203 |
SYNPOSIS
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
5204 |
run_query()
|
5205 |
drizzle DRIZZLE handle
|
|
5206 |
command currrent command pointer
|
|
1
by brian
clean slate |
5207 |
|
5208 |
flags control the phased/stages of query execution to be performed
|
|
5209 |
if QUERY_SEND_FLAG bit is on, the query will be sent. If QUERY_REAP_FLAG
|
|
5210 |
is on the result will be read - for regular query, both bits must be on
|
|
5211 |
*/
|
|
5212 |
||
206.3.1
by Patrick Galbraith
Most everything working with client rename |
5213 |
static void run_query(struct st_connection *cn, |
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
5214 |
struct st_command *command, |
5215 |
int flags) |
|
1
by brian
clean slate |
5216 |
{
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
5217 |
string *ds= NULL; |
5218 |
string *save_ds= NULL; |
|
5219 |
string ds_result; |
|
5220 |
string ds_sorted; |
|
5221 |
string ds_warnings; |
|
5222 |
string eval_query; |
|
1
by brian
clean slate |
5223 |
char *query; |
5224 |
int query_len; |
|
142.1.1
by Patrick
Removing DBUG from client |
5225 |
|
1
by brian
clean slate |
5226 |
|
5227 |
/* Scan for warning before sending to server */
|
|
5228 |
scan_command_for_warnings(command); |
|
5229 |
||
5230 |
/*
|
|
5231 |
Evaluate query if this is an eval command
|
|
5232 |
*/
|
|
5233 |
if (command->type == Q_EVAL) |
|
5234 |
{
|
|
163
by Brian Aker
Merge Monty's code. |
5235 |
do_eval(&eval_query, command->query, command->end, false); |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
5236 |
query = strdup(eval_query.c_str()); |
5237 |
query_len = eval_query.length(); |
|
1
by brian
clean slate |
5238 |
}
|
5239 |
else
|
|
5240 |
{
|
|
5241 |
query = command->query; |
|
5242 |
query_len = strlen(query); |
|
5243 |
}
|
|
5244 |
||
5245 |
/*
|
|
5246 |
When command->require_file is set the output of _this_ query
|
|
5247 |
should be compared with an already existing file
|
|
5248 |
Create a temporary dynamic string to contain the output from
|
|
5249 |
this query.
|
|
5250 |
*/
|
|
5251 |
if (command->require_file[0]) |
|
5252 |
{
|
|
5253 |
ds= &ds_result; |
|
5254 |
}
|
|
5255 |
else
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
5256 |
{
|
1
by brian
clean slate |
5257 |
ds= &ds_res; |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
5258 |
}
|
1
by brian
clean slate |
5259 |
/*
|
5260 |
Log the query into the output buffer
|
|
5261 |
*/
|
|
5262 |
if (!disable_query_log && (flags & QUERY_SEND_FLAG)) |
|
5263 |
{
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
5264 |
replace_append_mem(ds, query, query_len); |
5265 |
ds->append(delimiter, delimiter_length); |
|
5266 |
ds->append("\n"); |
|
1
by brian
clean slate |
5267 |
}
|
5268 |
||
5269 |
if (display_result_sorted) |
|
5270 |
{
|
|
5271 |
/*
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
5272 |
Collect the query output in a separate string
|
5273 |
that can be sorted before it's added to the
|
|
5274 |
global result string
|
|
1
by brian
clean slate |
5275 |
*/
|
5276 |
save_ds= ds; /* Remember original ds */ |
|
5277 |
ds= &ds_sorted; |
|
5278 |
}
|
|
5279 |
||
5280 |
/*
|
|
5281 |
Always run with normal C API if it's not a complete
|
|
5282 |
SEND + REAP
|
|
5283 |
*/
|
|
41
by Brian Aker
First pass at cleaning up regex from mysqltest.c |
5284 |
run_query_normal(cn, command, flags, query, query_len, |
5285 |
ds, &ds_warnings); |
|
1
by brian
clean slate |
5286 |
|
5287 |
if (display_result_sorted) |
|
5288 |
{
|
|
5289 |
/* Sort the result set and append it to result */
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
5290 |
append_sorted(save_ds, &ds_sorted); |
1
by brian
clean slate |
5291 |
ds= save_ds; |
5292 |
}
|
|
5293 |
||
5294 |
if (command->require_file[0]) |
|
5295 |
{
|
|
5296 |
/* A result file was specified for _this_ query
|
|
5297 |
and the output should be checked against an already
|
|
5298 |
existing file which has been specified using --require or --result
|
|
5299 |
*/
|
|
5300 |
check_require(ds, command->require_file); |
|
5301 |
}
|
|
5302 |
||
142.1.1
by Patrick
Removing DBUG from client |
5303 |
return; |
1
by brian
clean slate |
5304 |
}
|
5305 |
||
5306 |
||
5307 |
/****************************************************************************/
|
|
5308 |
||
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
5309 |
static void get_command_type(struct st_command* command) |
1
by brian
clean slate |
5310 |
{
|
5311 |
char save; |
|
5312 |
uint type; |
|
142.1.1
by Patrick
Removing DBUG from client |
5313 |
|
1
by brian
clean slate |
5314 |
|
5315 |
if (*command->query == '}') |
|
5316 |
{
|
|
5317 |
command->type = Q_END_BLOCK; |
|
142.1.1
by Patrick
Removing DBUG from client |
5318 |
return; |
1
by brian
clean slate |
5319 |
}
|
5320 |
||
5321 |
save= command->query[command->first_word_len]; |
|
5322 |
command->query[command->first_word_len]= 0; |
|
5323 |
type= find_type(command->query, &command_typelib, 1+2); |
|
5324 |
command->query[command->first_word_len]= save; |
|
5325 |
if (type > 0) |
|
5326 |
{
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
5327 |
command->type=(enum enum_commands) type; /* Found command */ |
1
by brian
clean slate |
5328 |
|
5329 |
/*
|
|
5330 |
Look for case where "query" was explicitly specified to
|
|
5331 |
force command being sent to server
|
|
5332 |
*/
|
|
5333 |
if (type == Q_QUERY) |
|
5334 |
{
|
|
5335 |
/* Skip the "query" part */
|
|
5336 |
command->query= command->first_argument; |
|
5337 |
}
|
|
5338 |
}
|
|
5339 |
else
|
|
5340 |
{
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
5341 |
/* No drizzletest command matched */
|
1
by brian
clean slate |
5342 |
|
5343 |
if (command->type != Q_COMMENT_WITH_COMMAND) |
|
5344 |
{
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
5345 |
/* A query that will sent to drizzled */
|
1
by brian
clean slate |
5346 |
command->type= Q_QUERY; |
5347 |
}
|
|
5348 |
else
|
|
5349 |
{
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
5350 |
/* -- comment that didn't contain a drizzletest command */
|
1
by brian
clean slate |
5351 |
command->type= Q_COMMENT; |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
5352 |
warning_msg("Suspicious command '--%s' detected, was this intentional? " \ |
1
by brian
clean slate |
5353 |
"Use # instead of -- to avoid this warning", |
5354 |
command->query); |
|
5355 |
||
5356 |
if (command->first_word_len && |
|
5357 |
strcmp(command->query + command->first_word_len - 1, delimiter) == 0) |
|
5358 |
{
|
|
5359 |
/*
|
|
5360 |
Detect comment with command using extra delimiter
|
|
5361 |
Ex --disable_query_log;
|
|
5362 |
^ Extra delimiter causing the command
|
|
5363 |
to be skipped
|
|
5364 |
*/
|
|
5365 |
save= command->query[command->first_word_len-1]; |
|
5366 |
command->query[command->first_word_len-1]= 0; |
|
5367 |
if (find_type(command->query, &command_typelib, 1+2) > 0) |
|
5368 |
die("Extra delimiter \";\" found"); |
|
5369 |
command->query[command->first_word_len-1]= save; |
|
5370 |
||
5371 |
}
|
|
5372 |
}
|
|
5373 |
}
|
|
5374 |
||
5375 |
/* Set expected error on command */
|
|
5376 |
memcpy(&command->expected_errors, &saved_expected_errors, |
|
5377 |
sizeof(saved_expected_errors)); |
|
5378 |
command->abort_on_error= (command->expected_errors.count == 0 && |
|
5379 |
abort_on_error); |
|
5380 |
||
142.1.1
by Patrick
Removing DBUG from client |
5381 |
return; |
1
by brian
clean slate |
5382 |
}
|
5383 |
||
5384 |
||
5385 |
||
5386 |
/*
|
|
5387 |
Record how many milliseconds it took to execute the test file
|
|
5388 |
up until the current line and save it in the dynamic string ds_progress.
|
|
5389 |
||
5390 |
The ds_progress will be dumped to <test_name>.progress when
|
|
5391 |
test run completes
|
|
5392 |
||
5393 |
*/
|
|
5394 |
||
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
5395 |
static void mark_progress(struct st_command* command __attribute__((unused)), |
5396 |
int line) |
|
1
by brian
clean slate |
5397 |
{
|
5398 |
char buf[32], *end; |
|
151
by Brian Aker
Ulonglong to uint64_t |
5399 |
uint64_t timer= timer_now(); |
1
by brian
clean slate |
5400 |
if (!progress_start) |
5401 |
progress_start= timer; |
|
5402 |
timer-= progress_start; |
|
5403 |
||
5404 |
/* Milliseconds since start */
|
|
152
by Brian Aker
longlong replacement |
5405 |
end= int64_t2str(timer, buf, 10); |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
5406 |
ds_progress.append(buf, (int)(end-buf)); |
5407 |
ds_progress.append("\t", 1); |
|
1
by brian
clean slate |
5408 |
|
5409 |
/* Parser line number */
|
|
5410 |
end= int10_to_str(line, buf, 10); |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
5411 |
ds_progress.append(buf, (int)(end-buf)); |
5412 |
ds_progress.append("\t", 1); |
|
1
by brian
clean slate |
5413 |
|
5414 |
/* Filename */
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
5415 |
ds_progress.append(cur_file->file_name); |
5416 |
ds_progress.append(":", 1); |
|
1
by brian
clean slate |
5417 |
|
5418 |
/* Line in file */
|
|
5419 |
end= int10_to_str(cur_file->lineno, buf, 10); |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
5420 |
ds_progress.append(buf, (int)(end-buf)); |
5421 |
||
5422 |
||
5423 |
ds_progress.append("\n", 1); |
|
1
by brian
clean slate |
5424 |
|
5425 |
}
|
|
5426 |
||
5427 |
||
5428 |
int main(int argc, char **argv) |
|
5429 |
{
|
|
5430 |
struct st_command *command; |
|
143
by Brian Aker
Bool cleanup. |
5431 |
bool q_send_flag= 0, abort_flag= 0; |
1
by brian
clean slate |
5432 |
uint command_executed= 0, last_command_executed= 0; |
5433 |
char save_file[FN_REFLEN]; |
|
15
by brian
Fix for stat, NETWARE removal |
5434 |
struct stat res_info; |
1
by brian
clean slate |
5435 |
MY_INIT(argv[0]); |
5436 |
||
5437 |
save_file[0]= 0; |
|
5438 |
TMPDIR[0]= 0; |
|
5439 |
||
5440 |
/* Init expected errors */
|
|
5441 |
memset(&saved_expected_errors, 0, sizeof(saved_expected_errors)); |
|
5442 |
||
5443 |
/* Init connections */
|
|
5444 |
memset(connections, 0, sizeof(connections)); |
|
5445 |
connections_end= connections + |
|
5446 |
(sizeof(connections)/sizeof(struct st_connection)) - 1; |
|
5447 |
next_con= connections + 1; |
|
5448 |
||
5449 |
/* Init file stack */
|
|
5450 |
memset(file_stack, 0, sizeof(file_stack)); |
|
5451 |
file_stack_end= |
|
5452 |
file_stack + (sizeof(file_stack)/sizeof(struct st_test_file)) - 1; |
|
5453 |
cur_file= file_stack; |
|
5454 |
||
5455 |
/* Init block stack */
|
|
5456 |
memset(block_stack, 0, sizeof(block_stack)); |
|
5457 |
block_stack_end= |
|
5458 |
block_stack + (sizeof(block_stack)/sizeof(struct st_block)) - 1; |
|
5459 |
cur_block= block_stack; |
|
163
by Brian Aker
Merge Monty's code. |
5460 |
cur_block->ok= true; /* Outer block should always be executed */ |
1
by brian
clean slate |
5461 |
cur_block->cmd= cmd_none; |
5462 |
||
5463 |
if (hash_init(&var_hash, charset_info, |
|
5464 |
1024, 0, 0, get_var_key, var_free, MYF(0))) |
|
5465 |
die("Variable hash initialization failed"); |
|
5466 |
||
319.1.1
by Grant Limberg
renamed all instances of MYSQL_ to DRIZZLE_ |
5467 |
var_set_string("$DRIZZLE_SERVER_VERSION", drizzle_get_client_info()); |
1
by brian
clean slate |
5468 |
|
5469 |
memset(&master_pos, 0, sizeof(master_pos)); |
|
5470 |
||
5471 |
parser.current_line= parser.read_lines= 0; |
|
5472 |
memset(&var_reg, 0, sizeof(var_reg)); |
|
5473 |
||
5474 |
init_builtin_echo(); |
|
5475 |
||
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
5476 |
ds_res.reserve(65536); |
5477 |
ds_progress.reserve(2048); |
|
5478 |
ds_warning_messages.reserve(2048); |
|
5479 |
||
1
by brian
clean slate |
5480 |
parse_args(argc, argv); |
5481 |
||
5482 |
server_initialized= 1; |
|
5483 |
if (cur_file == file_stack && cur_file->file == 0) |
|
5484 |
{
|
|
5485 |
cur_file->file= stdin; |
|
5486 |
cur_file->file_name= my_strdup("<stdin>", MYF(MY_WME)); |
|
5487 |
cur_file->lineno= 1; |
|
5488 |
}
|
|
5489 |
cur_con= connections; |
|
202.2.4
by Monty Taylor
Merged from Patrick. |
5490 |
if (!( drizzle_create(&cur_con->drizzle))) |
202.2.1
by Monty Taylor
Renamed mysql_init to drizzle_create. |
5491 |
die("Failed in drizzle_create()"); |
1
by brian
clean slate |
5492 |
if (opt_compress) |
461
by Monty Taylor
Removed NullS. bu-bye. |
5493 |
drizzle_options(&cur_con->drizzle,DRIZZLE_OPT_COMPRESS,NULL); |
206.3.1
by Patrick Galbraith
Most everything working with client rename |
5494 |
drizzle_options(&cur_con->drizzle, DRIZZLE_OPT_LOCAL_INFILE, 0); |
1
by brian
clean slate |
5495 |
|
5496 |
if (!(cur_con->name = my_strdup("default", MYF(MY_WME)))) |
|
5497 |
die("Out of memory"); |
|
5498 |
||
206.3.1
by Patrick Galbraith
Most everything working with client rename |
5499 |
safe_connect(&cur_con->drizzle, cur_con->name, opt_host, opt_user, opt_pass, |
1
by brian
clean slate |
5500 |
opt_db, opt_port); |
5501 |
||
5502 |
/* Use all time until exit if no explicit 'start_timer' */
|
|
5503 |
timer_start= timer_now(); |
|
5504 |
||
5505 |
/*
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
5506 |
Initialize $drizzle_errno with -1, so we can
|
1
by brian
clean slate |
5507 |
- distinguish it from valid values ( >= 0 ) and
|
5508 |
- detect if there was never a command sent to the server
|
|
5509 |
*/
|
|
5510 |
var_set_errno(-1); |
|
5511 |
||
206.3.1
by Patrick Galbraith
Most everything working with client rename |
5512 |
/* Update $drizzle_get_server_version to that of current connection */
|
5513 |
var_set_drizzle_get_server_version(&cur_con->drizzle); |
|
1
by brian
clean slate |
5514 |
|
5515 |
if (opt_include) |
|
5516 |
{
|
|
5517 |
open_file(opt_include); |
|
5518 |
}
|
|
5519 |
||
5520 |
while (!read_command(&command) && !abort_flag) |
|
5521 |
{
|
|
5522 |
int current_line_inc = 1, processed = 0; |
|
5523 |
if (command->type == Q_UNKNOWN || command->type == Q_COMMENT_WITH_COMMAND) |
|
5524 |
get_command_type(command); |
|
5525 |
||
5526 |
if (parsing_disabled && |
|
5527 |
command->type != Q_ENABLE_PARSING && |
|
5528 |
command->type != Q_DISABLE_PARSING) |
|
5529 |
{
|
|
5530 |
command->type= Q_COMMENT; |
|
5531 |
scan_command_for_warnings(command); |
|
5532 |
}
|
|
5533 |
||
5534 |
if (cur_block->ok) |
|
5535 |
{
|
|
5536 |
command->last_argument= command->first_argument; |
|
5537 |
processed = 1; |
|
5538 |
switch (command->type) { |
|
5539 |
case Q_CONNECT: |
|
5540 |
do_connect(command); |
|
5541 |
break; |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
5542 |
case Q_CONNECTION: |
5543 |
select_connection(command); |
|
5544 |
break; |
|
1
by brian
clean slate |
5545 |
case Q_DISCONNECT: |
5546 |
case Q_DIRTY_CLOSE: |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
5547 |
do_close_connection(command); break; |
1
by brian
clean slate |
5548 |
case Q_ENABLE_QUERY_LOG: disable_query_log=0; break; |
5549 |
case Q_DISABLE_QUERY_LOG: disable_query_log=1; break; |
|
5550 |
case Q_ENABLE_ABORT_ON_ERROR: abort_on_error=1; break; |
|
5551 |
case Q_DISABLE_ABORT_ON_ERROR: abort_on_error=0; break; |
|
5552 |
case Q_ENABLE_RESULT_LOG: disable_result_log=0; break; |
|
5553 |
case Q_DISABLE_RESULT_LOG: disable_result_log=1; break; |
|
5554 |
case Q_ENABLE_WARNINGS: disable_warnings=0; break; |
|
5555 |
case Q_DISABLE_WARNINGS: disable_warnings=1; break; |
|
5556 |
case Q_ENABLE_INFO: disable_info=0; break; |
|
5557 |
case Q_DISABLE_INFO: disable_info=1; break; |
|
5558 |
case Q_ENABLE_METADATA: display_metadata=1; break; |
|
5559 |
case Q_DISABLE_METADATA: display_metadata=0; break; |
|
5560 |
case Q_SOURCE: do_source(command); break; |
|
5561 |
case Q_SLEEP: do_sleep(command, 0); break; |
|
5562 |
case Q_REAL_SLEEP: do_sleep(command, 1); break; |
|
5563 |
case Q_WAIT_FOR_SLAVE_TO_STOP: do_wait_for_slave_to_stop(command); break; |
|
5564 |
case Q_INC: do_modify_var(command, DO_INC); break; |
|
5565 |
case Q_DEC: do_modify_var(command, DO_DEC); break; |
|
5566 |
case Q_ECHO: do_echo(command); command_executed++; break; |
|
5567 |
case Q_SYSTEM: do_system(command); break; |
|
5568 |
case Q_REMOVE_FILE: do_remove_file(command); break; |
|
5569 |
case Q_MKDIR: do_mkdir(command); break; |
|
5570 |
case Q_RMDIR: do_rmdir(command); break; |
|
5571 |
case Q_FILE_EXIST: do_file_exist(command); break; |
|
5572 |
case Q_WRITE_FILE: do_write_file(command); break; |
|
5573 |
case Q_APPEND_FILE: do_append_file(command); break; |
|
5574 |
case Q_DIFF_FILES: do_diff_files(command); break; |
|
5575 |
case Q_SEND_QUIT: do_send_quit(command); break; |
|
5576 |
case Q_CHANGE_USER: do_change_user(command); break; |
|
5577 |
case Q_CAT_FILE: do_cat_file(command); break; |
|
5578 |
case Q_COPY_FILE: do_copy_file(command); break; |
|
5579 |
case Q_CHMOD_FILE: do_chmod_file(command); break; |
|
5580 |
case Q_PERL: do_perl(command); break; |
|
5581 |
case Q_DELIMITER: |
|
5582 |
do_delimiter(command); |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
5583 |
break; |
1
by brian
clean slate |
5584 |
case Q_DISPLAY_VERTICAL_RESULTS: |
163
by Brian Aker
Merge Monty's code. |
5585 |
display_result_vertically= true; |
1
by brian
clean slate |
5586 |
break; |
5587 |
case Q_DISPLAY_HORIZONTAL_RESULTS: |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
5588 |
display_result_vertically= false; |
1
by brian
clean slate |
5589 |
break; |
5590 |
case Q_SORTED_RESULT: |
|
5591 |
/*
|
|
5592 |
Turn on sorting of result set, will be reset after next
|
|
5593 |
command
|
|
5594 |
*/
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
5595 |
display_result_sorted= true; |
1
by brian
clean slate |
5596 |
break; |
5597 |
case Q_LET: do_let(command); break; |
|
5598 |
case Q_EVAL_RESULT: |
|
5599 |
die("'eval_result' command is deprecated"); |
|
5600 |
case Q_EVAL: |
|
5601 |
case Q_QUERY_VERTICAL: |
|
5602 |
case Q_QUERY_HORIZONTAL: |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
5603 |
if (command->query == command->query_buf) |
1
by brian
clean slate |
5604 |
{
|
5605 |
/* Skip the first part of command, i.e query_xxx */
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
5606 |
command->query= command->first_argument; |
1
by brian
clean slate |
5607 |
command->first_word_len= 0; |
5608 |
}
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
5609 |
/* fall through */
|
1
by brian
clean slate |
5610 |
case Q_QUERY: |
5611 |
case Q_REAP: |
|
5612 |
{
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
5613 |
bool old_display_result_vertically= display_result_vertically; |
1
by brian
clean slate |
5614 |
/* Default is full query, both reap and send */
|
5615 |
int flags= QUERY_REAP_FLAG | QUERY_SEND_FLAG; |
|
5616 |
||
5617 |
if (q_send_flag) |
|
5618 |
{
|
|
5619 |
/* Last command was an empty 'send' */
|
|
5620 |
flags= QUERY_SEND_FLAG; |
|
5621 |
q_send_flag= 0; |
|
5622 |
}
|
|
5623 |
else if (command->type == Q_REAP) |
|
5624 |
{
|
|
5625 |
flags= QUERY_REAP_FLAG; |
|
5626 |
}
|
|
5627 |
||
5628 |
/* Check for special property for this query */
|
|
5629 |
display_result_vertically|= (command->type == Q_QUERY_VERTICAL); |
|
5630 |
||
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
5631 |
if (save_file[0]) |
5632 |
{
|
|
5633 |
strmake(command->require_file, save_file, sizeof(save_file) - 1); |
|
5634 |
save_file[0]= 0; |
|
5635 |
}
|
|
5636 |
run_query(cur_con, command, flags); |
|
5637 |
command_executed++; |
|
1
by brian
clean slate |
5638 |
command->last_argument= command->end; |
5639 |
||
5640 |
/* Restore settings */
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
5641 |
display_result_vertically= old_display_result_vertically; |
1
by brian
clean slate |
5642 |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
5643 |
break; |
1
by brian
clean slate |
5644 |
}
|
5645 |
case Q_SEND: |
|
5646 |
if (!*command->first_argument) |
|
5647 |
{
|
|
5648 |
/*
|
|
5649 |
This is a send without arguments, it indicates that _next_ query
|
|
5650 |
should be send only
|
|
5651 |
*/
|
|
5652 |
q_send_flag= 1; |
|
5653 |
break; |
|
5654 |
}
|
|
5655 |
||
5656 |
/* Remove "send" if this is first iteration */
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
5657 |
if (command->query == command->query_buf) |
5658 |
command->query= command->first_argument; |
|
1
by brian
clean slate |
5659 |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
5660 |
/*
|
5661 |
run_query() can execute a query partially, depending on the flags.
|
|
5662 |
QUERY_SEND_FLAG flag without QUERY_REAP_FLAG tells it to just send
|
|
1
by brian
clean slate |
5663 |
the query and read the result some time later when reap instruction
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
5664 |
is given on this connection.
|
1
by brian
clean slate |
5665 |
*/
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
5666 |
run_query(cur_con, command, QUERY_SEND_FLAG); |
5667 |
command_executed++; |
|
1
by brian
clean slate |
5668 |
command->last_argument= command->end; |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
5669 |
break; |
1
by brian
clean slate |
5670 |
case Q_REQUIRE: |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
5671 |
do_get_file_name(command, save_file, sizeof(save_file)); |
5672 |
break; |
|
1
by brian
clean slate |
5673 |
case Q_ERROR: |
5674 |
do_get_errcodes(command); |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
5675 |
break; |
1
by brian
clean slate |
5676 |
case Q_REPLACE: |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
5677 |
do_get_replace(command); |
5678 |
break; |
|
1
by brian
clean slate |
5679 |
case Q_REPLACE_REGEX: |
5680 |
do_get_replace_regex(command); |
|
5681 |
break; |
|
5682 |
case Q_REPLACE_COLUMN: |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
5683 |
do_get_replace_column(command); |
5684 |
break; |
|
1
by brian
clean slate |
5685 |
case Q_SAVE_MASTER_POS: do_save_master_pos(); break; |
5686 |
case Q_SYNC_WITH_MASTER: do_sync_with_master(command); break; |
|
5687 |
case Q_SYNC_SLAVE_WITH_MASTER: |
|
5688 |
{
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
5689 |
do_save_master_pos(); |
5690 |
if (*command->first_argument) |
|
5691 |
select_connection(command); |
|
5692 |
else
|
|
5693 |
select_connection_name("slave"); |
|
5694 |
do_sync_with_master2(0); |
|
5695 |
break; |
|
1
by brian
clean slate |
5696 |
}
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
5697 |
case Q_COMMENT: /* Ignore row */ |
1
by brian
clean slate |
5698 |
command->last_argument= command->end; |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
5699 |
break; |
1
by brian
clean slate |
5700 |
case Q_PING: |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
5701 |
(void) drizzle_ping(&cur_con->drizzle); |
5702 |
break; |
|
1
by brian
clean slate |
5703 |
case Q_EXEC: |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
5704 |
do_exec(command); |
5705 |
command_executed++; |
|
5706 |
break; |
|
1
by brian
clean slate |
5707 |
case Q_START_TIMER: |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
5708 |
/* Overwrite possible earlier start of timer */
|
5709 |
timer_start= timer_now(); |
|
5710 |
break; |
|
1
by brian
clean slate |
5711 |
case Q_END_TIMER: |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
5712 |
/* End timer before ending drizzletest */
|
5713 |
timer_output(); |
|
5714 |
break; |
|
1
by brian
clean slate |
5715 |
case Q_CHARACTER_SET: |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
5716 |
do_set_charset(command); |
5717 |
break; |
|
1
by brian
clean slate |
5718 |
case Q_DISABLE_RECONNECT: |
206.3.1
by Patrick Galbraith
Most everything working with client rename |
5719 |
set_reconnect(&cur_con->drizzle, 0); |
1
by brian
clean slate |
5720 |
break; |
5721 |
case Q_ENABLE_RECONNECT: |
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
5722 |
set_reconnect(&cur_con->drizzle, 1); |
1
by brian
clean slate |
5723 |
break; |
5724 |
case Q_DISABLE_PARSING: |
|
5725 |
if (parsing_disabled == 0) |
|
5726 |
parsing_disabled= 1; |
|
5727 |
else
|
|
5728 |
die("Parsing is already disabled"); |
|
5729 |
break; |
|
5730 |
case Q_ENABLE_PARSING: |
|
5731 |
/*
|
|
5732 |
Ensure we don't get parsing_disabled < 0 as this would accidentally
|
|
5733 |
disable code we don't want to have disabled
|
|
5734 |
*/
|
|
5735 |
if (parsing_disabled == 1) |
|
5736 |
parsing_disabled= 0; |
|
5737 |
else
|
|
5738 |
die("Parsing is already enabled"); |
|
5739 |
break; |
|
5740 |
case Q_DIE: |
|
5741 |
/* Abort test with error code and error message */
|
|
5742 |
die("%s", command->first_argument); |
|
5743 |
break; |
|
5744 |
case Q_EXIT: |
|
5745 |
/* Stop processing any more commands */
|
|
5746 |
abort_flag= 1; |
|
5747 |
break; |
|
5748 |
case Q_SKIP: |
|
5749 |
abort_not_supported_test("%s", command->first_argument); |
|
5750 |
break; |
|
5751 |
||
5752 |
case Q_RESULT: |
|
5753 |
die("result, deprecated command"); |
|
5754 |
break; |
|
5755 |
||
5756 |
default: |
|
5757 |
processed= 0; |
|
5758 |
break; |
|
5759 |
}
|
|
5760 |
}
|
|
5761 |
||
5762 |
if (!processed) |
|
5763 |
{
|
|
5764 |
current_line_inc= 0; |
|
5765 |
switch (command->type) { |
|
5766 |
case Q_WHILE: do_block(cmd_while, command); break; |
|
5767 |
case Q_IF: do_block(cmd_if, command); break; |
|
5768 |
case Q_END_BLOCK: do_done(command); break; |
|
5769 |
default: current_line_inc = 1; break; |
|
5770 |
}
|
|
5771 |
}
|
|
5772 |
else
|
|
5773 |
check_eol_junk(command->last_argument); |
|
5774 |
||
5775 |
if (command->type != Q_ERROR && |
|
5776 |
command->type != Q_COMMENT) |
|
5777 |
{
|
|
5778 |
/*
|
|
5779 |
As soon as any non "error" command or comment has been executed,
|
|
5780 |
the array with expected errors should be cleared
|
|
5781 |
*/
|
|
5782 |
memset(&saved_expected_errors, 0, sizeof(saved_expected_errors)); |
|
5783 |
}
|
|
5784 |
||
5785 |
if (command_executed != last_command_executed) |
|
5786 |
{
|
|
5787 |
/*
|
|
5788 |
As soon as any command has been executed,
|
|
5789 |
the replace structures should be cleared
|
|
5790 |
*/
|
|
5791 |
free_all_replace(); |
|
5792 |
||
5793 |
/* Also reset "sorted_result" */
|
|
163
by Brian Aker
Merge Monty's code. |
5794 |
display_result_sorted= false; |
1
by brian
clean slate |
5795 |
}
|
5796 |
last_command_executed= command_executed; |
|
5797 |
||
5798 |
parser.current_line += current_line_inc; |
|
5799 |
if ( opt_mark_progress ) |
|
5800 |
mark_progress(command, parser.current_line); |
|
5801 |
}
|
|
5802 |
||
5803 |
start_lineno= 0; |
|
5804 |
||
5805 |
if (parsing_disabled) |
|
5806 |
die("Test ended with parsing disabled"); |
|
5807 |
||
5808 |
/*
|
|
5809 |
The whole test has been executed _sucessfully_.
|
|
5810 |
Time to compare result or save it to record file.
|
|
5811 |
The entire output from test is now kept in ds_res.
|
|
5812 |
*/
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
5813 |
if (ds_res.length()) |
1
by brian
clean slate |
5814 |
{
|
5815 |
if (result_file_name) |
|
5816 |
{
|
|
5817 |
/* A result file has been specified */
|
|
5818 |
||
5819 |
if (record) |
|
5820 |
{
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
5821 |
/* Recording - dump the output from test to result file */
|
5822 |
str_to_file(result_file_name, ds_res.c_str(), ds_res.length()); |
|
1
by brian
clean slate |
5823 |
}
|
5824 |
else
|
|
5825 |
{
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
5826 |
/* Check that the output from test is equal to result file
|
5827 |
- detect missing result file
|
|
5828 |
- detect zero size result file
|
|
1
by brian
clean slate |
5829 |
*/
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
5830 |
check_result(&ds_res); |
1
by brian
clean slate |
5831 |
}
|
5832 |
}
|
|
5833 |
else
|
|
5834 |
{
|
|
5835 |
/* No result_file_name specified to compare with, print to stdout */
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
5836 |
printf("%s", ds_res.c_str()); |
1
by brian
clean slate |
5837 |
}
|
5838 |
}
|
|
5839 |
else
|
|
5840 |
{
|
|
5841 |
die("The test didn't produce any output"); |
|
5842 |
}
|
|
5843 |
||
5844 |
if (!command_executed && |
|
15
by brian
Fix for stat, NETWARE removal |
5845 |
result_file_name && !stat(result_file_name, &res_info)) |
1
by brian
clean slate |
5846 |
{
|
5847 |
/*
|
|
5848 |
my_stat() successful on result file. Check if we have not run a
|
|
5849 |
single query, but we do have a result file that contains data.
|
|
5850 |
Note that we don't care, if my_stat() fails. For example, for a
|
|
5851 |
non-existing or non-readable file, we assume it's fine to have
|
|
5852 |
no query output from the test file, e.g. regarded as no error.
|
|
5853 |
*/
|
|
5854 |
die("No queries executed but result file found!"); |
|
5855 |
}
|
|
5856 |
||
5857 |
if ( opt_mark_progress && result_file_name ) |
|
5858 |
dump_progress(); |
|
5859 |
||
5860 |
/* Dump warning messages */
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
5861 |
if (result_file_name && ds_warning_messages.length()) |
1
by brian
clean slate |
5862 |
dump_warning_messages(); |
5863 |
||
5864 |
timer_output(); |
|
5865 |
/* Yes, if we got this far the test has suceeded! Sakila smiles */
|
|
5866 |
cleanup_and_exit(0); |
|
5867 |
return 0; /* Keep compiler happy too */ |
|
5868 |
}
|
|
5869 |
||
5870 |
||
5871 |
/*
|
|
5872 |
A primitive timer that give results in milliseconds if the
|
|
5873 |
--timer-file=<filename> is given. The timer result is written
|
|
5874 |
to that file when the result is available. To not confuse
|
|
5875 |
mysql-test-run with an old obsolete result, we remove the file
|
|
5876 |
before executing any commands. The time we measure is
|
|
5877 |
||
5878 |
- If no explicit 'start_timer' or 'end_timer' is given in the
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
5879 |
test case, the timer measure how long we execute in drizzletest.
|
1
by brian
clean slate |
5880 |
|
5881 |
- If only 'start_timer' is given we measure how long we execute
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
5882 |
from that point until we terminate drizzletest.
|
1
by brian
clean slate |
5883 |
|
5884 |
- If only 'end_timer' is given we measure how long we execute
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
5885 |
from that we enter drizzletest to the 'end_timer' is command is
|
1
by brian
clean slate |
5886 |
executed.
|
5887 |
||
5888 |
- If both 'start_timer' and 'end_timer' are given we measure
|
|
5889 |
the time between executing the two commands.
|
|
5890 |
*/
|
|
5891 |
||
5892 |
void timer_output(void) |
|
5893 |
{
|
|
5894 |
if (timer_file) |
|
5895 |
{
|
|
5896 |
char buf[32], *end; |
|
151
by Brian Aker
Ulonglong to uint64_t |
5897 |
uint64_t timer= timer_now() - timer_start; |
152
by Brian Aker
longlong replacement |
5898 |
end= int64_t2str(timer, buf, 10); |
1
by brian
clean slate |
5899 |
str_to_file(timer_file,buf, (int) (end-buf)); |
5900 |
/* Timer has been written to the file, don't use it anymore */
|
|
5901 |
timer_file= 0; |
|
5902 |
}
|
|
5903 |
}
|
|
5904 |
||
5905 |
||
151
by Brian Aker
Ulonglong to uint64_t |
5906 |
uint64_t timer_now(void) |
1
by brian
clean slate |
5907 |
{
|
5908 |
return my_micro_time() / 1000; |
|
5909 |
}
|
|
5910 |
||
5911 |
||
5912 |
/*
|
|
5913 |
Get arguments for replace_columns. The syntax is:
|
|
5914 |
replace-column column_number to_string [column_number to_string ...]
|
|
5915 |
Where each argument may be quoted with ' or "
|
|
5916 |
A argument may also be a variable, in which case the value of the
|
|
5917 |
variable is replaced.
|
|
5918 |
*/
|
|
5919 |
||
5920 |
void do_get_replace_column(struct st_command *command) |
|
5921 |
{
|
|
5922 |
char *from= command->first_argument; |
|
5923 |
char *buff, *start; |
|
142.1.1
by Patrick
Removing DBUG from client |
5924 |
|
1
by brian
clean slate |
5925 |
|
5926 |
free_replace_column(); |
|
5927 |
if (!*from) |
|
5928 |
die("Missing argument in %s", command->query); |
|
5929 |
||
5930 |
/* Allocate a buffer for results */
|
|
77.1.31
by Monty Taylor
Replaced regex lib with pcre. Reworked mysqltest to use it. |
5931 |
start= buff= (char *)my_malloc(strlen(from)+1,MYF(MY_WME | MY_FAE)); |
1
by brian
clean slate |
5932 |
while (*from) |
5933 |
{
|
|
5934 |
char *to; |
|
5935 |
uint column_number; |
|
5936 |
||
5937 |
to= get_string(&buff, &from, command); |
|
5938 |
if (!(column_number= atoi(to)) || column_number > MAX_COLUMNS) |
|
5939 |
die("Wrong column number to replace_column in '%s'", command->query); |
|
5940 |
if (!*from) |
|
5941 |
die("Wrong number of arguments to replace_column in '%s'", command->query); |
|
5942 |
to= get_string(&buff, &from, command); |
|
477
by Monty Taylor
Removed my_free(). It turns out that it had been def'd to ignore the flags passed to it in the second arg anyway. Gotta love that. |
5943 |
free(replace_column[column_number-1]); |
1
by brian
clean slate |
5944 |
replace_column[column_number-1]= my_strdup(to, MYF(MY_WME | MY_FAE)); |
5945 |
set_if_bigger(max_replace_column, column_number); |
|
5946 |
}
|
|
477
by Monty Taylor
Removed my_free(). It turns out that it had been def'd to ignore the flags passed to it in the second arg anyway. Gotta love that. |
5947 |
free(start); |
1
by brian
clean slate |
5948 |
command->last_argument= command->end; |
5949 |
}
|
|
5950 |
||
5951 |
||
5952 |
void free_replace_column() |
|
5953 |
{
|
|
5954 |
uint i; |
|
5955 |
for (i=0 ; i < max_replace_column ; i++) |
|
5956 |
{
|
|
5957 |
if (replace_column[i]) |
|
5958 |
{
|
|
477
by Monty Taylor
Removed my_free(). It turns out that it had been def'd to ignore the flags passed to it in the second arg anyway. Gotta love that. |
5959 |
free(replace_column[i]); |
1
by brian
clean slate |
5960 |
replace_column[i]= 0; |
5961 |
}
|
|
5962 |
}
|
|
5963 |
max_replace_column= 0; |
|
5964 |
}
|
|
5965 |
||
5966 |
||
5967 |
/****************************************************************************/
|
|
5968 |
/*
|
|
5969 |
Replace functions
|
|
5970 |
*/
|
|
5971 |
||
5972 |
/* Definitions for replace result */
|
|
5973 |
||
206.3.1
by Patrick Galbraith
Most everything working with client rename |
5974 |
typedef struct st_pointer_array { /* when using array-strings */ |
5975 |
TYPELIB typelib; /* Pointer to strings */ |
|
481
by Brian Aker
Remove all of uchar. |
5976 |
unsigned char *str; /* Strings is here */ |
428
by Monty Taylor
Removed int7 and int15 and non-stdbool bool def. |
5977 |
uint8_t *flag; /* Flag about each var. */ |
206.3.1
by Patrick Galbraith
Most everything working with client rename |
5978 |
uint array_allocs,max_count,length,max_length; |
1
by brian
clean slate |
5979 |
} POINTER_ARRAY; |
5980 |
||
5981 |
struct st_replace; |
|
5982 |
struct st_replace *init_replace(char * *from, char * *to, uint count, |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
5983 |
char * word_end_chars); |
1
by brian
clean slate |
5984 |
int insert_pointer_name(POINTER_ARRAY *pa,char * name); |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
5985 |
void replace_strings_append(struct st_replace *rep, string* ds, |
1
by brian
clean slate |
5986 |
const char *from, int len); |
5987 |
void free_pointer_array(POINTER_ARRAY *pa); |
|
5988 |
||
5989 |
struct st_replace *glob_replace; |
|
5990 |
||
5991 |
/*
|
|
5992 |
Get arguments for replace. The syntax is:
|
|
5993 |
replace from to [from to ...]
|
|
5994 |
Where each argument may be quoted with ' or "
|
|
5995 |
A argument may also be a variable, in which case the value of the
|
|
5996 |
variable is replaced.
|
|
5997 |
*/
|
|
5998 |
||
5999 |
void do_get_replace(struct st_command *command) |
|
6000 |
{
|
|
6001 |
uint i; |
|
6002 |
char *from= command->first_argument; |
|
6003 |
char *buff, *start; |
|
6004 |
char word_end_chars[256], *pos; |
|
6005 |
POINTER_ARRAY to_array, from_array; |
|
142.1.1
by Patrick
Removing DBUG from client |
6006 |
|
1
by brian
clean slate |
6007 |
|
6008 |
free_replace(); |
|
6009 |
||
212.6.10
by Mats Kindahl
Removing redundant use of casts in client/ for memcmp(), memcpy(), memset(), and memmove(). |
6010 |
memset(&to_array, 0, sizeof(to_array)); |
6011 |
memset(&from_array, 0, sizeof(from_array)); |
|
1
by brian
clean slate |
6012 |
if (!*from) |
6013 |
die("Missing argument in %s", command->query); |
|
77.1.31
by Monty Taylor
Replaced regex lib with pcre. Reworked mysqltest to use it. |
6014 |
start= buff= (char *)my_malloc(strlen(from)+1,MYF(MY_WME | MY_FAE)); |
1
by brian
clean slate |
6015 |
while (*from) |
6016 |
{
|
|
6017 |
char *to= buff; |
|
6018 |
to= get_string(&buff, &from, command); |
|
6019 |
if (!*from) |
|
6020 |
die("Wrong number of arguments to replace_result in '%s'", |
|
6021 |
command->query); |
|
6022 |
insert_pointer_name(&from_array,to); |
|
6023 |
to= get_string(&buff, &from, command); |
|
6024 |
insert_pointer_name(&to_array,to); |
|
6025 |
}
|
|
6026 |
for (i= 1,pos= word_end_chars ; i < 256 ; i++) |
|
6027 |
if (my_isspace(charset_info,i)) |
|
6028 |
*pos++= i; |
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
6029 |
*pos=0; /* End pointer */ |
1
by brian
clean slate |
6030 |
if (!(glob_replace= init_replace((char**) from_array.typelib.type_names, |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
6031 |
(char**) to_array.typelib.type_names, |
6032 |
(uint) from_array.typelib.count, |
|
6033 |
word_end_chars))) |
|
1
by brian
clean slate |
6034 |
die("Can't initialize replace from '%s'", command->query); |
6035 |
free_pointer_array(&from_array); |
|
6036 |
free_pointer_array(&to_array); |
|
477
by Monty Taylor
Removed my_free(). It turns out that it had been def'd to ignore the flags passed to it in the second arg anyway. Gotta love that. |
6037 |
free(start); |
1
by brian
clean slate |
6038 |
command->last_argument= command->end; |
142.1.1
by Patrick
Removing DBUG from client |
6039 |
return; |
1
by brian
clean slate |
6040 |
}
|
6041 |
||
6042 |
||
6043 |
void free_replace() |
|
6044 |
{
|
|
142.1.1
by Patrick
Removing DBUG from client |
6045 |
|
1
by brian
clean slate |
6046 |
if (glob_replace) |
6047 |
{
|
|
477
by Monty Taylor
Removed my_free(). It turns out that it had been def'd to ignore the flags passed to it in the second arg anyway. Gotta love that. |
6048 |
free(glob_replace); |
1
by brian
clean slate |
6049 |
glob_replace=0; |
6050 |
}
|
|
142.1.1
by Patrick
Removing DBUG from client |
6051 |
return; |
1
by brian
clean slate |
6052 |
}
|
6053 |
||
6054 |
||
6055 |
typedef struct st_replace { |
|
143
by Brian Aker
Bool cleanup. |
6056 |
bool found; |
1
by brian
clean slate |
6057 |
struct st_replace *next[256]; |
6058 |
} REPLACE; |
|
6059 |
||
6060 |
typedef struct st_replace_found { |
|
143
by Brian Aker
Bool cleanup. |
6061 |
bool found; |
1
by brian
clean slate |
6062 |
char *replace_string; |
6063 |
uint to_offset; |
|
6064 |
int from_offset; |
|
6065 |
} REPLACE_STRING; |
|
6066 |
||
6067 |
||
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
6068 |
void replace_strings_append(REPLACE *rep, string* ds, |
6069 |
const char *str, int len) |
|
1
by brian
clean slate |
6070 |
{
|
6071 |
register REPLACE *rep_pos; |
|
6072 |
register REPLACE_STRING *rep_str; |
|
6073 |
const char *start, *from; |
|
142.1.1
by Patrick
Removing DBUG from client |
6074 |
|
1
by brian
clean slate |
6075 |
|
6076 |
start= from= str; |
|
6077 |
rep_pos=rep+1; |
|
6078 |
for (;;) |
|
6079 |
{
|
|
6080 |
/* Loop through states */
|
|
6081 |
while (!rep_pos->found) |
|
481
by Brian Aker
Remove all of uchar. |
6082 |
rep_pos= rep_pos->next[(unsigned char) *from++]; |
1
by brian
clean slate |
6083 |
|
6084 |
/* Does this state contain a string to be replaced */
|
|
6085 |
if (!(rep_str = ((REPLACE_STRING*) rep_pos))->replace_string) |
|
6086 |
{
|
|
6087 |
/* No match found */
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
6088 |
ds->append(start, from - start - 1); |
142.1.1
by Patrick
Removing DBUG from client |
6089 |
return; |
1
by brian
clean slate |
6090 |
}
|
6091 |
||
6092 |
/* Append part of original string before replace string */
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
6093 |
ds->append(start, (from - rep_str->to_offset) - start); |
1
by brian
clean slate |
6094 |
|
6095 |
/* Append replace string */
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
6096 |
ds->append(rep_str->replace_string, |
6097 |
strlen(rep_str->replace_string)); |
|
1
by brian
clean slate |
6098 |
|
6099 |
if (!*(from-=rep_str->from_offset) && rep_pos->found != 2) |
|
142.1.1
by Patrick
Removing DBUG from client |
6100 |
return; |
6101 |
||
142.1.2
by Patrick
All DBUG_x removed from client/ |
6102 |
assert(from <= str+len); |
1
by brian
clean slate |
6103 |
start= from; |
6104 |
rep_pos=rep; |
|
6105 |
}
|
|
6106 |
}
|
|
6107 |
||
6108 |
||
6109 |
/*
|
|
6110 |
Regex replace functions
|
|
6111 |
*/
|
|
6112 |
||
6113 |
||
6114 |
/* Stores regex substitutions */
|
|
6115 |
||
6116 |
struct st_regex |
|
6117 |
{
|
|
6118 |
char* pattern; /* Pattern to be replaced */ |
|
6119 |
char* replace; /* String or expression to replace the pattern with */ |
|
6120 |
int icase; /* true if the match is case insensitive */ |
|
6121 |
};
|
|
6122 |
||
6123 |
struct st_replace_regex |
|
6124 |
{
|
|
6125 |
DYNAMIC_ARRAY regex_arr; /* stores a list of st_regex subsitutions */ |
|
6126 |
||
6127 |
/*
|
|
6128 |
Temporary storage areas for substitutions. To reduce unnessary copying
|
|
6129 |
and memory freeing/allocation, we pre-allocate two buffers, and alternate
|
|
6130 |
their use, one for input/one for output, the roles changing on the next
|
|
6131 |
st_regex substition. At the end of substitutions buf points to the
|
|
6132 |
one containing the final result.
|
|
6133 |
*/
|
|
6134 |
char* buf; |
|
6135 |
char* even_buf; |
|
6136 |
char* odd_buf; |
|
6137 |
int even_buf_len; |
|
6138 |
int odd_buf_len; |
|
6139 |
};
|
|
6140 |
||
6141 |
struct st_replace_regex *glob_replace_regex= 0; |
|
6142 |
||
6143 |
int reg_replace(char** buf_p, int* buf_len_p, char *pattern, char *replace, |
|
6144 |
char *string, int icase); |
|
6145 |
||
6146 |
||
6147 |
||
6148 |
/*
|
|
6149 |
Finds the next (non-escaped) '/' in the expression.
|
|
6150 |
(If the character '/' is needed, it can be escaped using '\'.)
|
|
6151 |
*/
|
|
6152 |
||
6153 |
#define PARSE_REGEX_ARG \
|
|
6154 |
while (p < expr_end) \
|
|
6155 |
{ \
|
|
6156 |
char c= *p; \
|
|
6157 |
if (c == '/') \
|
|
6158 |
{ \
|
|
6159 |
if (last_c == '\\') \
|
|
6160 |
{ \
|
|
6161 |
buf_p[-1]= '/'; \
|
|
6162 |
} \
|
|
6163 |
else \
|
|
6164 |
{ \
|
|
6165 |
*buf_p++ = 0; \
|
|
6166 |
break; \
|
|
6167 |
} \
|
|
6168 |
} \
|
|
6169 |
else \
|
|
6170 |
*buf_p++ = c; \
|
|
6171 |
\
|
|
6172 |
last_c= c; \
|
|
6173 |
p++; \
|
|
6174 |
} \
|
|
6175 |
\
|
|
6176 |
/*
|
|
6177 |
Initializes the regular substitution expression to be used in the
|
|
6178 |
result output of test.
|
|
6179 |
||
6180 |
Returns: st_replace_regex struct with pairs of substitutions
|
|
6181 |
*/
|
|
6182 |
||
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
6183 |
static struct st_replace_regex* init_replace_regex(char* expr) |
1
by brian
clean slate |
6184 |
{
|
6185 |
struct st_replace_regex* res; |
|
6186 |
char* buf,*expr_end; |
|
6187 |
char* p; |
|
6188 |
char* buf_p; |
|
6189 |
uint expr_len= strlen(expr); |
|
6190 |
char last_c = 0; |
|
6191 |
struct st_regex reg; |
|
6192 |
||
6193 |
/* my_malloc() will die on fail with MY_FAE */
|
|
6194 |
res=(struct st_replace_regex*)my_malloc( |
|
6195 |
sizeof(*res)+expr_len ,MYF(MY_FAE+MY_WME)); |
|
6196 |
my_init_dynamic_array(&res->regex_arr,sizeof(struct st_regex),128,128); |
|
6197 |
||
6198 |
buf= (char*)res + sizeof(*res); |
|
6199 |
expr_end= expr + expr_len; |
|
6200 |
p= expr; |
|
6201 |
buf_p= buf; |
|
6202 |
||
6203 |
/* for each regexp substitution statement */
|
|
6204 |
while (p < expr_end) |
|
6205 |
{
|
|
212.6.1
by Mats Kindahl
Replacing all bzero() calls with memset() calls and removing the bzero.c file. |
6206 |
memset(®, 0, sizeof(reg)); |
1
by brian
clean slate |
6207 |
/* find the start of the statement */
|
6208 |
while (p < expr_end) |
|
6209 |
{
|
|
6210 |
if (*p == '/') |
|
6211 |
break; |
|
6212 |
p++; |
|
6213 |
}
|
|
6214 |
||
6215 |
if (p == expr_end || ++p == expr_end) |
|
6216 |
{
|
|
6217 |
if (res->regex_arr.elements) |
|
6218 |
break; |
|
6219 |
else
|
|
6220 |
goto err; |
|
6221 |
}
|
|
6222 |
/* we found the start */
|
|
6223 |
reg.pattern= buf_p; |
|
6224 |
||
6225 |
/* Find first argument -- pattern string to be removed */
|
|
6226 |
PARSE_REGEX_ARG
|
|
6227 |
||
6228 |
if (p == expr_end || ++p == expr_end) |
|
6229 |
goto err; |
|
6230 |
||
6231 |
/* buf_p now points to the replacement pattern terminated with \0 */
|
|
6232 |
reg.replace= buf_p; |
|
6233 |
||
6234 |
/* Find second argument -- replace string to replace pattern */
|
|
6235 |
PARSE_REGEX_ARG
|
|
6236 |
||
6237 |
if (p == expr_end) |
|
6238 |
goto err; |
|
6239 |
||
6240 |
/* skip the ending '/' in the statement */
|
|
6241 |
p++; |
|
6242 |
||
6243 |
/* Check if we should do matching case insensitive */
|
|
6244 |
if (p < expr_end && *p == 'i') |
|
6245 |
reg.icase= 1; |
|
6246 |
||
6247 |
/* done parsing the statement, now place it in regex_arr */
|
|
481
by Brian Aker
Remove all of uchar. |
6248 |
if (insert_dynamic(&res->regex_arr,(unsigned char*) ®)) |
1
by brian
clean slate |
6249 |
die("Out of memory"); |
6250 |
}
|
|
6251 |
res->odd_buf_len= res->even_buf_len= 8192; |
|
6252 |
res->even_buf= (char*)my_malloc(res->even_buf_len,MYF(MY_WME+MY_FAE)); |
|
6253 |
res->odd_buf= (char*)my_malloc(res->odd_buf_len,MYF(MY_WME+MY_FAE)); |
|
6254 |
res->buf= res->even_buf; |
|
6255 |
||
6256 |
return res; |
|
6257 |
||
6258 |
err: |
|
477
by Monty Taylor
Removed my_free(). It turns out that it had been def'd to ignore the flags passed to it in the second arg anyway. Gotta love that. |
6259 |
free(res); |
1
by brian
clean slate |
6260 |
die("Error parsing replace_regex \"%s\"", expr); |
6261 |
return 0; |
|
6262 |
}
|
|
6263 |
||
6264 |
/*
|
|
6265 |
Execute all substitutions on val.
|
|
6266 |
||
6267 |
Returns: true if substituition was made, false otherwise
|
|
6268 |
Side-effect: Sets r->buf to be the buffer with all substitutions done.
|
|
6269 |
||
6270 |
IN:
|
|
6271 |
struct st_replace_regex* r
|
|
6272 |
char* val
|
|
6273 |
Out:
|
|
6274 |
struct st_replace_regex* r
|
|
6275 |
r->buf points at the resulting buffer
|
|
6276 |
r->even_buf and r->odd_buf might have been reallocated
|
|
6277 |
r->even_buf_len and r->odd_buf_len might have been changed
|
|
6278 |
||
6279 |
TODO: at some point figure out if there is a way to do everything
|
|
6280 |
in one pass
|
|
6281 |
*/
|
|
6282 |
||
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
6283 |
static int multi_reg_replace(struct st_replace_regex* r,char* val) |
1
by brian
clean slate |
6284 |
{
|
6285 |
uint i; |
|
6286 |
char* in_buf, *out_buf; |
|
6287 |
int* buf_len_p; |
|
6288 |
||
6289 |
in_buf= val; |
|
6290 |
out_buf= r->even_buf; |
|
6291 |
buf_len_p= &r->even_buf_len; |
|
6292 |
r->buf= 0; |
|
6293 |
||
6294 |
/* For each substitution, do the replace */
|
|
6295 |
for (i= 0; i < r->regex_arr.elements; i++) |
|
6296 |
{
|
|
6297 |
struct st_regex re; |
|
6298 |
char* save_out_buf= out_buf; |
|
6299 |
||
481
by Brian Aker
Remove all of uchar. |
6300 |
get_dynamic(&r->regex_arr,(unsigned char*)&re,i); |
1
by brian
clean slate |
6301 |
|
6302 |
if (!reg_replace(&out_buf, buf_len_p, re.pattern, re.replace, |
|
6303 |
in_buf, re.icase)) |
|
6304 |
{
|
|
6305 |
/* if the buffer has been reallocated, make adjustements */
|
|
6306 |
if (save_out_buf != out_buf) |
|
6307 |
{
|
|
6308 |
if (save_out_buf == r->even_buf) |
|
6309 |
r->even_buf= out_buf; |
|
6310 |
else
|
|
6311 |
r->odd_buf= out_buf; |
|
6312 |
}
|
|
6313 |
||
6314 |
r->buf= out_buf; |
|
6315 |
if (in_buf == val) |
|
6316 |
in_buf= r->odd_buf; |
|
6317 |
||
322.2.2
by Mats Kindahl
Hiding THD::proc_info field and providing a setter and getter. |
6318 |
std::swap(in_buf,out_buf); |
1
by brian
clean slate |
6319 |
|
6320 |
buf_len_p= (out_buf == r->even_buf) ? &r->even_buf_len : |
|
6321 |
&r->odd_buf_len; |
|
6322 |
}
|
|
6323 |
}
|
|
6324 |
||
6325 |
return (r->buf == 0); |
|
6326 |
}
|
|
6327 |
||
6328 |
/*
|
|
6329 |
Parse the regular expression to be used in all result files
|
|
6330 |
from now on.
|
|
6331 |
||
6332 |
The syntax is --replace_regex /from/to/i /from/to/i ...
|
|
6333 |
i means case-insensitive match. If omitted, the match is
|
|
6334 |
case-sensitive
|
|
6335 |
||
6336 |
*/
|
|
6337 |
void do_get_replace_regex(struct st_command *command) |
|
6338 |
{
|
|
6339 |
char *expr= command->first_argument; |
|
6340 |
free_replace_regex(); |
|
6341 |
if (!(glob_replace_regex=init_replace_regex(expr))) |
|
6342 |
die("Could not init replace_regex"); |
|
6343 |
command->last_argument= command->end; |
|
6344 |
}
|
|
6345 |
||
6346 |
void free_replace_regex() |
|
6347 |
{
|
|
6348 |
if (glob_replace_regex) |
|
6349 |
{
|
|
6350 |
delete_dynamic(&glob_replace_regex->regex_arr); |
|
477
by Monty Taylor
Removed my_free(). It turns out that it had been def'd to ignore the flags passed to it in the second arg anyway. Gotta love that. |
6351 |
free(glob_replace_regex->even_buf); |
6352 |
free(glob_replace_regex->odd_buf); |
|
6353 |
free(glob_replace_regex); |
|
1
by brian
clean slate |
6354 |
glob_replace_regex=0; |
6355 |
}
|
|
6356 |
}
|
|
6357 |
||
6358 |
||
6359 |
||
6360 |
/*
|
|
6361 |
Performs a regex substitution
|
|
6362 |
||
6363 |
IN:
|
|
6364 |
||
6365 |
buf_p - result buffer pointer. Will change if reallocated
|
|
6366 |
buf_len_p - result buffer length. Will change if the buffer is reallocated
|
|
6367 |
pattern - regexp pattern to match
|
|
6368 |
replace - replacement expression
|
|
6369 |
string - the string to perform substituions in
|
|
6370 |
icase - flag, if set to 1 the match is case insensitive
|
|
6371 |
*/
|
|
6372 |
int reg_replace(char** buf_p, int* buf_len_p, char *pattern, |
|
77.1.31
by Monty Taylor
Replaced regex lib with pcre. Reworked mysqltest to use it. |
6373 |
char *replace, char *in_string, int icase) |
1
by brian
clean slate |
6374 |
{
|
77.1.31
by Monty Taylor
Replaced regex lib with pcre. Reworked mysqltest to use it. |
6375 |
string string_to_match(in_string); |
6376 |
pcrecpp::RE_Options opt; |
|
1
by brian
clean slate |
6377 |
|
6378 |
if (icase) |
|
77.1.31
by Monty Taylor
Replaced regex lib with pcre. Reworked mysqltest to use it. |
6379 |
opt.set_caseless(true); |
6380 |
||
6381 |
if (!pcrecpp::RE(pattern, opt).Replace(replace,&string_to_match)){ |
|
6382 |
return 1; |
|
6383 |
}
|
|
6384 |
||
6385 |
const char * new_str= string_to_match.c_str(); |
|
6386 |
*buf_len_p= strlen(new_str); |
|
6387 |
char * new_buf = (char *)malloc(*buf_len_p+1); |
|
6388 |
if (new_buf == NULL) |
|
6389 |
{
|
|
6390 |
return 1; |
|
6391 |
}
|
|
6392 |
strcpy(new_buf, new_str); |
|
496.1.7
by Paul McCullagh
Fixed the --replace_regex command |
6393 |
*buf_p= new_buf; |
77.1.31
by Monty Taylor
Replaced regex lib with pcre. Reworked mysqltest to use it. |
6394 |
|
1
by brian
clean slate |
6395 |
return 0; |
6396 |
}
|
|
6397 |
||
6398 |
||
6399 |
#ifndef WORD_BIT
|
|
6400 |
#define WORD_BIT (8*sizeof(uint))
|
|
6401 |
#endif
|
|
6402 |
||
6403 |
#define SET_MALLOC_HUNC 64
|
|
6404 |
#define LAST_CHAR_CODE 259
|
|
6405 |
||
6406 |
typedef struct st_rep_set { |
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
6407 |
uint *bits; /* Pointer to used sets */ |
6408 |
short next[LAST_CHAR_CODE]; /* Pointer to next sets */ |
|
6409 |
uint found_len; /* Best match to date */ |
|
6410 |
int found_offset; |
|
6411 |
uint table_offset; |
|
6412 |
uint size_of_bits; /* For convinience */ |
|
1
by brian
clean slate |
6413 |
} REP_SET; |
6414 |
||
6415 |
typedef struct st_rep_sets { |
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
6416 |
uint count; /* Number of sets */ |
6417 |
uint extra; /* Extra sets in buffer */ |
|
6418 |
uint invisible; /* Sets not chown */ |
|
6419 |
uint size_of_bits; |
|
6420 |
REP_SET *set,*set_buffer; |
|
6421 |
uint *bit_buffer; |
|
1
by brian
clean slate |
6422 |
} REP_SETS; |
6423 |
||
6424 |
typedef struct st_found_set { |
|
6425 |
uint table_offset; |
|
6426 |
int found_offset; |
|
6427 |
} FOUND_SET; |
|
6428 |
||
6429 |
typedef struct st_follow { |
|
6430 |
int chr; |
|
6431 |
uint table_offset; |
|
6432 |
uint len; |
|
6433 |
} FOLLOWS; |
|
6434 |
||
6435 |
||
6436 |
int init_sets(REP_SETS *sets,uint states); |
|
6437 |
REP_SET *make_new_set(REP_SETS *sets); |
|
6438 |
void make_sets_invisible(REP_SETS *sets); |
|
6439 |
void free_last_set(REP_SETS *sets); |
|
6440 |
void free_sets(REP_SETS *sets); |
|
6441 |
void internal_set_bit(REP_SET *set, uint bit); |
|
6442 |
void internal_clear_bit(REP_SET *set, uint bit); |
|
6443 |
void or_bits(REP_SET *to,REP_SET *from); |
|
6444 |
void copy_bits(REP_SET *to,REP_SET *from); |
|
6445 |
int cmp_bits(REP_SET *set1,REP_SET *set2); |
|
6446 |
int get_next_bit(REP_SET *set,uint lastpos); |
|
6447 |
int find_set(REP_SETS *sets,REP_SET *find); |
|
6448 |
int find_found(FOUND_SET *found_set,uint table_offset, |
|
6449 |
int found_offset); |
|
6450 |
uint start_at_word(char * pos); |
|
6451 |
uint end_of_word(char * pos); |
|
6452 |
||
6453 |
static uint found_sets=0; |
|
6454 |
||
6455 |
||
53.2.4
by Monty Taylor
Changes so that client/ builds cleanly with no warnings. |
6456 |
static uint replace_len(char * str) |
1
by brian
clean slate |
6457 |
{
|
6458 |
uint len=0; |
|
6459 |
while (*str) |
|
6460 |
{
|
|
6461 |
if (str[0] == '\\' && str[1]) |
|
6462 |
str++; |
|
6463 |
str++; |
|
6464 |
len++; |
|
6465 |
}
|
|
6466 |
return len; |
|
6467 |
}
|
|
6468 |
||
6469 |
/* Init a replace structure for further calls */
|
|
6470 |
||
6471 |
REPLACE *init_replace(char * *from, char * *to,uint count, |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
6472 |
char * word_end_chars) |
1
by brian
clean slate |
6473 |
{
|
6474 |
static const int SPACE_CHAR= 256; |
|
6475 |
static const int START_OF_LINE= 257; |
|
6476 |
static const int END_OF_LINE= 258; |
|
6477 |
||
6478 |
uint i,j,states,set_nr,len,result_len,max_length,found_end,bits_set,bit_nr; |
|
6479 |
int used_sets,chr,default_state; |
|
6480 |
char used_chars[LAST_CHAR_CODE],is_word_end[256]; |
|
6481 |
char * pos, *to_pos, **to_array; |
|
6482 |
REP_SETS sets; |
|
6483 |
REP_SET *set,*start_states,*word_states,*new_set; |
|
6484 |
FOLLOWS *follow,*follow_ptr; |
|
6485 |
REPLACE *replace; |
|
6486 |
FOUND_SET *found_set; |
|
6487 |
REPLACE_STRING *rep_str; |
|
142.1.1
by Patrick
Removing DBUG from client |
6488 |
|
1
by brian
clean slate |
6489 |
|
6490 |
/* Count number of states */
|
|
6491 |
for (i=result_len=max_length=0 , states=2 ; i < count ; i++) |
|
6492 |
{
|
|
6493 |
len=replace_len(from[i]); |
|
6494 |
if (!len) |
|
6495 |
{
|
|
6496 |
errno=EINVAL; |
|
142.1.1
by Patrick
Removing DBUG from client |
6497 |
return(0); |
1
by brian
clean slate |
6498 |
}
|
6499 |
states+=len+1; |
|
6500 |
result_len+=(uint) strlen(to[i])+1; |
|
6501 |
if (len > max_length) |
|
6502 |
max_length=len; |
|
6503 |
}
|
|
212.6.10
by Mats Kindahl
Removing redundant use of casts in client/ for memcmp(), memcpy(), memset(), and memmove(). |
6504 |
memset(is_word_end, 0, sizeof(is_word_end)); |
1
by brian
clean slate |
6505 |
for (i=0 ; word_end_chars[i] ; i++) |
481
by Brian Aker
Remove all of uchar. |
6506 |
is_word_end[(unsigned char) word_end_chars[i]]=1; |
1
by brian
clean slate |
6507 |
|
6508 |
if (init_sets(&sets,states)) |
|
142.1.1
by Patrick
Removing DBUG from client |
6509 |
return(0); |
1
by brian
clean slate |
6510 |
found_sets=0; |
6511 |
if (!(found_set= (FOUND_SET*) my_malloc(sizeof(FOUND_SET)*max_length*count, |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
6512 |
MYF(MY_WME)))) |
1
by brian
clean slate |
6513 |
{
|
6514 |
free_sets(&sets); |
|
142.1.1
by Patrick
Removing DBUG from client |
6515 |
return(0); |
1
by brian
clean slate |
6516 |
}
|
398.1.10
by Monty Taylor
Actually removed VOID() this time. |
6517 |
make_new_set(&sets); /* Set starting set */ |
206.3.1
by Patrick Galbraith
Most everything working with client rename |
6518 |
make_sets_invisible(&sets); /* Hide previus sets */ |
1
by brian
clean slate |
6519 |
used_sets=-1; |
206.3.1
by Patrick Galbraith
Most everything working with client rename |
6520 |
word_states=make_new_set(&sets); /* Start of new word */ |
6521 |
start_states=make_new_set(&sets); /* This is first state */ |
|
1
by brian
clean slate |
6522 |
if (!(follow=(FOLLOWS*) my_malloc((states+2)*sizeof(FOLLOWS),MYF(MY_WME)))) |
6523 |
{
|
|
6524 |
free_sets(&sets); |
|
477
by Monty Taylor
Removed my_free(). It turns out that it had been def'd to ignore the flags passed to it in the second arg anyway. Gotta love that. |
6525 |
free(found_set); |
142.1.1
by Patrick
Removing DBUG from client |
6526 |
return(0); |
1
by brian
clean slate |
6527 |
}
|
6528 |
||
6529 |
/* Init follow_ptr[] */
|
|
6530 |
for (i=0, states=1, follow_ptr=follow+1 ; i < count ; i++) |
|
6531 |
{
|
|
6532 |
if (from[i][0] == '\\' && from[i][1] == '^') |
|
6533 |
{
|
|
6534 |
internal_set_bit(start_states,states+1); |
|
6535 |
if (!from[i][2]) |
|
6536 |
{
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
6537 |
start_states->table_offset=i; |
6538 |
start_states->found_offset=1; |
|
1
by brian
clean slate |
6539 |
}
|
6540 |
}
|
|
6541 |
else if (from[i][0] == '\\' && from[i][1] == '$') |
|
6542 |
{
|
|
6543 |
internal_set_bit(start_states,states); |
|
6544 |
internal_set_bit(word_states,states); |
|
365.2.7
by Monty Taylor
INT32_MAX stuff. |
6545 |
if (!from[i][2] && start_states->table_offset == UINT32_MAX) |
1
by brian
clean slate |
6546 |
{
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
6547 |
start_states->table_offset=i; |
6548 |
start_states->found_offset=0; |
|
1
by brian
clean slate |
6549 |
}
|
6550 |
}
|
|
6551 |
else
|
|
6552 |
{
|
|
6553 |
internal_set_bit(word_states,states); |
|
6554 |
if (from[i][0] == '\\' && (from[i][1] == 'b' && from[i][2])) |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
6555 |
internal_set_bit(start_states,states+1); |
1
by brian
clean slate |
6556 |
else
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
6557 |
internal_set_bit(start_states,states); |
1
by brian
clean slate |
6558 |
}
|
6559 |
for (pos=from[i], len=0; *pos ; pos++) |
|
6560 |
{
|
|
6561 |
if (*pos == '\\' && *(pos+1)) |
|
6562 |
{
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
6563 |
pos++; |
6564 |
switch (*pos) { |
|
6565 |
case 'b': |
|
6566 |
follow_ptr->chr = SPACE_CHAR; |
|
6567 |
break; |
|
6568 |
case '^': |
|
6569 |
follow_ptr->chr = START_OF_LINE; |
|
6570 |
break; |
|
6571 |
case '$': |
|
6572 |
follow_ptr->chr = END_OF_LINE; |
|
6573 |
break; |
|
6574 |
case 'r': |
|
6575 |
follow_ptr->chr = '\r'; |
|
6576 |
break; |
|
6577 |
case 't': |
|
6578 |
follow_ptr->chr = '\t'; |
|
6579 |
break; |
|
6580 |
case 'v': |
|
6581 |
follow_ptr->chr = '\v'; |
|
6582 |
break; |
|
6583 |
default: |
|
481
by Brian Aker
Remove all of uchar. |
6584 |
follow_ptr->chr = (unsigned char) *pos; |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
6585 |
break; |
6586 |
}
|
|
1
by brian
clean slate |
6587 |
}
|
6588 |
else
|
|
481
by Brian Aker
Remove all of uchar. |
6589 |
follow_ptr->chr= (unsigned char) *pos; |
1
by brian
clean slate |
6590 |
follow_ptr->table_offset=i; |
6591 |
follow_ptr->len= ++len; |
|
6592 |
follow_ptr++; |
|
6593 |
}
|
|
6594 |
follow_ptr->chr=0; |
|
6595 |
follow_ptr->table_offset=i; |
|
6596 |
follow_ptr->len=len; |
|
6597 |
follow_ptr++; |
|
6598 |
states+=(uint) len+1; |
|
6599 |
}
|
|
6600 |
||
6601 |
||
6602 |
for (set_nr=0,pos=0 ; set_nr < sets.count ; set_nr++) |
|
6603 |
{
|
|
6604 |
set=sets.set+set_nr; |
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
6605 |
default_state= 0; /* Start from beginning */ |
1
by brian
clean slate |
6606 |
|
6607 |
/* If end of found-string not found or start-set with current set */
|
|
6608 |
||
365.2.7
by Monty Taylor
INT32_MAX stuff. |
6609 |
for (i= UINT32_MAX; (i=get_next_bit(set,i)) ;) |
1
by brian
clean slate |
6610 |
{
|
6611 |
if (!follow[i].chr) |
|
6612 |
{
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
6613 |
if (! default_state) |
6614 |
default_state= find_found(found_set,set->table_offset, |
|
6615 |
set->found_offset+1); |
|
1
by brian
clean slate |
6616 |
}
|
6617 |
}
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
6618 |
copy_bits(sets.set+used_sets,set); /* Save set for changes */ |
1
by brian
clean slate |
6619 |
if (!default_state) |
206.3.1
by Patrick Galbraith
Most everything working with client rename |
6620 |
or_bits(sets.set+used_sets,sets.set); /* Can restart from start */ |
1
by brian
clean slate |
6621 |
|
6622 |
/* Find all chars that follows current sets */
|
|
212.6.10
by Mats Kindahl
Removing redundant use of casts in client/ for memcmp(), memcpy(), memset(), and memmove(). |
6623 |
memset(used_chars, 0, sizeof(used_chars)); |
365.2.7
by Monty Taylor
INT32_MAX stuff. |
6624 |
for (i= UINT32_MAX; (i=get_next_bit(sets.set+used_sets,i)) ;) |
1
by brian
clean slate |
6625 |
{
|
6626 |
used_chars[follow[i].chr]=1; |
|
6627 |
if ((follow[i].chr == SPACE_CHAR && !follow[i+1].chr && |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
6628 |
follow[i].len > 1) || follow[i].chr == END_OF_LINE) |
6629 |
used_chars[0]=1; |
|
1
by brian
clean slate |
6630 |
}
|
6631 |
||
6632 |
/* Mark word_chars used if \b is in state */
|
|
6633 |
if (used_chars[SPACE_CHAR]) |
|
6634 |
for (pos= word_end_chars ; *pos ; pos++) |
|
481
by Brian Aker
Remove all of uchar. |
6635 |
used_chars[(int) (unsigned char) *pos] = 1; |
1
by brian
clean slate |
6636 |
|
6637 |
/* Handle other used characters */
|
|
6638 |
for (chr= 0 ; chr < 256 ; chr++) |
|
6639 |
{
|
|
6640 |
if (! used_chars[chr]) |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
6641 |
set->next[chr]= chr ? default_state : -1; |
1
by brian
clean slate |
6642 |
else
|
6643 |
{
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
6644 |
new_set=make_new_set(&sets); |
6645 |
set=sets.set+set_nr; /* if realloc */ |
|
6646 |
new_set->table_offset=set->table_offset; |
|
6647 |
new_set->found_len=set->found_len; |
|
6648 |
new_set->found_offset=set->found_offset+1; |
|
6649 |
found_end=0; |
|
1
by brian
clean slate |
6650 |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
6651 |
for (i= UINT32_MAX ; (i=get_next_bit(sets.set+used_sets,i)) ; ) |
6652 |
{
|
|
6653 |
if (!follow[i].chr || follow[i].chr == chr || |
|
6654 |
(follow[i].chr == SPACE_CHAR && |
|
6655 |
(is_word_end[chr] || |
|
6656 |
(!chr && follow[i].len > 1 && ! follow[i+1].chr))) || |
|
6657 |
(follow[i].chr == END_OF_LINE && ! chr)) |
|
6658 |
{
|
|
6659 |
if ((! chr || (follow[i].chr && !follow[i+1].chr)) && |
|
6660 |
follow[i].len > found_end) |
|
6661 |
found_end=follow[i].len; |
|
6662 |
if (chr && follow[i].chr) |
|
6663 |
internal_set_bit(new_set,i+1); /* To next set */ |
|
6664 |
else
|
|
6665 |
internal_set_bit(new_set,i); |
|
6666 |
}
|
|
6667 |
}
|
|
6668 |
if (found_end) |
|
6669 |
{
|
|
6670 |
new_set->found_len=0; /* Set for testing if first */ |
|
6671 |
bits_set=0; |
|
6672 |
for (i= UINT32_MAX; (i=get_next_bit(new_set,i)) ;) |
|
6673 |
{
|
|
6674 |
if ((follow[i].chr == SPACE_CHAR || |
|
6675 |
follow[i].chr == END_OF_LINE) && ! chr) |
|
6676 |
bit_nr=i+1; |
|
6677 |
else
|
|
6678 |
bit_nr=i; |
|
6679 |
if (follow[bit_nr-1].len < found_end || |
|
6680 |
(new_set->found_len && |
|
6681 |
(chr == 0 || !follow[bit_nr].chr))) |
|
6682 |
internal_clear_bit(new_set,i); |
|
6683 |
else
|
|
6684 |
{
|
|
6685 |
if (chr == 0 || !follow[bit_nr].chr) |
|
6686 |
{ /* best match */ |
|
6687 |
new_set->table_offset=follow[bit_nr].table_offset; |
|
6688 |
if (chr || (follow[i].chr == SPACE_CHAR || |
|
6689 |
follow[i].chr == END_OF_LINE)) |
|
6690 |
new_set->found_offset=found_end; /* New match */ |
|
6691 |
new_set->found_len=found_end; |
|
6692 |
}
|
|
6693 |
bits_set++; |
|
6694 |
}
|
|
6695 |
}
|
|
6696 |
if (bits_set == 1) |
|
6697 |
{
|
|
6698 |
set->next[chr] = find_found(found_set, |
|
6699 |
new_set->table_offset, |
|
6700 |
new_set->found_offset); |
|
6701 |
free_last_set(&sets); |
|
6702 |
}
|
|
6703 |
else
|
|
6704 |
set->next[chr] = find_set(&sets,new_set); |
|
6705 |
}
|
|
6706 |
else
|
|
6707 |
set->next[chr] = find_set(&sets,new_set); |
|
1
by brian
clean slate |
6708 |
}
|
6709 |
}
|
|
6710 |
}
|
|
6711 |
||
6712 |
/* Alloc replace structure for the replace-state-machine */
|
|
6713 |
||
6714 |
if ((replace=(REPLACE*) my_malloc(sizeof(REPLACE)*(sets.count)+ |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
6715 |
sizeof(REPLACE_STRING)*(found_sets+1)+ |
6716 |
sizeof(char *)*count+result_len, |
|
6717 |
MYF(MY_WME | MY_ZEROFILL)))) |
|
1
by brian
clean slate |
6718 |
{
|
6719 |
rep_str=(REPLACE_STRING*) (replace+sets.count); |
|
6720 |
to_array= (char **) (rep_str+found_sets+1); |
|
6721 |
to_pos=(char *) (to_array+count); |
|
6722 |
for (i=0 ; i < count ; i++) |
|
6723 |
{
|
|
6724 |
to_array[i]=to_pos; |
|
411.1.1
by Brian Aker
Work on removing GNU specific calls. |
6725 |
to_pos=my_stpcpy(to_pos,to[i])+1; |
1
by brian
clean slate |
6726 |
}
|
6727 |
rep_str[0].found=1; |
|
6728 |
rep_str[0].replace_string=0; |
|
6729 |
for (i=1 ; i <= found_sets ; i++) |
|
6730 |
{
|
|
6731 |
pos=from[found_set[i-1].table_offset]; |
|
212.6.10
by Mats Kindahl
Removing redundant use of casts in client/ for memcmp(), memcpy(), memset(), and memmove(). |
6732 |
rep_str[i].found= !memcmp(pos, "\\^", 3) ? 2 : 1; |
1
by brian
clean slate |
6733 |
rep_str[i].replace_string=to_array[found_set[i-1].table_offset]; |
6734 |
rep_str[i].to_offset=found_set[i-1].found_offset-start_at_word(pos); |
|
6735 |
rep_str[i].from_offset=found_set[i-1].found_offset-replace_len(pos)+ |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
6736 |
end_of_word(pos); |
1
by brian
clean slate |
6737 |
}
|
6738 |
for (i=0 ; i < sets.count ; i++) |
|
6739 |
{
|
|
6740 |
for (j=0 ; j < 256 ; j++) |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
6741 |
if (sets.set[i].next[j] >= 0) |
6742 |
replace[i].next[j]=replace+sets.set[i].next[j]; |
|
6743 |
else
|
|
6744 |
replace[i].next[j]=(REPLACE*) (rep_str+(-sets.set[i].next[j]-1)); |
|
1
by brian
clean slate |
6745 |
}
|
6746 |
}
|
|
477
by Monty Taylor
Removed my_free(). It turns out that it had been def'd to ignore the flags passed to it in the second arg anyway. Gotta love that. |
6747 |
free(follow); |
1
by brian
clean slate |
6748 |
free_sets(&sets); |
477
by Monty Taylor
Removed my_free(). It turns out that it had been def'd to ignore the flags passed to it in the second arg anyway. Gotta love that. |
6749 |
free(found_set); |
142.1.1
by Patrick
Removing DBUG from client |
6750 |
return(replace); |
1
by brian
clean slate |
6751 |
}
|
6752 |
||
6753 |
||
6754 |
int init_sets(REP_SETS *sets,uint states) |
|
6755 |
{
|
|
212.6.10
by Mats Kindahl
Removing redundant use of casts in client/ for memcmp(), memcpy(), memset(), and memmove(). |
6756 |
memset(sets, 0, sizeof(*sets)); |
1
by brian
clean slate |
6757 |
sets->size_of_bits=((states+7)/8); |
6758 |
if (!(sets->set_buffer=(REP_SET*) my_malloc(sizeof(REP_SET)*SET_MALLOC_HUNC, |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
6759 |
MYF(MY_WME)))) |
1
by brian
clean slate |
6760 |
return 1; |
6761 |
if (!(sets->bit_buffer=(uint*) my_malloc(sizeof(uint)*sets->size_of_bits* |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
6762 |
SET_MALLOC_HUNC,MYF(MY_WME)))) |
1
by brian
clean slate |
6763 |
{
|
477
by Monty Taylor
Removed my_free(). It turns out that it had been def'd to ignore the flags passed to it in the second arg anyway. Gotta love that. |
6764 |
free(sets->set); |
1
by brian
clean slate |
6765 |
return 1; |
6766 |
}
|
|
6767 |
return 0; |
|
6768 |
}
|
|
6769 |
||
6770 |
/* Make help sets invisible for nicer codeing */
|
|
6771 |
||
6772 |
void make_sets_invisible(REP_SETS *sets) |
|
6773 |
{
|
|
6774 |
sets->invisible=sets->count; |
|
6775 |
sets->set+=sets->count; |
|
6776 |
sets->count=0; |
|
6777 |
}
|
|
6778 |
||
6779 |
REP_SET *make_new_set(REP_SETS *sets) |
|
6780 |
{
|
|
6781 |
uint i,count,*bit_buffer; |
|
6782 |
REP_SET *set; |
|
6783 |
if (sets->extra) |
|
6784 |
{
|
|
6785 |
sets->extra--; |
|
6786 |
set=sets->set+ sets->count++; |
|
212.6.10
by Mats Kindahl
Removing redundant use of casts in client/ for memcmp(), memcpy(), memset(), and memmove(). |
6787 |
memset(set->bits, 0, sizeof(uint)*sets->size_of_bits); |
6788 |
memset(&set->next[0], 0, sizeof(set->next[0])*LAST_CHAR_CODE); |
|
1
by brian
clean slate |
6789 |
set->found_offset=0; |
6790 |
set->found_len=0; |
|
365.2.7
by Monty Taylor
INT32_MAX stuff. |
6791 |
set->table_offset= UINT32_MAX; |
1
by brian
clean slate |
6792 |
set->size_of_bits=sets->size_of_bits; |
6793 |
return set; |
|
6794 |
}
|
|
6795 |
count=sets->count+sets->invisible+SET_MALLOC_HUNC; |
|
481
by Brian Aker
Remove all of uchar. |
6796 |
if (!(set=(REP_SET*) my_realloc((unsigned char*) sets->set_buffer, |
1
by brian
clean slate |
6797 |
sizeof(REP_SET)*count, |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
6798 |
MYF(MY_WME)))) |
1
by brian
clean slate |
6799 |
return 0; |
6800 |
sets->set_buffer=set; |
|
6801 |
sets->set=set+sets->invisible; |
|
481
by Brian Aker
Remove all of uchar. |
6802 |
if (!(bit_buffer=(uint*) my_realloc((unsigned char*) sets->bit_buffer, |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
6803 |
(sizeof(uint)*sets->size_of_bits)*count, |
6804 |
MYF(MY_WME)))) |
|
1
by brian
clean slate |
6805 |
return 0; |
6806 |
sets->bit_buffer=bit_buffer; |
|
6807 |
for (i=0 ; i < count ; i++) |
|
6808 |
{
|
|
6809 |
sets->set_buffer[i].bits=bit_buffer; |
|
6810 |
bit_buffer+=sets->size_of_bits; |
|
6811 |
}
|
|
6812 |
sets->extra=SET_MALLOC_HUNC; |
|
6813 |
return make_new_set(sets); |
|
6814 |
}
|
|
6815 |
||
6816 |
void free_last_set(REP_SETS *sets) |
|
6817 |
{
|
|
6818 |
sets->count--; |
|
6819 |
sets->extra++; |
|
6820 |
return; |
|
6821 |
}
|
|
6822 |
||
6823 |
void free_sets(REP_SETS *sets) |
|
6824 |
{
|
|
477
by Monty Taylor
Removed my_free(). It turns out that it had been def'd to ignore the flags passed to it in the second arg anyway. Gotta love that. |
6825 |
free(sets->set_buffer); |
6826 |
free(sets->bit_buffer); |
|
1
by brian
clean slate |
6827 |
return; |
6828 |
}
|
|
6829 |
||
6830 |
void internal_set_bit(REP_SET *set, uint bit) |
|
6831 |
{
|
|
6832 |
set->bits[bit / WORD_BIT] |= 1 << (bit % WORD_BIT); |
|
6833 |
return; |
|
6834 |
}
|
|
6835 |
||
6836 |
void internal_clear_bit(REP_SET *set, uint bit) |
|
6837 |
{
|
|
6838 |
set->bits[bit / WORD_BIT] &= ~ (1 << (bit % WORD_BIT)); |
|
6839 |
return; |
|
6840 |
}
|
|
6841 |
||
6842 |
||
6843 |
void or_bits(REP_SET *to,REP_SET *from) |
|
6844 |
{
|
|
6845 |
register uint i; |
|
6846 |
for (i=0 ; i < to->size_of_bits ; i++) |
|
6847 |
to->bits[i]|=from->bits[i]; |
|
6848 |
return; |
|
6849 |
}
|
|
6850 |
||
6851 |
void copy_bits(REP_SET *to,REP_SET *from) |
|
6852 |
{
|
|
212.6.10
by Mats Kindahl
Removing redundant use of casts in client/ for memcmp(), memcpy(), memset(), and memmove(). |
6853 |
memcpy(to->bits,from->bits, |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
6854 |
(size_t) (sizeof(uint) * to->size_of_bits)); |
1
by brian
clean slate |
6855 |
}
|
6856 |
||
6857 |
int cmp_bits(REP_SET *set1,REP_SET *set2) |
|
6858 |
{
|
|
212.6.10
by Mats Kindahl
Removing redundant use of casts in client/ for memcmp(), memcpy(), memset(), and memmove(). |
6859 |
return memcmp(set1->bits,set2->bits, sizeof(uint) * set1->size_of_bits); |
1
by brian
clean slate |
6860 |
}
|
6861 |
||
6862 |
||
6863 |
/* Get next set bit from set. */
|
|
6864 |
||
6865 |
int get_next_bit(REP_SET *set,uint lastpos) |
|
6866 |
{
|
|
6867 |
uint pos,*start,*end,bits; |
|
6868 |
||
6869 |
start=set->bits+ ((lastpos+1) / WORD_BIT); |
|
6870 |
end=set->bits + set->size_of_bits; |
|
6871 |
bits=start[0] & ~((1 << ((lastpos+1) % WORD_BIT)) -1); |
|
6872 |
||
6873 |
while (! bits && ++start < end) |
|
6874 |
bits=start[0]; |
|
6875 |
if (!bits) |
|
6876 |
return 0; |
|
6877 |
pos=(uint) (start-set->bits)*WORD_BIT; |
|
6878 |
while (! (bits & 1)) |
|
6879 |
{
|
|
6880 |
bits>>=1; |
|
6881 |
pos++; |
|
6882 |
}
|
|
6883 |
return pos; |
|
6884 |
}
|
|
6885 |
||
6886 |
/* find if there is a same set in sets. If there is, use it and
|
|
6887 |
free given set, else put in given set in sets and return its
|
|
6888 |
position */
|
|
6889 |
||
6890 |
int find_set(REP_SETS *sets,REP_SET *find) |
|
6891 |
{
|
|
6892 |
uint i; |
|
6893 |
for (i=0 ; i < sets->count-1 ; i++) |
|
6894 |
{
|
|
6895 |
if (!cmp_bits(sets->set+i,find)) |
|
6896 |
{
|
|
6897 |
free_last_set(sets); |
|
6898 |
return i; |
|
6899 |
}
|
|
6900 |
}
|
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
6901 |
return i; /* return new postion */ |
1
by brian
clean slate |
6902 |
}
|
6903 |
||
6904 |
/* find if there is a found_set with same table_offset & found_offset
|
|
6905 |
If there is return offset to it, else add new offset and return pos.
|
|
6906 |
Pos returned is -offset-2 in found_set_structure because it is
|
|
6907 |
saved in set->next and set->next[] >= 0 points to next set and
|
|
6908 |
set->next[] == -1 is reserved for end without replaces.
|
|
6909 |
*/
|
|
6910 |
||
6911 |
int find_found(FOUND_SET *found_set,uint table_offset, int found_offset) |
|
6912 |
{
|
|
6913 |
int i; |
|
6914 |
for (i=0 ; (uint) i < found_sets ; i++) |
|
6915 |
if (found_set[i].table_offset == table_offset && |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
6916 |
found_set[i].found_offset == found_offset) |
1
by brian
clean slate |
6917 |
return -i-2; |
6918 |
found_set[i].table_offset=table_offset; |
|
6919 |
found_set[i].found_offset=found_offset; |
|
6920 |
found_sets++; |
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
6921 |
return -i-2; /* return new postion */ |
1
by brian
clean slate |
6922 |
}
|
6923 |
||
6924 |
/* Return 1 if regexp starts with \b or ends with \b*/
|
|
6925 |
||
6926 |
uint start_at_word(char * pos) |
|
6927 |
{
|
|
212.6.10
by Mats Kindahl
Removing redundant use of casts in client/ for memcmp(), memcpy(), memset(), and memmove(). |
6928 |
return (((!memcmp(pos, "\\b",2) && pos[2]) || |
6929 |
!memcmp(pos, "\\^", 2)) ? 1 : 0); |
|
1
by brian
clean slate |
6930 |
}
|
6931 |
||
6932 |
uint end_of_word(char * pos) |
|
6933 |
{
|
|
376
by Brian Aker
strend remove |
6934 |
char * end= strchr(pos, '\0'); |
212.6.10
by Mats Kindahl
Removing redundant use of casts in client/ for memcmp(), memcpy(), memset(), and memmove(). |
6935 |
return ((end > pos+2 && !memcmp(end-2, "\\b", 2)) || |
6936 |
(end >= pos+2 && !memcmp(end-2, "\\$",2))) ? 1 : 0; |
|
1
by brian
clean slate |
6937 |
}
|
6938 |
||
6939 |
/****************************************************************************
|
|
6940 |
* Handle replacement of strings
|
|
6941 |
****************************************************************************/
|
|
6942 |
||
206.3.1
by Patrick Galbraith
Most everything working with client rename |
6943 |
#define PC_MALLOC 256 /* Bytes for pointers */ |
6944 |
#define PS_MALLOC 512 /* Bytes for data */ |
|
1
by brian
clean slate |
6945 |
|
6946 |
int insert_pointer_name(POINTER_ARRAY *pa,char * name) |
|
6947 |
{
|
|
6948 |
uint i,length,old_count; |
|
481
by Brian Aker
Remove all of uchar. |
6949 |
unsigned char *new_pos; |
1
by brian
clean slate |
6950 |
const char **new_array; |
142.1.1
by Patrick
Removing DBUG from client |
6951 |
|
1
by brian
clean slate |
6952 |
|
6953 |
if (! pa->typelib.count) |
|
6954 |
{
|
|
6955 |
if (!(pa->typelib.type_names=(const char **) |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
6956 |
my_malloc(((PC_MALLOC-MALLOC_OVERHEAD)/ |
6957 |
(sizeof(char *)+sizeof(*pa->flag))* |
|
6958 |
(sizeof(char *)+sizeof(*pa->flag))),MYF(MY_WME)))) |
|
142.1.1
by Patrick
Removing DBUG from client |
6959 |
return(-1); |
481
by Brian Aker
Remove all of uchar. |
6960 |
if (!(pa->str= (unsigned char*) my_malloc((uint) (PS_MALLOC-MALLOC_OVERHEAD), |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
6961 |
MYF(MY_WME)))) |
1
by brian
clean slate |
6962 |
{
|
477
by Monty Taylor
Removed my_free(). It turns out that it had been def'd to ignore the flags passed to it in the second arg anyway. Gotta love that. |
6963 |
free((char*) pa->typelib.type_names); |
142.1.1
by Patrick
Removing DBUG from client |
6964 |
return (-1); |
1
by brian
clean slate |
6965 |
}
|
481
by Brian Aker
Remove all of uchar. |
6966 |
pa->max_count=(PC_MALLOC-MALLOC_OVERHEAD)/(sizeof(unsigned char*)+ |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
6967 |
sizeof(*pa->flag)); |
428
by Monty Taylor
Removed int7 and int15 and non-stdbool bool def. |
6968 |
pa->flag= (uint8_t*) (pa->typelib.type_names+pa->max_count); |
1
by brian
clean slate |
6969 |
pa->length=0; |
6970 |
pa->max_length=PS_MALLOC-MALLOC_OVERHEAD; |
|
6971 |
pa->array_allocs=1; |
|
6972 |
}
|
|
6973 |
length=(uint) strlen(name)+1; |
|
6974 |
if (pa->length+length >= pa->max_length) |
|
6975 |
{
|
|
481
by Brian Aker
Remove all of uchar. |
6976 |
if (!(new_pos= (unsigned char*) my_realloc((unsigned char*) pa->str, |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
6977 |
(uint) (pa->max_length+PS_MALLOC), |
6978 |
MYF(MY_WME)))) |
|
142.1.1
by Patrick
Removing DBUG from client |
6979 |
return(1); |
1
by brian
clean slate |
6980 |
if (new_pos != pa->str) |
6981 |
{
|
|
6982 |
my_ptrdiff_t diff=PTR_BYTE_DIFF(new_pos,pa->str); |
|
6983 |
for (i=0 ; i < pa->typelib.count ; i++) |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
6984 |
pa->typelib.type_names[i]= ADD_TO_PTR(pa->typelib.type_names[i],diff, |
6985 |
char*); |
|
1
by brian
clean slate |
6986 |
pa->str=new_pos; |
6987 |
}
|
|
6988 |
pa->max_length+=PS_MALLOC; |
|
6989 |
}
|
|
6990 |
if (pa->typelib.count >= pa->max_count-1) |
|
6991 |
{
|
|
6992 |
int len; |
|
6993 |
pa->array_allocs++; |
|
6994 |
len=(PC_MALLOC*pa->array_allocs - MALLOC_OVERHEAD); |
|
481
by Brian Aker
Remove all of uchar. |
6995 |
if (!(new_array=(const char **) my_realloc((unsigned char*) pa->typelib.type_names, |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
6996 |
(uint) len/ |
481
by Brian Aker
Remove all of uchar. |
6997 |
(sizeof(unsigned char*)+sizeof(*pa->flag))* |
6998 |
(sizeof(unsigned char*)+sizeof(*pa->flag)), |
|
1
by brian
clean slate |
6999 |
MYF(MY_WME)))) |
142.1.1
by Patrick
Removing DBUG from client |
7000 |
return(1); |
1
by brian
clean slate |
7001 |
pa->typelib.type_names=new_array; |
7002 |
old_count=pa->max_count; |
|
481
by Brian Aker
Remove all of uchar. |
7003 |
pa->max_count=len/(sizeof(unsigned char*) + sizeof(*pa->flag)); |
428
by Monty Taylor
Removed int7 and int15 and non-stdbool bool def. |
7004 |
pa->flag= (uint8_t*) (pa->typelib.type_names+pa->max_count); |
212.6.10
by Mats Kindahl
Removing redundant use of casts in client/ for memcmp(), memcpy(), memset(), and memmove(). |
7005 |
memcpy(pa->flag, pa->typelib.type_names+old_count, |
7006 |
old_count*sizeof(*pa->flag)); |
|
1
by brian
clean slate |
7007 |
}
|
206.3.1
by Patrick Galbraith
Most everything working with client rename |
7008 |
pa->flag[pa->typelib.count]=0; /* Reset flag */ |
1
by brian
clean slate |
7009 |
pa->typelib.type_names[pa->typelib.count++]= (char*) pa->str+pa->length; |
461
by Monty Taylor
Removed NullS. bu-bye. |
7010 |
pa->typelib.type_names[pa->typelib.count]= NULL; /* Put end-mark */ |
419
by Monty
Merged up to 408 of stdint-includes-fix. |
7011 |
my_stpcpy((char*) pa->str+pa->length,name); |
1
by brian
clean slate |
7012 |
pa->length+=length; |
142.1.1
by Patrick
Removing DBUG from client |
7013 |
return(0); |
1
by brian
clean slate |
7014 |
} /* insert_pointer_name */ |
7015 |
||
7016 |
||
7017 |
/* free pointer array */
|
|
7018 |
||
7019 |
void free_pointer_array(POINTER_ARRAY *pa) |
|
7020 |
{
|
|
7021 |
if (pa->typelib.count) |
|
7022 |
{
|
|
7023 |
pa->typelib.count=0; |
|
477
by Monty Taylor
Removed my_free(). It turns out that it had been def'd to ignore the flags passed to it in the second arg anyway. Gotta love that. |
7024 |
free((char*) pa->typelib.type_names); |
1
by brian
clean slate |
7025 |
pa->typelib.type_names=0; |
477
by Monty Taylor
Removed my_free(). It turns out that it had been def'd to ignore the flags passed to it in the second arg anyway. Gotta love that. |
7026 |
free(pa->str); |
1
by brian
clean slate |
7027 |
}
|
7028 |
} /* free_pointer_array */ |
|
7029 |
||
7030 |
||
7031 |
/* Functions that uses replace and replace_regex */
|
|
7032 |
||
7033 |
/* Append the string to ds, with optional replace */
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
7034 |
void replace_append_mem(string *ds, |
7035 |
const char *val, int len) |
|
1
by brian
clean slate |
7036 |
{
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
7037 |
char *v= strdup(val); |
7038 |
||
1
by brian
clean slate |
7039 |
if (glob_replace_regex) |
7040 |
{
|
|
7041 |
/* Regex replace */
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
7042 |
if (!multi_reg_replace(glob_replace_regex, v)) |
1
by brian
clean slate |
7043 |
{
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
7044 |
v= glob_replace_regex->buf; |
7045 |
len= strlen(v); |
|
1
by brian
clean slate |
7046 |
}
|
7047 |
}
|
|
7048 |
||
7049 |
if (glob_replace) |
|
7050 |
{
|
|
7051 |
/* Normal replace */
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
7052 |
replace_strings_append(glob_replace, ds, v, len); |
1
by brian
clean slate |
7053 |
}
|
7054 |
else
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
7055 |
{
|
7056 |
ds->append(v, len); |
|
7057 |
}
|
|
1
by brian
clean slate |
7058 |
}
|
7059 |
||
7060 |
||
7061 |
/* Append zero-terminated string to ds, with optional replace */
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
7062 |
void replace_append(string *ds, const char *val) |
1
by brian
clean slate |
7063 |
{
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
7064 |
replace_append_mem(ds, val, strlen(val)); |
1
by brian
clean slate |
7065 |
}
|
7066 |
||
7067 |
/* Append uint to ds, with optional replace */
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
7068 |
void replace_append_uint(string *ds, uint val) |
1
by brian
clean slate |
7069 |
{
|
7070 |
char buff[22]; /* This should be enough for any int */ |
|
152
by Brian Aker
longlong replacement |
7071 |
char *end= int64_t10_to_str(val, buff, 10); |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
7072 |
replace_append_mem(ds, buff, end - buff); |
7073 |
||
1
by brian
clean slate |
7074 |
}
|
7075 |
||
7076 |
||
7077 |
||
7078 |
/*
|
|
7079 |
Build a list of pointer to each line in ds_input, sort
|
|
7080 |
the list and use the sorted list to append the strings
|
|
7081 |
sorted to the output ds
|
|
7082 |
||
7083 |
SYNOPSIS
|
|
7084 |
dynstr_append_sorted
|
|
7085 |
ds - string where the sorted output will be appended
|
|
7086 |
ds_input - string to be sorted
|
|
7087 |
||
7088 |
*/
|
|
7089 |
||
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
7090 |
|
7091 |
void append_sorted(string* ds, string *ds_input) |
|
7092 |
{
|
|
496.1.6
by Paul McCullagh
Fixed the --sorted_result command and changed to sorting accending |
7093 |
priority_queue<string, vector<string>, greater<string> > lines; |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
7094 |
|
7095 |
if (ds_input->empty()) |
|
142.1.1
by Patrick
Removing DBUG from client |
7096 |
return; /* No input */ |
1
by brian
clean slate |
7097 |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
7098 |
unsigned long eol_pos= 0; |
7099 |
||
7100 |
eol_pos= ds_input->find_first_of('\n', 0); |
|
7101 |
if (eol_pos == string::npos) |
|
7102 |
return; // We should have at least one header here |
|
7103 |
||
496.1.6
by Paul McCullagh
Fixed the --sorted_result command and changed to sorting accending |
7104 |
ds->append(ds_input->substr(0, eol_pos+1)); |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
7105 |
|
7106 |
unsigned long start_pos= eol_pos+1; |
|
1
by brian
clean slate |
7107 |
|
7108 |
/* Insert line(s) in array */
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
7109 |
do { |
1
by brian
clean slate |
7110 |
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
7111 |
eol_pos= ds_input->find_first_of('\n', start_pos); |
1
by brian
clean slate |
7112 |
/* Find end of line */
|
496.1.6
by Paul McCullagh
Fixed the --sorted_result command and changed to sorting accending |
7113 |
lines.push(ds_input->substr(start_pos, eol_pos-start_pos+1)); |
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
7114 |
start_pos= eol_pos+1; |
7115 |
||
7116 |
} while ( eol_pos != string::npos); |
|
1
by brian
clean slate |
7117 |
|
7118 |
/* Create new result */
|
|
373.1.8
by Monty Taylor
Removed DYNAMIC_STRING. |
7119 |
while (!lines.empty()) { |
7120 |
ds->append(lines.top()); |
|
7121 |
lines.pop(); |
|
1
by brian
clean slate |
7122 |
}
|
7123 |
||
142.1.1
by Patrick
Removing DBUG from client |
7124 |
return; |
1
by brian
clean slate |
7125 |
}
|