27
27
// / See @ref PAGE_MYSQL_TEST_RUN "The MySQL Test Framework" for more
28
28
// / information.
29
29
30
- #include " client/mysqltest/mysqltest_expected_error .h"
31
-
32
- #include " my_config .h"
30
+ #include " client/mysqltest/error_names .h"
31
+ # include " client/mysqltest/expected_errors.h "
32
+ #include " client/mysqltest/secondary_engine .h"
33
33
34
34
#include < algorithm>
35
35
#include < cmath> // std::isinf
72
72
#include " map_helpers.h"
73
73
#include " mf_wcomp.h" // wild_compare
74
74
#include " my_compiler.h"
75
+ #include " my_config.h"
75
76
#include " my_dbug.h"
76
77
#include " my_default.h"
77
78
#include " my_dir.h"
@@ -145,7 +146,8 @@ static void signal_handler(int sig);
145
146
static bool get_one_option (int optid, const struct my_option *, char *argument);
146
147
147
148
enum {
148
- OPT_COLORED_DIFF = OPT_MAX_CLIENT_OPTION,
149
+ OPT_CHANGE_PROPAGATION = OPT_MAX_CLIENT_OPTION,
150
+ OPT_COLORED_DIFF,
149
151
OPT_CURSOR_PROTOCOL,
150
152
OPT_EXPLAIN_PROTOCOL,
151
153
OPT_JSON_EXPLAIN_PROTOCOL,
@@ -159,6 +161,7 @@ enum {
159
161
#ifdef _WIN32
160
162
OPT_SAFEPROCESS_PID,
161
163
#endif
164
+ OPT_SECONDARY_ENGINE,
162
165
OPT_SP_PROTOCOL,
163
166
OPT_TAIL_LINES,
164
167
OPT_TRACE_EXEC,
@@ -206,6 +209,10 @@ static const char *load_default_groups[] = {"mysqltest", "client", 0};
206
209
static char line_buffer[MAX_DELIMITER_LENGTH], *line_buffer_pos = line_buffer;
207
210
static bool can_handle_expired_passwords = true ;
208
211
212
+ // Secondary engine options
213
+ static int opt_change_propagation;
214
+ static const char *opt_secondary_engine;
215
+
209
216
#ifdef _WIN32
210
217
static DWORD opt_safe_process_pid;
211
218
static HANDLE mysqltest_thread;
@@ -615,7 +622,6 @@ void str_to_file(const char *fname, char *str, size_t size);
615
622
void str_to_file2 (const char *fname, char *str, size_t size, bool append);
616
623
617
624
void fix_win_paths (const char *val, size_t len);
618
- const char *get_errname_from_code (uint error_code);
619
625
int multi_reg_replace (struct st_replace_regex *r, char *val);
620
626
621
627
#ifdef _WIN32
@@ -2354,81 +2360,48 @@ static void do_result_format_version(struct st_command *command) {
2354
2360
DBUG_VOID_RETURN;
2355
2361
}
2356
2362
2357
- /* List of error names to error codes */
2358
- typedef struct {
2359
- const char *name;
2360
- uint code;
2361
- const char *text;
2362
- /* SQLSTATE */
2363
- const char *odbc_state;
2364
- const char *jdbc_state;
2365
- uint error_index;
2366
- } st_error;
2367
-
2368
- static st_error global_error_names[] = {{" <No error>" , (uint )-1 , " " , " " , " " , 0 },
2369
- #ifndef IN_DOXYGEN
2370
- #include < mysqlclient_ername.h>
2371
- #include < mysqld_ername.h>
2372
- #endif /* IN_DOXYGEN */
2373
- {0 , 0 , 0 , 0 , 0 , 0 }};
2374
-
2375
- uint get_errcode_from_name (char *, char *);
2376
-
2377
- /*
2378
-
2379
- This function is useful when one needs to convert between error numbers and
2380
- error strings
2381
-
2382
- SYNOPSIS
2383
- var_set_convert_error(struct st_command *command,VAR *var)
2384
-
2385
- DESCRIPTION
2386
- let $var=convert_error(ER_UNKNOWN_ERROR);
2387
- let $var=convert_error(1234);
2388
-
2389
- The variable var will be populated with error number if the argument is
2390
- string. The variable var will be populated with error string if the argument
2391
- is number.
2392
-
2393
- */
2363
+ // / Convert between error numbers and error names/strings.
2364
+ // /
2365
+ // / @code
2366
+ // / let $var = convert_error(ER_UNKNOWN_ERROR);
2367
+ // / let $var = convert_error(1234);
2368
+ // / @endcode
2369
+ // /
2370
+ // / The variable '$var' will be populated with error number if the
2371
+ // / argument is string. The variable var will be populated with error
2372
+ // / string if the argument is number.
2373
+ // /
2374
+ // / @param command Pointer to the st_command structure which holds the
2375
+ // / arguments and information for the command.
2376
+ // / @param var Pointer to VAR object containing a variable
2377
+ // / information.
2394
2378
static void var_set_convert_error (struct st_command *command, VAR *var) {
2395
- char *last;
2396
- char *first = command->query ;
2397
- const char *err_name ;
2379
+ // The command->query contains the statement convert_error(1234)
2380
+ char *first = std::strchr ( command->query , ' ( ' ) + 1 ;
2381
+ char *last = std::strchr (command-> query , ' ) ' ) ;
2398
2382
2399
- DBUG_ENTER (" var_set_convert_error" );
2400
-
2401
- DBUG_PRINT (" info" , (" query: %s" , command->query ));
2402
-
2403
- /* the command->query contains the statement convert_error(1234) */
2404
- first = strchr (command->query , ' (' ) + 1 ;
2405
- last = strchr (command->query , ' )' );
2406
-
2407
- if (last == first) /* denoting an empty string */
2408
- {
2383
+ // Denoting an empty string
2384
+ if (last == first) {
2409
2385
eval_expr (var, " 0" , 0 );
2410
- DBUG_VOID_RETURN ;
2386
+ return ;
2411
2387
}
2412
2388
2413
- /* if the string is an error string , it starts with 'E' as is the norm*/
2389
+ // If the string is an error string , it starts with 'E' as is the norm
2414
2390
if (*first == ' E' ) {
2391
+ std::string error_name (first, int (last - first));
2392
+ int error = get_errcode_from_name (error_name);
2393
+ if (error == -1 ) die (" Unknown SQL error name '%s'." , error_name.c_str ());
2415
2394
char str[100 ];
2416
- uint num;
2417
- num = get_errcode_from_name (first, last);
2418
- sprintf (str, " %i" , num);
2395
+ std::sprintf (str, " %d" , error);
2419
2396
eval_expr (var, str, 0 );
2420
- } else if (my_isdigit (charset_info, *first)) /* if the error is a number */
2421
- {
2422
- long int err;
2423
-
2424
- err = strtol (first, &last, 0 );
2425
- err_name = get_errname_from_code (err);
2397
+ } else if (my_isdigit (charset_info, *first)) {
2398
+ // Error number argument
2399
+ long int err = std::strtol (first, &last, 0 );
2400
+ const char *err_name = get_errname_from_code (err);
2426
2401
eval_expr (var, err_name, 0 );
2427
2402
} else {
2428
2403
die (" Invalid error in input" );
2429
2404
}
2430
-
2431
- DBUG_VOID_RETURN;
2432
2405
}
2433
2406
2434
2407
/*
@@ -5431,47 +5404,6 @@ static void do_shutdown_server(struct st_command *command) {
5431
5404
DBUG_VOID_RETURN;
5432
5405
}
5433
5406
5434
- uint get_errcode_from_name (char *error_name, char *error_end) {
5435
- /* SQL error as string */
5436
- st_error *e = global_error_names;
5437
-
5438
- DBUG_ENTER (" get_errcode_from_name" );
5439
- DBUG_PRINT (" enter" , (" error_name: %s" , error_name));
5440
-
5441
- /* Loop through the array of known error names */
5442
- for (; e->name ; e++) {
5443
- /*
5444
- If we get a match, we need to check the length of the name we
5445
- matched against in case it was longer than what we are checking
5446
- (as in ER_WRONG_VALUE vs. ER_WRONG_VALUE_COUNT).
5447
- */
5448
- if (!std::strncmp (error_name, e->name , (int )(error_end - error_name)) &&
5449
- (uint )std::strlen (e->name ) == (uint )(error_end - error_name)) {
5450
- DBUG_RETURN (e->code );
5451
- }
5452
- }
5453
- if (!e->name ) die (" Unknown SQL error name '%s'" , error_name);
5454
- DBUG_RETURN (0 );
5455
- }
5456
-
5457
- const char *get_errname_from_code (uint error_code) {
5458
- st_error *e = global_error_names;
5459
-
5460
- DBUG_ENTER (" get_errname_from_code" );
5461
- DBUG_PRINT (" enter" , (" error_code: %d" , error_code));
5462
-
5463
- if (!error_code) {
5464
- DBUG_RETURN (" " );
5465
- }
5466
- for (; e->name ; e++) {
5467
- if (e->code == error_code) {
5468
- DBUG_RETURN (e->name );
5469
- }
5470
- }
5471
- /* Apparently, errors without known names may occur */
5472
- DBUG_RETURN (" <Unknown>" );
5473
- }
5474
-
5475
5407
// / Get the error code corresponding to an error string or to a
5476
5408
// / SQLSTATE string.
5477
5409
// /
@@ -5536,7 +5468,10 @@ static void do_get_errcodes(struct st_command *command) {
5536
5468
else if (*p == ' E' || *p == ' C' ) {
5537
5469
// Error name string
5538
5470
DBUG_PRINT (" info" , (" Error name: %s" , p));
5539
- std::uint32_t error_code = get_errcode_from_name (p, end);
5471
+ std::string error_name (p, int (end - p));
5472
+ int error_code = get_errcode_from_name (error_name);
5473
+ if (error_code == -1 )
5474
+ die (" Unknown SQL error name '%s'." , error_name.c_str ());
5540
5475
expected_errors->add_error (error_code, " 00000" , ERR_ERRNO);
5541
5476
DBUG_PRINT (" info" , (" ERR_ERRNO: %d" , error_code));
5542
5477
} else if (*p == ' e' || *p == ' c' ) {
@@ -6941,6 +6876,10 @@ static struct my_option my_long_options[] = {
6941
6876
#include " sslopt-longopts.h"
6942
6877
{" basedir" , ' b' , " Basedir for tests." , &opt_basedir, &opt_basedir, 0 ,
6943
6878
GET_STR, REQUIRED_ARG, 0 , 0 , 0 , 0 , 0 , 0 },
6879
+ {" change-propagation" , OPT_CHANGE_PROPAGATION,
6880
+ " Disable/enable change propagation when secondary engine is enabled." ,
6881
+ &opt_change_propagation, &opt_change_propagation, 0 , GET_INT, REQUIRED_ARG,
6882
+ -1 , -1 , 1 , 0 , 0 , 0 },
6944
6883
{" character-sets-dir" , OPT_CHARSETS_DIR,
6945
6884
" Directory for character set files." , &opt_charsets_dir, &opt_charsets_dir,
6946
6885
0 , GET_STR, REQUIRED_ARG, 0 , 0 , 0 , 0 , 0 , 0 },
@@ -7050,6 +6989,9 @@ static struct my_option my_long_options[] = {
7050
6989
&opt_safe_process_pid, &opt_safe_process_pid, 0 , GET_INT, REQUIRED_ARG, 0 ,
7051
6990
0 , 0 , 0 , 0 , 0 },
7052
6991
#endif
6992
+ {" secondary-engine" , OPT_SECONDARY_ENGINE,
6993
+ " Enable a secondary storage engine." , &opt_secondary_engine,
6994
+ &opt_secondary_engine, 0 , GET_STR, REQUIRED_ARG, 0 , 0 , 0 , 0 , 0 , 0 },
7053
6995
{" shared-memory-base-name" , OPT_SHARED_MEMORY_BASE_NAME,
7054
6996
" Base name of shared memory." , &shared_memory_base_name,
7055
6997
&shared_memory_base_name, 0 , GET_STR, REQUIRED_ARG, 0 , 0 , 0 , 0 , 0 , 0 },
@@ -7715,6 +7657,13 @@ static void run_query_normal(struct st_connection *cn,
7715
7657
DBUG_PRINT (" enter" , (" flags: %d" , flags));
7716
7658
DBUG_PRINT (" enter" , (" query: '%-.60s'" , query));
7717
7659
7660
+ if (opt_change_propagation != -1 ) {
7661
+ std::vector<unsigned int > ignore_errors = expected_errors->errors ();
7662
+ // Run secondary engine unload statements.
7663
+ if (run_secondary_engine_unload_statements (query, mysql, ignore_errors))
7664
+ die (" Original query '%s'." , query);
7665
+ }
7666
+
7718
7667
if (flags & QUERY_SEND_FLAG) {
7719
7668
/*
7720
7669
Send the query
@@ -7814,6 +7763,15 @@ static void run_query_normal(struct st_connection *cn,
7814
7763
variable then can be used from the test case itself.
7815
7764
*/
7816
7765
var_set_errno (mysql_errno (mysql));
7766
+
7767
+ if (opt_change_propagation != -1 ) {
7768
+ std::vector<unsigned int > ignore_errors = expected_errors->errors ();
7769
+ // Run secondary engine load statements.
7770
+ if (run_secondary_engine_load_statements (opt_secondary_engine, query, mysql,
7771
+ ignore_errors))
7772
+ die (" Original query '%s'." , query);
7773
+ }
7774
+
7817
7775
DBUG_VOID_RETURN;
7818
7776
}
7819
7777
@@ -7843,6 +7801,13 @@ static void run_query_stmt(MYSQL *mysql, struct st_command *command,
7843
7801
DBUG_ENTER (" run_query_stmt" );
7844
7802
DBUG_PRINT (" query" , (" '%-.60s'" , query));
7845
7803
7804
+ if (opt_change_propagation != -1 ) {
7805
+ std::vector<unsigned int > ignore_errors = expected_errors->errors ();
7806
+ // Run secondary engine unload statements.
7807
+ if (run_secondary_engine_unload_statements (query, mysql, ignore_errors))
7808
+ die (" Original query '%s'." , query);
7809
+ }
7810
+
7846
7811
/*
7847
7812
Init a new stmt if it's not already one created for this connection
7848
7813
*/
@@ -8028,6 +7993,14 @@ static void run_query_stmt(MYSQL *mysql, struct st_command *command,
8028
7993
cur_con->stmt = NULL ;
8029
7994
}
8030
7995
7996
+ if (opt_change_propagation != -1 ) {
7997
+ std::vector<unsigned int > ignore_errors = expected_errors->errors ();
7998
+ // Run secondary engine load statements.
7999
+ if (run_secondary_engine_load_statements (opt_secondary_engine, query, mysql,
8000
+ ignore_errors))
8001
+ die (" Original query '%s'." , query);
8002
+ }
8003
+
8031
8004
DBUG_VOID_RETURN;
8032
8005
}
8033
8006
0 commit comments