mirror of
https://github.com/MariaDB/server.git
synced 2025-01-31 11:01:52 +01:00
Merge paul@work.mysql.com:/home/bk/mysql-4.0
into teton.kitebird.com:/home/paul/mysql-4.0
This commit is contained in:
commit
cc0ec228db
68 changed files with 1051 additions and 971 deletions
|
@ -19017,7 +19017,7 @@ in MySQL < 4.0.2 whether index is @code{FULLTEXT} or not.
|
|||
Note that as the @code{Cardinality} is counted based on statistics
|
||||
stored as integers, it's not necessarily accurate for small tables.
|
||||
|
||||
The @code{Null} and @code{Index_type} column was added in MySQL 4.0.2.
|
||||
The @code{Null} and @code{Index_type} columns were added in MySQL 4.0.2.
|
||||
|
||||
@node SHOW TABLE STATUS, SHOW STATUS, SHOW DATABASE INFO, SHOW
|
||||
@subsubsection @code{SHOW TABLE STATUS}
|
||||
|
@ -29836,6 +29836,32 @@ mysql> select 1 IS NOT NULL, 0 IS NOT NULL, NULL IS NOT NULL;
|
|||
-> 1 1 0
|
||||
@end example
|
||||
|
||||
@cindex ODBC compatibility
|
||||
@cindex compatibility, with ODBC
|
||||
To be able to work good with other programs, MySQL supports the following
|
||||
extra features when using @code{IS NULL}:
|
||||
|
||||
@itemize @bullet
|
||||
@item
|
||||
You can find the last inserted row with:
|
||||
|
||||
@example
|
||||
SELECT * FROM tbl_name WHERE auto_col IS NULL
|
||||
@end example
|
||||
|
||||
This can be disabled by setting @code{SQL_AUTO_IS_NULL=0}. @xref{SET OPTION}.
|
||||
@item
|
||||
For @code{NOT NULL} @code{DATE} and @code{DATETIME} columns you can find
|
||||
the special date @code{0000-00-00} by using:
|
||||
|
||||
@example
|
||||
SELECT * FROM tbl_name WHERE date_column IS NULL
|
||||
@end example
|
||||
|
||||
This is needed to get some ODBC applications to work (as ODBC doesn't
|
||||
support a @code{0000-00-00} date)
|
||||
@end itemize
|
||||
|
||||
@findex BETWEEN ... AND
|
||||
@item expr BETWEEN min AND max
|
||||
If @code{expr} is greater than or equal to @code{min} and @code{expr} is
|
||||
|
@ -32000,7 +32026,7 @@ mysql> select CAST(1 AS UNSIGNED) -2.0
|
|||
If you are using a string in an arithmetic operation, this is converted
|
||||
to a floating point number.
|
||||
|
||||
The @code{CAST()} and @code{CONVERT()} function was added in MySQL 4.0.2.
|
||||
The @code{CAST()} and @code{CONVERT()} functions were added in MySQL 4.0.2.
|
||||
|
||||
The handing of unsigned values was changed in MySQL 4.0 to be able to
|
||||
support @code{BIGINT} values properly. If you have some code that you
|
||||
|
@ -48385,6 +48411,11 @@ Our TODO section contains what we plan to have in 4.0. @xref{TODO MySQL 4.0}.
|
|||
|
||||
@itemize @bullet
|
||||
@item
|
||||
Fixed a bug where @code{SQL_CALC_ROWS} returned a wrong value when used
|
||||
with one table and @code{ORDER BY} and with InnoDB tables.
|
||||
@item
|
||||
Fixed that @code{SELECT 0 LIMIT 0} doesn't hang thread.
|
||||
@item
|
||||
Fixed some problems with @code{USE KEYS} / @code{IGNORE KEYS} when using
|
||||
many keys with the same start column.
|
||||
@item
|
||||
|
@ -48393,7 +48424,7 @@ an index that covers the whole row.
|
|||
@item
|
||||
Optimized InnoDB sort-buffer handling to take less memory.
|
||||
@item
|
||||
Fixed bug in multi-table-delete and InnoDB tables.
|
||||
Fixed bug in multi table @code{DELETE} and InnoDB tables.
|
||||
@item
|
||||
Fixed problem with @code{TRUNCATE} and InnoDB that gave the error
|
||||
@code{Can't execute the given command because you have active locked
|
||||
|
@ -48414,24 +48445,24 @@ repair tables with @code{nan} in float or double columns.
|
|||
Fixed new bug in @code{myisamchk} where it didn't correctly update number of
|
||||
``parts'' in the MyISAM index file.
|
||||
@item
|
||||
Changed to use autoconf 2.52 (from Autconf 2.13).
|
||||
Changed to use @code{autoconf} 2.52 (from @code{autoconf} 2.13).
|
||||
@item
|
||||
Fixed optimization problem where a MySQL was a long time in a
|
||||
``preparing'' state when selecting from an empty table which had contained
|
||||
Fixed optimization problem where the MySQL Server was in ``preparing'' state
|
||||
for a long time when selecting from an empty table which had contained
|
||||
a lot of rows.
|
||||
@item
|
||||
Fixed bug in complicated join with @code{const} tables. This fix also
|
||||
improves performance a bit when referring to another table from a
|
||||
@code{const} table.
|
||||
@item
|
||||
First pre-version of multi table updates.
|
||||
First pre-version of multi table @code{UPDATE}s.
|
||||
@item
|
||||
Fixed bug in multi table delete.
|
||||
Fixed bug in multi table @code{DELETE}.
|
||||
@item
|
||||
Fixed bug in @code{SELECT CONCAT(argument-list) ... GROUP BY 1}.
|
||||
@item
|
||||
@code{SELECT ... INSERT} did a full rollback in case of an error. Fixed
|
||||
so that we only roll back the last statement.
|
||||
@code{INSERT ... SELECT} did a full rollback in case of an error. Fixed
|
||||
so that we only roll back the last statement in the current transaction.
|
||||
@item
|
||||
Fixed bug with empty expression for boolean fulltext search.
|
||||
@item
|
||||
|
|
|
@ -192,6 +192,7 @@ Q_ENABLE_QUERY_LOG, Q_DISABLE_QUERY_LOG,
|
|||
Q_ENABLE_RESULT_LOG, Q_DISABLE_RESULT_LOG,
|
||||
Q_SERVER_START, Q_SERVER_STOP,Q_REQUIRE_MANAGER,
|
||||
Q_WAIT_FOR_SLAVE_TO_STOP,
|
||||
Q_REQUIRE_VERSION,
|
||||
Q_UNKNOWN, /* Unknown command. */
|
||||
Q_COMMENT, /* Comments, ignored. */
|
||||
Q_COMMENT_WITH_COMMAND
|
||||
|
@ -228,6 +229,7 @@ const char *command_names[] = {
|
|||
"enable_result_log", "disable_result_log",
|
||||
"server_start", "server_stop",
|
||||
"require_manager", "wait_for_slave_to_stop",
|
||||
"require_version",
|
||||
0
|
||||
};
|
||||
|
||||
|
@ -748,6 +750,42 @@ int do_server_op(struct st_query* q,const char* op)
|
|||
}
|
||||
#endif
|
||||
|
||||
int do_require_version(struct st_query* q)
|
||||
{
|
||||
MYSQL* mysql = &cur_con->mysql;
|
||||
MYSQL_RES* res;
|
||||
MYSQL_ROW row;
|
||||
char* p=q->first_argument, *ver_arg;
|
||||
uint ver_arg_len,ver_len;
|
||||
LINT_INIT(res);
|
||||
|
||||
if (!*p)
|
||||
die("Missing version argument in require_version\n");
|
||||
ver_arg = p;
|
||||
while (*p && !isspace(*p))
|
||||
p++;
|
||||
*p = 0;
|
||||
ver_arg_len = p - ver_arg;
|
||||
|
||||
if (mysql_query(mysql, "select version()") ||
|
||||
!(res=mysql_store_result(mysql)))
|
||||
die("Query failed while check server version: %s",
|
||||
mysql_error(mysql));
|
||||
if (!(row=mysql_fetch_row(res)) || !row[0])
|
||||
{
|
||||
mysql_free_result(res);
|
||||
die("Strange result from query while checking version");
|
||||
}
|
||||
ver_len = strlen(row[0]);
|
||||
if (ver_len < ver_arg_len || memcmp(row[0],ver_arg,ver_arg_len))
|
||||
{
|
||||
mysql_free_result(res);
|
||||
abort_not_supported_test();
|
||||
}
|
||||
mysql_free_result(res);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int do_source(struct st_query* q)
|
||||
{
|
||||
char* p=q->first_argument, *name;
|
||||
|
@ -2379,6 +2417,7 @@ int main(int argc, char** argv)
|
|||
case Q_DISABLE_RESULT_LOG: disable_result_log=1; break;
|
||||
case Q_SOURCE: do_source(q); break;
|
||||
case Q_SLEEP: do_sleep(q); break;
|
||||
case Q_REQUIRE_VERSION: do_require_version(q); break;
|
||||
case Q_WAIT_FOR_SLAVE_TO_STOP: do_wait_for_slave_to_stop(q); break;
|
||||
case Q_REQUIRE_MANAGER: do_require_manager(q); break;
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
|
|
|
@ -188,7 +188,7 @@ AC_DEFINE(SPRINTF_RETURNS_INT) AC_MSG_RESULT("int"),
|
|||
|
||||
|
||||
# option, cache_name, variable,
|
||||
# code to execute if yes, code to exectute if fal
|
||||
# code to execute if yes, code to exectute if fail
|
||||
AC_DEFUN(AC_SYS_COMPILER_FLAG,
|
||||
[
|
||||
AC_MSG_CHECKING($1)
|
||||
|
|
|
@ -42,7 +42,6 @@ struct my_option
|
|||
longlong sub_size; /* Subtract this from given value */
|
||||
long block_size; /* Value should be a mult. of this */
|
||||
int app_type; /* To be used by an application */
|
||||
my_bool opt_is_var; /* If true, the option is a variable */
|
||||
};
|
||||
|
||||
extern int handle_options (int *argc, char ***argv,
|
||||
|
@ -50,3 +49,5 @@ extern int handle_options (int *argc, char ***argv,
|
|||
my_bool (*get_one_option)(int,
|
||||
const struct my_option *,
|
||||
char *));
|
||||
extern void my_print_help(const struct my_option *options);
|
||||
extern void my_print_variables(const struct my_option *options);
|
||||
|
|
|
@ -152,71 +152,145 @@ enum options {
|
|||
|
||||
static struct my_option my_long_options[] =
|
||||
{
|
||||
{"analyze", "", 0, 0, 0, GET_NO_ARG, NO_ARG, 'a', 0, 0, 0, 0, 0, 0, 0},
|
||||
{"block-search", "", 0, 0, 0, GET_LONG, REQUIRED_ARG, 'b', 0, 0, 0, 0, 0, 0, 0},
|
||||
{"backup", "", 0, 0, 0, GET_NO_ARG, NO_ARG, 'B', 0, 0, 0, 0, 0, 0, 0},
|
||||
{"character-sets-dir", "", (gptr*) &set_charset_name, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0, 0, 1},
|
||||
|
||||
{"check", "", 0, 0, 0, GET_NO_ARG, NO_ARG, 'c', 0, 0, 0, 0, 0, 0, 0},
|
||||
{"check-only-changed", "", 0, 0, 0, GET_NO_ARG, NO_ARG, 'C', 0, 0, 0, 0, 0, 0, 0},
|
||||
|
||||
{"correct-checksum", "", 0, 0, 0, GET_NO_ARG, NO_ARG, OPT_CORRECT_CHECKSUM, 0, 0, 0, 0, 0, 0, 0},
|
||||
{"analyze",
|
||||
"Analyze distribution of keys. Will make some joins in MySQL faster. You can check the calculated distribution.", 0, 0, 0, GET_NO_ARG, NO_ARG, 'a', 0, 0,
|
||||
0, 0, 0, 0},
|
||||
{"block-search", "No help available.", 0, 0, 0, GET_LONG, REQUIRED_ARG, 'b',
|
||||
0, 0, 0, 0, 0, 0},
|
||||
{"backup", "Make a backup of the .MYD file as 'filename-time.BAK'", 0, 0, 0,
|
||||
GET_NO_ARG, NO_ARG, 'B', 0, 0, 0, 0, 0, 0},
|
||||
{"character-sets-dir", "Directory where character sets are.",
|
||||
(gptr*) &set_charset_name, 0, 0, GET_STR, REQUIRED_ARG, OPT_CHARSETS_DIR, 0,
|
||||
0, 0, 0, 0, 0},
|
||||
{"check", "Check table for errors.", 0, 0, 0, GET_NO_ARG, NO_ARG, 'c', 0, 0,
|
||||
0, 0, 0, 0},
|
||||
{"check-only-changed",
|
||||
"Check only tables that has changed since last check.", 0, 0, 0, GET_NO_ARG,
|
||||
NO_ARG, 'C', 0, 0, 0, 0, 0, 0},
|
||||
{"correct-checksum", "Correct checksum information for table.", 0, 0, 0,
|
||||
GET_NO_ARG, NO_ARG, OPT_CORRECT_CHECKSUM, 0, 0, 0, 0, 0, 0},
|
||||
#ifndef DBUG_OFF
|
||||
{"debug", "", 0, 0, 0, GET_STR, OPT_ARG, '#', 0, 0, 0, 0, 0, 0, 0},
|
||||
{"debug", "Output debug log. Often this is 'd:t:o,filename'.", 0, 0, 0,
|
||||
GET_STR, OPT_ARG, '#', 0, 0, 0, 0, 0, 0},
|
||||
#endif
|
||||
{"description", "", 0, 0, 0, GET_NO_ARG, NO_ARG, 'd', 0, 0, 0, 0, 0, 0, 0},
|
||||
{"data-file-length", "", 0, 0, 0, GET_LONG, REQUIRED_ARG, 'D', 0, 0, 0, 0, 0, 0, 0},
|
||||
{"extend-check", "", 0, 0, 0, GET_NO_ARG, NO_ARG, 'e', 0, 0, 0, 0, 0, 0, 0},
|
||||
{"fast", "", 0, 0, 0, GET_NO_ARG, NO_ARG, 'F', 0, 0, 0, 0, 0, 0, 0},
|
||||
{"force", "", 0, 0, 0, GET_NO_ARG, NO_ARG, 'f', 0, 0, 0, 0, 0, 0, 0},
|
||||
{"help", "", 0, 0, 0, GET_NO_ARG, NO_ARG, '?', 0, 0, 0, 0, 0, 0, 0},
|
||||
{"information", "", 0, 0, 0, GET_NO_ARG, NO_ARG, 'i', 0, 0, 0, 0, 0, 0, 0},
|
||||
{"keys-used", "", 0, 0, 0, GET_LONG, REQUIRED_ARG, 'k', 0, 0, 0, 0, 0, 0, 0},
|
||||
{"medium-check", "", 0, 0, 0, GET_NO_ARG, NO_ARG, 'm', 0, 0, 0, 0, 0, 0, 0},
|
||||
{"quick", "", 0, 0, 0, GET_NO_ARG, NO_ARG, 'q', 0, 0, 0, 0, 0, 0, 0},
|
||||
{"read-only", "", 0, 0, 0, GET_NO_ARG, NO_ARG, 'T', 0, 0, 0, 0, 0, 0, 0},
|
||||
{"recover", "", 0, 0, 0, GET_NO_ARG, NO_ARG, 'r', 0, 0, 0, 0, 0, 0, 0},
|
||||
{"safe-recover", "", 0, 0, 0, GET_NO_ARG, NO_ARG, 'o', 0, 0, 0, 0, 0, 0, 0},
|
||||
{"start-check-pos", "", 0, 0, 0, GET_LONG, REQUIRED_ARG, OPT_START_CHECK_POS, 0, 0, 0, 0, 0, 0, 0},
|
||||
{"set-auto-increment", "", 0, 0, 0, GET_LONG, OPT_ARG, 'A', 0, 0, 0, 0, 0, 0, 0},
|
||||
{"set-character-set", "", 0, 0, 0, GET_STR, REQUIRED_ARG, OPT_SET_CHARSET, 0, 0, 0, 0, 0, 0, 0},
|
||||
{"set-variable", "", 0, 0, 0, GET_STR, REQUIRED_ARG, 'O', 0, 0, 0, 0, 0, 0, 0},
|
||||
{"silent", "", 0, 0, 0, GET_NO_ARG, NO_ARG, 's', 0, 0, 0, 0, 0, 0, 0},
|
||||
{"sort-index", "", 0, 0, 0, GET_NO_ARG, NO_ARG, 'S', 0, 0, 0, 0, 0, 0, 0},
|
||||
{"sort-records", "", 0, 0, 0, GET_LONG, REQUIRED_ARG, 'R', 0, 0, 0, 0, 0, 0, 0},
|
||||
{"sort-recover", "", 0, 0, 0, GET_NO_ARG, NO_ARG, 'n', 0, 0, 0, 0, 0, 0, 0},
|
||||
{"tmpdir", "", 0, 0, 0, GET_STR, REQUIRED_ARG, 't', 0, 0, 0, 0, 0, 0, 0},
|
||||
{"update-state", "", 0, 0, 0, GET_NO_ARG, NO_ARG, 'U', 0, 0, 0, 0, 0, 0, 0},
|
||||
{"unpack", "", 0, 0, 0, GET_NO_ARG, NO_ARG, 'u', 0, 0, 0, 0, 0, 0, 0},
|
||||
{"verbose", "", 0, 0, 0, GET_NO_ARG, NO_ARG, 'v', 0, 0, 0, 0, 0, 0, 0},
|
||||
{"version", "", 0, 0, 0, GET_NO_ARG, NO_ARG, 'V', 0, 0, 0, 0, 0, 0, 0},
|
||||
{"wait", "", 0, 0, 0, GET_NO_ARG, NO_ARG, 'w', 0, 0, 0, 0, 0, 0, 0},
|
||||
|
||||
/* variables begin here */
|
||||
{ "key_buffer_size", "", (gptr*) &check_param.use_buffers, (gptr*) &check_param.use_buffers, 0, GET_LONG, REQUIRED_ARG, OPT_KEY_BUFFER_SIZE, (long) USE_BUFFER_INIT, (long) MALLOC_OVERHEAD, (long) ~0L, (long) MALLOC_OVERHEAD, (long) IO_SIZE, 0, 1},
|
||||
{ "myisam_block_size", "", (gptr*) &opt_myisam_block_size, (gptr*) &opt_myisam_block_size, 0, GET_LONG, REQUIRED_ARG, OPT_MYISAM_BLOCK_SIZE, MI_KEY_BLOCK_LENGTH, MI_MIN_KEY_BLOCK_LENGTH, MI_MAX_KEY_BLOCK_LENGTH, 0, MI_MIN_KEY_BLOCK_LENGTH, 0, 1},
|
||||
{ "read_buffer_size", "", (gptr*) &check_param.read_buffer_length, (gptr*) &check_param.read_buffer_length, 0, GET_LONG, REQUIRED_ARG, OPT_READ_BUFFER_SIZE, (long) READ_BUFFER_INIT, (long) MALLOC_OVERHEAD, (long) ~0L, (long) MALLOC_OVERHEAD, (long) 1L, 0, 1},
|
||||
{ "write_buffer_size", "", (gptr*) &check_param.write_buffer_length, (gptr*) &check_param.write_buffer_length, 0, GET_LONG, REQUIRED_ARG, OPT_WRITE_BUFFER_SIZE, (long) READ_BUFFER_INIT, (long) MALLOC_OVERHEAD, (long) ~0L, (long) MALLOC_OVERHEAD, (long) 1L, 0, 1},
|
||||
{ "sort_buffer_size", "", (gptr*) &check_param.sort_buffer_length, (gptr*) &check_param.sort_buffer_length, 0, GET_LONG, REQUIRED_ARG, OPT_SORT_BUFFER_SIZE, (long) SORT_BUFFER_INIT, (long) (MIN_SORT_BUFFER + MALLOC_OVERHEAD), (long) ~0L, (long) MALLOC_OVERHEAD, (long) 1L, 0, 1},
|
||||
{ "sort_key_blocks", "", (gptr*) &check_param.sort_key_blocks, (gptr*) &check_param.sort_key_blocks, 0, GET_LONG, REQUIRED_ARG, OPT_SORT_KEY_BLOCKS, BUFFERS_WHEN_SORTING, 4L, 100L, 0L, 1L, 0, 1},
|
||||
{ "decode_bits", "", (gptr*) &decode_bits, (gptr*) &decode_bits, 0, GET_LONG, REQUIRED_ARG, OPT_DECODE_BITS, 9L, 4L, 17L, 0L, 1L, 0, 1},
|
||||
{ "ft_min_word_len", "", (gptr*) &ft_min_word_len, (gptr*) &ft_min_word_len, 0, GET_LONG, REQUIRED_ARG, OPT_FT_MIN_WORD_LEN, 4, 1, HA_FT_MAXLEN, 0, 1, 0, 1},
|
||||
{ "ft_max_word_len", "", (gptr*) &ft_max_word_len, (gptr*) &ft_max_word_len, 0, GET_LONG, REQUIRED_ARG, OPT_FT_MAX_WORD_LEN, HA_FT_MAXLEN, 10, HA_FT_MAXLEN, 0, 1, 0, 1},
|
||||
{ "ft_max_word_len_for_sort", "", (gptr*) &ft_max_word_len_for_sort, (gptr*) &ft_max_word_len_for_sort, 0, GET_LONG, REQUIRED_ARG, OPT_FT_MAX_WORD_LEN_FOR_SORT, 20, 4, HA_FT_MAXLEN, 0, 1, 0, 1},
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
{"description", "Prints some information about table.", 0, 0, 0, GET_NO_ARG,
|
||||
NO_ARG, 'd', 0, 0, 0, 0, 0, 0},
|
||||
{"data-file-length",
|
||||
"Max length of data file (when recreating data-file when it's full).",
|
||||
(gptr*) &check_param.max_data_file_length,
|
||||
(gptr*) &check_param.max_data_file_length, 0, GET_LONG, REQUIRED_ARG, 'D',
|
||||
0, 0, 0, 0, 0, 0},
|
||||
{"extend-check",
|
||||
"Try to recover every possible row from the data file. Normally this will also find a lot of garbage rows; Don't use this option if you are not totally desperate.", 0, 0, 0, GET_NO_ARG, NO_ARG, 'e', 0, 0, 0, 0, 0, 0},
|
||||
{"fast", "Check only tables that hasn't been closed properly.", 0, 0, 0,
|
||||
GET_NO_ARG, NO_ARG, 'F', 0, 0, 0, 0, 0, 0},
|
||||
{"force",
|
||||
"Restart with -r if there are any errors in the table. States will be updated as with --update-state.", 0, 0, 0, GET_NO_ARG, NO_ARG, 'f', 0, 0, 0, 0, 0,
|
||||
0},
|
||||
{"help", "Display this help and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, '?', 0,
|
||||
0, 0, 0, 0, 0},
|
||||
{"information", "Print statistics information about table that is checked.",
|
||||
0, 0, 0, GET_NO_ARG, NO_ARG, 'i', 0, 0, 0, 0, 0, 0},
|
||||
{"keys-used", "Tell MyISAM to update only some specific keys. # is a bit mask of which keys to use. This can be used to get faster inserts!",
|
||||
(gptr*) &check_param.keys_in_use, (gptr*) &check_param.keys_in_use, 0,
|
||||
GET_LL, REQUIRED_ARG, 'k', -1LL, 0, 0, 0, 0, 0},
|
||||
{"medium-check",
|
||||
"Faster than extended-check, but only finds 99.99% of all errors. Should be good enough for most cases.", 0, 0, 0, GET_NO_ARG, NO_ARG, 'm', 0, 0, 0, 0, 0,
|
||||
0},
|
||||
{"quick", "Faster repair by not modifying the data file.", 0, 0, 0,
|
||||
GET_NO_ARG, NO_ARG, 'q', 0, 0, 0, 0, 0, 0},
|
||||
{"read-only", "Don't mark table as checked.", 0, 0, 0, GET_NO_ARG, NO_ARG,
|
||||
'T', 0, 0, 0, 0, 0, 0},
|
||||
{"recover",
|
||||
"Can fix almost anything except unique keys that aren't unique.", 0, 0, 0,
|
||||
GET_NO_ARG, NO_ARG, 'r', 0, 0, 0, 0, 0, 0},
|
||||
{"safe-recover",
|
||||
"Uses old recovery method; Slower than '-r' but can handle a couple of cases where '-r' reports that it can't fix the data file.", 0, 0, 0, GET_NO_ARG,
|
||||
NO_ARG, 'o', 0, 0, 0, 0, 0, 0},
|
||||
{"start-check-pos", "No help available.", 0, 0, 0, GET_LONG, REQUIRED_ARG,
|
||||
OPT_START_CHECK_POS, 0, 0, 0, 0, 0, 0},
|
||||
{"set-auto-increment",
|
||||
"Force auto_increment to start at this or higher value. If no value is given, then sets the next auto_increment value to the highest used value for the auto key + 1.", (gptr*) &check_param.auto_increment_value,
|
||||
(gptr*) &check_param.auto_increment_value, 0, GET_LONG, OPT_ARG, 'A', 0, 0,
|
||||
0, 0, 0, 0},
|
||||
{"set-character-set", "Change the character set used by the index", 0, 0, 0,
|
||||
GET_STR, REQUIRED_ARG, OPT_SET_CHARSET, 0, 0, 0, 0, 0, 0},
|
||||
{"set-variable", "Change the value of a variable. Please note that this option is depricated; you can set variables directly with --variable-name=value.",
|
||||
0, 0, 0, GET_STR, REQUIRED_ARG, 'O', 0, 0, 0, 0, 0, 0},
|
||||
{"silent",
|
||||
"Only print errors. One can use two -s to make myisamchk very silent.", 0,
|
||||
0, 0, GET_NO_ARG, NO_ARG, 's', 0, 0, 0, 0, 0, 0},
|
||||
{"sort-index",
|
||||
"Sort index blocks. This speeds up 'read-next' in applications.", 0, 0, 0,
|
||||
GET_NO_ARG, NO_ARG, 'S', 0, 0, 0, 0, 0, 0},
|
||||
{"sort-records",
|
||||
"Sort records according to an index. This makes your data much more localized and may speed up things. (It may be VERY slow to do a sort the first time!)",
|
||||
(gptr*) &check_param.opt_sort_key, (gptr*) &check_param.opt_sort_key, 0,
|
||||
GET_LONG, REQUIRED_ARG, 'R', 0, 0, 0, 0, 0, 0},
|
||||
{"sort-recover",
|
||||
"Force recovering with sorting even if the temporary file was very big.",
|
||||
0, 0, 0, GET_NO_ARG, NO_ARG, 'n', 0, 0, 0, 0, 0, 0},
|
||||
{"tmpdir", "Path for temporary files.", (gptr*) &check_param.tmpdir, 0, 0,
|
||||
GET_STR, REQUIRED_ARG, 't', 0, 0, 0, 0, 0, 0},
|
||||
{"update-state", "Mark tables as crashed if any errors were found.", 0, 0,
|
||||
0, GET_NO_ARG, NO_ARG, 'U', 0, 0, 0, 0, 0, 0},
|
||||
{"unpack", "Unpack file packed with myisampack.", 0, 0, 0, GET_NO_ARG,
|
||||
NO_ARG, 'u', 0, 0, 0, 0, 0, 0},
|
||||
{"verbose",
|
||||
"Print more information. This can be used with --describe and --check. Use many -v for more verbosity!", 0, 0, 0, GET_NO_ARG, NO_ARG, 'v', 0, 0, 0, 0, 0,
|
||||
0},
|
||||
{"version", "Print version and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, 'V', 0,
|
||||
0, 0, 0, 0, 0},
|
||||
{"wait", "Wait if table is locked.", 0, 0, 0, GET_NO_ARG, NO_ARG, 'w', 0, 0,
|
||||
0, 0, 0, 0},
|
||||
{ "key_buffer_size", "", (gptr*) &check_param.use_buffers,
|
||||
(gptr*) &check_param.use_buffers, 0, GET_LONG, REQUIRED_ARG,
|
||||
OPT_KEY_BUFFER_SIZE, (long) USE_BUFFER_INIT, (long) MALLOC_OVERHEAD,
|
||||
(long) ~0L, (long) MALLOC_OVERHEAD, (long) IO_SIZE, 0},
|
||||
{ "myisam_block_size", "", (gptr*) &opt_myisam_block_size,
|
||||
(gptr*) &opt_myisam_block_size, 0, GET_LONG, REQUIRED_ARG,
|
||||
OPT_MYISAM_BLOCK_SIZE, MI_KEY_BLOCK_LENGTH, MI_MIN_KEY_BLOCK_LENGTH,
|
||||
MI_MAX_KEY_BLOCK_LENGTH, 0, MI_MIN_KEY_BLOCK_LENGTH, 0},
|
||||
{ "read_buffer_size", "", (gptr*) &check_param.read_buffer_length,
|
||||
(gptr*) &check_param.read_buffer_length, 0, GET_LONG, REQUIRED_ARG,
|
||||
OPT_READ_BUFFER_SIZE, (long) READ_BUFFER_INIT, (long) MALLOC_OVERHEAD,
|
||||
(long) ~0L, (long) MALLOC_OVERHEAD, (long) 1L, 0},
|
||||
{ "write_buffer_size", "", (gptr*) &check_param.write_buffer_length,
|
||||
(gptr*) &check_param.write_buffer_length, 0, GET_LONG, REQUIRED_ARG,
|
||||
OPT_WRITE_BUFFER_SIZE, (long) READ_BUFFER_INIT, (long) MALLOC_OVERHEAD,
|
||||
(long) ~0L, (long) MALLOC_OVERHEAD, (long) 1L, 0},
|
||||
{ "sort_buffer_size", "", (gptr*) &check_param.sort_buffer_length,
|
||||
(gptr*) &check_param.sort_buffer_length, 0, GET_LONG, REQUIRED_ARG,
|
||||
OPT_SORT_BUFFER_SIZE, (long) SORT_BUFFER_INIT,
|
||||
(long) (MIN_SORT_BUFFER + MALLOC_OVERHEAD), (long) ~0L,
|
||||
(long) MALLOC_OVERHEAD, (long) 1L, 0},
|
||||
{ "sort_key_blocks", "", (gptr*) &check_param.sort_key_blocks,
|
||||
(gptr*) &check_param.sort_key_blocks, 0, GET_LONG, REQUIRED_ARG,
|
||||
OPT_SORT_KEY_BLOCKS, BUFFERS_WHEN_SORTING, 4L, 100L, 0L, 1L, 0},
|
||||
{ "decode_bits", "", (gptr*) &decode_bits, (gptr*) &decode_bits, 0,
|
||||
GET_LONG, REQUIRED_ARG, OPT_DECODE_BITS, 9L, 4L, 17L, 0L, 1L, 0},
|
||||
{ "ft_min_word_len", "", (gptr*) &ft_min_word_len, (gptr*) &ft_min_word_len,
|
||||
0, GET_LONG, REQUIRED_ARG, OPT_FT_MIN_WORD_LEN, 4, 1, HA_FT_MAXLEN, 0, 1,
|
||||
0},
|
||||
{ "ft_max_word_len", "", (gptr*) &ft_max_word_len, (gptr*) &ft_max_word_len,
|
||||
0, GET_LONG, REQUIRED_ARG, OPT_FT_MAX_WORD_LEN, HA_FT_MAXLEN, 10,
|
||||
HA_FT_MAXLEN, 0, 1, 0},
|
||||
{ "ft_max_word_len_for_sort", "", (gptr*) &ft_max_word_len_for_sort,
|
||||
(gptr*) &ft_max_word_len_for_sort, 0, GET_LONG, REQUIRED_ARG,
|
||||
OPT_FT_MAX_WORD_LEN_FOR_SORT, 20, 4, HA_FT_MAXLEN, 0, 1, 0},
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
|
||||
static void print_version(void)
|
||||
{
|
||||
printf("%s Ver 2.2 for %s at %s\n", my_progname, SYSTEM_TYPE,
|
||||
printf("%s Ver 2.3 for %s at %s\n", my_progname, SYSTEM_TYPE,
|
||||
MACHINE_TYPE);
|
||||
}
|
||||
|
||||
|
||||
static void usage(void)
|
||||
{
|
||||
uint i;
|
||||
print_version();
|
||||
puts("By Monty, for your professional use");
|
||||
puts("This software comes with NO WARRANTY: see the PUBLIC for details.\n");
|
||||
|
@ -297,17 +371,9 @@ static void usage(void)
|
|||
data much more localized and may speed up things\n\
|
||||
(It may be VERY slow to do a sort the first time!)");
|
||||
|
||||
print_defaults("my",load_default_groups);
|
||||
printf("\nThe variables you can set are:\n");
|
||||
for (i=0; my_long_options[i].name ; i++)
|
||||
{
|
||||
if (!my_long_options[i].opt_is_var)
|
||||
continue;
|
||||
#ifdef TO_BE_FIXED
|
||||
printf("%-20s current value: %lu\n", my_long_options[i].name,
|
||||
*my_long_options[i].value);
|
||||
#endif
|
||||
}
|
||||
print_defaults("my", load_default_groups);
|
||||
putchar('\n');
|
||||
my_print_variables(my_long_options);
|
||||
}
|
||||
|
||||
|
||||
|
@ -318,127 +384,217 @@ get_one_option(int optid,
|
|||
const struct my_option *opt __attribute__((unused)),
|
||||
char *argument)
|
||||
{
|
||||
uint old_testflag;
|
||||
|
||||
switch (optid) {
|
||||
case 'a':
|
||||
check_param.testflag|= T_STATISTICS;
|
||||
if (argument && *argument == '0')
|
||||
check_param.testflag&= ~T_STATISTICS;
|
||||
else
|
||||
check_param.testflag|= T_STATISTICS;
|
||||
break;
|
||||
case 'A':
|
||||
if (argument)
|
||||
check_param.auto_increment_value=strtoull(argument, NULL, 0);
|
||||
check_param.auto_increment_value= strtoull(argument, NULL, 0);
|
||||
else
|
||||
check_param.auto_increment_value=0; /* Set to max used value */
|
||||
check_param.auto_increment_value= 0; /* Set to max used value */
|
||||
check_param.testflag|= T_AUTO_INC;
|
||||
break;
|
||||
case 'b':
|
||||
check_param.search_after_block=strtoul(argument, NULL, 10);
|
||||
check_param.search_after_block= strtoul(argument, NULL, 10);
|
||||
break;
|
||||
case 'B':
|
||||
check_param.testflag|= T_BACKUP_DATA;
|
||||
if (argument && *argument == '0')
|
||||
check_param.testflag&= ~T_BACKUP_DATA;
|
||||
else
|
||||
check_param.testflag|= T_BACKUP_DATA;
|
||||
break;
|
||||
case 'c':
|
||||
check_param.testflag|= T_CHECK;
|
||||
if (argument && *argument == '0')
|
||||
check_param.testflag&= ~T_CHECK;
|
||||
else
|
||||
check_param.testflag|= T_CHECK;
|
||||
break;
|
||||
case 'C':
|
||||
check_param.testflag|= T_CHECK | T_CHECK_ONLY_CHANGED;
|
||||
if (argument && *argument == '0')
|
||||
check_param.testflag&= ~(T_CHECK | T_CHECK_ONLY_CHANGED);
|
||||
else
|
||||
check_param.testflag|= T_CHECK | T_CHECK_ONLY_CHANGED;
|
||||
break;
|
||||
case 'D':
|
||||
check_param.max_data_file_length=strtoll(argument, NULL, 10);
|
||||
break;
|
||||
case 's': /* silent */
|
||||
if (check_param.testflag & T_SILENT)
|
||||
check_param.testflag|=T_VERY_SILENT;
|
||||
check_param.testflag|= T_SILENT;
|
||||
check_param.testflag&= ~T_WRITE_LOOP;
|
||||
if (argument && *argument == '0')
|
||||
check_param.testflag&= ~(T_SILENT | T_VERY_SILENT);
|
||||
else
|
||||
{
|
||||
if (check_param.testflag & T_SILENT)
|
||||
check_param.testflag|= T_VERY_SILENT;
|
||||
check_param.testflag|= T_SILENT;
|
||||
check_param.testflag&= ~T_WRITE_LOOP;
|
||||
}
|
||||
break;
|
||||
case 'w':
|
||||
check_param.testflag|= T_WAIT_FOREVER;
|
||||
if (argument && *argument == '0')
|
||||
check_param.testflag&= ~T_WAIT_FOREVER;
|
||||
else
|
||||
check_param.testflag|= T_WAIT_FOREVER;
|
||||
break;
|
||||
case 'd': /* description if isam-file */
|
||||
check_param.testflag|= T_DESCRIPT;
|
||||
if (argument && *argument == '0')
|
||||
check_param.testflag&= ~T_DESCRIPT;
|
||||
else
|
||||
check_param.testflag|= T_DESCRIPT;
|
||||
break;
|
||||
case 'e': /* extend check */
|
||||
check_param.testflag|= T_EXTEND;
|
||||
if (argument && *argument == '0')
|
||||
check_param.testflag&= ~T_EXTEND;
|
||||
else
|
||||
check_param.testflag|= T_EXTEND;
|
||||
break;
|
||||
case 'i':
|
||||
check_param.testflag|= T_INFO;
|
||||
if (argument && *argument == '0')
|
||||
check_param.testflag&= ~T_INFO;
|
||||
else
|
||||
check_param.testflag|= T_INFO;
|
||||
break;
|
||||
case 'f':
|
||||
check_param.tmpfile_createflag= O_RDWR | O_TRUNC;
|
||||
check_param.testflag|= T_FORCE_CREATE | T_UPDATE_STATE;
|
||||
if (argument && *argument == '0')
|
||||
{
|
||||
check_param.tmpfile_createflag= O_RDWR | O_TRUNC | O_EXCL;
|
||||
check_param.testflag&= ~(T_FORCE_CREATE | T_UPDATE_STATE);
|
||||
}
|
||||
else
|
||||
{
|
||||
check_param.tmpfile_createflag= O_RDWR | O_TRUNC;
|
||||
check_param.testflag|= T_FORCE_CREATE | T_UPDATE_STATE;
|
||||
}
|
||||
break;
|
||||
case 'F':
|
||||
check_param.testflag|=T_FAST;
|
||||
if (argument && *argument == '0')
|
||||
check_param.testflag&= ~T_FAST;
|
||||
else
|
||||
check_param.testflag|= T_FAST;
|
||||
break;
|
||||
case 'k':
|
||||
check_param.keys_in_use= (ulonglong) strtoll(argument, NULL, 10);
|
||||
break;
|
||||
case 'm':
|
||||
check_param.testflag|= T_MEDIUM; /* Medium check */
|
||||
if (argument && *argument == '0')
|
||||
check_param.testflag&= ~T_MEDIUM;
|
||||
else
|
||||
check_param.testflag|= T_MEDIUM; /* Medium check */
|
||||
break;
|
||||
case 'r': /* Repair table */
|
||||
check_param.testflag= (check_param.testflag & ~T_REP) | T_REP_BY_SORT;
|
||||
if (argument && *argument == '0')
|
||||
check_param.testflag&= ~(T_REP | T_REP_BY_SORT);
|
||||
else
|
||||
check_param.testflag= (check_param.testflag & ~T_REP) | T_REP_BY_SORT;
|
||||
break;
|
||||
case 'o':
|
||||
check_param.testflag= (check_param.testflag & ~T_REP_BY_SORT) | T_REP;
|
||||
check_param.force_sort=0;
|
||||
my_disable_async_io=1; /* More safety */
|
||||
if (argument && *argument == '0')
|
||||
{
|
||||
check_param.testflag&= ~(T_REP | T_REP_BY_SORT);
|
||||
check_param.force_sort= 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
check_param.testflag= (check_param.testflag & ~T_REP_BY_SORT) | T_REP;
|
||||
check_param.force_sort= 0;
|
||||
my_disable_async_io= 1; /* More safety */
|
||||
}
|
||||
break;
|
||||
case 'n':
|
||||
check_param.testflag= (check_param.testflag & ~T_REP) | T_REP_BY_SORT;
|
||||
check_param.force_sort=1;
|
||||
if (argument && *argument == '0')
|
||||
{
|
||||
check_param.testflag&= ~(T_REP | T_REP_BY_SORT);
|
||||
check_param.force_sort= 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
check_param.testflag= (check_param.testflag & ~T_REP) | T_REP_BY_SORT;
|
||||
check_param.force_sort= 1;
|
||||
}
|
||||
break;
|
||||
case 'q':
|
||||
check_param.opt_rep_quick++;
|
||||
if (argument && *argument == '0')
|
||||
check_param.opt_rep_quick=0;
|
||||
else
|
||||
check_param.opt_rep_quick++;
|
||||
break;
|
||||
case 'u':
|
||||
check_param.testflag|= T_UNPACK | T_REP_BY_SORT;
|
||||
if (argument && *argument == '0')
|
||||
check_param.testflag&= ~(T_UNPACK | T_REP_BY_SORT);
|
||||
else
|
||||
check_param.testflag|= T_UNPACK | T_REP_BY_SORT;
|
||||
break;
|
||||
case 'v': /* Verbose */
|
||||
check_param.testflag|= T_VERBOSE;
|
||||
check_param.verbose++;
|
||||
if (argument && *argument == '0')
|
||||
{
|
||||
check_param.testflag&= ~T_VERBOSE;
|
||||
check_param.verbose=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
check_param.testflag|= T_VERBOSE;
|
||||
check_param.verbose++;
|
||||
}
|
||||
break;
|
||||
case 'R': /* Sort records */
|
||||
old_testflag=check_param.testflag;
|
||||
check_param.testflag|= T_SORT_RECORDS;
|
||||
check_param.opt_sort_key=(uint) atoi(argument) - 1;
|
||||
if (check_param.opt_sort_key >= MI_MAX_KEY)
|
||||
if (argument && *argument == '0')
|
||||
check_param.testflag&= ~T_SORT_RECORDS;
|
||||
else
|
||||
{
|
||||
fprintf(stderr,
|
||||
"The value of the sort key is bigger than max key: %d.\n",
|
||||
MI_MAX_KEY);
|
||||
exit(1);
|
||||
check_param.testflag|= T_SORT_RECORDS;
|
||||
check_param.opt_sort_key= (uint) atoi(argument) - 1;
|
||||
if (check_param.opt_sort_key >= MI_MAX_KEY)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"The value of the sort key is bigger than max key: %d.\n",
|
||||
MI_MAX_KEY);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'S': /* Sort index */
|
||||
old_testflag=check_param.testflag;
|
||||
check_param.testflag|= T_SORT_INDEX;
|
||||
break;
|
||||
case 't':
|
||||
check_param.tmpdir=argument;
|
||||
if (argument && *argument == '0')
|
||||
check_param.testflag&= ~T_SORT_INDEX;
|
||||
else
|
||||
check_param.testflag|= T_SORT_INDEX;
|
||||
break;
|
||||
case 'T':
|
||||
check_param.testflag|= T_READONLY;
|
||||
if (argument && *argument == '0')
|
||||
check_param.testflag&= ~T_READONLY;
|
||||
else
|
||||
check_param.testflag|= T_READONLY;
|
||||
break;
|
||||
case 'U':
|
||||
check_param.testflag|= T_UPDATE_STATE;
|
||||
if (argument && *argument == '0')
|
||||
check_param.testflag&= ~T_UPDATE_STATE;
|
||||
else
|
||||
check_param.testflag|= T_UPDATE_STATE;
|
||||
break;
|
||||
case '#':
|
||||
DBUG_PUSH(argument ? argument : "d:t:o,/tmp/myisamchk.trace");
|
||||
if (argument && *argument == '0')
|
||||
{
|
||||
DBUG_POP();
|
||||
}
|
||||
else
|
||||
{
|
||||
DBUG_PUSH(argument ? argument : "d:t:o,/tmp/myisamchk.trace");
|
||||
}
|
||||
break;
|
||||
case 'V':
|
||||
print_version();
|
||||
exit(0);
|
||||
case OPT_CORRECT_CHECKSUM:
|
||||
if (*argument && *argument == '0')
|
||||
if (argument && *argument == '0')
|
||||
check_param.testflag&= ~T_CALC_CHECKSUM;
|
||||
else
|
||||
check_param.testflag|=T_CALC_CHECKSUM;
|
||||
check_param.testflag|= T_CALC_CHECKSUM;
|
||||
break;
|
||||
#ifdef DEBUG /* Only useful if debugging */
|
||||
case OPT_START_CHECK_POS:
|
||||
check_param.start_check_pos=strtoull(argument, NULL, 0);
|
||||
check_param.start_check_pos= strtoull(argument, NULL, 0);
|
||||
break;
|
||||
#endif
|
||||
case '?':
|
||||
|
|
|
@ -20,6 +20,7 @@ TZ=GMT-3; export TZ # for UNIX_TIMESTAMP tests to work
|
|||
#--
|
||||
|
||||
PATH=/bin:/usr/bin:/usr/local/bin:/usr/bsd:/usr/X11R6/bin:/usr/openwin/bin
|
||||
MASTER_40_ARGS="--rpl-recovery-rank=1 --init-rpl-role=master"
|
||||
|
||||
# Standard functions
|
||||
|
||||
|
@ -58,7 +59,7 @@ sleep_until_file_deleted ()
|
|||
done
|
||||
}
|
||||
|
||||
sleep_until_file_exists ()
|
||||
sleep_until_file_created ()
|
||||
{
|
||||
file=$1
|
||||
loop=$2
|
||||
|
@ -190,6 +191,11 @@ while test $# -gt 0; do
|
|||
--user=*) DBUSER=`$ECHO "$1" | $SED -e "s;--user=;;"` ;;
|
||||
--force) FORCE=1 ;;
|
||||
--verbose-manager) MANAGER_QUIET_OPT="" ;;
|
||||
--old-master) MASTER_40_ARGS="";;
|
||||
--master-binary=*)
|
||||
MASTER_MYSQLD=`$ECHO "$1" | $SED -e "s;--master-binary=;;"` ;;
|
||||
--slave-binary=*)
|
||||
SLAVE_MYSQLD=`$ECHO "$1" | $SED -e "s;--slave-binary=;;"` ;;
|
||||
--local) USE_RUNNING_SERVER="" ;;
|
||||
--tmpdir=*) MYSQL_TMP_DIR=`$ECHO "$1" | $SED -e "s;--tmpdir=;;"` ;;
|
||||
--local-master)
|
||||
|
@ -394,6 +400,16 @@ else
|
|||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$MASTER_MYSQLD" ]
|
||||
then
|
||||
MASTER_MYSQLD=$MYSQLD
|
||||
fi
|
||||
|
||||
if [ -z "$SLAVE_MYSQLD" ]
|
||||
then
|
||||
SLAVE_MYSQLD=$MYSQLD
|
||||
fi
|
||||
|
||||
# If we should run all tests cases, we will use a local server for that
|
||||
|
||||
if [ -z "$1" ]
|
||||
|
@ -430,7 +446,6 @@ GPROF_DIR=$MYSQL_TMP_DIR/gprof
|
|||
GPROF_MASTER=$GPROF_DIR/master.gprof
|
||||
GPROF_SLAVE=$GPROF_DIR/slave.gprof
|
||||
TIMEFILE="$MYSQL_TEST_DIR/var/log/mysqltest-time"
|
||||
SLAVE_MYSQLD=$MYSQLD #this can be changed later if we are doing gcov
|
||||
XTERM=`which xterm`
|
||||
|
||||
#++
|
||||
|
@ -564,11 +579,11 @@ gprof_prepare ()
|
|||
gprof_collect ()
|
||||
{
|
||||
if [ -f $MASTER_MYDDIR/gmon.out ]; then
|
||||
gprof $MYSQLD $MASTER_MYDDIR/gmon.out > $GPROF_MASTER
|
||||
gprof $MASTER_MYSQLD $MASTER_MYDDIR/gmon.out > $GPROF_MASTER
|
||||
echo "Master execution profile has been saved in $GPROF_MASTER"
|
||||
fi
|
||||
if [ -f $SLAVE_MYDDIR/gmon.out ]; then
|
||||
gprof $MYSQLD $SLAVE_MYDDIR/gmon.out > $GPROF_SLAVE
|
||||
gprof $SLAVE_MYSQLD $SLAVE_MYDDIR/gmon.out > $GPROF_SLAVE
|
||||
echo "Slave execution profile has been saved in $GPROF_SLAVE"
|
||||
fi
|
||||
}
|
||||
|
@ -708,8 +723,8 @@ start_master()
|
|||
if [ -z "$DO_BENCH" ]
|
||||
then
|
||||
master_args="--no-defaults --log-bin=$MYSQL_TEST_DIR/var/log/master-bin \
|
||||
--server-id=1 --rpl-recovery-rank=1 \
|
||||
--basedir=$MY_BASEDIR --init-rpl-role=master \
|
||||
--server-id=1 \
|
||||
--basedir=$MY_BASEDIR \
|
||||
--port=$MASTER_MYPORT \
|
||||
--exit-info=256 \
|
||||
--core \
|
||||
|
@ -722,6 +737,7 @@ start_master()
|
|||
--tmpdir=$MYSQL_TMP_DIR \
|
||||
--language=$LANGUAGE \
|
||||
--innodb_data_file_path=ibdata1:50M \
|
||||
$MASTER_40_ARGS \
|
||||
$SMALL_SERVER \
|
||||
$EXTRA_MASTER_OPT $EXTRA_MASTER_MYSQLD_OPT"
|
||||
else
|
||||
|
@ -738,6 +754,7 @@ start_master()
|
|||
--tmpdir=$MYSQL_TMP_DIR \
|
||||
--language=$LANGUAGE \
|
||||
--innodb_data_file_path=ibdata1:50M \
|
||||
$MASTER_40_ARGS \
|
||||
$SMALL_SERVER \
|
||||
$EXTRA_MASTER_OPT $EXTRA_MASTER_MYSQLD_OPT"
|
||||
fi
|
||||
|
@ -749,14 +766,14 @@ start_master()
|
|||
then
|
||||
$ECHO "set args $master_args" > $GDB_MASTER_INIT
|
||||
manager_launch master ddd -display $DISPLAY --debugger \
|
||||
"gdb -x $GDB_MASTER_INIT" $MYSQLD
|
||||
"gdb -x $GDB_MASTER_INIT" $MASTER_MYSQLD
|
||||
elif [ x$DO_GDB = x1 ]
|
||||
then
|
||||
if [ x$MANUAL_GDB = x1 ]
|
||||
then
|
||||
$ECHO "set args $master_args" > $GDB_MASTER_INIT
|
||||
$ECHO "To start gdb for the master , type in another window:"
|
||||
$ECHO "cd $CWD ; gdb -x $GDB_MASTER_INIT $MYSQLD"
|
||||
$ECHO "cd $CWD ; gdb -x $GDB_MASTER_INIT $MASTER_MYSQLD"
|
||||
wait_for_master=1500
|
||||
else
|
||||
( $ECHO set args $master_args;
|
||||
|
@ -770,12 +787,12 @@ r
|
|||
EOF
|
||||
fi ) > $GDB_MASTER_INIT
|
||||
manager_launch master $XTERM -display $DISPLAY \
|
||||
-title "Master" -e gdb -x $GDB_MASTER_INIT $MYSQLD
|
||||
-title "Master" -e gdb -x $GDB_MASTER_INIT $MASTER_MYSQLD
|
||||
fi
|
||||
else
|
||||
manager_launch master $MYSQLD $master_args
|
||||
manager_launch master $MASTER_MYSQLD $master_args
|
||||
fi
|
||||
sleep_until_file_exists $MASTER_MYPID $wait_for_master
|
||||
sleep_until_file_created $MASTER_MYPID $wait_for_master
|
||||
wait_for_master=$SLEEP_TIME_FOR_SECOND_MASTER
|
||||
MASTER_RUNNING=1
|
||||
}
|
||||
|
@ -866,7 +883,7 @@ start_slave()
|
|||
if [ x$MANUAL_GDB = x1 ]
|
||||
then
|
||||
echo "To start gdb for the slave, type in another window:"
|
||||
echo "cd $CWD ; gdb -x $GDB_SLAVE_INIT $MYSQLD"
|
||||
echo "cd $CWD ; gdb -x $GDB_SLAVE_INIT $SLAVE_MYSQLD"
|
||||
wait_for_slave=1500
|
||||
else
|
||||
manager_launch $slave_ident $XTERM -display $DISPLAY -title "Slave" -e \
|
||||
|
@ -876,7 +893,7 @@ start_slave()
|
|||
manager_launch $slave_ident $SLAVE_MYSQLD $slave_args
|
||||
fi
|
||||
eval "SLAVE$1_RUNNING=1"
|
||||
sleep_until_file_exists $slave_pid $wait_for_slave
|
||||
sleep_until_file_created $slave_pid $wait_for_slave
|
||||
wait_for_slave=$SLEEP_TIME_FOR_SECOND_SLAVE
|
||||
}
|
||||
|
||||
|
|
|
@ -48,3 +48,5 @@ i
|
|||
2
|
||||
1
|
||||
drop table t1;
|
||||
select 0 limit 0;
|
||||
0
|
||||
|
|
|
@ -7,7 +7,7 @@ use test;
|
|||
drop table if exists t1,t3;
|
||||
create table t1 (word char(20) not null);
|
||||
load data infile '../../std_data/words.dat' into table t1;
|
||||
load data local infile '/home/sasha/bk/mysql-4.0/mysql-test/std_data/words.dat' into table t1;
|
||||
load data local infile 'MYSQL_TEST_DIR/std_data/words.dat' into table t1;
|
||||
select * from t1;
|
||||
word
|
||||
Aarhus
|
||||
|
|
77
mysql-test/r/rpl_compat.result
Normal file
77
mysql-test/r/rpl_compat.result
Normal file
|
@ -0,0 +1,77 @@
|
|||
slave stop;
|
||||
reset master;
|
||||
reset slave;
|
||||
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
|
||||
slave start;
|
||||
use test;
|
||||
drop table if exists t1,t3;
|
||||
create table t1 (word char(20) not null);
|
||||
load data infile '../../std_data/words.dat' into table t1;
|
||||
select * from t1;
|
||||
word
|
||||
Aarhus
|
||||
Aaron
|
||||
Ababa
|
||||
aback
|
||||
abaft
|
||||
abandon
|
||||
abandoned
|
||||
abandoning
|
||||
abandonment
|
||||
abandons
|
||||
set password for root@"localhost" = password('foo');
|
||||
set password for root@"localhost" = password('');
|
||||
create table t3(n int);
|
||||
insert into t3 values(1),(2);
|
||||
use test;
|
||||
select * from t3;
|
||||
n
|
||||
1
|
||||
2
|
||||
select sum(length(word)) from t1;
|
||||
sum(length(word))
|
||||
71
|
||||
drop table t1,t3;
|
||||
reset master;
|
||||
slave stop;
|
||||
reset slave;
|
||||
create table t1(n int);
|
||||
insert into t1 values (1),(2),(3);
|
||||
create table t2(id int);
|
||||
insert into t2 values(connection_id());
|
||||
create temporary table t1_temp(n int);
|
||||
insert into t1_temp select get_lock('crash_lock%20C', 1) from t2;
|
||||
update t1 set n = n + get_lock('crash_lock%20C', 2);
|
||||
select (@id := id) - id from t2;
|
||||
(@id := id) - id
|
||||
0
|
||||
kill @id;
|
||||
drop table t2;
|
||||
Server shutdown in progress
|
||||
slave start;
|
||||
set sql_slave_skip_counter=1;
|
||||
slave start;
|
||||
select count(*) from t1;
|
||||
count(*)
|
||||
3
|
||||
drop table t1;
|
||||
create table t1 (n int);
|
||||
insert into t1 values(3456);
|
||||
use mysql;
|
||||
insert into user (Host, User, Password)
|
||||
VALUES ("10.10.10.%", "blafasel2", password("blafasel2"));
|
||||
select select_priv,user from mysql.user where user = 'blafasel2';
|
||||
select_priv user
|
||||
N blafasel2
|
||||
update user set Select_priv = "Y" where User="blafasel2";
|
||||
select select_priv,user from mysql.user where user = 'blafasel2';
|
||||
select_priv user
|
||||
Y blafasel2
|
||||
use test;
|
||||
select n from t1;
|
||||
n
|
||||
3456
|
||||
select select_priv,user from mysql.user where user = 'blafasel2';
|
||||
select_priv user
|
||||
Y blafasel2
|
||||
drop table t1;
|
|
@ -1331,10 +1331,10 @@ table type possible_keys key key_len ref rows Extra
|
|||
t2 ref fld3 fld3 30 const 1 where used; Using index
|
||||
explain select fld3 from t2 ignore index (fld3) where fld3 = 'honeysuckle';
|
||||
table type possible_keys key key_len ref rows Extra
|
||||
t2 index fld3 fld3 30 NULL 1199 where used; Using index
|
||||
t2 index NULL fld3 30 NULL 1199 where used; Using index
|
||||
explain select fld3 from t2 use index (fld1) where fld3 = 'honeysuckle';
|
||||
table type possible_keys key key_len ref rows Extra
|
||||
t2 index fld3 fld3 30 NULL 1199 where used; Using index
|
||||
t2 index NULL fld3 30 NULL 1199 where used; Using index
|
||||
explain select fld3 from t2 use index (fld3) where fld3 = 'honeysuckle';
|
||||
table type possible_keys key key_len ref rows Extra
|
||||
t2 ref fld3 fld3 30 const 1 where used; Using index
|
||||
|
|
|
@ -45,3 +45,20 @@ select found_rows();
|
|||
FOUND_ROWS()
|
||||
8
|
||||
drop table t1;
|
||||
create table t1 (a int not null primary key);
|
||||
insert into t1 values (1),(2),(3),(4),(5);
|
||||
select sql_calc_found_rows a from t1 where a in (1,2,3) order by a desc limit 0,2;
|
||||
a
|
||||
3
|
||||
2
|
||||
select FOUND_ROWS();
|
||||
FOUND_ROWS()
|
||||
3
|
||||
select sql_calc_found_rows a from t1 where a in (1,2,3) order by a+2 desc limit 0,2;
|
||||
a
|
||||
3
|
||||
2
|
||||
select FOUND_ROWS();
|
||||
FOUND_ROWS()
|
||||
3
|
||||
drop table t1;
|
||||
|
|
|
@ -28,3 +28,5 @@ delete from t1 limit 0;
|
|||
update t1 set i=3 limit 0;
|
||||
select * from t1;
|
||||
drop table t1;
|
||||
|
||||
select 0 limit 0;
|
||||
|
|
|
@ -5,6 +5,7 @@ use test;
|
|||
drop table if exists t1,t3;
|
||||
create table t1 (word char(20) not null);
|
||||
load data infile '../../std_data/words.dat' into table t1;
|
||||
--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
|
||||
eval load data local infile '$MYSQL_TEST_DIR/std_data/words.dat' into table t1;
|
||||
select * from t1;
|
||||
set password for root@"localhost" = password('foo');
|
||||
|
|
86
mysql-test/t/rpl_compat.test
Normal file
86
mysql-test/t/rpl_compat.test
Normal file
|
@ -0,0 +1,86 @@
|
|||
eval_result;
|
||||
source include/master-slave.inc;
|
||||
connection master;
|
||||
require_version 3.23;
|
||||
use test;
|
||||
drop table if exists t1,t3;
|
||||
create table t1 (word char(20) not null);
|
||||
load data infile '../../std_data/words.dat' into table t1;
|
||||
select * from t1;
|
||||
set password for root@"localhost" = password('foo');
|
||||
set password for root@"localhost" = password('');
|
||||
create table t3(n int);
|
||||
insert into t3 values(1),(2);
|
||||
save_master_pos;
|
||||
connection slave;
|
||||
sync_with_master;
|
||||
use test;
|
||||
select * from t3;
|
||||
select sum(length(word)) from t1;
|
||||
connection master;
|
||||
drop table t1,t3;
|
||||
save_master_pos;
|
||||
connection slave;
|
||||
sync_with_master;
|
||||
|
||||
#test handling of aborted connection in the middle of update
|
||||
connection master;
|
||||
reset master;
|
||||
connection slave;
|
||||
slave stop;
|
||||
reset slave;
|
||||
|
||||
connection master;
|
||||
create table t1(n int);
|
||||
insert into t1 values (1),(2),(3);
|
||||
create table t2(id int);
|
||||
insert into t2 values(connection_id());
|
||||
save_master_pos;
|
||||
|
||||
connection master1;
|
||||
#avoid generating result
|
||||
create temporary table t1_temp(n int);
|
||||
insert into t1_temp select get_lock('crash_lock%20C', 1) from t2;
|
||||
|
||||
connection master;
|
||||
send update t1 set n = n + get_lock('crash_lock%20C', 2);
|
||||
connection master1;
|
||||
sleep 2;
|
||||
select (@id := id) - id from t2;
|
||||
kill @id;
|
||||
drop table t2;
|
||||
connection master;
|
||||
--error 1053;
|
||||
reap;
|
||||
connection slave;
|
||||
slave start;
|
||||
sync_with_master ;
|
||||
#now slave will hit an error
|
||||
wait_for_slave_to_stop;
|
||||
|
||||
set sql_slave_skip_counter=1;
|
||||
slave start;
|
||||
select count(*) from t1;
|
||||
connection master1;
|
||||
drop table t1;
|
||||
create table t1 (n int);
|
||||
insert into t1 values(3456);
|
||||
use mysql;
|
||||
insert into user (Host, User, Password)
|
||||
VALUES ("10.10.10.%", "blafasel2", password("blafasel2"));
|
||||
select select_priv,user from mysql.user where user = 'blafasel2';
|
||||
update user set Select_priv = "Y" where User="blafasel2";
|
||||
select select_priv,user from mysql.user where user = 'blafasel2';
|
||||
use test;
|
||||
save_master_pos;
|
||||
connection slave;
|
||||
sync_with_master;
|
||||
select n from t1;
|
||||
select select_priv,user from mysql.user where user = 'blafasel2';
|
||||
connection master1;
|
||||
drop table t1;
|
||||
save_master_pos;
|
||||
connection slave;
|
||||
sync_with_master;
|
||||
|
||||
|
|
@ -18,3 +18,15 @@ select found_rows();
|
|||
select SQL_CALC_FOUND_ROWS * from t1 left join t1 as t2 on (t1.b=t2.a) limit 2,1;
|
||||
select found_rows();
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Test SQL_CALC_FOUND_ROWS optimization when used with one table and filesort
|
||||
#
|
||||
|
||||
create table t1 (a int not null primary key);
|
||||
insert into t1 values (1),(2),(3),(4),(5);
|
||||
select sql_calc_found_rows a from t1 where a in (1,2,3) order by a desc limit 0,2;
|
||||
select FOUND_ROWS();
|
||||
select sql_calc_found_rows a from t1 where a in (1,2,3) order by a+2 desc limit 0,2;
|
||||
select FOUND_ROWS();
|
||||
drop table t1;
|
||||
|
|
|
@ -1,74 +0,0 @@
|
|||
This directory contains all of the test cases for the MySQL Test Suite
|
||||
marked up in XML.
|
||||
|
||||
To convert these test cases from XML into 'mysqltest' format, one needs
|
||||
an XSL translator installed on their system. At MySQL, we use Sablotron
|
||||
(http://www.gingerall.com/). Once installed, conversion happens with a
|
||||
command like this:
|
||||
|
||||
sabcmd xsl/mysqltest.xsl < tests/sel000001.xml > sel000001.test
|
||||
|
||||
The file 'sel000001.test' contains the plain text conversion that is
|
||||
to be fed into the 'mysqltest' program.
|
||||
|
||||
Below is an example of a test case marked up in XML; illustrating all
|
||||
of the XML mark-up currently supported in our 'mysqltest.xsl' stylesheet.
|
||||
|
||||
----------------------------------------------------
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
|
||||
<!-- This file is maintained by matt@mysql.com -->
|
||||
|
||||
<test name="sel000001">
|
||||
|
||||
<version value="3.22"/>
|
||||
<version value="3.23"/>
|
||||
|
||||
<description>This test will monkey around trying to kill mysqld.</description>
|
||||
|
||||
<connect name="Test_Connect1"
|
||||
host="MyHostName"
|
||||
user="Matt"
|
||||
pass="MattPass"
|
||||
db="MyDB"
|
||||
port="3306"
|
||||
sock="MyDB.sock"
|
||||
/>
|
||||
|
||||
<connection name="Test_Connect1">
|
||||
<resultfile name="sel000001.result">
|
||||
<sql>SELECT y FROM foo WHERE bar='2'</sql>
|
||||
</resultfile>
|
||||
<sql>INSERT INTO foo VALUES (y='2') WHERE bar='1'</sql>
|
||||
</connection>
|
||||
|
||||
</test>
|
||||
----------------------------------------------------
|
||||
|
||||
|
||||
The converted (mysqltest format) output of this source XML file looks
|
||||
like:
|
||||
|
||||
|
||||
----------------------------------------------------
|
||||
# sel000001
|
||||
#
|
||||
# Versions
|
||||
# --------
|
||||
# 3.22
|
||||
# 3.23
|
||||
#
|
||||
# Description
|
||||
# -----------
|
||||
# This test will monkey around trying to kill mysqld.
|
||||
#
|
||||
|
||||
|
||||
connect(Test_Connect1, MyHostName, Matt, MattPass, MyDB, 3306, MyDB.sock)
|
||||
|
||||
connection Test_Connect1
|
||||
INSERT INTO foo VALUES (y='2') WHERE bar='1';
|
||||
@sel000001.result SELECT y FROM foo WHERE bar='2';
|
||||
----------------------------------------------------
|
||||
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
<?xml version="1.0" standalone="no"?>
|
||||
|
||||
<!-- This file is maintained by matt@mysql.com -->
|
||||
|
||||
<test name="sel000001">
|
||||
|
||||
<version value="3.22"/>
|
||||
<version value="3.23"/>
|
||||
|
||||
<description>This test is just a simple select.</description>
|
||||
<description>Testing WHERE clause.</description>
|
||||
|
||||
<sql>DROP TABLE IF EXISTS t</sql>
|
||||
<sql>CREATE TABLE t (s CHAR(20) PRIMARY KEY, id INT)</sql>
|
||||
<sql>INSERT INTO t VALUES ('cat', 1), ('mouse', 3), ('dog', 2), ('snake', 77)</sql>
|
||||
|
||||
<resultfile name="r/3.23/sel000001.result">
|
||||
<sql>SELECT s, id FROM t WHERE s = 'mouse'</sql>
|
||||
</resultfile>
|
||||
|
||||
</test>
|
|
@ -1,20 +0,0 @@
|
|||
<?xml version="1.0" standalone="no"?>
|
||||
|
||||
<!-- This file is maintained by matt@mysql.com -->
|
||||
|
||||
<test name="sel000002">
|
||||
|
||||
<version value="3.22"/>
|
||||
<version value="3.23"/>
|
||||
|
||||
<description>This test is just a simple select.</description>
|
||||
|
||||
<sql>DROP TABLE IF EXISTS t</sql>
|
||||
<sql>CREATE TABLE t (n INT)</sql>
|
||||
<sql>INSERT INTO t VALUES (1), (2), (3)</sql>
|
||||
|
||||
<resultfile name="r/3.23/sel000002.result">
|
||||
<sql>SELECT * FROM t</sql>
|
||||
</resultfile>
|
||||
|
||||
</test>
|
|
@ -1,21 +0,0 @@
|
|||
<?xml version="1.0" standalone="no"?>
|
||||
|
||||
<!-- This file is maintained by matt@mysql.com -->
|
||||
|
||||
<test name="sel000003">
|
||||
|
||||
<version value="3.22"/>
|
||||
<version value="3.23"/>
|
||||
|
||||
<description>This test is just a simple select.</description>
|
||||
<description>Testing count() function and GROUP BY clause.</description>
|
||||
|
||||
<sql>DROP TABLE IF EXISTS t</sql>
|
||||
<sql>CREATE TABLE t (name CHAR(20) NOT NULL PRIMARY KEY, score SMALLINT NOT NULL, KEY(score))</sql>
|
||||
<sql>INSERT INTO t VALUES ('Sasha', 20), ('Matt', 20), ('Monty', 10), ('David', 10), ('Tim', 10), ('Jeremy', 10)</sql>
|
||||
|
||||
<resultfile name="r/3.23/sel000003.result">
|
||||
<sql>SELECT COUNT(*) as n, score FROM t GROUP BY score</sql>
|
||||
</resultfile>
|
||||
|
||||
</test>
|
|
@ -1,17 +0,0 @@
|
|||
<?xml version="1.0" standalone="no"?>
|
||||
|
||||
<!-- This file is maintained by matt@mysql.com -->
|
||||
|
||||
<test name="sel000004">
|
||||
|
||||
<version value="3.22"/>
|
||||
<version value="3.23"/>
|
||||
|
||||
<description>Simple arithmetic.</description>
|
||||
<description>Testing MOD(), SIGN(), and arithmetic grouping.</description>
|
||||
|
||||
<resultfile name="r/3.23/sel000004.result">
|
||||
<sql>SELECT 1+1,1-1,1+1*2,8/5,8%5,MOD(8,5),MOD(8,5)|0,-(1+1)*-2,SIGN(-5)</sql>
|
||||
</resultfile>
|
||||
|
||||
</test>
|
|
@ -1,17 +0,0 @@
|
|||
<?xml version="1.0" standalone="no"?>
|
||||
|
||||
<!-- This file is maintained by matt@mysql.com -->
|
||||
|
||||
<test name="sel000005">
|
||||
|
||||
<version value="3.22"/>
|
||||
<version value="3.23"/>
|
||||
|
||||
<description>Numeric functions.</description>
|
||||
<description>Testing FLOOR(), CEILING(), ROUND().</description>
|
||||
|
||||
<resultfile name="r/3.23/sel000005.result">
|
||||
<sql>SELECT FLOOR(5.5),FLOOR(-5.5),CEILING(5.5),CEILING(-5.5),ROUND(5.5),ROUND(-5.5)</sql>
|
||||
</resultfile>
|
||||
|
||||
</test>
|
|
@ -1,17 +0,0 @@
|
|||
<?xml version="1.0" standalone="no"?>
|
||||
|
||||
<!-- This file is maintained by matt@mysql.com -->
|
||||
|
||||
<test name="sel000006">
|
||||
|
||||
<version value="3.22"/>
|
||||
<version value="3.23"/>
|
||||
|
||||
<description>Numeric functions.</description>
|
||||
<description>Testing ROUND(); hundreths precision.</description>
|
||||
|
||||
<resultfile name="r/3.23/sel000006.result">
|
||||
<sql>SELECT ROUND(5.64,1),ROUND(5.64,2),ROUND(5.64,-1),ROUND(5.64,-2)</sql>
|
||||
</resultfile>
|
||||
|
||||
</test>
|
|
@ -1,17 +0,0 @@
|
|||
<?xml version="1.0" standalone="no"?>
|
||||
|
||||
<!-- This file is maintained by matt@mysql.com -->
|
||||
|
||||
<test name="sel000007">
|
||||
|
||||
<version value="3.22"/>
|
||||
<version value="3.23"/>
|
||||
|
||||
<description>Numeric functions.</description>
|
||||
<description>Testing TRUNCATE().</description>
|
||||
|
||||
<resultfile name="r/3.23/sel000007.result">
|
||||
<sql>SELECT TRUNCATE(52.64,1),TRUNCATE(52.64,2),TRUNCATE(52.64,-1),TRUNCATE(52.64,-2)</sql>
|
||||
</resultfile>
|
||||
|
||||
</test>
|
|
@ -1,17 +0,0 @@
|
|||
<?xml version="1.0" standalone="no"?>
|
||||
|
||||
<!-- This file is maintained by matt@mysql.com -->
|
||||
|
||||
<test name="sel000008">
|
||||
|
||||
<version value="3.22"/>
|
||||
<version value="3.23"/>
|
||||
|
||||
<description>Numeric functions.</description>
|
||||
<description>Testing ABS(), LOG(), LOG10(), EXP(), SQRT(), POW(), RAND(), POWER().</description>
|
||||
|
||||
<resultfile name="r/3.23/sel000008.result">
|
||||
<sql>SELECT ABS(-10),LOG(EXP(10)),EXP(LOG(SQRT(10))*2),POW(10,LOG10(10)),RAND(999999),RAND(),POWER(2,4)</sql>
|
||||
</resultfile>
|
||||
|
||||
</test>
|
|
@ -1,17 +0,0 @@
|
|||
<?xml version="1.0" standalone="no"?>
|
||||
|
||||
<!-- This file is maintained by matt@mysql.com -->
|
||||
|
||||
<test name="sel000009">
|
||||
|
||||
<version value="3.22"/>
|
||||
<version value="3.23"/>
|
||||
|
||||
<description>Numeric functions.</description>
|
||||
<description>Testing PI(), SIN(), COS(), TAN(), COT(), ASIN(), ACOS(), ATAN().</description>
|
||||
|
||||
<resultfile name="r/3.23/sel000009.result">
|
||||
<sql>SELECT PI(),SIN(PI()/2),COS(PI()/2),TAN(PI()),COT(1),ASIN(1),ACOS(0),ATAN(1)</sql>
|
||||
</resultfile>
|
||||
|
||||
</test>
|
|
@ -1,17 +0,0 @@
|
|||
<?xml version="1.0" standalone="no"?>
|
||||
|
||||
<!-- This file is maintained by matt@mysql.com -->
|
||||
|
||||
<test name="sel000010">
|
||||
|
||||
<version value="3.22"/>
|
||||
<version value="3.23"/>
|
||||
|
||||
<description>Numeric bitwise comparisons.</description>
|
||||
<description>Testing |, &, BIT_COUNT().</description>
|
||||
|
||||
<resultfile name="r/3.23/sel000010.result">
|
||||
<sql>SELECT 1 | (1+1),5 & 3,BIT_COUNT(7)</sql>
|
||||
</resultfile>
|
||||
|
||||
</test>
|
|
@ -1,17 +0,0 @@
|
|||
<?xml version="1.0" standalone="no"?>
|
||||
|
||||
<!-- This file is maintained by matt@mysql.com -->
|
||||
|
||||
<test name="sel000011">
|
||||
|
||||
<version value="3.22"/>
|
||||
<version value="3.23"/>
|
||||
|
||||
<description>Numeric bitmoving comparisons.</description>
|
||||
<description>Testing <<, >>.</description>
|
||||
|
||||
<resultfile name="r/3.23/sel000011.result">
|
||||
<sql>SELECT 1 << 32,1 << 63, 1 << 64, 4 >> 2, 4 >> 63, 1<< 63 >> 60</sql>
|
||||
</resultfile>
|
||||
|
||||
</test>
|
|
@ -1,16 +0,0 @@
|
|||
<?xml version="1.0" standalone="no"?>
|
||||
|
||||
<!-- This file is maintained by matt@mysql.com -->
|
||||
|
||||
<test name="sel000012">
|
||||
|
||||
<version value="3.22"/>
|
||||
<version value="3.23"/>
|
||||
|
||||
<description>Numeric floating point.</description>
|
||||
|
||||
<resultfile name="r/3.23/sel000012.result">
|
||||
<sql>SELECT 10,10.0,10.,.1e+2,100.0e-1</sql>
|
||||
</resultfile>
|
||||
|
||||
</test>
|
|
@ -1,16 +0,0 @@
|
|||
<?xml version="1.0" standalone="no"?>
|
||||
|
||||
<!-- This file is maintained by matt@mysql.com -->
|
||||
|
||||
<test name="sel000013">
|
||||
|
||||
<version value="3.22"/>
|
||||
<version value="3.23"/>
|
||||
|
||||
<description>Numeric floating point.</description>
|
||||
|
||||
<resultfile name="r/3.23/sel000013.result">
|
||||
<sql>SELECT 6e-05, -6e-05, --6e-05, -6e-05+1.000000</sql>
|
||||
</resultfile>
|
||||
|
||||
</test>
|
|
@ -1,17 +0,0 @@
|
|||
<?xml version="1.0" standalone="no"?>
|
||||
|
||||
<!-- This file is maintained by matt@mysql.com -->
|
||||
|
||||
<test name="sel000014">
|
||||
|
||||
<version value="3.22"/>
|
||||
<version value="3.23"/>
|
||||
|
||||
<description>Numerics.</description>
|
||||
<description>Testing pos/neg and zero padding.</description>
|
||||
|
||||
<resultfile name="r/3.23/sel000014.result">
|
||||
<sql>SELECT 0,256,00000000000000065536,2147483647,-2147483648,2147483648,+4294967296</sql>
|
||||
</resultfile>
|
||||
|
||||
</test>
|
|
@ -1,17 +0,0 @@
|
|||
<?xml version="1.0" standalone="no"?>
|
||||
|
||||
<!-- This file is maintained by matt@mysql.com -->
|
||||
|
||||
<test name="sel000015">
|
||||
|
||||
<version value="3.22"/>
|
||||
<version value="3.23"/>
|
||||
|
||||
<description>Numerics.</description>
|
||||
<description>Testing big numbers.</description>
|
||||
|
||||
<resultfile name="r/3.23/sel000015.result">
|
||||
<sql>SELECT 922337203685477580,92233720368547758000</sql>
|
||||
</resultfile>
|
||||
|
||||
</test>
|
|
@ -1,17 +0,0 @@
|
|||
<?xml version="1.0" standalone="no"?>
|
||||
|
||||
<!-- This file is maintained by matt@mysql.com -->
|
||||
|
||||
<test name="sel000016">
|
||||
|
||||
<version value="3.22"/>
|
||||
<version value="3.23"/>
|
||||
|
||||
<description>Numerics.</description>
|
||||
<description>Testing big negative numbers.</description>
|
||||
|
||||
<resultfile name="r/3.23/sel000016.result">
|
||||
<sql>SELECT -922337203685477580,-92233720368547758000</sql>
|
||||
</resultfile>
|
||||
|
||||
</test>
|
|
@ -1,17 +0,0 @@
|
|||
<?xml version="1.0" standalone="no"?>
|
||||
|
||||
<!-- This file is maintained by matt@mysql.com -->
|
||||
|
||||
<test name="sel000017">
|
||||
|
||||
<version value="3.22"/>
|
||||
<version value="3.23"/>
|
||||
|
||||
<description>Numerics.</description>
|
||||
<description>Testing big pos/neg numbers.</description>
|
||||
|
||||
<resultfile name="r/3.23/sel000017.result">
|
||||
<sql>SELECT 9223372036854775807,-009223372036854775808</sql>
|
||||
</resultfile>
|
||||
|
||||
</test>
|
|
@ -1,17 +0,0 @@
|
|||
<?xml version="1.0" standalone="no"?>
|
||||
|
||||
<!-- This file is maintained by matt@mysql.com -->
|
||||
|
||||
<test name="sel000018">
|
||||
|
||||
<version value="3.22"/>
|
||||
<version value="3.23"/>
|
||||
|
||||
<description>Numerics.</description>
|
||||
<description>Testing big pos/neg numbers.</description>
|
||||
|
||||
<resultfile name="r/3.23/sel000018.result">
|
||||
<sql>SELECT +9999999999999999999,-9999999999999999999</sql>
|
||||
</resultfile>
|
||||
|
||||
</test>
|
|
@ -1,17 +0,0 @@
|
|||
<?xml version="1.0" standalone="no"?>
|
||||
|
||||
<!-- This file is maintained by matt@mysql.com -->
|
||||
|
||||
<test name="sel000019">
|
||||
|
||||
<version value="3.22"/>
|
||||
<version value="3.23"/>
|
||||
|
||||
<description>Numerics.</description>
|
||||
<description>Testing DEGREES(), RADIANS().</description>
|
||||
|
||||
<resultfile name="r/3.23/sel000019.result">
|
||||
<sql>SELECT DEGREES(PI()),RADIANS(360)</sql>
|
||||
</resultfile>
|
||||
|
||||
</test>
|
|
@ -1,17 +0,0 @@
|
|||
<?xml version="1.0" standalone="no"?>
|
||||
|
||||
<!-- This file is maintained by matt@mysql.com -->
|
||||
|
||||
<test name="sel000020">
|
||||
|
||||
<version value="3.22"/>
|
||||
<version value="3.23"/>
|
||||
|
||||
<description>Strings.</description>
|
||||
<description>Testing string comparisons; STRCMP(), =, >, >=, <=, !=.</description>
|
||||
|
||||
<resultfile name="r/3.23/sel000020.result">
|
||||
<sql>SELECT 0=0,1>0,1>=1,1<0,1<=0,1!=0,STRCMP("abc","abcd"),STRCMP("b","a"),STRCMP("a","a")</sql>
|
||||
</resultfile>
|
||||
|
||||
</test>
|
|
@ -1,17 +0,0 @@
|
|||
<?xml version="1.0" standalone="no"?>
|
||||
|
||||
<!-- This file is maintained by matt@mysql.com -->
|
||||
|
||||
<test name="sel000021">
|
||||
|
||||
<version value="3.22"/>
|
||||
<version value="3.23"/>
|
||||
|
||||
<description>Strings.</description>
|
||||
<description>Testing string comparisons; =, >, >=, <=, <>.</description>
|
||||
|
||||
<resultfile name="r/3.23/sel000021.result">
|
||||
<sql>SELECT "a"<"b","a"<="b","b">="a","b">"a","a"="A","a"<>"b"</sql>
|
||||
</resultfile>
|
||||
|
||||
</test>
|
|
@ -1,17 +0,0 @@
|
|||
<?xml version="1.0" standalone="no"?>
|
||||
|
||||
<!-- This file is maintained by matt@mysql.com -->
|
||||
|
||||
<test name="sel000022">
|
||||
|
||||
<version value="3.22"/>
|
||||
<version value="3.23"/>
|
||||
|
||||
<description>Strings.</description>
|
||||
<description>Testing string comparisons; =, >, <=.</description>
|
||||
|
||||
<resultfile name="r/3.23/sel000022.result">
|
||||
<sql>SELECT "a "="A", "A "="a", "a " <= "A b"</sql>
|
||||
</resultfile>
|
||||
|
||||
</test>
|
|
@ -1,17 +0,0 @@
|
|||
<?xml version="1.0" standalone="no"?>
|
||||
|
||||
<!-- This file is maintained by matt@mysql.com -->
|
||||
|
||||
<test name="sel000023">
|
||||
|
||||
<version value="3.22"/>
|
||||
<version value="3.23"/>
|
||||
|
||||
<description>Strings.</description>
|
||||
<description>Testing string comparisons; LIKE, NOT LIKE, '%'.</description>
|
||||
|
||||
<resultfile name="r/3.23/sel000023.result">
|
||||
<sql>SELECT "abc" LIKE "a%", "abc" NOT LIKE "%d%", "a%" LIKE "a\%","abc%" LIKE "a%\%","abcd" LIKE "a%b_%d", "a" LIKE "%%a","abcde" LIKE "a%_e","abc" LIKE "abc%"</sql>
|
||||
</resultfile>
|
||||
|
||||
</test>
|
|
@ -1,17 +0,0 @@
|
|||
<?xml version="1.0" standalone="no"?>
|
||||
|
||||
<!-- This file is maintained by matt@mysql.com -->
|
||||
|
||||
<test name="sel000024">
|
||||
|
||||
<version value="3.22"/>
|
||||
<version value="3.23"/>
|
||||
|
||||
<description>Strings.</description>
|
||||
<description>Testing string comparisons; LIKE, '%'.</description>
|
||||
|
||||
<resultfile name="r/3.23/sel000024.result">
|
||||
<sql>SELECT "a" LIKE "%%b","a" LIKE "%%ab","ab" LIKE "a\%", "ab" LIKE "_", "ab" LIKE "ab_", "abc" LIKE "%_d", "abc" LIKE "abc%d"</sql>
|
||||
</resultfile>
|
||||
|
||||
</test>
|
|
@ -1,17 +0,0 @@
|
|||
<?xml version="1.0" standalone="no"?>
|
||||
|
||||
<!-- This file is maintained by matt@mysql.com -->
|
||||
|
||||
<test name="sel000025">
|
||||
|
||||
<version value="3.22"/>
|
||||
<version value="3.23"/>
|
||||
|
||||
<description>Strings.</description>
|
||||
<description>Testing string comparisons; LIKE, ESCAPE, '%'.</description>
|
||||
|
||||
<resultfile name="r/3.23/sel000025.result">
|
||||
<sql>SELECT '?' LIKE '|%', '?' LIKE '|%' ESCAPE '|', '%' LIKE '|%', '%' LIKE '|%' ESCAPE '|', '%' LIKE '%'</sql>
|
||||
</resultfile>
|
||||
|
||||
</test>
|
|
@ -1,17 +0,0 @@
|
|||
<?xml version="1.0" standalone="no"?>
|
||||
|
||||
<!-- This file is maintained by matt@mysql.com -->
|
||||
|
||||
<test name="sel000026">
|
||||
|
||||
<version value="3.22"/>
|
||||
<version value="3.23"/>
|
||||
|
||||
<description>Strings.</description>
|
||||
<description>Testing string comparisons; LIKE, '%'.</description>
|
||||
|
||||
<resultfile name="r/3.23/sel000026.result">
|
||||
<sql>SELECT 'abc' LIKE '%c','abcabc' LIKE '%c', "ab" LIKE "", "ab" LIKE "a", "ab" LIKE "ab"</sql>
|
||||
</resultfile>
|
||||
|
||||
</test>
|
|
@ -1,17 +0,0 @@
|
|||
<?xml version="1.0" standalone="no"?>
|
||||
|
||||
<!-- This file is maintained by matt@mysql.com -->
|
||||
|
||||
<test name="sel000027">
|
||||
|
||||
<version value="3.22"/>
|
||||
<version value="3.23"/>
|
||||
|
||||
<description>Strings.</description>
|
||||
<description>Testing string comparisons; REGEXP.</description>
|
||||
|
||||
<resultfile name="r/3.23/sel000027.result">
|
||||
<sql>SELECT "Det här är svenska" REGEXP "h[[:alpha:]]+r", "aba" REGEXP "^(a|b)*$"</sql>
|
||||
</resultfile>
|
||||
|
||||
</test>
|
|
@ -1,17 +0,0 @@
|
|||
<?xml version="1.0" standalone="no"?>
|
||||
|
||||
<!-- This file is maintained by matt@mysql.com -->
|
||||
|
||||
<test name="sel000028">
|
||||
|
||||
<version value="3.22"/>
|
||||
<version value="3.23"/>
|
||||
|
||||
<description>Strings.</description>
|
||||
<description>Testing string comparisons; REGEXP, CONCAT().</description>
|
||||
|
||||
<resultfile name="r/3.23/sel000028.result">
|
||||
<sql>SELECT "aba" REGEXP CONCAT("^","a")</sql>
|
||||
</resultfile>
|
||||
|
||||
</test>
|
|
@ -1,17 +0,0 @@
|
|||
<?xml version="1.0" standalone="no"?>
|
||||
|
||||
<!-- This file is maintained by matt@mysql.com -->
|
||||
|
||||
<test name="sel000029">
|
||||
|
||||
<version value="3.22"/>
|
||||
<version value="3.23"/>
|
||||
|
||||
<description>Strings.</description>
|
||||
<description>Testing string comparisons; NOT, AND, OR, !, &&, ||.</description>
|
||||
|
||||
<resultfile name="r/3.23/sel000029.result">
|
||||
<sql>SELECT !0,NOT 0=1,!(0=0),1 AND 1,1 && 0,0 OR 1,1 || NULL, 1=1 OR 1=1 AND 1=0</sql>
|
||||
</resultfile>
|
||||
|
||||
</test>
|
|
@ -1,17 +0,0 @@
|
|||
<?xml version="1.0" standalone="no"?>
|
||||
|
||||
<!-- This file is maintained by matt@mysql.com -->
|
||||
|
||||
<test name="sel000030">
|
||||
|
||||
<version value="3.22"/>
|
||||
<version value="3.23"/>
|
||||
|
||||
<description>Control flow.</description>
|
||||
<description>Testing control flow; IF()</description>
|
||||
|
||||
<resultfile name="r/3.23/sel000030.result">
|
||||
<sql>SELECT IF(0,"ERROR","this"),IF(1,"is","ERROR"),IF(NULL,"ERROR","a"),IF(1,2,3)|0,IF(1,2.0,3.0)+0</sql>
|
||||
</resultfile>
|
||||
|
||||
</test>
|
|
@ -1,4 +0,0 @@
|
|||
XML Stylesheets for converting test cases in XML to other forms.
|
||||
|
||||
- mysqltest.xsl -> mysqltest format (text)
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
|
||||
|
||||
<xsl:output method="text"/>
|
||||
|
||||
<xsl:template match="/"><xsl:apply-templates /></xsl:template>
|
||||
|
||||
<!-- Main Template -->
|
||||
|
||||
<xsl:template match="/test"># <xsl:apply-templates select="@name"/>
|
||||
#
|
||||
# Versions
|
||||
# --------<xsl:apply-templates select="version"/>
|
||||
#
|
||||
# Description
|
||||
# -----------<xsl:apply-templates select="description"/>
|
||||
#
|
||||
|
||||
<xsl:apply-templates select="connect"/>
|
||||
|
||||
<xsl:apply-templates select="connection"/>
|
||||
|
||||
<xsl:apply-templates select="sql"/>
|
||||
|
||||
<xsl:apply-templates select="resultfile"/>
|
||||
|
||||
</xsl:template>
|
||||
|
||||
<!-- End Main Template -->
|
||||
|
||||
|
||||
<xsl:template match="version">
|
||||
# <xsl:apply-templates select="@value"/>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="description">
|
||||
# <xsl:apply-templates />
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="connect">
|
||||
connect(<xsl:apply-templates select="@name"/>, <xsl:apply-templates select="@host"/>, <xsl:apply-templates select="@user"/>, <xsl:apply-templates select="@pass"/>, <xsl:apply-templates select="@db"/>, <xsl:apply-templates select="@port"/>, <xsl:apply-templates select="@sock"/>)
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="connection">
|
||||
<xsl:text>
|
||||
connection </xsl:text><xsl:apply-templates select="@name"/>
|
||||
<xsl:text>
|
||||
</xsl:text>
|
||||
<xsl:apply-templates select="sql"/>
|
||||
<xsl:apply-templates select="resultfile"/>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="resultfile">@<xsl:apply-templates select="@name"/><xsl:text> </xsl:text><xsl:apply-templates select="sql"/>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="sql">
|
||||
<xsl:apply-templates />;
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
|
@ -29,8 +29,15 @@ static my_bool compare_strings (register const char *s, register const char *t,
|
|||
static longlong getopt_ll (char *arg, const struct my_option *optp, int *err);
|
||||
static void init_variables(const struct my_option *options);
|
||||
|
||||
|
||||
#define DISABLE_OPTION_COUNT 2
|
||||
|
||||
static const char *special_opt_prefix[]=
|
||||
{"skip", "disable", "enable", "maximum", 0};
|
||||
|
||||
|
||||
/* Return error values from handle_options */
|
||||
|
||||
#define ERR_UNKNOWN_OPTION 1
|
||||
#define ERR_AMBIGUOUS_OPTION 2
|
||||
#define ERR_NO_ARGUMENT_ALLOWED 3
|
||||
|
@ -41,9 +48,6 @@ static void init_variables(const struct my_option *options);
|
|||
#define ERR_UNKNOWN_SUFFIX 8
|
||||
#define ERR_NO_PTR_TO_VARIABLE 9
|
||||
|
||||
static const char *special_opt_prefix[]=
|
||||
{"skip", "disable", "enable", "maximum", 0};
|
||||
|
||||
|
||||
/*
|
||||
function: handle_options
|
||||
|
@ -63,95 +67,91 @@ int handle_options(int *argc, char ***argv,
|
|||
{
|
||||
uint opt_found, argvpos= 0, length, spec_len, i;
|
||||
int err;
|
||||
my_bool end_of_options= 0, must_be_var, set_maximum_value;
|
||||
my_bool end_of_options= 0, must_be_var, set_maximum_value, special_used;
|
||||
char *progname= *(*argv), **pos, *optend, *prev_found;
|
||||
const struct my_option *optp;
|
||||
|
||||
LINT_INIT(opt_found);
|
||||
(*argc)--; /* Skip the program name */
|
||||
(*argv)++; /* --- || ---- */
|
||||
init_variables(longopts);
|
||||
for (pos= *argv; *pos; pos++)
|
||||
{
|
||||
char *cur_arg= *pos;
|
||||
if (*cur_arg == '-' && *(cur_arg + 1) && !end_of_options) /* must be opt */
|
||||
if (cur_arg[0] == '-' && cur_arg[1] && !end_of_options) /* must be opt */
|
||||
{
|
||||
char *argument= 0;
|
||||
must_be_var= 0;
|
||||
char *argument= 0;
|
||||
must_be_var= 0;
|
||||
set_maximum_value= 0;
|
||||
special_used= 0;
|
||||
|
||||
/* check for long option, or --set-variable (-O) */
|
||||
if (*(cur_arg + 1) == '-' || *(cur_arg + 1) == 'O')
|
||||
cur_arg++; /* skip '-' */
|
||||
if (*cur_arg == 'O')
|
||||
{
|
||||
if (*(cur_arg + 1) == 'O' ||
|
||||
!compare_strings(cur_arg, "--set-variable", 14))
|
||||
must_be_var= 1;
|
||||
|
||||
if (!(*++cur_arg)) /* If not -Ovar=# */
|
||||
{
|
||||
/* the argument must be in next argv */
|
||||
if (!*++pos)
|
||||
{
|
||||
fprintf(stderr, "%s: Option '-O' requires an argument\n",
|
||||
progname);
|
||||
return ERR_ARGUMENT_REQUIRED;
|
||||
}
|
||||
cur_arg= *pos;
|
||||
(*argc)--;
|
||||
}
|
||||
}
|
||||
else if (*cur_arg == '-') /* check for long option, or --set-variable */
|
||||
{
|
||||
if (!compare_strings(cur_arg, "-set-variable", 13))
|
||||
{
|
||||
must_be_var= 1;
|
||||
|
||||
if (*(cur_arg + 1) == 'O')
|
||||
{
|
||||
cur_arg+= 2;
|
||||
if (!(*cur_arg))
|
||||
{
|
||||
/* the argument must be in next argv */
|
||||
if (!(*(pos + 1)))
|
||||
{
|
||||
fprintf(stderr, "%s: Option '-O' requires an argument\n",
|
||||
progname);
|
||||
return ERR_ARGUMENT_REQUIRED;
|
||||
}
|
||||
pos++;
|
||||
cur_arg= *pos;
|
||||
(*argc)--;
|
||||
}
|
||||
}
|
||||
else /* Option argument begins with string '--set-variable' */
|
||||
if (cur_arg[13] == '=')
|
||||
{
|
||||
cur_arg+= 14;
|
||||
if (*cur_arg == '=')
|
||||
if (!*cur_arg)
|
||||
{
|
||||
cur_arg++;
|
||||
if (!(*cur_arg))
|
||||
{
|
||||
fprintf(stderr,
|
||||
"%s: Option '--set-variable' requires an argument\n",
|
||||
progname);
|
||||
return ERR_ARGUMENT_REQUIRED;
|
||||
}
|
||||
fprintf(stderr,
|
||||
"%s: Option '--set-variable' requires an argument\n",
|
||||
progname);
|
||||
return ERR_ARGUMENT_REQUIRED;
|
||||
}
|
||||
else if (*cur_arg) /* garbage, or another option. break out */
|
||||
}
|
||||
else if (cur_arg[14]) /* garbage, or another option. break out */
|
||||
must_be_var= 0;
|
||||
else
|
||||
{
|
||||
/* the argument must be in next argv */
|
||||
if (!*++pos)
|
||||
{
|
||||
cur_arg-= 14;
|
||||
must_be_var= 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* the argument must be in next argv */
|
||||
if (!(*(pos + 1)))
|
||||
{
|
||||
fprintf(stderr,
|
||||
"%s: Option '--set-variable' requires an argument\n",
|
||||
progname);
|
||||
return ERR_ARGUMENT_REQUIRED;
|
||||
}
|
||||
pos++;
|
||||
cur_arg= *pos;
|
||||
(*argc)--;
|
||||
fprintf(stderr,
|
||||
"%s: Option '--set-variable' requires an argument\n",
|
||||
progname);
|
||||
return ERR_ARGUMENT_REQUIRED;
|
||||
}
|
||||
cur_arg= *pos;
|
||||
(*argc)--;
|
||||
}
|
||||
}
|
||||
else if (!must_be_var)
|
||||
{
|
||||
/* '--' means end of options, look no further */
|
||||
if (!*(cur_arg + 2))
|
||||
if (!*++cur_arg) /* skip the double dash */
|
||||
{
|
||||
/* '--' means end of options, look no further */
|
||||
end_of_options= 1;
|
||||
(*argc)--;
|
||||
continue;
|
||||
}
|
||||
cur_arg+= 2; /* skip the double dash */
|
||||
}
|
||||
for (optend= cur_arg; *optend && *optend != '='; optend++) ;
|
||||
optend= strcend(cur_arg, '=');
|
||||
length= optend - cur_arg;
|
||||
if (*optend == '=')
|
||||
optend++;
|
||||
else
|
||||
optend=0;
|
||||
|
||||
/*
|
||||
Find first the right option. Return error in case of an ambiguous,
|
||||
or unknown option
|
||||
|
@ -165,7 +165,7 @@ int handle_options(int *argc, char ***argv,
|
|||
*/
|
||||
if (!must_be_var)
|
||||
{
|
||||
if (*optend == '=')
|
||||
if (optend)
|
||||
must_be_var= 1;
|
||||
for (i= 0; special_opt_prefix[i]; i++)
|
||||
{
|
||||
|
@ -176,6 +176,7 @@ int handle_options(int *argc, char ***argv,
|
|||
/*
|
||||
We were called with a special prefix, we can reuse opt_found
|
||||
*/
|
||||
special_used= 1;
|
||||
cur_arg += (spec_len + 1);
|
||||
if ((opt_found= findopt(cur_arg, length - (spec_len + 1),
|
||||
&optp, &prev_found)))
|
||||
|
@ -189,9 +190,9 @@ int handle_options(int *argc, char ***argv,
|
|||
return ERR_AMBIGUOUS_OPTION;
|
||||
}
|
||||
if (i < DISABLE_OPTION_COUNT)
|
||||
optend= (char*) "=0";
|
||||
optend= (char*) "0";
|
||||
else if (!compare_strings(special_opt_prefix[i],"enable",6))
|
||||
optend= (char*) "=1";
|
||||
optend= (char*) "1";
|
||||
else if (!compare_strings(special_opt_prefix[i],"maximum",7))
|
||||
{
|
||||
set_maximum_value= 1;
|
||||
|
@ -233,81 +234,81 @@ int handle_options(int *argc, char ***argv,
|
|||
return ERR_AMBIGUOUS_OPTION;
|
||||
}
|
||||
}
|
||||
if (must_be_var && !optp->opt_is_var)
|
||||
if (must_be_var && !optp->value)
|
||||
{
|
||||
fprintf(stderr, "%s: the argument '%s' is not an variable\n",
|
||||
progname, *pos);
|
||||
return ERR_MUST_BE_VARIABLE;
|
||||
}
|
||||
if (optp->arg_type == NO_ARG && *optend == '=')
|
||||
if (optp->arg_type == NO_ARG && optend && !special_used)
|
||||
{
|
||||
fprintf(stderr, "%s: option '--%s' cannot take an argument\n",
|
||||
progname, optp->name);
|
||||
return ERR_NO_ARGUMENT_ALLOWED;
|
||||
}
|
||||
else if (optp->arg_type == REQUIRED_ARG && !*optend)
|
||||
else if (optp->arg_type == REQUIRED_ARG && !optend)
|
||||
{
|
||||
/* Check if there are more arguments after this one */
|
||||
if (!(*(pos + 1)))
|
||||
if (!*++pos)
|
||||
{
|
||||
fprintf(stderr, "%s: option '--%s' requires an argument\n",
|
||||
progname, optp->name);
|
||||
return ERR_ARGUMENT_REQUIRED;
|
||||
}
|
||||
pos++;
|
||||
argument= *pos;
|
||||
(*argc)--;
|
||||
}
|
||||
else if (*optend == '=')
|
||||
argument= *(optend + 1) ? optend + 1 : (char*) "";
|
||||
else
|
||||
argument= optend;
|
||||
}
|
||||
else /* must be short option */
|
||||
{
|
||||
my_bool skip;
|
||||
for (skip= 0, optend= (cur_arg + 1); *optend && !skip; optend++)
|
||||
for (optend= cur_arg; *optend; optend++, opt_found= 0)
|
||||
{
|
||||
for (optp= longopts; optp->id ; optp++)
|
||||
for (optp= longopts; optp->id; optp++)
|
||||
{
|
||||
if (optp->id == (int) (uchar) *optend)
|
||||
{
|
||||
/* Option recognized. Find next what to do with it */
|
||||
opt_found= 1;
|
||||
if (optp->arg_type == REQUIRED_ARG || optp->arg_type == OPT_ARG)
|
||||
{
|
||||
if (*(optend + 1))
|
||||
{
|
||||
argument= (optend + 1);
|
||||
/*
|
||||
The rest of the option is option argument
|
||||
This is in effect a jump out of this loop
|
||||
*/
|
||||
skip= 1;
|
||||
// The rest of the option is option argument
|
||||
argument= optend + 1;
|
||||
// This is in effect a jump out of the outer loop
|
||||
optend= (char*) " ";
|
||||
}
|
||||
else if (optp->arg_type == REQUIRED_ARG)
|
||||
{
|
||||
/* Check if there are more arguments after this one */
|
||||
if (!(*(pos + 1)))
|
||||
if (!*++pos)
|
||||
{
|
||||
fprintf(stderr, "%s: option '-%c' requires an argument\n",
|
||||
progname, optp->id);
|
||||
return ERR_ARGUMENT_REQUIRED;
|
||||
}
|
||||
pos++;
|
||||
argument= *pos;
|
||||
(*argc)--;
|
||||
/* the other loop will break, because *optend + 1 == 0 */
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* we are hitting many options in 1 argv */
|
||||
if (*(optend + 1))
|
||||
get_one_option(optp->id, optp, 0);
|
||||
}
|
||||
get_one_option(optp->id, optp, argument);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!opt_found)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"%s: unknown option '-%c'\n", progname, *cur_arg);
|
||||
return ERR_UNKNOWN_OPTION;
|
||||
}
|
||||
}
|
||||
(*argc)--; /* option handled (short), decrease argument count */
|
||||
continue;
|
||||
}
|
||||
if (optp->opt_is_var)
|
||||
if (optp->value)
|
||||
{
|
||||
gptr *result_pos= (set_maximum_value) ?
|
||||
optp->u_max_value : optp->value;
|
||||
|
@ -349,6 +350,7 @@ int handle_options(int *argc, char ***argv,
|
|||
list the option found, if any. In case of ambiguous option, store
|
||||
the name in ffname argument
|
||||
*/
|
||||
|
||||
static int findopt (char *optpat, uint length,
|
||||
const struct my_option **opt_res,
|
||||
char **ffname)
|
||||
|
@ -378,6 +380,7 @@ static int findopt (char *optpat, uint length,
|
|||
Works like strncmp, other than 1.) considers '-' and '_' the same.
|
||||
2.) Returns -1 if strings differ, 0 if they are equal
|
||||
*/
|
||||
|
||||
static my_bool compare_strings(register const char *s, register const char *t,
|
||||
uint length)
|
||||
{
|
||||
|
@ -401,6 +404,7 @@ static my_bool compare_strings(register const char *s, register const char *t,
|
|||
that those values are honored.
|
||||
In case of an error, set error value in *err.
|
||||
*/
|
||||
|
||||
static longlong getopt_ll (char *arg, const struct my_option *optp, int *err)
|
||||
{
|
||||
char *endchar;
|
||||
|
@ -423,11 +427,14 @@ static longlong getopt_ll (char *arg, const struct my_option *optp, int *err)
|
|||
}
|
||||
if (num < (longlong) optp->min_value)
|
||||
num= (longlong) optp->min_value;
|
||||
else if (num > 0 && (ulonglong) num > (ulonglong) (ulong) optp->max_value)
|
||||
else if (num > 0 && (ulonglong) num > (ulonglong) (ulong) optp->max_value
|
||||
&& optp->max_value) // if max value is not set -> no upper limit
|
||||
num= (longlong) (ulong) optp->max_value;
|
||||
num= ((num - (longlong) optp->sub_size) / (ulonglong) optp->block_size);
|
||||
|
||||
return (longlong) (num * (ulonglong) optp->block_size);
|
||||
num= ((num - (longlong) optp->sub_size) / (optp->block_size ?
|
||||
(ulonglong) optp->block_size :
|
||||
1L));
|
||||
return (longlong) (num * (optp->block_size ? (ulonglong) optp->block_size :
|
||||
1L));
|
||||
}
|
||||
|
||||
|
||||
|
@ -436,11 +443,12 @@ static longlong getopt_ll (char *arg, const struct my_option *optp, int *err)
|
|||
|
||||
initialize all variables to their default values
|
||||
*/
|
||||
|
||||
static void init_variables(const struct my_option *options)
|
||||
{
|
||||
for ( ; options->name ; options++)
|
||||
for (; options->name; options++)
|
||||
{
|
||||
if (options->opt_is_var)
|
||||
if (options->value)
|
||||
{
|
||||
if (options->var_type == GET_LONG)
|
||||
*((long*) options->u_max_value)= *((long*) options->value)=
|
||||
|
@ -451,3 +459,120 @@ static void init_variables(const struct my_option *options)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
function: my_print_options
|
||||
|
||||
Print help for all options and variables.
|
||||
*/
|
||||
|
||||
void my_print_help(const struct my_option *options)
|
||||
{
|
||||
uint col, name_space= 22, comment_space= 57;
|
||||
const char *line_end;
|
||||
const struct my_option *optp;
|
||||
|
||||
for (optp= options; optp->id; optp++)
|
||||
{
|
||||
if (optp->id < 256)
|
||||
{
|
||||
printf(" -%c, ", optp->id);
|
||||
col= 6;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf(" ");
|
||||
col= 2;
|
||||
}
|
||||
printf("--%s", optp->name);
|
||||
col+= 2 + strlen(optp->name);
|
||||
if (optp->var_type == GET_STR)
|
||||
{
|
||||
printf("=name ");
|
||||
col+= 6;
|
||||
}
|
||||
else if (optp->var_type == GET_NO_ARG)
|
||||
{
|
||||
putchar(' ');
|
||||
col++;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("=# ");
|
||||
col+= 3;
|
||||
}
|
||||
if (col > name_space)
|
||||
{
|
||||
putchar('\n');
|
||||
col= 0;
|
||||
}
|
||||
for (; col < name_space; col++)
|
||||
putchar(' ');
|
||||
if (optp->comment && *optp->comment)
|
||||
{
|
||||
const char *comment= optp->comment, *end= strend(comment);
|
||||
|
||||
while ((uint) (end - comment) > comment_space)
|
||||
{
|
||||
for (line_end= comment + comment_space; *line_end != ' '; line_end--);
|
||||
for (; comment != line_end; comment++)
|
||||
putchar(*comment);
|
||||
comment++; // skip the space, as a newline will take it's place now
|
||||
putchar('\n');
|
||||
for (col= 0; col < name_space; col++)
|
||||
putchar(' ');
|
||||
}
|
||||
printf("%s", comment);
|
||||
}
|
||||
putchar('\n');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
function: my_print_options
|
||||
|
||||
Print variables.
|
||||
*/
|
||||
|
||||
void my_print_variables(const struct my_option *options)
|
||||
{
|
||||
uint name_space= 34, length;
|
||||
char buff[255];
|
||||
const struct my_option *optp;
|
||||
|
||||
printf("Variables (--variable-name=value) Default value\n");
|
||||
printf("--------------------------------- -------------\n");
|
||||
for (optp= options; optp->id; optp++)
|
||||
{
|
||||
if (optp->value)
|
||||
{
|
||||
printf("%s", optp->name);
|
||||
length= strlen(optp->name);
|
||||
for (; length < name_space; length++)
|
||||
putchar(' ');
|
||||
if (optp->var_type == GET_STR)
|
||||
{
|
||||
if (!optp->def_value && !*((char**) optp->value))
|
||||
printf("(No default value)\n");
|
||||
else
|
||||
printf("%s\n", *((char**) optp->value));
|
||||
}
|
||||
else if (optp->var_type == GET_LONG)
|
||||
{
|
||||
if (!optp->def_value && !*((long*) optp->value))
|
||||
printf("(No default value)\n");
|
||||
else
|
||||
printf("%lu\n", *((long*) optp->value));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!optp->def_value && !*((longlong*) optp->value))
|
||||
printf("(No default value)\n");
|
||||
else
|
||||
printf("%s\n", llstr(*((longlong*) optp->value), buff));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,6 +45,7 @@ static int NEAR_F delete_file(const char *name,const char *ext,int extflag);
|
|||
ulong ha_read_count, ha_write_count, ha_delete_count, ha_update_count,
|
||||
ha_read_key_count, ha_read_next_count, ha_read_prev_count,
|
||||
ha_read_first_count, ha_read_last_count,
|
||||
ha_commit_count, ha_rollback_count,
|
||||
ha_read_rnd_count, ha_read_rnd_next_count;
|
||||
|
||||
const char *ha_table_type[] = {
|
||||
|
@ -267,6 +268,7 @@ int ha_commit_trans(THD *thd, THD_TRANS* trans)
|
|||
#ifdef USING_TRANSACTIONS
|
||||
if (opt_using_transactions)
|
||||
{
|
||||
bool operation_done=0;
|
||||
/* Update the binary log if we have cached some queries */
|
||||
if (trans == &thd->transaction.all && mysql_bin_log.is_open() &&
|
||||
my_b_tell(&thd->transaction.trans_log))
|
||||
|
@ -297,12 +299,17 @@ int ha_commit_trans(THD *thd, THD_TRANS* trans)
|
|||
}
|
||||
trans->innodb_active_trans=0;
|
||||
if (trans == &thd->transaction.all)
|
||||
{
|
||||
query_cache.invalidate(Query_cache_table::INNODB);
|
||||
operation_done=1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (error && trans == &thd->transaction.all && mysql_bin_log.is_open())
|
||||
sql_print_error("Error: Got error during commit; Binlog is not up to date!");
|
||||
thd->tx_isolation=thd->session_tx_isolation;
|
||||
if (operation_done)
|
||||
statistic_increment(ha_commit_count,&LOCK_status);
|
||||
}
|
||||
#endif // using transactions
|
||||
DBUG_RETURN(error);
|
||||
|
@ -316,6 +323,7 @@ int ha_rollback_trans(THD *thd, THD_TRANS *trans)
|
|||
#ifdef USING_TRANSACTIONS
|
||||
if (opt_using_transactions)
|
||||
{
|
||||
bool operation_done=0;
|
||||
#ifdef HAVE_BERKELEY_DB
|
||||
if (trans->bdb_tid)
|
||||
{
|
||||
|
@ -325,6 +333,7 @@ int ha_rollback_trans(THD *thd, THD_TRANS *trans)
|
|||
error=1;
|
||||
}
|
||||
trans->bdb_tid=0;
|
||||
operation_done=1;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_INNOBASE_DB
|
||||
|
@ -336,6 +345,7 @@ int ha_rollback_trans(THD *thd, THD_TRANS *trans)
|
|||
error=1;
|
||||
}
|
||||
trans->innodb_active_trans=0;
|
||||
operation_done=1;
|
||||
}
|
||||
#endif
|
||||
if (trans == &thd->transaction.all)
|
||||
|
@ -343,6 +353,8 @@ int ha_rollback_trans(THD *thd, THD_TRANS *trans)
|
|||
WRITE_CACHE, (my_off_t) 0, 0, 1);
|
||||
thd->transaction.trans_log.end_of_file= max_binlog_cache_size;
|
||||
thd->tx_isolation=thd->session_tx_isolation;
|
||||
if (operation_done)
|
||||
statistic_increment(ha_rollback_count,&LOCK_status);
|
||||
}
|
||||
#endif /* USING_TRANSACTIONS */
|
||||
DBUG_RETURN(error);
|
||||
|
|
|
@ -556,6 +556,8 @@ Log_event* Log_event::read_log_event(const char* buf, int event_len,
|
|||
ev = new Query_log_event(buf, event_len, old_format);
|
||||
break;
|
||||
case LOAD_EVENT:
|
||||
ev = new Create_file_log_event(buf, event_len, old_format);
|
||||
break;
|
||||
case NEW_LOAD_EVENT:
|
||||
ev = new Load_log_event(buf, event_len, old_format);
|
||||
break;
|
||||
|
@ -566,7 +568,7 @@ Log_event* Log_event::read_log_event(const char* buf, int event_len,
|
|||
ev = new Slave_log_event(buf, event_len);
|
||||
break;
|
||||
case CREATE_FILE_EVENT:
|
||||
ev = new Create_file_log_event(buf, event_len);
|
||||
ev = new Create_file_log_event(buf, event_len, old_format);
|
||||
break;
|
||||
case APPEND_BLOCK_EVENT:
|
||||
ev = new Append_block_log_event(buf, event_len);
|
||||
|
@ -959,6 +961,12 @@ char* sql_ex_info::init(char* buf,char* buf_end,bool use_new_format)
|
|||
if (use_new_format)
|
||||
{
|
||||
empty_flags=0;
|
||||
/* the code below assumes that buf will not disappear from
|
||||
under our feet during the lifetime of the event. This assumption
|
||||
holds true in the slave thread if the log is in new format, but is not
|
||||
the case when we have old format because we will be reusing net buffer
|
||||
to read the actual file before we write out the Create_file event
|
||||
*/
|
||||
if (read_str(buf, buf_end, field_term, field_term_len) ||
|
||||
read_str(buf, buf_end, enclosed, enclosed_len) ||
|
||||
read_str(buf, buf_end, line_term, line_term_len) ||
|
||||
|
@ -970,11 +978,11 @@ char* sql_ex_info::init(char* buf,char* buf_end,bool use_new_format)
|
|||
else
|
||||
{
|
||||
field_term_len= enclosed_len= line_term_len= line_start_len= escaped_len=1;
|
||||
*field_term=*buf++;
|
||||
*enclosed= *buf++;
|
||||
*line_term= *buf++;
|
||||
*line_start=*buf++;
|
||||
*escaped= *buf++;
|
||||
field_term = buf++;
|
||||
enclosed= buf++;
|
||||
line_term= buf++;
|
||||
line_start= buf++;
|
||||
escaped= buf++;
|
||||
opt_flags = *buf++;
|
||||
empty_flags=*buf++;
|
||||
if (empty_flags & FIELD_TERM_EMPTY)
|
||||
|
@ -1095,7 +1103,9 @@ int Load_log_event::copy_log_event(const char *buf, ulong event_len,
|
|||
db_len = (uint)data_head[L_DB_LEN_OFFSET];
|
||||
num_fields = uint4korr(data_head + L_NUM_FIELDS_OFFSET);
|
||||
|
||||
int body_offset = get_data_body_offset();
|
||||
int body_offset = (buf[EVENT_TYPE_OFFSET] == LOAD_EVENT) ?
|
||||
LOAD_HEADER_LEN + OLD_HEADER_LEN : get_data_body_offset();
|
||||
|
||||
if ((int) event_len < body_offset)
|
||||
return 1;
|
||||
//sql_ex.init() on success returns the pointer to the first byte after
|
||||
|
@ -1117,7 +1127,6 @@ int Load_log_event::copy_log_event(const char *buf, ulong event_len,
|
|||
table_name = fields + field_block_len;
|
||||
db = table_name + table_name_len + 1;
|
||||
fname = db + db_len + 1;
|
||||
int type_code = get_type_code();
|
||||
fname_len = strlen(fname);
|
||||
// null termination is accomplished by the caller doing buf[event_len]=0
|
||||
return 0;
|
||||
|
@ -1367,20 +1376,29 @@ int Create_file_log_event::write_base(IO_CACHE* file)
|
|||
return res;
|
||||
}
|
||||
|
||||
Create_file_log_event::Create_file_log_event(const char* buf, int len):
|
||||
Load_log_event(buf,0,0),fake_base(0),block(0)
|
||||
Create_file_log_event::Create_file_log_event(const char* buf, int len,
|
||||
bool old_format):
|
||||
Load_log_event(buf,0,old_format),fake_base(0),block(0),inited_from_old(0)
|
||||
{
|
||||
int block_offset;
|
||||
if (copy_log_event(buf,len,0))
|
||||
if (copy_log_event(buf,len,old_format))
|
||||
return;
|
||||
file_id = uint4korr(buf + LOG_EVENT_HEADER_LEN +
|
||||
+ LOAD_HEADER_LEN + CF_FILE_ID_OFFSET);
|
||||
block_offset = LOG_EVENT_HEADER_LEN + Load_log_event::get_data_size() +
|
||||
CREATE_FILE_HEADER_LEN + 1; // 1 for \0 terminating fname
|
||||
if (len < block_offset)
|
||||
return;
|
||||
block = (char*)buf + block_offset;
|
||||
block_len = len - block_offset;
|
||||
if (!old_format)
|
||||
{
|
||||
file_id = uint4korr(buf + LOG_EVENT_HEADER_LEN +
|
||||
+ LOAD_HEADER_LEN + CF_FILE_ID_OFFSET);
|
||||
block_offset = LOG_EVENT_HEADER_LEN + Load_log_event::get_data_size() +
|
||||
CREATE_FILE_HEADER_LEN + 1; // 1 for \0 terminating fname
|
||||
if (len < block_offset)
|
||||
return;
|
||||
block = (char*)buf + block_offset;
|
||||
block_len = len - block_offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
sql_ex.force_new_format();
|
||||
inited_from_old = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1568,6 +1586,7 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli)
|
|||
int expected_error,actual_error = 0;
|
||||
init_sql_alloc(&thd->mem_root, 8192,0);
|
||||
thd->db = rewrite_db((char*)db);
|
||||
DBUG_ASSERT(q_len == strlen(query));
|
||||
if (db_ok(thd->db, replicate_do_db, replicate_ignore_db))
|
||||
{
|
||||
thd->query = (char*)query;
|
||||
|
@ -1739,11 +1758,12 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli)
|
|||
|
||||
int Start_log_event::exec_event(struct st_relay_log_info* rli)
|
||||
{
|
||||
close_temporary_tables(thd);
|
||||
// if we have old format, load_tmpdir is cleaned up by the I/O thread
|
||||
// TODO: cleanup_load_tmpdir() needs to remove only the files associated
|
||||
// with the server id that has just started
|
||||
if (!rli->mi->old_format)
|
||||
{
|
||||
close_temporary_tables(thd);
|
||||
cleanup_load_tmpdir();
|
||||
}
|
||||
return Log_event::exec_event(rli);
|
||||
}
|
||||
|
||||
|
|
|
@ -64,6 +64,8 @@ struct old_sql_ex
|
|||
char empty_flags;
|
||||
};
|
||||
|
||||
#define NUM_LOAD_DELIM_STRS 5
|
||||
|
||||
|
||||
struct sql_ex_info
|
||||
{
|
||||
|
@ -153,8 +155,8 @@ struct sql_ex_info
|
|||
#define L_THREAD_ID_OFFSET 0
|
||||
#define L_EXEC_TIME_OFFSET 4
|
||||
#define L_SKIP_LINES_OFFSET 8
|
||||
#define L_DB_LEN_OFFSET 12
|
||||
#define L_TBL_LEN_OFFSET 13
|
||||
#define L_TBL_LEN_OFFSET 12
|
||||
#define L_DB_LEN_OFFSET 13
|
||||
#define L_NUM_FIELDS_OFFSET 14
|
||||
#define L_SQL_EX_OFFSET 18
|
||||
#define L_DATA_OFFSET LOAD_HEADER_LEN
|
||||
|
@ -570,6 +572,7 @@ public:
|
|||
char* block;
|
||||
uint block_len;
|
||||
uint file_id;
|
||||
bool inited_from_old;
|
||||
#ifndef MYSQL_CLIENT
|
||||
Create_file_log_event(THD* thd, sql_exchange* ex, const char* db_arg,
|
||||
const char* table_name_arg,
|
||||
|
@ -578,7 +581,7 @@ public:
|
|||
char* block_arg, uint block_len_arg);
|
||||
#endif
|
||||
|
||||
Create_file_log_event(const char* buf, int event_len);
|
||||
Create_file_log_event(const char* buf, int event_len, bool old_format);
|
||||
~Create_file_log_event()
|
||||
{
|
||||
}
|
||||
|
@ -591,7 +594,7 @@ public:
|
|||
4 + 1 + block_len;}
|
||||
int get_data_body_offset() { return fake_base ? LOAD_EVENT_OVERHEAD:
|
||||
LOAD_EVENT_OVERHEAD + CREATE_FILE_HEADER_LEN; }
|
||||
bool is_valid() { return block != 0; }
|
||||
bool is_valid() { return inited_from_old || block != 0; }
|
||||
int write_data_header(IO_CACHE* file);
|
||||
int write_data_body(IO_CACHE* file);
|
||||
int write_base(IO_CACHE* file); // cut out Create_file extentions and
|
||||
|
|
|
@ -48,6 +48,7 @@ char *sql_strmake(const char *str,uint len);
|
|||
gptr sql_memdup(const void * ptr,unsigned size);
|
||||
void sql_element_free(void *ptr);
|
||||
void kill_one_thread(THD *thd, ulong id);
|
||||
int net_request_file(NET* net, const char* fname);
|
||||
char* query_table_status(THD *thd,const char *db,const char *table_name);
|
||||
|
||||
#define x_free(A) { my_free((gptr) (A),MYF(MY_WME | MY_FAE | MY_ALLOW_ZERO_PTR)); }
|
||||
|
@ -586,7 +587,8 @@ extern char f_fyllchar;
|
|||
extern ulong ha_read_count, ha_write_count, ha_delete_count, ha_update_count,
|
||||
ha_read_key_count, ha_read_next_count, ha_read_prev_count,
|
||||
ha_read_first_count, ha_read_last_count,
|
||||
ha_read_rnd_count, ha_read_rnd_next_count;
|
||||
ha_read_rnd_count, ha_read_rnd_next_count,
|
||||
ha_commit_count, ha_rollback_count;
|
||||
extern MY_BITMAP temp_pool;
|
||||
extern uchar *days_in_month;
|
||||
extern DATE_FORMAT dayord;
|
||||
|
|
|
@ -3068,7 +3068,7 @@ struct show_var_st init_vars[]= {
|
|||
{"log_update", (char*) &opt_update_log, SHOW_BOOL},
|
||||
{"log_bin", (char*) &opt_bin_log, SHOW_BOOL},
|
||||
{"log_slave_updates", (char*) &opt_log_slave_updates, SHOW_BOOL},
|
||||
{"log_long_queries", (char*) &opt_slow_log, SHOW_BOOL},
|
||||
{"log_slow_queries", (char*) &opt_slow_log, SHOW_BOOL},
|
||||
{"long_query_time", (char*) &long_query_time, SHOW_LONG},
|
||||
{"low_priority_updates", (char*) &low_priority_updates, SHOW_BOOL},
|
||||
{"lower_case_table_names", (char*) &lower_case_table_names, SHOW_LONG},
|
||||
|
@ -3211,6 +3211,7 @@ struct show_var_st status_vars[]= {
|
|||
{"Delayed_writes", (char*) &delayed_insert_writes, SHOW_LONG},
|
||||
{"Delayed_errors", (char*) &delayed_insert_errors, SHOW_LONG},
|
||||
{"Flush_commands", (char*) &refresh_version, SHOW_LONG_CONST},
|
||||
{"Handler_commit", (char*) &ha_commit_count, SHOW_LONG},
|
||||
{"Handler_delete", (char*) &ha_delete_count, SHOW_LONG},
|
||||
{"Handler_read_first", (char*) &ha_read_first_count, SHOW_LONG},
|
||||
{"Handler_read_key", (char*) &ha_read_key_count, SHOW_LONG},
|
||||
|
@ -3218,6 +3219,7 @@ struct show_var_st status_vars[]= {
|
|||
{"Handler_read_prev", (char*) &ha_read_prev_count, SHOW_LONG},
|
||||
{"Handler_read_rnd", (char*) &ha_read_rnd_count, SHOW_LONG},
|
||||
{"Handler_read_rnd_next", (char*) &ha_read_rnd_next_count, SHOW_LONG},
|
||||
{"Handler_rollback", (char*) &ha_rollback_count, SHOW_LONG},
|
||||
{"Handler_update", (char*) &ha_update_count, SHOW_LONG},
|
||||
{"Handler_write", (char*) &ha_write_count, SHOW_LONG},
|
||||
{"Key_blocks_used", (char*) &_my_blocks_used, SHOW_LONG_CONST},
|
||||
|
|
|
@ -814,3 +814,14 @@ my_net_read(NET *net)
|
|||
#endif /* HAVE_COMPRESS */
|
||||
return len;
|
||||
}
|
||||
|
||||
int net_request_file(NET* net, const char* fname)
|
||||
{
|
||||
char tmp [FN_REFLEN+1],*end;
|
||||
DBUG_ENTER("net_request_file");
|
||||
tmp[0] = (char) 251; /* NULL_LENGTH */
|
||||
end=strnmov(tmp+1,fname,sizeof(tmp)-2);
|
||||
DBUG_RETURN(my_net_write(net,tmp,(uint) (end-tmp)) ||
|
||||
net_flush(net));
|
||||
}
|
||||
|
||||
|
|
|
@ -828,6 +828,7 @@ int load_master_data(THD* thd)
|
|||
active_mi->rli.master_log_pos = active_mi->master_log_pos;
|
||||
strnmov(active_mi->rli.master_log_name,active_mi->master_log_name,
|
||||
sizeof(active_mi->rli.master_log_name));
|
||||
flush_relay_log_info(&active_mi->rli);
|
||||
pthread_cond_broadcast(&active_mi->rli.data_cond);
|
||||
pthread_mutex_unlock(&active_mi->rli.data_lock);
|
||||
thd->proc_info = "starting slave";
|
||||
|
|
148
sql/slave.cc
148
sql/slave.cc
|
@ -55,6 +55,7 @@ typedef enum { SLAVE_THD_IO, SLAVE_THD_SQL} SLAVE_THD_TYPE;
|
|||
|
||||
void skip_load_data_infile(NET* net);
|
||||
static int process_io_rotate(MASTER_INFO* mi, Rotate_log_event* rev);
|
||||
static int process_io_create_file(MASTER_INFO* mi, Create_file_log_event* cev);
|
||||
static int queue_old_event(MASTER_INFO* mi, const char* buf,
|
||||
uint event_len);
|
||||
static inline bool slave_killed(THD* thd,MASTER_INFO* mi);
|
||||
|
@ -654,7 +655,7 @@ char* rewrite_db(char* db)
|
|||
int db_ok(const char* db, I_List<i_string> &do_list,
|
||||
I_List<i_string> &ignore_list )
|
||||
{
|
||||
if(do_list.is_empty() && ignore_list.is_empty())
|
||||
if (do_list.is_empty() && ignore_list.is_empty())
|
||||
return 1; // ok to replicate if the user puts no constraints
|
||||
|
||||
// if the user has specified restrictions on which databases to replicate
|
||||
|
@ -1058,6 +1059,8 @@ int init_master_info(MASTER_INFO* mi, const char* master_info_fname,
|
|||
if (init_relay_log_info(&mi->rli, slave_info_fname))
|
||||
return 1;
|
||||
mi->rli.mi = mi;
|
||||
mi->mysql=0;
|
||||
mi->file_id=1;
|
||||
mi->ignore_stop_event=0;
|
||||
int fd,error;
|
||||
MY_STAT stat_area;
|
||||
|
@ -1535,10 +1538,6 @@ static int exec_relay_log_event(THD* thd, RELAY_LOG_INFO* rli)
|
|||
if (ev->server_id == ::server_id ||
|
||||
(rli->slave_skip_counter && type_code != ROTATE_EVENT))
|
||||
{
|
||||
/*
|
||||
TODO: I/O thread must handle skipping file delivery for
|
||||
old load data infile events
|
||||
*/
|
||||
/* TODO: I/O thread should not even log events with the same server id */
|
||||
rli->inc_pos(ev->get_event_len(),
|
||||
type_code != STOP_EVENT ? ev->log_pos : LL(0),
|
||||
|
@ -1621,7 +1620,7 @@ slave_begin:
|
|||
DBUG_PRINT("info",("master info: log_file_name=%s, position=%s",
|
||||
mi->master_log_name, llstr(mi->master_log_pos,llbuff)));
|
||||
|
||||
if (!(mysql = mc_mysql_init(NULL)))
|
||||
if (!(mi->mysql = mysql = mc_mysql_init(NULL)))
|
||||
{
|
||||
sql_print_error("Slave I/O thread: error in mc_mysql_init()");
|
||||
goto err;
|
||||
|
@ -1780,8 +1779,11 @@ err:
|
|||
sql_print_error("Slave I/O thread exiting, read up to log '%s', position %s",
|
||||
IO_RPL_LOG_NAME, llstr(mi->master_log_pos,llbuff));
|
||||
thd->query = thd->db = 0; // extra safety
|
||||
if(mysql)
|
||||
if (mysql)
|
||||
{
|
||||
mc_mysql_close(mysql);
|
||||
mi->mysql=0;
|
||||
}
|
||||
thd->proc_info = "Waiting for slave mutex on exit";
|
||||
pthread_mutex_lock(&mi->run_lock);
|
||||
mi->slave_running = 0;
|
||||
|
@ -1790,7 +1792,7 @@ err:
|
|||
change_rpl_status(RPL_ACTIVE_SLAVE,RPL_IDLE_SLAVE);
|
||||
mi->abort_slave = 0; // TODO: check if this is needed
|
||||
DBUG_ASSERT(thd->net.buff != 0);
|
||||
net_end(&thd->net); // destructor will not free it, because we are weird
|
||||
net_end(&thd->net); // destructor will not free it, because net.vio is 0
|
||||
pthread_mutex_lock(&LOCK_thread_count);
|
||||
delete thd;
|
||||
pthread_mutex_unlock(&LOCK_thread_count);
|
||||
|
@ -1926,11 +1928,101 @@ the slave SQL thread with \"SLAVE START\". We stopped at log \
|
|||
DBUG_RETURN(0); // Can't return anything here
|
||||
}
|
||||
|
||||
static int process_io_create_file(MASTER_INFO* mi, Create_file_log_event* cev)
|
||||
{
|
||||
int error = 1;
|
||||
ulong num_bytes;
|
||||
bool cev_not_written;
|
||||
THD* thd;
|
||||
NET* net = &mi->mysql->net;
|
||||
|
||||
if (unlikely(!cev->is_valid()))
|
||||
return 1;
|
||||
/*
|
||||
TODO: fix to honor table rules, not only db rules
|
||||
*/
|
||||
if (!db_ok(cev->db, replicate_do_db, replicate_ignore_db))
|
||||
{
|
||||
skip_load_data_infile(net);
|
||||
return 0;
|
||||
}
|
||||
DBUG_ASSERT(cev->inited_from_old);
|
||||
thd = mi->io_thd;
|
||||
thd->file_id = cev->file_id = mi->file_id++;
|
||||
thd->server_id = cev->server_id;
|
||||
cev_not_written = 1;
|
||||
|
||||
if (unlikely(net_request_file(net,cev->fname)))
|
||||
{
|
||||
sql_print_error("Slave I/O: failed requesting download of '%s'",
|
||||
cev->fname);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* this dummy block is so we could insantiate Append_block_log_event
|
||||
once and then modify it slightly instead of doing it multiple times
|
||||
in the loop
|
||||
*/
|
||||
{
|
||||
Append_block_log_event aev(thd,0,0);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (unlikely((num_bytes=my_net_read(net)) == packet_error))
|
||||
{
|
||||
sql_print_error("Network read error downloading '%s' from master",
|
||||
cev->fname);
|
||||
goto err;
|
||||
}
|
||||
if (unlikely(!num_bytes)) /* eof */
|
||||
{
|
||||
send_ok(net); /* 3.23 master wants it */
|
||||
Execute_load_log_event xev(thd);
|
||||
xev.log_pos = mi->master_log_pos;
|
||||
if (unlikely(mi->rli.relay_log.append(&xev)))
|
||||
{
|
||||
sql_print_error("Slave I/O: error writing Exec_load event to \
|
||||
relay log");
|
||||
goto err;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (unlikely(cev_not_written))
|
||||
{
|
||||
cev->block = (char*)net->read_pos;
|
||||
cev->block_len = num_bytes;
|
||||
cev->log_pos = mi->master_log_pos;
|
||||
if (unlikely(mi->rli.relay_log.append(cev)))
|
||||
{
|
||||
sql_print_error("Slave I/O: error writing Create_file event to \
|
||||
relay log");
|
||||
goto err;
|
||||
}
|
||||
cev_not_written=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
aev.block = (char*)net->read_pos;
|
||||
aev.block_len = num_bytes;
|
||||
aev.log_pos = mi->master_log_pos;
|
||||
if (unlikely(mi->rli.relay_log.append(&aev)))
|
||||
{
|
||||
sql_print_error("Slave I/O: error writing Append_block event to \
|
||||
relay log");
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
error=0;
|
||||
err:
|
||||
return error;
|
||||
}
|
||||
|
||||
// We assume we already locked mi->data_lock
|
||||
static int process_io_rotate(MASTER_INFO* mi, Rotate_log_event* rev)
|
||||
{
|
||||
if (!rev->is_valid())
|
||||
if (unlikely(!rev->is_valid()))
|
||||
return 1;
|
||||
DBUG_ASSERT(rev->ident_len<sizeof(mi->master_log_name));
|
||||
memcpy(mi->master_log_name,rev->new_log_ident,
|
||||
|
@ -1961,6 +2053,21 @@ static int queue_old_event(MASTER_INFO *mi, const char *buf,
|
|||
const char *errmsg = 0;
|
||||
bool inc_pos = 1;
|
||||
bool processed_stop_event = 0;
|
||||
char* tmp_buf = 0;
|
||||
/* if we get Load event, we need to pass a non-reusable buffer
|
||||
to read_log_event, so we do a trick
|
||||
*/
|
||||
if (buf[EVENT_TYPE_OFFSET] == LOAD_EVENT)
|
||||
{
|
||||
if (unlikely(!(tmp_buf=(char*)my_malloc(event_len+1,MYF(MY_WME)))))
|
||||
{
|
||||
sql_print_error("Slave I/O: out of memory for Load event");
|
||||
return 1;
|
||||
}
|
||||
memcpy(tmp_buf,buf,event_len);
|
||||
tmp_buf[event_len]=0; // Create_file constructor wants null-term buffer
|
||||
buf = (const char*)tmp_buf;
|
||||
}
|
||||
Log_event *ev = Log_event::read_log_event(buf,event_len, &errmsg,
|
||||
1 /*old format*/ );
|
||||
if (unlikely(!ev))
|
||||
|
@ -1968,6 +2075,7 @@ static int queue_old_event(MASTER_INFO *mi, const char *buf,
|
|||
sql_print_error("Read invalid event from master: '%s',\
|
||||
master could be corrupt but a more likely cause of this is a bug",
|
||||
errmsg);
|
||||
my_free((char*)tmp_buf, MYF(MY_ALLOW_ZERO_PTR));
|
||||
return 1;
|
||||
}
|
||||
pthread_mutex_lock(&mi->data_lock);
|
||||
|
@ -1978,6 +2086,7 @@ static int queue_old_event(MASTER_INFO *mi, const char *buf,
|
|||
{
|
||||
delete ev;
|
||||
pthread_mutex_unlock(&mi->data_lock);
|
||||
DBUG_ASSERT(!tmp_buf);
|
||||
return 1;
|
||||
}
|
||||
mi->ignore_stop_event=1;
|
||||
|
@ -1986,12 +2095,16 @@ static int queue_old_event(MASTER_INFO *mi, const char *buf,
|
|||
case STOP_EVENT:
|
||||
processed_stop_event=1;
|
||||
break;
|
||||
case LOAD_EVENT:
|
||||
// TODO: actually process it
|
||||
mi->master_log_pos += event_len;
|
||||
case CREATE_FILE_EVENT:
|
||||
{
|
||||
int error = process_io_create_file(mi,(Create_file_log_event*)ev);
|
||||
delete ev;
|
||||
mi->master_log_pos += event_len;
|
||||
pthread_mutex_unlock(&mi->data_lock);
|
||||
return 0;
|
||||
DBUG_ASSERT(tmp_buf);
|
||||
my_free((char*)tmp_buf, MYF(0));
|
||||
return error;
|
||||
}
|
||||
default:
|
||||
mi->ignore_stop_event=0;
|
||||
break;
|
||||
|
@ -2002,6 +2115,7 @@ static int queue_old_event(MASTER_INFO *mi, const char *buf,
|
|||
{
|
||||
delete ev;
|
||||
pthread_mutex_unlock(&mi->data_lock);
|
||||
DBUG_ASSERT(!tmp_buf);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
@ -2011,6 +2125,7 @@ static int queue_old_event(MASTER_INFO *mi, const char *buf,
|
|||
if (unlikely(processed_stop_event))
|
||||
mi->ignore_stop_event=1;
|
||||
pthread_mutex_unlock(&mi->data_lock);
|
||||
DBUG_ASSERT(!tmp_buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -2173,7 +2288,7 @@ static int safe_reconnect(THD* thd, MYSQL* mysql, MASTER_INFO* mi)
|
|||
|
||||
int flush_relay_log_info(RELAY_LOG_INFO* rli)
|
||||
{
|
||||
IO_CACHE* file = &rli->info_file;
|
||||
register IO_CACHE* file = &rli->info_file;
|
||||
char lbuf[22],lbuf1[22];
|
||||
|
||||
my_b_seek(file, 0L);
|
||||
|
@ -2251,7 +2366,10 @@ Log_event* next_event(RELAY_LOG_INFO* rli)
|
|||
}
|
||||
DBUG_ASSERT(my_b_tell(cur_log) >= 4);
|
||||
DBUG_ASSERT(my_b_tell(cur_log) == rli->relay_log_pos + rli->pending);
|
||||
if ((ev=Log_event::read_log_event(cur_log,0,rli->mi->old_format)))
|
||||
/* relay log is always in new format - if the master is 3.23, the
|
||||
I/O thread will convert the format for us
|
||||
*/
|
||||
if ((ev=Log_event::read_log_event(cur_log,0,(bool)0/*new format*/)))
|
||||
{
|
||||
DBUG_ASSERT(thd==rli->sql_thd);
|
||||
if (hot_log)
|
||||
|
|
|
@ -254,6 +254,8 @@ typedef struct st_master_info
|
|||
pthread_mutex_t data_lock,run_lock;
|
||||
pthread_cond_t data_cond,start_cond,stop_cond;
|
||||
THD *io_thd;
|
||||
MYSQL* mysql;
|
||||
uint32 file_id; // for 3.23 load data infile
|
||||
RELAY_LOG_INFO rli;
|
||||
uint port;
|
||||
uint connect_retry;
|
||||
|
|
|
@ -708,11 +708,11 @@ TABLE *reopen_name_locked_table(THD* thd, TABLE_LIST* table_list)
|
|||
if (open_unireg_entry(thd, table, db, table_name, table_name, 1) ||
|
||||
!(table->table_cache_key =memdup_root(&table->mem_root,(char*) key,
|
||||
key_length)))
|
||||
{
|
||||
closefrm(table);
|
||||
pthread_mutex_unlock(&LOCK_open);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
{
|
||||
closefrm(table);
|
||||
pthread_mutex_unlock(&LOCK_open);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
table->key_length=key_length;
|
||||
table->version=0;
|
||||
|
|
|
@ -136,12 +136,12 @@ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0),
|
|||
|
||||
/* Initialize sub structures */
|
||||
bzero((char*) &mem_root,sizeof(mem_root));
|
||||
user_connect=(UC *)0;
|
||||
hash_init(&user_vars, USER_VARS_HASH_SIZE, 0, 0,
|
||||
(hash_get_key) get_var_key,
|
||||
(void (*)(void*)) free_var,0);
|
||||
#ifdef USING_TRANSACTIONS
|
||||
bzero((char*) &transaction,sizeof(transaction));
|
||||
user_connect=(UC *)0;
|
||||
if (opt_using_transactions)
|
||||
{
|
||||
if (open_cached_file(&transaction.trans_log,
|
||||
|
|
|
@ -147,12 +147,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
|
|||
|
||||
if (read_file_from_client && (thd->client_capabilities & CLIENT_LOCAL_FILES))
|
||||
{
|
||||
char tmp [FN_REFLEN+1],*end;
|
||||
DBUG_PRINT("info",("reading local file"));
|
||||
tmp[0] = (char) 251; /* NULL_LENGTH */
|
||||
end=strnmov(tmp+1,ex->file_name,sizeof(tmp)-2);
|
||||
(void) my_net_write(&thd->net,tmp,(uint) (end-tmp));
|
||||
(void) net_flush(&thd->net);
|
||||
(void)net_request_file(&thd->net,ex->file_name);
|
||||
file = -1;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -233,8 +233,7 @@ static bool check_user(THD *thd,enum_server_command command, const char *user,
|
|||
db ? db : (char*) "");
|
||||
thd->db_access=0;
|
||||
/* Don't allow user to connect if he has done too many queries */
|
||||
if ((max_questions || max_user_connections) &&
|
||||
get_or_create_user_conn(thd,user,thd->host_or_ip,max_questions))
|
||||
if ((max_questions || max_user_connections) && get_or_create_user_conn(thd,user,thd->host_or_ip,max_questions))
|
||||
return -1;
|
||||
if (max_user_connections && thd->user_connect &&
|
||||
check_for_max_user_connections(thd->user_connect))
|
||||
|
|
|
@ -2929,17 +2929,17 @@ return_zero_rows(select_result *result,TABLE_LIST *tables,List<Item> &fields,
|
|||
if (having && having->val_int() == 0)
|
||||
send_row=0;
|
||||
}
|
||||
if (!tables || !(result->send_fields(fields,1)))
|
||||
if (!(result->send_fields(fields,1)))
|
||||
{
|
||||
if (send_row)
|
||||
result->send_data(fields);
|
||||
if (tables) // Not from do_select()
|
||||
if (tables) // Not from do_select()
|
||||
{
|
||||
/* Close open cursors */
|
||||
for (TABLE_LIST *table=tables; table ; table=table->next)
|
||||
table->table->file->index_end();
|
||||
result->send_eof(); // Should be safe
|
||||
}
|
||||
result->send_eof(); // Should be safe
|
||||
}
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
@ -4877,8 +4877,10 @@ end_send(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
|
|||
{
|
||||
JOIN_TAB *jt=join->join_tab;
|
||||
if ((join->tables == 1) && !join->tmp_table && !join->sort_and_group
|
||||
&& !join->send_group_parts && !join->having && !jt->select_cond)
|
||||
&& !join->send_group_parts && !join->having && !jt->select_cond &&
|
||||
!(jt->table->file->option_flag() & HA_NOT_EXACT_COUNT))
|
||||
{
|
||||
/* Join over all rows in table; Return number of found rows */
|
||||
join->select_options ^= OPTION_FOUND_ROWS;
|
||||
join->send_records = jt->records;
|
||||
}
|
||||
|
@ -5603,6 +5605,7 @@ create_sort_index(JOIN_TAB *tab,ORDER *order,ha_rows select_limit)
|
|||
table->file->info(HA_STATUS_VARIABLE); // Get record count
|
||||
table->found_records=filesort(table,sortorder,length,
|
||||
select, 0L, select_limit, &examined_rows);
|
||||
tab->records=table->found_records; // For SQL_CALC_ROWS
|
||||
delete select; // filesort did select
|
||||
tab->select=0;
|
||||
tab->select_cond=0;
|
||||
|
|
|
@ -911,6 +911,11 @@ static int prepare_for_restore(THD* thd, TABLE_LIST* table)
|
|||
"Failed generating table from .frm file"));
|
||||
}
|
||||
}
|
||||
|
||||
// now we should be able to open the partially restored table
|
||||
// to finish the restore in the handler later on
|
||||
if (!(table->table = reopen_name_locked_table(thd, table)))
|
||||
unlock_table_name(thd, table);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
|
@ -919,8 +924,9 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables,
|
|||
HA_CHECK_OPT* check_opt,
|
||||
const char *operator_name,
|
||||
thr_lock_type lock_type,
|
||||
bool open_for_modify, bool restore,
|
||||
bool open_for_modify,
|
||||
uint extra_open_options,
|
||||
int (*prepare_func)(THD *, TABLE_LIST *),
|
||||
int (handler::*operator_func)
|
||||
(THD *, HA_CHECK_OPT *))
|
||||
{
|
||||
|
@ -952,18 +958,13 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables,
|
|||
table->table = open_ltable(thd, table, lock_type);
|
||||
thd->open_options&= ~extra_open_options;
|
||||
packet->length(0);
|
||||
if (restore)
|
||||
if (prepare_func)
|
||||
{
|
||||
switch (prepare_for_restore(thd, table)) {
|
||||
case 1: continue; // error, message written to net
|
||||
case -1: goto err; // error, message could be written to net
|
||||
default: ;// should be 0 otherwise
|
||||
switch ((*prepare_func)(thd, table)) {
|
||||
case 1: continue; // error, message written to net
|
||||
case -1: goto err; // error, message could be written to net
|
||||
default: ; // should be 0 otherwise
|
||||
}
|
||||
|
||||
// now we should be able to open the partially restored table
|
||||
// to finish the restore in the handler later on
|
||||
if (!(table->table = reopen_name_locked_table(thd, table)))
|
||||
unlock_table_name(thd, table);
|
||||
}
|
||||
|
||||
if (!table->table)
|
||||
|
@ -1096,7 +1097,8 @@ int mysql_restore_table(THD* thd, TABLE_LIST* table_list)
|
|||
{
|
||||
DBUG_ENTER("mysql_restore_table");
|
||||
DBUG_RETURN(mysql_admin_table(thd, table_list, 0,
|
||||
"restore", TL_WRITE, 1, 1,0,
|
||||
"restore", TL_WRITE, 1, 0,
|
||||
&prepare_for_restore,
|
||||
&handler::restore));
|
||||
}
|
||||
|
||||
|
@ -1104,7 +1106,7 @@ int mysql_repair_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt)
|
|||
{
|
||||
DBUG_ENTER("mysql_repair_table");
|
||||
DBUG_RETURN(mysql_admin_table(thd, tables, check_opt,
|
||||
"repair", TL_WRITE, 1, 0, HA_OPEN_FOR_REPAIR,
|
||||
"repair", TL_WRITE, 1, HA_OPEN_FOR_REPAIR, 0,
|
||||
&handler::repair));
|
||||
}
|
||||
|
||||
|
@ -1143,7 +1145,7 @@ int mysql_check_table(THD* thd, TABLE_LIST* tables,HA_CHECK_OPT* check_opt)
|
|||
DBUG_ENTER("mysql_check_table");
|
||||
DBUG_RETURN(mysql_admin_table(thd, tables, check_opt,
|
||||
"check", lock_type,
|
||||
0, 0, HA_OPEN_FOR_REPAIR,
|
||||
0, HA_OPEN_FOR_REPAIR, 0,
|
||||
&handler::check));
|
||||
}
|
||||
|
||||
|
@ -1157,7 +1159,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
|||
ORDER *order,
|
||||
bool drop_primary,
|
||||
enum enum_duplicates handle_duplicates,
|
||||
enum enum_enable_or_disable keys_onoff,
|
||||
enum enum_enable_or_disable keys_onoff,
|
||||
bool simple_alter)
|
||||
{
|
||||
TABLE *table,*new_table;
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
# MySQL.
|
||||
#
|
||||
# You can copy this file to
|
||||
# /etc/mf.cnf to set global options,
|
||||
# /etc/my.cnf to set global options,
|
||||
# mysql-data-dir/my.cnf to set server-specific options (in this
|
||||
# installation this directory is @localstatedir@) or
|
||||
# ~/.my.cnf to set user-specific options.
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
# MySQL.
|
||||
#
|
||||
# You can copy this file to
|
||||
# /etc/mf.cnf to set global options,
|
||||
# /etc/my.cnf to set global options,
|
||||
# mysql-data-dir/my.cnf to set server-specific options (in this
|
||||
# installation this directory is @localstatedir@) or
|
||||
# ~/.my.cnf to set user-specific options.
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
# other programs (like a web server)
|
||||
#
|
||||
# You can copy this file to
|
||||
# /etc/mf.cnf to set global options,
|
||||
# /etc/my.cnf to set global options,
|
||||
# mysql-data-dir/my.cnf to set server-specific options (in this
|
||||
# installation this directory is @localstatedir@) or
|
||||
# ~/.my.cnf to set user-specific options.
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
# doesn't use much resources.
|
||||
#
|
||||
# You can copy this file to
|
||||
# /etc/mf.cnf to set global options,
|
||||
# /etc/my.cnf to set global options,
|
||||
# mysql-data-dir/my.cnf to set server-specific options (in this
|
||||
# installation this directory is @localstatedir@) or
|
||||
# ~/.my.cnf to set user-specific options.
|
||||
|
|
Loading…
Add table
Reference in a new issue