manually merged
This commit is contained in:
commit
a04fc26c54
@ -1,5 +1,16 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ "$BK_USER" = "Administrator" -o "$BK_USER" = "mysqldev" ]
|
||||
then
|
||||
echo "Error: you cannot checkin as 'Administrator' or 'mysqldev' user."
|
||||
echo "as a workaround set BK_USER to your nickname"
|
||||
echo "e.g.: export BK_USER='bar'"
|
||||
echo ""
|
||||
echo "Checkin FAILED!"
|
||||
echo "Set BK_USER and retry."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ `tail -c1 $BK_FILE` ]
|
||||
then
|
||||
echo "File $BK_FILE does not end with a new-line character!"
|
||||
|
@ -49,4 +49,5 @@ enum options_client
|
||||
#ifdef HAVE_NDBCLUSTER_DB
|
||||
,OPT_NDBCLUSTER,OPT_NDB_CONNECTSTRING
|
||||
#endif
|
||||
,OPT_IGNORE_TABLE
|
||||
};
|
||||
|
@ -43,6 +43,7 @@
|
||||
#include <my_sys.h>
|
||||
#include <m_string.h>
|
||||
#include <m_ctype.h>
|
||||
#include <hash.h>
|
||||
|
||||
#include "client_priv.h"
|
||||
#include "mysql.h"
|
||||
@ -130,6 +131,15 @@ const char *compatible_mode_names[]=
|
||||
TYPELIB compatible_mode_typelib= {array_elements(compatible_mode_names) - 1,
|
||||
"", compatible_mode_names, NULL};
|
||||
|
||||
#define TABLE_RULE_HASH_SIZE 16
|
||||
|
||||
typedef struct st_table_rule_ent
|
||||
{
|
||||
char* key; /* dbname.tablename */
|
||||
uint key_len;
|
||||
} TABLE_RULE_ENT;
|
||||
|
||||
HASH ignore_table;
|
||||
|
||||
static struct my_option my_long_options[] =
|
||||
{
|
||||
@ -235,6 +245,11 @@ static struct my_option my_long_options[] =
|
||||
(gptr*) &opt_hex_blob, (gptr*) &opt_hex_blob, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
|
||||
{"host", 'h', "Connect to host.", (gptr*) ¤t_host,
|
||||
(gptr*) ¤t_host, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
||||
{"ignore-table", OPT_IGNORE_TABLE,
|
||||
"Do not dump the specified table. To specify more than one table to ignore, "
|
||||
"use the directive multiple times, once for each table. Each table must "
|
||||
"be specified with both database and table names, e.g. --ignore-table=database.table",
|
||||
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
||||
{"lines-terminated-by", OPT_LTB, "Lines in the i.file are terminated by ...",
|
||||
(gptr*) &lines_terminated, (gptr*) &lines_terminated, 0, GET_STR,
|
||||
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
||||
@ -506,6 +521,28 @@ static void write_footer(FILE *sql_file)
|
||||
} /* write_footer */
|
||||
|
||||
|
||||
static void free_table_ent(TABLE_RULE_ENT* e)
|
||||
{
|
||||
my_free((gptr) e, MYF(0));
|
||||
}
|
||||
|
||||
|
||||
static byte* get_table_key(TABLE_RULE_ENT* e, uint* len,
|
||||
my_bool not_used __attribute__((unused)))
|
||||
{
|
||||
*len= e->key_len;
|
||||
return (byte*)e->key;
|
||||
}
|
||||
|
||||
|
||||
void init_table_rule_hash(HASH* h)
|
||||
{
|
||||
if(hash_init(h, charset_info, TABLE_RULE_HASH_SIZE, 0, 0,
|
||||
(hash_get_key) get_table_key,
|
||||
(hash_free_key) free_table_ent, 0))
|
||||
exit(EX_EOM);
|
||||
}
|
||||
|
||||
|
||||
static my_bool
|
||||
get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
|
||||
@ -577,8 +614,32 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
|
||||
case (int) OPT_TABLES:
|
||||
opt_databases=0;
|
||||
break;
|
||||
case (int) OPT_IGNORE_TABLE:
|
||||
{
|
||||
uint len= (uint)strlen(argument);
|
||||
TABLE_RULE_ENT* e;
|
||||
if (!strchr(argument, '.'))
|
||||
{
|
||||
fprintf(stderr, "Illegal use of option --ignore-table=<database>.<table>\n");
|
||||
exit(1);
|
||||
}
|
||||
/* len is always > 0 because we know the there exists a '.' */
|
||||
e= (TABLE_RULE_ENT*)my_malloc(sizeof(TABLE_RULE_ENT) + len, MYF(MY_WME));
|
||||
if (!e)
|
||||
exit(EX_EOM);
|
||||
e->key= (char*)e + sizeof(TABLE_RULE_ENT);
|
||||
e->key_len= len;
|
||||
memcpy(e->key, argument, len);
|
||||
|
||||
if (!hash_inited(&ignore_table))
|
||||
init_table_rule_hash(&ignore_table);
|
||||
|
||||
if(my_hash_insert(&ignore_table, (byte*)e))
|
||||
exit(EX_EOM);
|
||||
break;
|
||||
}
|
||||
case (int) OPT_COMPATIBLE:
|
||||
{
|
||||
{
|
||||
char buff[255];
|
||||
char *end= compatible_mode_normal_str;
|
||||
int i;
|
||||
@ -617,6 +678,12 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
|
||||
}
|
||||
if (end!=compatible_mode_normal_str)
|
||||
end[-1]= 0;
|
||||
/*
|
||||
Set charset to the default compiled value if it hasn't
|
||||
been reset yet by --default-character-set=xxx.
|
||||
*/
|
||||
if (default_charset == (char*) MYSQL_UNIVERSAL_CLIENT_CHARSET)
|
||||
default_charset= (char*) MYSQL_DEFAULT_CHARSET_NAME;
|
||||
break;
|
||||
}
|
||||
case (int) OPT_MYSQL_PROTOCOL:
|
||||
@ -1991,6 +2058,14 @@ static int init_dumping(char *database)
|
||||
} /* init_dumping */
|
||||
|
||||
|
||||
my_bool include_table(byte* hash_key, uint len)
|
||||
{
|
||||
if (hash_search(&ignore_table, (byte*) hash_key, len))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static int dump_all_tables_in_db(char *database)
|
||||
{
|
||||
@ -1998,6 +2073,12 @@ static int dump_all_tables_in_db(char *database)
|
||||
uint numrows;
|
||||
char table_buff[NAME_LEN*2+3];
|
||||
|
||||
char hash_key[2*NAME_LEN+2]; /* "db.tablename" */
|
||||
char *afterdot;
|
||||
|
||||
afterdot= strmov(hash_key, database);
|
||||
*afterdot++= '.';
|
||||
|
||||
if (init_dumping(database))
|
||||
return 1;
|
||||
if (opt_xml)
|
||||
@ -2006,7 +2087,7 @@ static int dump_all_tables_in_db(char *database)
|
||||
{
|
||||
DYNAMIC_STRING query;
|
||||
init_dynamic_string(&query, "LOCK TABLES ", 256, 1024);
|
||||
for (numrows=0 ; (table = getTableName(1)) ; numrows++)
|
||||
for (numrows= 0 ; (table= getTableName(1)) ; numrows++)
|
||||
{
|
||||
dynstr_append(&query, quote_name(table, table_buff, 1));
|
||||
dynstr_append(&query, " READ /*!32311 LOCAL */,");
|
||||
@ -2022,13 +2103,17 @@ static int dump_all_tables_in_db(char *database)
|
||||
DBerror(sock, "when doing refresh");
|
||||
/* We shall continue here, if --force was given */
|
||||
}
|
||||
while ((table = getTableName(0)))
|
||||
while ((table= getTableName(0)))
|
||||
{
|
||||
numrows = getTableStructure(table, database);
|
||||
if (!dFlag && numrows > 0)
|
||||
dumpTable(numrows,table);
|
||||
my_free(order_by, MYF(MY_ALLOW_ZERO_PTR));
|
||||
order_by= 0;
|
||||
char *end= strmov(afterdot, table);
|
||||
if (include_table(hash_key, end - hash_key))
|
||||
{
|
||||
numrows = getTableStructure(table, database);
|
||||
if (!dFlag && numrows > 0)
|
||||
dumpTable(numrows,table);
|
||||
my_free(order_by, MYF(MY_ALLOW_ZERO_PTR));
|
||||
order_by= 0;
|
||||
}
|
||||
}
|
||||
if (opt_xml)
|
||||
{
|
||||
|
@ -24,7 +24,7 @@ NDB_VERSION_STATUS="alpha"
|
||||
# Remember that regexps needs to quote [ and ] since this is run through m4
|
||||
MYSQL_NO_DASH_VERSION=`echo $VERSION | sed -e "s|[[a-z]]*-.*$||"`
|
||||
MYSQL_BASE_VERSION=`echo $MYSQL_NO_DASH_VERSION | sed -e "s|\.[[^.]]*$||"`
|
||||
MYSQL_VERSION_ID=`echo $MYSQL_NO_DASH_VERSION. | sed -e 's/\./ /g; s/ \([[0-9]]\) / 0\\1 /g; s/ //g'`
|
||||
MYSQL_VERSION_ID=`echo $MYSQL_NO_DASH_VERSION. | sed -e 's/[[^0-9.]]//g; s/\./ /g; s/ \([[0-9]]\) / 0\\1 /g; s/ //g'`
|
||||
|
||||
# The port should be constant for a LONG time
|
||||
MYSQL_TCP_PORT_DEFAULT=3306
|
||||
|
@ -39,16 +39,17 @@ enum enum_vio_type
|
||||
|
||||
Vio* vio_new(my_socket sd, enum enum_vio_type type, my_bool localhost);
|
||||
#ifdef __WIN__
|
||||
Vio* vio_new_win32pipe(HANDLE hPipe);
|
||||
Vio* vio_new_win32shared_memory(NET *net,HANDLE handle_file_map,
|
||||
HANDLE handle_map,
|
||||
HANDLE event_server_wrote,
|
||||
HANDLE event_server_read,
|
||||
HANDLE event_client_wrote,
|
||||
HANDLE event_client_read);
|
||||
int vio_read_pipe(Vio *vio, gptr buf, int size);
|
||||
int vio_write_pipe(Vio *vio, const gptr buf, int size);
|
||||
int vio_close_pipe(Vio * vio);
|
||||
Vio* vio_new_win32pipe(HANDLE hPipe);
|
||||
Vio* vio_new_win32shared_memory(NET *net,HANDLE handle_file_map,
|
||||
HANDLE handle_map,
|
||||
HANDLE event_server_wrote,
|
||||
HANDLE event_server_read,
|
||||
HANDLE event_client_wrote,
|
||||
HANDLE event_client_read,
|
||||
HANDLE event_conn_closed);
|
||||
int vio_read_pipe(Vio *vio, gptr buf, int size);
|
||||
int vio_write_pipe(Vio *vio, const gptr buf, int size);
|
||||
int vio_close_pipe(Vio * vio);
|
||||
#else
|
||||
#define HANDLE void *
|
||||
#endif /* __WIN__ */
|
||||
@ -197,6 +198,7 @@ struct st_vio
|
||||
HANDLE event_server_read;
|
||||
HANDLE event_client_wrote;
|
||||
HANDLE event_client_read;
|
||||
HANDLE event_conn_closed;
|
||||
long shared_memory_remain;
|
||||
char *shared_memory_pos;
|
||||
NET *net;
|
||||
|
@ -332,7 +332,7 @@ buf_read_page(
|
||||
if (err == DB_TABLESPACE_DELETED) {
|
||||
ut_print_timestamp(stderr);
|
||||
fprintf(stderr,
|
||||
" InnoDB: error: trying to access tablespace %lu page no. %lu,\n"
|
||||
" InnoDB: Error: trying to access tablespace %lu page no. %lu,\n"
|
||||
"InnoDB: but the tablespace does not exist or is just being dropped.\n",
|
||||
(ulong) space, (ulong) offset);
|
||||
}
|
||||
|
@ -207,12 +207,14 @@ loop:
|
||||
In a crash recovery we already have all the tablespace objects created.
|
||||
This function compares the space id information in the InnoDB data dictionary
|
||||
to what we already read with fil_load_single_table_tablespaces().
|
||||
In a normal startup we just scan the biggest space id, and store it to
|
||||
fil_system. */
|
||||
|
||||
In a normal startup, we create the tablespace objects for every table in
|
||||
InnoDB's data dictionary, if the corresponding .ibd file exists.
|
||||
We also scan the biggest space id, and store it to fil_system. */
|
||||
|
||||
void
|
||||
dict_check_tablespaces_or_store_max_id(
|
||||
/*===================================*/
|
||||
dict_check_tablespaces_and_store_max_id(
|
||||
/*====================================*/
|
||||
ibool in_crash_recovery) /* in: are we doing a crash recovery */
|
||||
{
|
||||
dict_table_t* sys_tables;
|
||||
@ -283,6 +285,14 @@ loop:
|
||||
FALSE, TRUE, TRUE);
|
||||
}
|
||||
|
||||
if (space_id != 0 && !in_crash_recovery) {
|
||||
/* It is a normal database startup: create the space
|
||||
object and check that the .ibd file exists. */
|
||||
|
||||
fil_open_single_table_tablespace(FALSE, space_id,
|
||||
name);
|
||||
}
|
||||
|
||||
mem_free(name);
|
||||
|
||||
if (space_id > max_space_id) {
|
||||
@ -797,8 +807,18 @@ dict_load_table(
|
||||
/* Ok; (if we did a crash recovery then the tablespace
|
||||
can already be in the memory cache) */
|
||||
} else {
|
||||
/* In >= 4.1.9, InnoDB scans the data dictionary also
|
||||
at a normal mysqld startup. It is an error if the
|
||||
space object does not exist in memory. */
|
||||
|
||||
ut_print_timestamp(stderr);
|
||||
fprintf(stderr,
|
||||
" InnoDB: error: space object of table %s,\n"
|
||||
"InnoDB: space id %lu did not exist in memory. Retrying an open.\n",
|
||||
name, (ulong)space);
|
||||
/* Try to open the tablespace */
|
||||
if (!fil_open_single_table_tablespace(space, name)) {
|
||||
if (!fil_open_single_table_tablespace(TRUE,
|
||||
space, name)) {
|
||||
/* We failed to find a sensible tablespace
|
||||
file */
|
||||
|
||||
|
@ -469,6 +469,10 @@ fil_node_open_file(
|
||||
ulint size_low;
|
||||
ulint size_high;
|
||||
ibool ret;
|
||||
byte* buf2;
|
||||
byte* page;
|
||||
ibool success;
|
||||
ulint space_id;
|
||||
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
ut_ad(mutex_own(&(system->mutex)));
|
||||
@ -497,6 +501,8 @@ fil_node_open_file(
|
||||
system->n_open++;
|
||||
|
||||
if (node->size == 0) {
|
||||
ut_a(space->purpose != FIL_LOG);
|
||||
|
||||
os_file_get_size(node->handle, &size_low, &size_high);
|
||||
|
||||
size_bytes = (((ib_longlong)size_high) << 32)
|
||||
@ -510,6 +516,46 @@ fil_node_open_file(
|
||||
|
||||
ut_a(space->id != 0);
|
||||
|
||||
if (size_bytes < FIL_IBD_FILE_INITIAL_SIZE * UNIV_PAGE_SIZE) {
|
||||
fprintf(stderr,
|
||||
"InnoDB: Error: the size of single-table tablespace file %s\n"
|
||||
"InnoDB: is only %lu %lu, should be at least %lu!", node->name,
|
||||
(ulong) size_high,
|
||||
(ulong) size_low, (ulong) (4 * UNIV_PAGE_SIZE));
|
||||
|
||||
ut_a(0);
|
||||
}
|
||||
|
||||
/* Read the first page of the tablespace */
|
||||
|
||||
buf2 = ut_malloc(2 * UNIV_PAGE_SIZE);
|
||||
/* Align the memory for file i/o if we might have O_DIRECT
|
||||
set */
|
||||
page = ut_align(buf2, UNIV_PAGE_SIZE);
|
||||
|
||||
success = os_file_read(node->handle, page, 0, 0,
|
||||
UNIV_PAGE_SIZE);
|
||||
space_id = fsp_header_get_space_id(page);
|
||||
|
||||
ut_free(buf2);
|
||||
|
||||
if (space_id == ULINT_UNDEFINED || space_id == 0) {
|
||||
fprintf(stderr,
|
||||
"InnoDB: Error: tablespace id %lu in file %s is not sensible\n",
|
||||
(ulong) space_id,
|
||||
node->name);
|
||||
|
||||
ut_a(0);
|
||||
}
|
||||
|
||||
if (space_id != space->id) {
|
||||
fprintf(stderr,
|
||||
"InnoDB: Error: tablespace id is %lu in the data dictionary\n"
|
||||
"InnoDB: but in file %s it is %lu!\n", space->id, node->name, space_id);
|
||||
|
||||
ut_a(0);
|
||||
}
|
||||
|
||||
if (size_bytes >= FSP_EXTENT_SIZE * UNIV_PAGE_SIZE) {
|
||||
node->size = (ulint) ((size_bytes / (1024 * 1024))
|
||||
* ((1024 * 1024) / UNIV_PAGE_SIZE));
|
||||
@ -2498,21 +2544,29 @@ func_exit:
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
Tries to open a single-table tablespace and checks the space id is right in
|
||||
it. If does not succeed, prints an error message to the .err log. This
|
||||
function is used to open the tablespace when we load a table definition
|
||||
to the dictionary cache. NOTE that we assume this operation is used under the
|
||||
protection of the dictionary mutex, so that two users cannot race here. This
|
||||
operation does not leave the file associated with the tablespace open, but
|
||||
closes it after we have looked at the space id in it. */
|
||||
Tries to open a single-table tablespace and optionally checks the space id is
|
||||
right in it. If does not succeed, prints an error message to the .err log. This
|
||||
function is used to open a tablespace when we start up mysqld, and also in
|
||||
IMPORT TABLESPACE.
|
||||
NOTE that we assume this operation is used either at the database startup
|
||||
or under the protection of the dictionary mutex, so that two users cannot
|
||||
race here. This operation does not leave the file associated with the
|
||||
tablespace open, but closes it after we have looked at the space id in it. */
|
||||
|
||||
ibool
|
||||
fil_open_single_table_tablespace(
|
||||
/*=============================*/
|
||||
/* out: TRUE if success */
|
||||
ulint id, /* in: space id */
|
||||
const char* name) /* in: table name in the
|
||||
databasename/tablename format */
|
||||
/* out: TRUE if success */
|
||||
ibool check_space_id, /* in: should we check that the space
|
||||
id in the file is right; we assume
|
||||
that this function runs much faster
|
||||
if no check is made, since accessing
|
||||
the file inode probably is much
|
||||
faster (the OS caches them) than
|
||||
accessing the first page of the file */
|
||||
ulint id, /* in: space id */
|
||||
const char* name) /* in: table name in the
|
||||
databasename/tablename format */
|
||||
{
|
||||
os_file_t file;
|
||||
char* filepath;
|
||||
@ -2551,6 +2605,12 @@ fil_open_single_table_tablespace(
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
if (!check_space_id) {
|
||||
space_id = id;
|
||||
|
||||
goto skip_check;
|
||||
}
|
||||
|
||||
/* Read the first page of the tablespace */
|
||||
|
||||
buf2 = ut_malloc(2 * UNIV_PAGE_SIZE);
|
||||
@ -2563,6 +2623,8 @@ fil_open_single_table_tablespace(
|
||||
|
||||
space_id = fsp_header_get_space_id(page);
|
||||
|
||||
ut_free(buf2);
|
||||
|
||||
if (space_id != id) {
|
||||
ut_print_timestamp(stderr);
|
||||
|
||||
@ -2583,6 +2645,7 @@ fil_open_single_table_tablespace(
|
||||
goto func_exit;
|
||||
}
|
||||
|
||||
skip_check:
|
||||
success = fil_space_create(filepath, space_id, FIL_TABLESPACE);
|
||||
|
||||
if (!success) {
|
||||
@ -2595,7 +2658,6 @@ fil_open_single_table_tablespace(
|
||||
fil_node_create(filepath, 0, space_id, FALSE);
|
||||
func_exit:
|
||||
os_file_close(file);
|
||||
ut_free(buf2);
|
||||
mem_free(filepath);
|
||||
|
||||
return(ret);
|
||||
@ -2662,7 +2724,7 @@ fil_load_single_table_tablespace(
|
||||
fprintf(stderr,
|
||||
"InnoDB: Error: could not open single-table tablespace file\n"
|
||||
"InnoDB: %s!\n"
|
||||
"InnoDB: We do not continue crash recovery, because the table will become\n"
|
||||
"InnoDB: We do not continue the crash recovery, because the table may become\n"
|
||||
"InnoDB: corrupt if we cannot apply the log records in the InnoDB log to it.\n"
|
||||
"InnoDB: To fix the problem and start mysqld:\n"
|
||||
"InnoDB: 1) If there is a permission problem in the file and mysqld cannot\n"
|
||||
@ -2833,8 +2895,9 @@ fil_load_single_table_tablespace(
|
||||
goto func_exit;
|
||||
}
|
||||
|
||||
/* We do not measure the size of the file, that is why we pass the 0
|
||||
below */
|
||||
/* We do not use the size information we have about the file, because
|
||||
the rounding formula for extents and pages is somewhat complex; we
|
||||
let fil_node_open() do that task. */
|
||||
|
||||
fil_node_create(filepath, 0, space_id, FALSE);
|
||||
func_exit:
|
||||
|
@ -18,12 +18,14 @@ Created 4/24/1996 Heikki Tuuri
|
||||
In a crash recovery we already have all the tablespace objects created.
|
||||
This function compares the space id information in the InnoDB data dictionary
|
||||
to what we already read with fil_load_single_table_tablespaces().
|
||||
In a normal startup we just scan the biggest space id, and store it to
|
||||
fil_system. */
|
||||
|
||||
In a normal startup, we create the tablespace objects for every table in
|
||||
InnoDB's data dictionary, if the corresponding .ibd file exists.
|
||||
We also scan the biggest space id, and store it to fil_system. */
|
||||
|
||||
void
|
||||
dict_check_tablespaces_or_store_max_id(
|
||||
/*===================================*/
|
||||
dict_check_tablespaces_and_store_max_id(
|
||||
/*====================================*/
|
||||
ibool in_crash_recovery); /* in: are we doing a crash recovery */
|
||||
/************************************************************************
|
||||
Finds the first table name in the given database. */
|
||||
|
@ -366,19 +366,29 @@ fil_create_new_single_table_tablespace(
|
||||
tablespace file in pages,
|
||||
must be >= FIL_IBD_FILE_INITIAL_SIZE */
|
||||
/************************************************************************
|
||||
Tries to open a single-table tablespace and checks the space id is right in
|
||||
it. If does not succeed, prints an error message to the .err log. This
|
||||
function is used to open the tablespace when we load a table definition
|
||||
to the dictionary cache. NOTE that we assume this operation is used under the
|
||||
protection of the dictionary mutex, so that two users cannot race here. */
|
||||
Tries to open a single-table tablespace and optionally checks the space id is
|
||||
right in it. If does not succeed, prints an error message to the .err log. This
|
||||
function is used to open a tablespace when we start up mysqld, and also in
|
||||
IMPORT TABLESPACE.
|
||||
NOTE that we assume this operation is used either at the database startup
|
||||
or under the protection of the dictionary mutex, so that two users cannot
|
||||
race here. This operation does not leave the file associated with the
|
||||
tablespace open, but closes it after we have looked at the space id in it. */
|
||||
|
||||
ibool
|
||||
fil_open_single_table_tablespace(
|
||||
/*=============================*/
|
||||
/* out: TRUE if success */
|
||||
ulint id, /* in: space id */
|
||||
const char* name); /* in: table name in the
|
||||
databasename/tablename format */
|
||||
/* out: TRUE if success */
|
||||
ibool check_space_id, /* in: should we check that the space
|
||||
id in the file is right; we assume
|
||||
that this function runs much faster
|
||||
if no check is made, since accessing
|
||||
the file inode probably is much
|
||||
faster (the OS caches them) than
|
||||
accessing the first page of the file */
|
||||
ulint id, /* in: space id */
|
||||
const char* name); /* in: table name in the
|
||||
databasename/tablename format */
|
||||
/************************************************************************
|
||||
It is possible, though very improbable, that the lsn's in the tablespace to be
|
||||
imported have risen above the current system lsn, if a lengthy purge, ibuf
|
||||
|
@ -378,25 +378,7 @@ row_drop_table_for_mysql(
|
||||
/*************************************************************************
|
||||
Discards the tablespace of a table which stored in an .ibd file. Discarding
|
||||
means that this function deletes the .ibd file and assigns a new table id for
|
||||
the table. Also the flag table->ibd_file_missing is set TRUE.
|
||||
|
||||
How do we prevent crashes caused by ongoing operations on the table? Old
|
||||
operations could try to access non-existent pages.
|
||||
|
||||
1) SQL queries, INSERT, SELECT, ...: we must get an exclusive MySQL table lock
|
||||
on the table before we can do DISCARD TABLESPACE. Then there are no running
|
||||
queries on the table.
|
||||
2) Purge and rollback: we assign a new table id for the table. Since purge and
|
||||
rollback look for the table based on the table id, they see the table as
|
||||
'dropped' and discard their operations.
|
||||
3) Insert buffer: we remove all entries for the tablespace in the insert
|
||||
buffer tree; as long as the tablespace mem object does not exist, ongoing
|
||||
insert buffer page merges are discarded in buf0rea.c. If we recreate the
|
||||
tablespace mem object with IMPORT TABLESPACE later, then the tablespace will
|
||||
have the same id, but the tablespace_version field in the mem object is
|
||||
different, and ongoing old insert buffer page merges get discarded.
|
||||
4) Linear readahead and random readahead: we use the same method as in 3) to
|
||||
discard ongoing operations. */
|
||||
the table. Also the flag table->ibd_file_missing is set TRUE. */
|
||||
|
||||
int
|
||||
row_discard_tablespace_for_mysql(
|
||||
|
@ -414,6 +414,19 @@ struct trx_struct{
|
||||
replication slave, this is the
|
||||
position in the log file up to which
|
||||
replication has processed */
|
||||
/* A MySQL variable mysql_thd->synchronous_repl tells if we have
|
||||
to use synchronous replication. See ha_innodb.cc. */
|
||||
char* repl_wait_binlog_name;/* NULL, or if synchronous MySQL
|
||||
replication is used, the binlog name
|
||||
up to which we must communicate the
|
||||
binlog to the slave, before returning
|
||||
from a commit; this is the same as
|
||||
mysql_log_file_name, but we allocate
|
||||
and copy the name to a separate buffer
|
||||
here */
|
||||
ib_longlong repl_wait_binlog_pos;/* see above at
|
||||
repl_wait_binlog_name */
|
||||
|
||||
os_thread_id_t mysql_thread_id;/* id of the MySQL thread associated
|
||||
with this transaction object */
|
||||
ulint mysql_process_no;/* since in Linux, 'top' reports
|
||||
|
@ -1854,6 +1854,7 @@ os_file_pread(
|
||||
return(n_bytes);
|
||||
#else
|
||||
{
|
||||
off_t ret_offset;
|
||||
ssize_t ret;
|
||||
ulint i;
|
||||
|
||||
@ -1862,12 +1863,12 @@ os_file_pread(
|
||||
|
||||
os_mutex_enter(os_file_seek_mutexes[i]);
|
||||
|
||||
ret = lseek(file, offs, 0);
|
||||
ret_offset = lseek(file, offs, SEEK_SET);
|
||||
|
||||
if (ret < 0) {
|
||||
if (ret_offset < 0) {
|
||||
os_mutex_exit(os_file_seek_mutexes[i]);
|
||||
|
||||
return(ret);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
ret = read(file, buf, (ssize_t)n);
|
||||
@ -1940,6 +1941,7 @@ os_file_pwrite(
|
||||
return(ret);
|
||||
#else
|
||||
{
|
||||
off_t ret_offset;
|
||||
ulint i;
|
||||
|
||||
/* Protect the seek / write operation with a mutex */
|
||||
@ -1947,12 +1949,12 @@ os_file_pwrite(
|
||||
|
||||
os_mutex_enter(os_file_seek_mutexes[i]);
|
||||
|
||||
ret = lseek(file, offs, 0);
|
||||
ret_offset = lseek(file, offs, SEEK_SET);
|
||||
|
||||
if (ret < 0) {
|
||||
if (ret_offset < 0) {
|
||||
os_mutex_exit(os_file_seek_mutexes[i]);
|
||||
|
||||
return(ret);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
ret = write(file, buf, (ssize_t)n);
|
||||
|
@ -1187,7 +1187,7 @@ run_again:
|
||||
check_index = foreign->foreign_index;
|
||||
}
|
||||
|
||||
if (check_table == NULL) {
|
||||
if (check_table == NULL || check_table->ibd_file_missing) {
|
||||
if (check_ref) {
|
||||
FILE* ef = dict_foreign_err_file;
|
||||
mutex_enter(&dict_foreign_err_mutex);
|
||||
@ -1206,7 +1206,7 @@ run_again:
|
||||
dtuple_print(ef, entry);
|
||||
fputs("\nBut the parent table ", ef);
|
||||
ut_print_name(ef, trx, foreign->referenced_table_name);
|
||||
fputs(" does not currently exist!\n", ef);
|
||||
fputs("\nor its .ibd file does not currently exist!\n", ef);
|
||||
mutex_exit(&dict_foreign_err_mutex);
|
||||
|
||||
err = DB_NO_REFERENCED_ROW;
|
||||
@ -1437,8 +1437,34 @@ row_ins_check_foreign_constraints(
|
||||
row_mysql_freeze_data_dictionary(trx);
|
||||
}
|
||||
|
||||
if (foreign->referenced_table) {
|
||||
mutex_enter(&(dict_sys->mutex));
|
||||
|
||||
(foreign->referenced_table
|
||||
->n_foreign_key_checks_running)++;
|
||||
|
||||
mutex_exit(&(dict_sys->mutex));
|
||||
}
|
||||
|
||||
/* NOTE that if the thread ends up waiting for a lock
|
||||
we will release dict_operation_lock temporarily!
|
||||
But the counter on the table protects the referenced
|
||||
table from being dropped while the check is running. */
|
||||
|
||||
err = row_ins_check_foreign_constraint(TRUE, foreign,
|
||||
table, entry, thr);
|
||||
|
||||
if (foreign->referenced_table) {
|
||||
mutex_enter(&(dict_sys->mutex));
|
||||
|
||||
ut_a(foreign->referenced_table
|
||||
->n_foreign_key_checks_running > 0);
|
||||
(foreign->referenced_table
|
||||
->n_foreign_key_checks_running)--;
|
||||
|
||||
mutex_exit(&(dict_sys->mutex));
|
||||
}
|
||||
|
||||
if (got_s_lock) {
|
||||
row_mysql_unfreeze_data_dictionary(trx);
|
||||
}
|
||||
|
@ -875,7 +875,21 @@ row_insert_for_mysql(
|
||||
|
||||
ut_ad(trx);
|
||||
ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
|
||||
|
||||
|
||||
if (prebuilt->table->ibd_file_missing) {
|
||||
ut_print_timestamp(stderr);
|
||||
fprintf(stderr, " InnoDB: Error:\n"
|
||||
"InnoDB: MySQL is trying to use a table handle but the .ibd file for\n"
|
||||
"InnoDB: table %s does not exist.\n"
|
||||
"InnoDB: Have you deleted the .ibd file from the database directory under\n"
|
||||
"InnoDB: the MySQL datadir, or have you used DISCARD TABLESPACE?\n"
|
||||
"InnoDB: Look from\n"
|
||||
"http://dev.mysql.com/doc/mysql/en/InnoDB_troubleshooting_datadict.html\n"
|
||||
"InnoDB: how you can resolve the problem.\n",
|
||||
prebuilt->table->name);
|
||||
return(DB_ERROR);
|
||||
}
|
||||
|
||||
if (prebuilt->magic_n != ROW_PREBUILT_ALLOCATED) {
|
||||
fprintf(stderr,
|
||||
"InnoDB: Error: trying to free a corrupt\n"
|
||||
@ -1094,6 +1108,20 @@ row_update_for_mysql(
|
||||
ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
|
||||
UT_NOT_USED(mysql_rec);
|
||||
|
||||
if (prebuilt->table->ibd_file_missing) {
|
||||
ut_print_timestamp(stderr);
|
||||
fprintf(stderr, " InnoDB: Error:\n"
|
||||
"InnoDB: MySQL is trying to use a table handle but the .ibd file for\n"
|
||||
"InnoDB: table %s does not exist.\n"
|
||||
"InnoDB: Have you deleted the .ibd file from the database directory under\n"
|
||||
"InnoDB: the MySQL datadir, or have you used DISCARD TABLESPACE?\n"
|
||||
"InnoDB: Look from\n"
|
||||
"http://dev.mysql.com/doc/mysql/en/InnoDB_troubleshooting_datadict.html\n"
|
||||
"InnoDB: how you can resolve the problem.\n",
|
||||
prebuilt->table->name);
|
||||
return(DB_ERROR);
|
||||
}
|
||||
|
||||
if (prebuilt->magic_n != ROW_PREBUILT_ALLOCATED) {
|
||||
fprintf(stderr,
|
||||
"InnoDB: Error: trying to free a corrupt\n"
|
||||
@ -1865,20 +1893,19 @@ row_drop_table_for_mysql_in_background(
|
||||
|
||||
trx = trx_allocate_for_background();
|
||||
|
||||
/* If the original transaction was dropping a table referenced by
|
||||
foreign keys, we must set the following to be able to drop the
|
||||
table: */
|
||||
|
||||
trx->check_foreigns = FALSE;
|
||||
|
||||
/* fputs("InnoDB: Error: Dropping table ", stderr);
|
||||
ut_print_name(stderr, name);
|
||||
fputs(" in background drop list\n", stderr); */
|
||||
|
||||
/* Drop the table in InnoDB */
|
||||
/* Try to drop the table in InnoDB */
|
||||
|
||||
error = row_drop_table_for_mysql(name, trx, FALSE);
|
||||
|
||||
if (error != DB_SUCCESS) {
|
||||
ut_print_timestamp(stderr);
|
||||
fputs(" InnoDB: Error: Dropping table ", stderr);
|
||||
ut_print_name(stderr, trx, name);
|
||||
fputs(" in background drop list failed\n", stderr);
|
||||
}
|
||||
|
||||
/* Flush the log to reduce probability that the .frm files and
|
||||
the InnoDB data dictionary get out-of-sync if the user runs
|
||||
@ -1890,7 +1917,7 @@ row_drop_table_for_mysql_in_background(
|
||||
|
||||
trx_free_for_background(trx);
|
||||
|
||||
return(DB_SUCCESS);
|
||||
return(error);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
@ -1924,6 +1951,7 @@ loop:
|
||||
mutex_exit(&kernel_mutex);
|
||||
|
||||
if (drop == NULL) {
|
||||
/* All tables dropped */
|
||||
|
||||
return(n_tables + n_tables_dropped);
|
||||
}
|
||||
@ -1938,16 +1966,16 @@ loop:
|
||||
|
||||
goto already_dropped;
|
||||
}
|
||||
|
||||
if (table->n_mysql_handles_opened > 0
|
||||
|| table->n_foreign_key_checks_running > 0) {
|
||||
|
||||
if (DB_SUCCESS != row_drop_table_for_mysql_in_background(
|
||||
drop->table_name)) {
|
||||
/* If the DROP fails for some table, we return, and let the
|
||||
main thread retry later */
|
||||
|
||||
return(n_tables + n_tables_dropped);
|
||||
}
|
||||
|
||||
n_tables_dropped++;
|
||||
|
||||
row_drop_table_for_mysql_in_background(drop->table_name);
|
||||
|
||||
already_dropped:
|
||||
mutex_enter(&kernel_mutex);
|
||||
@ -1991,21 +2019,21 @@ row_get_background_drop_list_len_low(void)
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
Adds a table to the list of tables which the master thread drops in
|
||||
background. We need this on Unix because in ALTER TABLE MySQL may call
|
||||
drop table even if the table has running queries on it. */
|
||||
If a table is not yet in the drop list, adds the table to the list of tables
|
||||
which the master thread drops in background. We need this on Unix because in
|
||||
ALTER TABLE MySQL may call drop table even if the table has running queries on
|
||||
it. Also, if there are running foreign key checks on the table, we drop the
|
||||
table lazily. */
|
||||
static
|
||||
void
|
||||
ibool
|
||||
row_add_table_to_background_drop_list(
|
||||
/*==================================*/
|
||||
/* out: TRUE if the table was not yet in the
|
||||
drop list, and was added there */
|
||||
dict_table_t* table) /* in: table */
|
||||
{
|
||||
row_mysql_drop_t* drop;
|
||||
|
||||
drop = mem_alloc(sizeof(row_mysql_drop_t));
|
||||
|
||||
drop->table_name = mem_strdup(table->name);
|
||||
|
||||
mutex_enter(&kernel_mutex);
|
||||
|
||||
if (!row_mysql_drop_list_inited) {
|
||||
@ -2013,7 +2041,26 @@ row_add_table_to_background_drop_list(
|
||||
UT_LIST_INIT(row_mysql_drop_list);
|
||||
row_mysql_drop_list_inited = TRUE;
|
||||
}
|
||||
|
||||
/* Look if the table already is in the drop list */
|
||||
drop = UT_LIST_GET_FIRST(row_mysql_drop_list);
|
||||
|
||||
while (drop != NULL) {
|
||||
if (strcmp(drop->table_name, table->name) == 0) {
|
||||
/* Already in the list */
|
||||
|
||||
mutex_exit(&kernel_mutex);
|
||||
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
drop = UT_LIST_GET_NEXT(row_mysql_drop_list, drop);
|
||||
}
|
||||
|
||||
drop = mem_alloc(sizeof(row_mysql_drop_t));
|
||||
|
||||
drop->table_name = mem_strdup(table->name);
|
||||
|
||||
UT_LIST_ADD_LAST(row_mysql_drop_list, row_mysql_drop_list, drop);
|
||||
|
||||
/* fputs("InnoDB: Adding table ", stderr);
|
||||
@ -2021,14 +2068,32 @@ row_add_table_to_background_drop_list(
|
||||
fputs(" to background drop list\n", stderr); */
|
||||
|
||||
mutex_exit(&kernel_mutex);
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
Discards the tablespace of a table which stored in an .ibd file. Discarding
|
||||
means that this function deletes the .ibd file and assigns a new table id for
|
||||
the table. Also the flag table->ibd_file_missing is set TRUE.
|
||||
the table. Also the flag table->ibd_file_missing is set TRUE. */
|
||||
|
||||
How do we prevent crashes caused by ongoing operations on the table? Old
|
||||
int
|
||||
row_discard_tablespace_for_mysql(
|
||||
/*=============================*/
|
||||
/* out: error code or DB_SUCCESS */
|
||||
const char* name, /* in: table name */
|
||||
trx_t* trx) /* in: transaction handle */
|
||||
{
|
||||
dict_foreign_t* foreign;
|
||||
dulint new_id;
|
||||
dict_table_t* table;
|
||||
que_thr_t* thr;
|
||||
que_t* graph = NULL;
|
||||
ibool success;
|
||||
ulint err;
|
||||
char* buf;
|
||||
|
||||
/* How do we prevent crashes caused by ongoing operations on the table? Old
|
||||
operations could try to access non-existent pages.
|
||||
|
||||
1) SQL queries, INSERT, SELECT, ...: we must get an exclusive MySQL table lock
|
||||
@ -2044,22 +2109,9 @@ tablespace mem object with IMPORT TABLESPACE later, then the tablespace will
|
||||
have the same id, but the tablespace_version field in the mem object is
|
||||
different, and ongoing old insert buffer page merges get discarded.
|
||||
4) Linear readahead and random readahead: we use the same method as in 3) to
|
||||
discard ongoing operations. */
|
||||
|
||||
int
|
||||
row_discard_tablespace_for_mysql(
|
||||
/*=============================*/
|
||||
/* out: error code or DB_SUCCESS */
|
||||
const char* name, /* in: table name */
|
||||
trx_t* trx) /* in: transaction handle */
|
||||
{
|
||||
dulint new_id;
|
||||
dict_table_t* table;
|
||||
que_thr_t* thr;
|
||||
que_t* graph = NULL;
|
||||
ibool success;
|
||||
ulint err;
|
||||
char* buf;
|
||||
discard ongoing operations.
|
||||
5) FOREIGN KEY operations: if table->n_foreign_key_checks_running > 0, we
|
||||
do not allow the discard. We also reserve the data dictionary latch. */
|
||||
|
||||
static const char discard_tablespace_proc1[] =
|
||||
"PROCEDURE DISCARD_TABLESPACE_PROC () IS\n"
|
||||
@ -2120,6 +2172,54 @@ row_discard_tablespace_for_mysql(
|
||||
goto funct_exit;
|
||||
}
|
||||
|
||||
if (table->n_foreign_key_checks_running > 0) {
|
||||
|
||||
ut_print_timestamp(stderr);
|
||||
fputs(" InnoDB: You are trying to DISCARD table ", stderr);
|
||||
ut_print_name(stderr, trx, table->name);
|
||||
fputs("\n"
|
||||
"InnoDB: though there is a foreign key check running on it.\n"
|
||||
"InnoDB: Cannot discard the table.\n",
|
||||
stderr);
|
||||
|
||||
err = DB_ERROR;
|
||||
|
||||
goto funct_exit;
|
||||
}
|
||||
|
||||
/* Check if the table is referenced by foreign key constraints from
|
||||
some other table (not the table itself) */
|
||||
|
||||
foreign = UT_LIST_GET_FIRST(table->referenced_list);
|
||||
|
||||
while (foreign && foreign->foreign_table == table) {
|
||||
foreign = UT_LIST_GET_NEXT(referenced_list, foreign);
|
||||
}
|
||||
|
||||
if (foreign && trx->check_foreigns) {
|
||||
|
||||
FILE* ef = dict_foreign_err_file;
|
||||
|
||||
/* We only allow discarding a referenced table if
|
||||
FOREIGN_KEY_CHECKS is set to 0 */
|
||||
|
||||
err = DB_CANNOT_DROP_CONSTRAINT;
|
||||
|
||||
mutex_enter(&dict_foreign_err_mutex);
|
||||
rewind(ef);
|
||||
ut_print_timestamp(ef);
|
||||
|
||||
fputs(" Cannot DISCARD table ", ef);
|
||||
ut_print_name(ef, trx, name);
|
||||
fputs("\n"
|
||||
"because it is referenced by ", ef);
|
||||
ut_print_name(ef, trx, foreign->foreign_table_name);
|
||||
putc('\n', ef);
|
||||
mutex_exit(&dict_foreign_err_mutex);
|
||||
|
||||
goto funct_exit;
|
||||
}
|
||||
|
||||
new_id = dict_hdr_get_new_id(DICT_HDR_TABLE_ID);
|
||||
|
||||
buf = mem_alloc((sizeof discard_tablespace_proc1) +
|
||||
@ -2137,6 +2237,10 @@ row_discard_tablespace_for_mysql(
|
||||
|
||||
ut_a(graph);
|
||||
|
||||
/* Remove any locks there are on the table or its records */
|
||||
|
||||
lock_reset_all_on_table(table);
|
||||
|
||||
graph->trx = trx;
|
||||
trx->graph = NULL;
|
||||
|
||||
@ -2287,8 +2391,8 @@ row_import_tablespace_for_mysql(
|
||||
|
||||
ibuf_delete_for_discarded_space(table->space);
|
||||
|
||||
success = fil_open_single_table_tablespace(table->space, table->name);
|
||||
|
||||
success = fil_open_single_table_tablespace(TRUE, table->space,
|
||||
table->name);
|
||||
if (success) {
|
||||
table->ibd_file_missing = FALSE;
|
||||
table->tablespace_discarded = FALSE;
|
||||
@ -2296,7 +2400,7 @@ row_import_tablespace_for_mysql(
|
||||
if (table->ibd_file_missing) {
|
||||
ut_print_timestamp(stderr);
|
||||
fputs(
|
||||
" InnoDB: cannot find of open in the database directory the .ibd file of\n"
|
||||
" InnoDB: cannot find or open in the database directory the .ibd file of\n"
|
||||
"InnoDB: table ", stderr);
|
||||
ut_print_name(stderr, trx, name);
|
||||
fputs("\n"
|
||||
@ -2318,7 +2422,7 @@ funct_exit:
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
Drops a table for MySQL. If the name of the table to be dropped is equal
|
||||
Drops a table for MySQL. If the name of the table to be dropped is equal
|
||||
with one of the predefined magic table names, then this also stops printing
|
||||
the corresponding monitor output by the master thread. */
|
||||
|
||||
@ -2552,36 +2656,60 @@ row_drop_table_for_mysql(
|
||||
}
|
||||
|
||||
if (table->n_mysql_handles_opened > 0) {
|
||||
ibool added;
|
||||
|
||||
ut_print_timestamp(stderr);
|
||||
fputs(" InnoDB: Warning: MySQL is trying to drop table ",
|
||||
stderr);
|
||||
ut_print_name(stderr, trx, table->name);
|
||||
fputs("\n"
|
||||
"InnoDB: though there are still open handles to it.\n"
|
||||
"InnoDB: Adding the table to the background drop queue.\n",
|
||||
added = row_add_table_to_background_drop_list(table);
|
||||
|
||||
if (added) {
|
||||
ut_print_timestamp(stderr);
|
||||
fputs(" InnoDB: Warning: MySQL is trying to drop table ", stderr);
|
||||
ut_print_name(stderr, trx, table->name);
|
||||
fputs("\n"
|
||||
"InnoDB: though there are still open handles to it.\n"
|
||||
"InnoDB: Adding the table to the background drop queue.\n",
|
||||
stderr);
|
||||
|
||||
/* We return DB_SUCCESS to MySQL though the drop will
|
||||
happen lazily later */
|
||||
|
||||
row_add_table_to_background_drop_list(table);
|
||||
|
||||
err = DB_SUCCESS;
|
||||
err = DB_SUCCESS;
|
||||
} else {
|
||||
/* The table is already in the background drop list */
|
||||
err = DB_ERROR;
|
||||
}
|
||||
|
||||
goto funct_exit;
|
||||
}
|
||||
|
||||
/* TODO: could we replace the counter n_foreign_key_checks_running
|
||||
with lock checks on the table? Acquire here an exclusive lock on the
|
||||
table, and rewrite lock0lock.c and the lock wait in srv0srv.c so that
|
||||
they can cope with the table having been dropped here? Foreign key
|
||||
checks take an IS or IX lock on the table. */
|
||||
|
||||
if (table->n_foreign_key_checks_running > 0) {
|
||||
|
||||
ut_print_timestamp(stderr);
|
||||
fputs(" InnoDB: You are trying to drop table ", stderr);
|
||||
ut_print_name(stderr, trx, table->name);
|
||||
fputs("\n"
|
||||
"InnoDB: though there is a foreign key check running on it.\n"
|
||||
"InnoDB: Adding the table to the background drop queue.\n",
|
||||
ibool added;
|
||||
|
||||
added = row_add_table_to_background_drop_list(table);
|
||||
|
||||
if (added) {
|
||||
ut_print_timestamp(stderr);
|
||||
fputs(" InnoDB: You are trying to drop table ", stderr);
|
||||
ut_print_name(stderr, trx, table->name);
|
||||
fputs("\n"
|
||||
"InnoDB: though there is a foreign key check running on it.\n"
|
||||
"InnoDB: Adding the table to the background drop queue.\n",
|
||||
stderr);
|
||||
|
||||
row_add_table_to_background_drop_list(table);
|
||||
/* We return DB_SUCCESS to MySQL though the drop will
|
||||
happen lazily later */
|
||||
|
||||
err = DB_SUCCESS;
|
||||
err = DB_SUCCESS;
|
||||
} else {
|
||||
/* The table is already in the background drop list */
|
||||
err = DB_ERROR;
|
||||
}
|
||||
|
||||
goto funct_exit;
|
||||
}
|
||||
@ -3349,6 +3477,20 @@ row_check_table_for_mysql(
|
||||
ulint ret = DB_SUCCESS;
|
||||
ulint old_isolation_level;
|
||||
|
||||
if (prebuilt->table->ibd_file_missing) {
|
||||
ut_print_timestamp(stderr);
|
||||
fprintf(stderr, " InnoDB: Error:\n"
|
||||
"InnoDB: MySQL is trying to use a table handle but the .ibd file for\n"
|
||||
"InnoDB: table %s does not exist.\n"
|
||||
"InnoDB: Have you deleted the .ibd file from the database directory under\n"
|
||||
"InnoDB: the MySQL datadir, or have you used DISCARD TABLESPACE?\n"
|
||||
"InnoDB: Look from\n"
|
||||
"http://dev.mysql.com/doc/mysql/en/InnoDB_troubleshooting_datadict.html\n"
|
||||
"InnoDB: how you can resolve the problem.\n",
|
||||
prebuilt->table->name);
|
||||
return(DB_ERROR);
|
||||
}
|
||||
|
||||
prebuilt->trx->op_info = "checking table";
|
||||
|
||||
old_isolation_level = prebuilt->trx->isolation_level;
|
||||
|
@ -2897,7 +2897,7 @@ row_search_for_mysql(
|
||||
/* out: DB_SUCCESS,
|
||||
DB_RECORD_NOT_FOUND,
|
||||
DB_END_OF_INDEX, DB_DEADLOCK,
|
||||
DB_LOCK_TABLE_FULL,
|
||||
DB_LOCK_TABLE_FULL, DB_CORRUPTION,
|
||||
or DB_TOO_BIG_RECORD */
|
||||
byte* buf, /* in/out: buffer for the fetched
|
||||
row in the MySQL format */
|
||||
@ -2952,7 +2952,21 @@ row_search_for_mysql(
|
||||
|
||||
ut_ad(index && pcur && search_tuple);
|
||||
ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
|
||||
|
||||
|
||||
if (prebuilt->table->ibd_file_missing) {
|
||||
ut_print_timestamp(stderr);
|
||||
fprintf(stderr, " InnoDB: Error:\n"
|
||||
"InnoDB: MySQL is trying to use a table handle but the .ibd file for\n"
|
||||
"InnoDB: table %s does not exist.\n"
|
||||
"InnoDB: Have you deleted the .ibd file from the database directory under\n"
|
||||
"InnoDB: the MySQL datadir, or have you used DISCARD TABLESPACE?\n"
|
||||
"InnoDB: Look from\n"
|
||||
"http://dev.mysql.com/doc/mysql/en/InnoDB_troubleshooting_datadict.html\n"
|
||||
"InnoDB: how you can resolve the problem.\n",
|
||||
prebuilt->table->name);
|
||||
return(DB_ERROR);
|
||||
}
|
||||
|
||||
if (prebuilt->magic_n != ROW_PREBUILT_ALLOCATED) {
|
||||
fprintf(stderr,
|
||||
"InnoDB: Error: trying to free a corrupt\n"
|
||||
|
@ -1378,14 +1378,39 @@ NetWare. */
|
||||
return(DB_ERROR);
|
||||
}
|
||||
|
||||
/* Since ibuf init is in dict_boot, and ibuf is needed
|
||||
in any disk i/o, first call dict_boot */
|
||||
/* Since the insert buffer init is in dict_boot, and the
|
||||
insert buffer is needed in any disk i/o, first we call
|
||||
dict_boot(). Note that trx_sys_init_at_db_start() only needs
|
||||
to access space 0, and the insert buffer at this stage already
|
||||
works for space 0. */
|
||||
|
||||
dict_boot();
|
||||
trx_sys_init_at_db_start();
|
||||
|
||||
/* The following needs trx lists which are initialized in
|
||||
trx_sys_init_at_db_start */
|
||||
if (srv_force_recovery < SRV_FORCE_NO_IBUF_MERGE) {
|
||||
/* The following call is necessary for the insert
|
||||
buffer to work with multiple tablespaces. We must
|
||||
know the mapping between space id's and .ibd file
|
||||
names.
|
||||
|
||||
In a crash recovery, we check that the info in data
|
||||
dictionary is consistent with what we already know
|
||||
about space id's from the call of
|
||||
fil_load_single_table_tablespaces().
|
||||
|
||||
In a normal startup, we create the space objects for
|
||||
every table in the InnoDB data dictionary that has
|
||||
an .ibd file.
|
||||
|
||||
We also determine the maximum tablespace id used.
|
||||
|
||||
TODO: We may have incomplete transactions in the
|
||||
data dictionary tables. Does that harm the scanning of
|
||||
the data dictionary below? */
|
||||
|
||||
dict_check_tablespaces_and_store_max_id(
|
||||
recv_needed_recovery);
|
||||
}
|
||||
|
||||
srv_startup_is_before_trx_rollback_phase = FALSE;
|
||||
|
||||
@ -1393,6 +1418,9 @@ NetWare. */
|
||||
system */
|
||||
fsp_header_get_free_limit(0);
|
||||
|
||||
/* recv_recovery_from_checkpoint_finish needs trx lists which
|
||||
are initialized in trx_sys_init_at_db_start(). */
|
||||
|
||||
recv_recovery_from_checkpoint_finish();
|
||||
}
|
||||
|
||||
@ -1431,13 +1459,6 @@ NetWare. */
|
||||
}
|
||||
}
|
||||
#endif /* UNIV_LOG_ARCHIVE */
|
||||
if (!create_new_db && srv_force_recovery == 0) {
|
||||
/* After a crash recovery we only check that the info in data
|
||||
dictionary is consistent with what we already know about space
|
||||
id's from the call of fil_load_single_table_tablespaces(). */
|
||||
|
||||
dict_check_tablespaces_or_store_max_id(recv_needed_recovery);
|
||||
}
|
||||
|
||||
if (srv_measure_contention) {
|
||||
/* os_thread_create(&test_measure_cont, NULL, thread_ids +
|
||||
@ -1505,6 +1526,21 @@ NetWare. */
|
||||
"InnoDB: the sum of data file sizes is %lu pages\n",
|
||||
(ulong) tablespace_size_in_header,
|
||||
(ulong) sum_of_data_file_sizes);
|
||||
|
||||
if (srv_force_recovery == 0
|
||||
&& sum_of_data_file_sizes < tablespace_size_in_header) {
|
||||
/* This is a fatal error, the tail of a tablespace is
|
||||
missing */
|
||||
|
||||
fprintf(stderr,
|
||||
"InnoDB: Cannot start InnoDB. The tail of the system tablespace is\n"
|
||||
"InnoDB: missing. Have you edited innodb_data_file_path in my.cnf in an\n"
|
||||
"InnoDB: inappropriate way, removing ibdata files from there?\n"
|
||||
"InnoDB: You can set innodb_force_recovery=1 in my.cnf to force\n"
|
||||
"InnoDB: a startup if you are trying to recover a badly corrupt database.\n");
|
||||
|
||||
return(DB_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
if (srv_auto_extend_last_data_file
|
||||
@ -1515,6 +1551,18 @@ NetWare. */
|
||||
"InnoDB: the sum of data file sizes is only %lu pages\n",
|
||||
(ulong) tablespace_size_in_header,
|
||||
(ulong) sum_of_data_file_sizes);
|
||||
|
||||
if (srv_force_recovery == 0) {
|
||||
|
||||
fprintf(stderr,
|
||||
"InnoDB: Cannot start InnoDB. The tail of the system tablespace is\n"
|
||||
"InnoDB: missing. Have you edited innodb_data_file_path in my.cnf in an\n"
|
||||
"InnoDB: inappropriate way, removing ibdata files from there?\n"
|
||||
"InnoDB: You can set innodb_force_recovery=1 in my.cnf to force\n"
|
||||
"InnoDB: a startup if you are trying to recover a badly corrupt database.\n");
|
||||
|
||||
return(DB_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check that os_fast_mutexes work as expected */
|
||||
|
@ -110,6 +110,9 @@ trx_create(
|
||||
trx->mysql_log_offset = 0;
|
||||
trx->mysql_master_log_file_name = "";
|
||||
trx->mysql_master_log_pos = 0;
|
||||
|
||||
trx->repl_wait_binlog_name = NULL;
|
||||
trx->repl_wait_binlog_pos = 0;
|
||||
|
||||
mutex_create(&(trx->undo_mutex));
|
||||
mutex_set_level(&(trx->undo_mutex), SYNC_TRX_UNDO);
|
||||
@ -277,6 +280,11 @@ trx_free(
|
||||
trx_undo_arr_free(trx->undo_no_arr);
|
||||
}
|
||||
|
||||
if (trx->repl_wait_binlog_name != NULL) {
|
||||
|
||||
mem_free(trx->repl_wait_binlog_name);
|
||||
}
|
||||
|
||||
ut_a(UT_LIST_GET_LEN(trx->signals) == 0);
|
||||
ut_a(UT_LIST_GET_LEN(trx->reply_signals) == 0);
|
||||
|
||||
|
@ -604,7 +604,7 @@ static char *dup_str_aux(MEM_ROOT *root, const char *from, uint length,
|
||||
uint new_len= (tocs->mbmaxlen * length) / fromcs->mbminlen + 1;
|
||||
result= (char *)alloc_root(root, new_len);
|
||||
length= copy_and_convert(result, new_len,
|
||||
tocs, from, length, fromcs, &dummy_err);
|
||||
tocs, from, length, fromcs, &dummy_err);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -645,15 +645,15 @@ bool Protocol::send_fields(List<Item> *list, uint flags)
|
||||
item->make_field(&server_field);
|
||||
|
||||
client_field->db= dup_str_aux(field_alloc, server_field.db_name,
|
||||
strlen(server_field.db_name), cs, thd_cs);
|
||||
strlen(server_field.db_name), cs, thd_cs);
|
||||
client_field->table= dup_str_aux(field_alloc, server_field.table_name,
|
||||
strlen(server_field.table_name), cs, thd_cs);
|
||||
strlen(server_field.table_name), cs, thd_cs);
|
||||
client_field->name= dup_str_aux(field_alloc, server_field.col_name,
|
||||
strlen(server_field.col_name), cs, thd_cs);
|
||||
strlen(server_field.col_name), cs, thd_cs);
|
||||
client_field->org_table= dup_str_aux(field_alloc, server_field.org_table_name,
|
||||
strlen(server_field.org_table_name), cs, thd_cs);
|
||||
strlen(server_field.org_table_name), cs, thd_cs);
|
||||
client_field->org_name= dup_str_aux(field_alloc, server_field.org_col_name,
|
||||
strlen(server_field.org_col_name), cs, thd_cs);
|
||||
strlen(server_field.org_col_name), cs, thd_cs);
|
||||
if (item->collation.collation == &my_charset_bin || thd_cs == NULL)
|
||||
{
|
||||
/* No conversion */
|
||||
|
@ -596,7 +596,8 @@ MYSQL_DUMP="$MYSQL_DUMP --no-defaults -uroot --socket=$MASTER_MYSOCK --password=
|
||||
MYSQL_BINLOG="$MYSQL_BINLOG --no-defaults --local-load=$MYSQL_TMP_DIR $EXTRA_MYSQLBINLOG_OPT"
|
||||
MYSQL_FIX_SYSTEM_TABLES="$MYSQL_FIX_SYSTEM_TABLES --no-defaults --host=localhost --port=$MASTER_MYPORT --socket=$MASTER_MYSOCK --user=root --password=$DBPASSWD --basedir=$BASEDIR --bindir=$CLIENT_BINDIR --verbose"
|
||||
MYSQL="$MYSQL --host=localhost --port=$MASTER_MYPORT --socket=$MASTER_MYSOCK --user=root --password=$DBPASSWD"
|
||||
export MYSQL MYSQL_DUMP MYSQL_BINLOG MYSQL_FIX_SYSTEM_TABLES CLIENT_BINDIR TESTS_BINDIR
|
||||
export MYSQL MYSQL_DUMP MYSQL_BINLOG MYSQL_FIX_SYSTEM_TABLES
|
||||
export CLIENT_BINDIR TESTS_BINDIR CHARSETSDIR
|
||||
export NDB_TOOLS_DIR
|
||||
|
||||
MYSQL_TEST_ARGS="--no-defaults --socket=$MASTER_MYSOCK --database=$DB \
|
||||
|
@ -31,12 +31,12 @@ QUIT Quit management client
|
||||
<id> = ALL | Any database node id
|
||||
|
||||
Connected to Management Server at: localhost:1186
|
||||
Node 1: started (Version 4.1.8)
|
||||
Node 2: started (Version 4.1.8)
|
||||
Node 1: started (Version 4.1.9)
|
||||
Node 2: started (Version 4.1.9)
|
||||
|
||||
Node 1: started (Version 4.1.8)
|
||||
Node 1: started (Version 4.1.9)
|
||||
|
||||
Node 2: started (Version 4.1.8)
|
||||
Node 2: started (Version 4.1.9)
|
||||
|
||||
Executing CLUSTERLOG on node 1 OK!
|
||||
Executing CLUSTERLOG on node 2 OK!
|
||||
|
@ -121,7 +121,7 @@ create database mysqltest;
|
||||
create table mysqltest.t1 (a int,b int,c int);
|
||||
grant all on mysqltest.t1 to mysqltest_1@localhost;
|
||||
alter table t1 rename t2;
|
||||
ERROR 42000: insert command denied to user 'mysqltest_1'@'localhost' for table 't2'
|
||||
ERROR 42000: INSERT,CREATE command denied to user 'mysqltest_1'@'localhost' for table 't2'
|
||||
revoke all privileges on mysqltest.t1 from mysqltest_1@localhost;
|
||||
delete from mysql.user where user=_binary'mysqltest_1';
|
||||
drop database mysqltest;
|
||||
|
@ -591,3 +591,14 @@ x,y 0078002C0079
|
||||
z 007A
|
||||
x,y,z,ä,ö,ü 0078002C0079002C007A002C00E4002C00F6002C00FC
|
||||
drop table t1;
|
||||
create table t1(a enum('a','b','c')) default character set ucs2;
|
||||
insert into t1 values('a'),('b'),('c');
|
||||
alter table t1 add b char(1);
|
||||
show warnings;
|
||||
Level Code Message
|
||||
select * from t1 order by a;
|
||||
a b
|
||||
a NULL
|
||||
b NULL
|
||||
c NULL
|
||||
drop table t1;
|
||||
|
@ -296,6 +296,9 @@ Tuesday 52 2001 %W %V %X 00:00:00
|
||||
15-01-2001 %d-%m-%Y %H:%i:%S 00:00:00
|
||||
15-01-20 %d-%m-%y 00:00:00
|
||||
15-2001-1 %d-%Y-%c 00:00:00
|
||||
select concat('',str_to_date('8:11:2.123456 03-01-02','%H:%i:%S.%f %y-%m-%d'));
|
||||
concat('',str_to_date('8:11:2.123456 03-01-02','%H:%i:%S.%f %y-%m-%d'))
|
||||
2003-01-02 08:11:02.123456
|
||||
truncate table t1;
|
||||
insert into t1 values
|
||||
('2003-01-02 10:11:12 PM', '%Y-%m-%d %H:%i:%S %p'),
|
||||
|
@ -63,8 +63,8 @@ a0
|
||||
select 'a' union select concat('a', -0.0);
|
||||
a
|
||||
a
|
||||
a-0.0
|
||||
a0.0
|
||||
select 'a' union select concat('a', -0.0000);
|
||||
a
|
||||
a
|
||||
a-0.0000
|
||||
a0.0000
|
||||
|
@ -124,3 +124,5 @@ id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||
Warnings:
|
||||
Note 1003 select degrees(pi()) AS `degrees(pi())`,radians(360) AS `radians(360)`
|
||||
select rand(rand);
|
||||
ERROR 42S22: Unknown column 'rand' in 'field list'
|
||||
|
@ -691,3 +691,15 @@ select count(*) as total, left(c,10) as reg from t1 group by reg order by reg de
|
||||
total reg
|
||||
10 2004-12-10
|
||||
drop table t1;
|
||||
select quote(ltrim(concat(' ', 'a')));
|
||||
quote(ltrim(concat(' ', 'a')))
|
||||
'a'
|
||||
select quote(trim(concat(' ', 'a')));
|
||||
quote(trim(concat(' ', 'a')))
|
||||
'a'
|
||||
select trim(null from 'kate') as "must_be_null";
|
||||
must_be_null
|
||||
NULL
|
||||
select trim('xyz' from null) as "must_be_null";
|
||||
must_be_null
|
||||
NULL
|
||||
|
@ -37,6 +37,28 @@ Grants for mysqltest_1@localhost
|
||||
GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' REQUIRE ISSUER 'MySQL AB' SUBJECT 'testsubject' CIPHER 'EDH-RSA-DES-CBC3-SHA'
|
||||
delete from mysql.user where user='mysqltest_1';
|
||||
flush privileges;
|
||||
delete from mysql.user where user='mysqltest_1';
|
||||
flush privileges;
|
||||
grant usage on *.* to mysqltest_1@localhost with max_queries_per_hour 10;
|
||||
select * from mysql.user where user="mysqltest_1";
|
||||
Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections
|
||||
localhost mysqltest_1 N N N N N N N N N N N N N N N N N N N N N 10 0 0
|
||||
show grants for mysqltest_1@localhost;
|
||||
Grants for mysqltest_1@localhost
|
||||
GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' WITH MAX_QUERIES_PER_HOUR 10
|
||||
grant usage on *.* to mysqltest_1@localhost with max_updates_per_hour 20 max_connections_per_hour 30;
|
||||
select * from mysql.user where user="mysqltest_1";
|
||||
Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections
|
||||
localhost mysqltest_1 N N N N N N N N N N N N N N N N N N N N N 10 20 30
|
||||
show grants for mysqltest_1@localhost;
|
||||
Grants for mysqltest_1@localhost
|
||||
GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' WITH MAX_QUERIES_PER_HOUR 10 MAX_UPDATES_PER_HOUR 20 MAX_CONNECTIONS_PER_HOUR 30
|
||||
flush privileges;
|
||||
show grants for mysqltest_1@localhost;
|
||||
Grants for mysqltest_1@localhost
|
||||
GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' WITH MAX_QUERIES_PER_HOUR 10 MAX_UPDATES_PER_HOUR 20 MAX_CONNECTIONS_PER_HOUR 30
|
||||
delete from mysql.user where user='mysqltest_1';
|
||||
flush privileges;
|
||||
grant CREATE TEMPORARY TABLES, LOCK TABLES on mysqltest.* to mysqltest_1@localhost;
|
||||
show grants for mysqltest_1@localhost;
|
||||
Grants for mysqltest_1@localhost
|
||||
|
@ -45,7 +45,6 @@ show grants for current_user();
|
||||
Grants for mysqltest_1@localhost
|
||||
GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost'
|
||||
GRANT SELECT, INSERT ON `mysqltest`.* TO 'mysqltest_1'@'localhost'
|
||||
use mysqltest;
|
||||
insert into t1 values (1, 'I can''t change it!');
|
||||
update t1 set data='I can change it!' where id = 1;
|
||||
ERROR 42000: update command denied to user 'mysqltest_1'@'localhost' for table 't1'
|
||||
@ -55,8 +54,6 @@ select * from t1;
|
||||
id data
|
||||
1 I can't change it!
|
||||
drop table t1;
|
||||
drop database mysqltest;
|
||||
use test;
|
||||
delete from mysql.user where user like 'mysqltest\_%';
|
||||
delete from mysql.db where user like 'mysqltest\_%';
|
||||
flush privileges;
|
||||
@ -222,3 +219,17 @@ drop user mysqltest_B@'%';
|
||||
ERROR 42000: Access denied for user 'mysqltest_3'@'localhost' to database 'mysql'
|
||||
drop user mysqltest_B@'%';
|
||||
drop user mysqltest_3@localhost;
|
||||
create table t1 (a int, b int);
|
||||
grant select (a) on t1 to mysqltest_1@localhost with grant option;
|
||||
grant select (a,b) on t1 to mysqltest_2@localhost;
|
||||
ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for column 'b' in table 't1'
|
||||
grant select on t1 to mysqltest_3@localhost;
|
||||
ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for table 't1'
|
||||
drop table t1;
|
||||
delete from mysql.user where user like 'mysqltest\_%';
|
||||
delete from mysql.db where user like 'mysqltest\_%';
|
||||
delete from mysql.tables_priv where user like 'mysqltest\_%';
|
||||
delete from mysql.columns_priv where user like 'mysqltest\_%';
|
||||
flush privileges;
|
||||
drop database mysqltest;
|
||||
use test;
|
||||
|
@ -134,7 +134,7 @@ a b c a
|
||||
1 1 1 test.t1
|
||||
2 2 2 test.t1
|
||||
select * from t2;
|
||||
ERROR 42000: select command denied to user 'mysqltest_2'@'localhost' for table 't2'
|
||||
ERROR 42000: SELECT command denied to user 'mysqltest_2'@'localhost' for table 't2'
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 6
|
||||
@ -148,7 +148,7 @@ select "user3";
|
||||
user3
|
||||
user3
|
||||
select * from t1;
|
||||
ERROR 42000: select command denied to user 'mysqltest_3'@'localhost' for column 'b' in table 't1'
|
||||
ERROR 42000: SELECT command denied to user 'mysqltest_3'@'localhost' for column 'b' in table 't1'
|
||||
select a from t1;
|
||||
a
|
||||
1
|
||||
@ -156,7 +156,7 @@ a
|
||||
select c from t1;
|
||||
ERROR 42000: SELECT command denied to user 'mysqltest_3'@'localhost' for column 'c' in table 't1'
|
||||
select * from t2;
|
||||
ERROR 42000: select command denied to user 'mysqltest_3'@'localhost' for table 't2'
|
||||
ERROR 42000: SELECT command denied to user 'mysqltest_3'@'localhost' for table 't2'
|
||||
select mysqltest.t1.c from test.t1,mysqltest.t1;
|
||||
ERROR 42000: SELECT command denied to user 'mysqltest_3'@'localhost' for column 'c' in table 't1'
|
||||
show status like "Qcache_queries_in_cache";
|
||||
|
@ -677,4 +677,9 @@ a b c
|
||||
1 2 0
|
||||
1 1 1
|
||||
1 1 0
|
||||
show index from t3;
|
||||
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
|
||||
t3 1 a 1 a A NULL NULL NULL YES BTREE
|
||||
t3 1 a 2 b A NULL NULL NULL YES BTREE
|
||||
t3 1 a 3 c A NULL NULL NULL YES BTREE
|
||||
drop table t1, t2, t3;
|
||||
|
@ -387,6 +387,7 @@ USE `test`;
|
||||
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
|
||||
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
|
||||
|
||||
drop database mysqldump_test_db;
|
||||
create database mysqldump_test_db character set latin2 collate latin2_bin;
|
||||
|
||||
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
|
||||
@ -409,3 +410,143 @@ USE `mysqldump_test_db`;
|
||||
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
|
||||
|
||||
drop database mysqldump_test_db;
|
||||
CREATE TABLE t1 (a CHAR(10));
|
||||
INSERT INTO t1 VALUES (_latin1 'ÄÖÜß');
|
||||
|
||||
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
|
||||
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
|
||||
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
|
||||
/*!40101 SET NAMES utf8 */;
|
||||
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
|
||||
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
|
||||
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE="NO_AUTO_VALUE_ON_ZERO" */;
|
||||
DROP TABLE IF EXISTS `t1`;
|
||||
CREATE TABLE `t1` (
|
||||
`a` char(10) default NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
|
||||
|
||||
|
||||
/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
|
||||
LOCK TABLES `t1` WRITE;
|
||||
INSERT INTO `t1` VALUES ('ÄÖÜß');
|
||||
UNLOCK TABLES;
|
||||
/*!40000 ALTER TABLE `t1` ENABLE KEYS */;
|
||||
|
||||
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
|
||||
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
|
||||
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
|
||||
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
||||
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
|
||||
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
|
||||
|
||||
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
|
||||
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
|
||||
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE="NO_AUTO_VALUE_ON_ZERO,MYSQL323" */;
|
||||
DROP TABLE IF EXISTS `t1`;
|
||||
CREATE TABLE `t1` (
|
||||
`a` char(10) default NULL
|
||||
) TYPE=MyISAM;
|
||||
|
||||
|
||||
/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
|
||||
LOCK TABLES `t1` WRITE;
|
||||
INSERT INTO `t1` VALUES ('ÄÖÜß');
|
||||
UNLOCK TABLES;
|
||||
/*!40000 ALTER TABLE `t1` ENABLE KEYS */;
|
||||
|
||||
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
|
||||
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
|
||||
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
|
||||
|
||||
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
|
||||
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
|
||||
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE="NO_AUTO_VALUE_ON_ZERO,MYSQL323" */;
|
||||
DROP TABLE IF EXISTS `t1`;
|
||||
CREATE TABLE `t1` (
|
||||
`a` char(10) default NULL
|
||||
) TYPE=MyISAM;
|
||||
|
||||
|
||||
/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
|
||||
LOCK TABLES `t1` WRITE;
|
||||
INSERT INTO `t1` VALUES ('Ž™šá');
|
||||
UNLOCK TABLES;
|
||||
/*!40000 ALTER TABLE `t1` ENABLE KEYS */;
|
||||
|
||||
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
|
||||
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
|
||||
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
|
||||
|
||||
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
|
||||
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
|
||||
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE="NO_AUTO_VALUE_ON_ZERO,MYSQL323" */;
|
||||
DROP TABLE IF EXISTS `t1`;
|
||||
CREATE TABLE `t1` (
|
||||
`a` char(10) default NULL
|
||||
) TYPE=MyISAM;
|
||||
|
||||
|
||||
/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
|
||||
LOCK TABLES `t1` WRITE;
|
||||
INSERT INTO `t1` VALUES ('Ž™šá');
|
||||
UNLOCK TABLES;
|
||||
/*!40000 ALTER TABLE `t1` ENABLE KEYS */;
|
||||
|
||||
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
|
||||
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
|
||||
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
|
||||
|
||||
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
|
||||
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
|
||||
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE="NO_AUTO_VALUE_ON_ZERO,MYSQL323" */;
|
||||
DROP TABLE IF EXISTS `t1`;
|
||||
CREATE TABLE `t1` (
|
||||
`a` char(10) default NULL
|
||||
) TYPE=MyISAM;
|
||||
|
||||
|
||||
/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
|
||||
LOCK TABLES `t1` WRITE;
|
||||
INSERT INTO `t1` VALUES ('ÄÖÜß');
|
||||
UNLOCK TABLES;
|
||||
/*!40000 ALTER TABLE `t1` ENABLE KEYS */;
|
||||
|
||||
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
|
||||
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
|
||||
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
|
||||
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (a int);
|
||||
CREATE TABLE t2 (a int);
|
||||
INSERT INTO t1 VALUES (1),(2),(3);
|
||||
INSERT INTO t2 VALUES (4),(5),(6);
|
||||
|
||||
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
|
||||
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
|
||||
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
|
||||
/*!40101 SET NAMES utf8 */;
|
||||
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
|
||||
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
|
||||
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE="NO_AUTO_VALUE_ON_ZERO" */;
|
||||
DROP TABLE IF EXISTS `t2`;
|
||||
CREATE TABLE `t2` (
|
||||
`a` int(11) default NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
|
||||
|
||||
|
||||
/*!40000 ALTER TABLE `t2` DISABLE KEYS */;
|
||||
LOCK TABLES `t2` WRITE;
|
||||
INSERT INTO `t2` VALUES (4),(5),(6);
|
||||
UNLOCK TABLES;
|
||||
/*!40000 ALTER TABLE `t2` ENABLE KEYS */;
|
||||
|
||||
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
|
||||
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
|
||||
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
|
||||
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
||||
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
|
||||
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
|
||||
|
||||
DROP TABLE t1;
|
||||
DROP TABLE t2;
|
||||
drop database mysqldump_test_db;
|
||||
|
@ -467,3 +467,21 @@ a b
|
||||
1 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
2 BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
|
||||
drop table t1;
|
||||
create table t1 (
|
||||
id int(11) unsigned primary key NOT NULL auto_increment,
|
||||
msg text NOT NULL
|
||||
) engine=ndbcluster default charset=utf8;
|
||||
insert into t1 (msg) values(
|
||||
'Tries to validate (8 byte length + inline bytes) as UTF8 :(
|
||||
Fast fix: removed validation for Text. It is not yet indexable
|
||||
so bad data will not crash kernel.
|
||||
Proper fix: Set inline bytes to multiple of mbmaxlen and
|
||||
validate it (after the 8 byte length).');
|
||||
select * from t1;
|
||||
id msg
|
||||
1 Tries to validate (8 byte length + inline bytes) as UTF8 :(
|
||||
Fast fix: removed validation for Text. It is not yet indexable
|
||||
so bad data will not crash kernel.
|
||||
Proper fix: Set inline bytes to multiple of mbmaxlen and
|
||||
validate it (after the 8 byte length).
|
||||
drop table t1;
|
||||
|
@ -834,7 +834,7 @@ execute s_t9 ;
|
||||
my_col
|
||||
1
|
||||
select a as my_col from t1;
|
||||
ERROR 42000: select command denied to user 'second_user'@'localhost' for table 't1'
|
||||
ERROR 42000: SELECT command denied to user 'second_user'@'localhost' for table 't1'
|
||||
grant select on mysqltest.t1 to second_user@localhost
|
||||
identified by 'looser' ;
|
||||
show grants for second_user@localhost ;
|
||||
@ -873,7 +873,7 @@ Grants for second_user@localhost
|
||||
GRANT USAGE ON *.* TO 'second_user'@'localhost' IDENTIFIED BY PASSWORD '*13843FE600B19A81E32AF50D4A6FED25875FF1F3'
|
||||
GRANT SELECT ON `mysqltest`.`t9` TO 'second_user'@'localhost'
|
||||
execute s_t1 ;
|
||||
ERROR 42000: select command denied to user 'second_user'@'localhost' for table 't1'
|
||||
ERROR 42000: SELECT command denied to user 'second_user'@'localhost' for table 't1'
|
||||
revoke all privileges, grant option from second_user@localhost ;
|
||||
show grants for second_user@localhost ;
|
||||
Grants for second_user@localhost
|
||||
|
@ -1433,7 +1433,7 @@ Note 1003 (select `test`.`t1`.`s1` AS `s1` from `test`.`t1`)
|
||||
s1
|
||||
tttt
|
||||
drop table t1;
|
||||
create table t1 (s1 char(5), index s1(s1));
|
||||
create table t1 (s1 char(5) not null, index s1(s1));
|
||||
create table t2 (s1 char(5), index s1(s1));
|
||||
insert into t1 values ('a1'),('a2'),('a3');
|
||||
insert into t2 values ('a1'),('a2');
|
||||
@ -1459,25 +1459,25 @@ a2 1
|
||||
a3 1
|
||||
explain extended select s1, s1 NOT IN (SELECT s1 FROM t2) from t1;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 index NULL s1 6 NULL 3 Using index
|
||||
1 PRIMARY t1 index NULL s1 5 NULL 3 Using index
|
||||
2 DEPENDENT SUBQUERY t2 index_subquery s1 s1 6 func 2 Using index
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`s1` AS `s1`,not(<in_optimizer>(`test`.`t1`.`s1`,<exists>(<index_lookup>(<cache>(`test`.`t1`.`s1`) in t2 on s1 chicking NULL)))) AS `s1 NOT IN (SELECT s1 FROM t2)` from `test`.`t1`
|
||||
explain extended select s1, s1 = ANY (SELECT s1 FROM t2) from t1;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 index NULL s1 6 NULL 3 Using index
|
||||
1 PRIMARY t1 index NULL s1 5 NULL 3 Using index
|
||||
2 DEPENDENT SUBQUERY t2 index_subquery s1 s1 6 func 2 Using index
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`s1` AS `s1`,<in_optimizer>(`test`.`t1`.`s1`,<exists>(<index_lookup>(<cache>(`test`.`t1`.`s1`) in t2 on s1 chicking NULL))) AS `s1 = ANY (SELECT s1 FROM t2)` from `test`.`t1`
|
||||
explain extended select s1, s1 <> ALL (SELECT s1 FROM t2) from t1;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 index NULL s1 6 NULL 3 Using index
|
||||
1 PRIMARY t1 index NULL s1 5 NULL 3 Using index
|
||||
2 DEPENDENT SUBQUERY t2 index_subquery s1 s1 6 func 2 Using index
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`s1` AS `s1`,not(<in_optimizer>(`test`.`t1`.`s1`,<exists>(<index_lookup>(<cache>(`test`.`t1`.`s1`) in t2 on s1 chicking NULL)))) AS `s1 <> ALL (SELECT s1 FROM t2)` from `test`.`t1`
|
||||
explain extended select s1, s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2') from t1;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 index NULL s1 6 NULL 3 Using index
|
||||
1 PRIMARY t1 index NULL s1 5 NULL 3 Using index
|
||||
2 DEPENDENT SUBQUERY t2 index_subquery s1 s1 6 func 1 Using index; Using where
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`s1` AS `s1`,not(<in_optimizer>(`test`.`t1`.`s1`,<exists>(<index_lookup>(<cache>(`test`.`t1`.`s1`) in t2 on s1 chicking NULL where (`test`.`t2`.`s1` < _latin1'a2'))))) AS `s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2')` from `test`.`t1`
|
||||
@ -2133,3 +2133,30 @@ SELECT DISTINCT Continent AS c FROM t1 WHERE Code <> SOME ( SELECT Code FROM t1
|
||||
c
|
||||
Oceania
|
||||
drop table t1;
|
||||
CREATE TABLE t1 ( f1 BIGINT );
|
||||
INSERT INTO t1 SET f1= NULL;
|
||||
INSERT INTO t1 SET f1= 1;
|
||||
CREATE TABLE t2 ( f1 BIGINT );
|
||||
SELECT f1 FROM t1
|
||||
WHERE f1 <> ALL ( SELECT f1 FROM t2 );
|
||||
f1
|
||||
NULL
|
||||
1
|
||||
INSERT INTO t2 VALUES (1), (2);
|
||||
SELECT f1 FROM t1
|
||||
WHERE f1 <> ALL ( SELECT f1 FROM t2 WHERE f1 > 2 );
|
||||
f1
|
||||
NULL
|
||||
1
|
||||
SELECT f1 FROM t1
|
||||
WHERE f1 <> ALL ( SELECT f1 FROM t2 WHERE f1 > 2
|
||||
UNION
|
||||
SELECT f1 FROM t2 WHERE f1 > 3);
|
||||
f1
|
||||
NULL
|
||||
1
|
||||
SELECT f1 FROM t1
|
||||
WHERE f1 <> ALL ( SELECT SUM(f1) AS sf1 FROM t2 HAVING sf1 > 10000);
|
||||
f1
|
||||
NULL
|
||||
1
|
||||
|
@ -297,9 +297,9 @@ convert_tz(b, 'Europe/Moscow', 'UTC')
|
||||
update t1, t2 set t1.b = convert_tz('2004-11-30 12:00:00', 'Europe/Moscow', 'UTC')
|
||||
where t1.a = t2.c and t2.d = (select max(d) from t2);
|
||||
select * from mysql.time_zone_name;
|
||||
ERROR 42000: select command denied to user 'mysqltest_1'@'localhost' for table 'time_zone_name'
|
||||
ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for table 'time_zone_name'
|
||||
select Name, convert_tz('2004-11-30 12:00:00', Name, 'UTC') from mysql.time_zone_name;
|
||||
ERROR 42000: select command denied to user 'mysqltest_1'@'localhost' for table 'time_zone_name'
|
||||
ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for table 'time_zone_name'
|
||||
delete from mysql.user where user like 'mysqltest\_%';
|
||||
delete from mysql.db where user like 'mysqltest\_%';
|
||||
delete from mysql.tables_priv where user like 'mysqltest\_%';
|
||||
|
@ -145,13 +145,13 @@ set global timed_mutexes=0;
|
||||
show variables like 'timed_mutexes';
|
||||
Variable_name Value
|
||||
timed_mutexes OFF
|
||||
set storage_engine=MYISAM, storage_engine="HEAP", global storage_engine="INNODB";
|
||||
set storage_engine=MYISAM, storage_engine="HEAP", global storage_engine="MERGE";
|
||||
show local variables like 'storage_engine';
|
||||
Variable_name Value
|
||||
storage_engine HEAP
|
||||
show global variables like 'storage_engine';
|
||||
Variable_name Value
|
||||
storage_engine InnoDB
|
||||
storage_engine MERGE
|
||||
set GLOBAL query_cache_size=100000;
|
||||
set GLOBAL myisam_max_sort_file_size=2000000;
|
||||
show global variables like 'myisam_max_sort_file_size';
|
||||
@ -250,7 +250,7 @@ set max_join_size="hello";
|
||||
ERROR 42000: Incorrect argument type to variable 'max_join_size'
|
||||
set storage_engine=UNKNOWN_TABLE_TYPE;
|
||||
ERROR 42000: Unknown table engine 'UNKNOWN_TABLE_TYPE'
|
||||
set storage_engine=INNODB, big_tables=2;
|
||||
set storage_engine=MERGE, big_tables=2;
|
||||
ERROR 42000: Variable 'big_tables' can't be set to the value of '2'
|
||||
show local variables like 'storage_engine';
|
||||
Variable_name Value
|
||||
|
@ -376,3 +376,13 @@ insert into t1 values ('x,y');
|
||||
insert into t1 values ('x,y,z,Ä,Ö,Ü');
|
||||
select a, hex(a) from t1 order by a;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Bug#7302 UCS2 data in ENUM fields get truncated when new column is added
|
||||
#
|
||||
create table t1(a enum('a','b','c')) default character set ucs2;
|
||||
insert into t1 values('a'),('b'),('c');
|
||||
alter table t1 add b char(1);
|
||||
show warnings;
|
||||
select * from t1 order by a;
|
||||
drop table t1;
|
||||
|
@ -166,6 +166,8 @@ select date,format,cast(str_to_date(date, format) as datetime) as datetime from
|
||||
select date,format,DATE(str_to_date(date, format)) as date2 from t1;
|
||||
select date,format,TIME(str_to_date(date, format)) as time from t1;
|
||||
select date,format,concat(TIME(str_to_date(date, format))) as time2 from t1;
|
||||
# Test small bug in %f handling
|
||||
select concat('',str_to_date('8:11:2.123456 03-01-02','%H:%i:%S.%f %y-%m-%d'));
|
||||
|
||||
# Test wrong dates or converion specifiers
|
||||
|
||||
|
@ -51,3 +51,10 @@ SELECT ASIN(1.2-0.2);
|
||||
#select floor(log(16)/log(2));
|
||||
|
||||
explain extended select degrees(pi()),radians(360);
|
||||
|
||||
#
|
||||
# Bug #7281: problem with rand()
|
||||
#
|
||||
|
||||
--error 1054
|
||||
select rand(rand);
|
||||
|
@ -429,3 +429,17 @@ create table t1 (a int not null primary key, b varchar(40), c datetime);
|
||||
insert into t1 (a,b,c) values (1,'Tom','2004-12-10 12:13:14'),(2,'ball games','2004-12-10 12:13:14'), (3,'Basil','2004-12-10 12:13:14'), (4,'Dean','2004-12-10 12:13:14'),(5,'Ellis','2004-12-10 12:13:14'), (6,'Serg','2004-12-10 12:13:14'), (7,'Sergei','2004-12-10 12:13:14'),(8,'Georg','2004-12-10 12:13:14'),(9,'Salle','2004-12-10 12:13:14'),(10,'Sinisa','2004-12-10 12:13:14');
|
||||
select count(*) as total, left(c,10) as reg from t1 group by reg order by reg desc limit 0,12;
|
||||
drop table t1;
|
||||
# crashing bug with QUOTE() and LTRIM() or TRIM() fixed
|
||||
# Bug #7495
|
||||
#
|
||||
|
||||
select quote(ltrim(concat(' ', 'a')));
|
||||
select quote(trim(concat(' ', 'a')));
|
||||
|
||||
#
|
||||
# Bug#7455 unexpected result: TRIM(<NULL> FROM <whatever>) gives NOT NULL
|
||||
# According to ANSI if one of the TRIM arguments is NULL, then the result
|
||||
# must be NULL too.
|
||||
#
|
||||
select trim(null from 'kate') as "must_be_null";
|
||||
select trim('xyz' from null) as "must_be_null";
|
||||
|
@ -32,6 +32,23 @@ show grants for mysqltest_1@localhost;
|
||||
delete from mysql.user where user='mysqltest_1';
|
||||
flush privileges;
|
||||
|
||||
#
|
||||
# Test of GRANTS specifying user limits
|
||||
#
|
||||
delete from mysql.user where user='mysqltest_1';
|
||||
flush privileges;
|
||||
grant usage on *.* to mysqltest_1@localhost with max_queries_per_hour 10;
|
||||
select * from mysql.user where user="mysqltest_1";
|
||||
show grants for mysqltest_1@localhost;
|
||||
grant usage on *.* to mysqltest_1@localhost with max_updates_per_hour 20 max_connections_per_hour 30;
|
||||
select * from mysql.user where user="mysqltest_1";
|
||||
show grants for mysqltest_1@localhost;
|
||||
# This is just to double check that one won't ignore results of selects
|
||||
flush privileges;
|
||||
show grants for mysqltest_1@localhost;
|
||||
delete from mysql.user where user='mysqltest_1';
|
||||
flush privileges;
|
||||
|
||||
#
|
||||
# Test that the new db privileges are stored/retrieved correctly
|
||||
#
|
||||
|
@ -59,10 +59,9 @@ flush privileges;
|
||||
use mysqltest;
|
||||
create table t1 (id int primary key, data varchar(255));
|
||||
|
||||
connect (mrbad, localhost, mysqltest_1,,);
|
||||
connect (mrbad, localhost, mysqltest_1,,mysqltest);
|
||||
connection mrbad;
|
||||
show grants for current_user();
|
||||
use mysqltest;
|
||||
insert into t1 values (1, 'I can''t change it!');
|
||||
--error 1142
|
||||
update t1 set data='I can change it!' where id = 1;
|
||||
@ -70,11 +69,10 @@ update t1 set data='I can change it!' where id = 1;
|
||||
--error 1142
|
||||
insert into t1 values (1, 'XXX') on duplicate key update data= 'I can change it!';
|
||||
select * from t1;
|
||||
disconnect mrbad;
|
||||
|
||||
connection default;
|
||||
drop table t1;
|
||||
drop database mysqltest;
|
||||
use test;
|
||||
delete from mysql.user where user like 'mysqltest\_%';
|
||||
delete from mysql.db where user like 'mysqltest\_%';
|
||||
flush privileges;
|
||||
@ -226,4 +224,26 @@ connection default;
|
||||
drop user mysqltest_B@'%';
|
||||
drop user mysqltest_3@localhost;
|
||||
#
|
||||
#
|
||||
#
|
||||
create table t1 (a int, b int);
|
||||
grant select (a) on t1 to mysqltest_1@localhost with grant option;
|
||||
connect (mrugly, localhost, mysqltest_1,,mysqltest);
|
||||
connection mrugly;
|
||||
--error 1143
|
||||
grant select (a,b) on t1 to mysqltest_2@localhost;
|
||||
--error 1142
|
||||
grant select on t1 to mysqltest_3@localhost;
|
||||
disconnect mrugly;
|
||||
|
||||
connection default;
|
||||
drop table t1;
|
||||
delete from mysql.user where user like 'mysqltest\_%';
|
||||
delete from mysql.db where user like 'mysqltest\_%';
|
||||
delete from mysql.tables_priv where user like 'mysqltest\_%';
|
||||
delete from mysql.columns_priv where user like 'mysqltest\_%';
|
||||
flush privileges;
|
||||
|
||||
drop database mysqltest;
|
||||
use test;
|
||||
|
||||
|
@ -303,5 +303,8 @@ select a,b,c from t3 force index (a) where a=1 order by a,b,c;
|
||||
explain select a,b,c from t3 force index (a) where a=1 order by a desc, b desc, c desc;
|
||||
select a,b,c from t3 force index (a) where a=1 order by a desc, b desc, c desc;
|
||||
|
||||
# BUG#7377 SHOW index on MERGE table crashes debug server
|
||||
show index from t3;
|
||||
|
||||
drop table t1, t2, t3;
|
||||
|
||||
|
@ -434,6 +434,7 @@ delete t1 from t1,t2 where t1.col1 < (select max(col1) from t1) and t1.col1 = t2
|
||||
drop table t1,t2;
|
||||
|
||||
# Test for BUG#5837 - delete with outer join and const tables
|
||||
--disable_warnings
|
||||
create table t1 (
|
||||
aclid bigint not null primary key,
|
||||
status tinyint(1) not null
|
||||
@ -443,6 +444,7 @@ create table t2 (
|
||||
refid bigint not null primary key,
|
||||
aclid bigint, index idx_acl(aclid)
|
||||
) engine = innodb;
|
||||
--enable_warnings
|
||||
insert into t2 values(1,null);
|
||||
delete t2, t1 from t2 left join t1 on (t2.aclid=t1.aclid) where t2.refid='1';
|
||||
drop table t1, t2;
|
||||
|
@ -146,3 +146,31 @@ drop table t1;
|
||||
create database mysqldump_test_db character set latin2 collate latin2_bin;
|
||||
--exec $MYSQL_DUMP --skip-comments --databases mysqldump_test_db;
|
||||
drop database mysqldump_test_db;
|
||||
|
||||
#
|
||||
# Bug #7020
|
||||
# Check that we don't dump in UTF8 in compatible mode by default,
|
||||
# but use the default compiled values, or the values given in
|
||||
# --default-character-set=xxx. However, we should dump in UTF8
|
||||
# if it is explicitely set.
|
||||
|
||||
CREATE TABLE t1 (a CHAR(10));
|
||||
INSERT INTO t1 VALUES (_latin1 'ÄÖÜß');
|
||||
--exec $MYSQL_DUMP --character-sets-dir=$CHARSETSDIR --skip-comments test t1
|
||||
--exec $MYSQL_DUMP --character-sets-dir=$CHARSETSDIR --skip-comments --compatible=mysql323 test t1
|
||||
--exec $MYSQL_DUMP --character-sets-dir=$CHARSETSDIR --skip-comments --compatible=mysql323 --default-character-set=cp850 test t1
|
||||
--exec $MYSQL_DUMP --character-sets-dir=$CHARSETSDIR --skip-comments --default-character-set=cp850 --compatible=mysql323 test t1
|
||||
--exec $MYSQL_DUMP --character-sets-dir=$CHARSETSDIR --skip-comments --default-character-set=utf8 --compatible=mysql323 test t1
|
||||
DROP TABLE t1;
|
||||
|
||||
#
|
||||
# WL #2319: Exclude Tables from dump
|
||||
#
|
||||
|
||||
CREATE TABLE t1 (a int);
|
||||
CREATE TABLE t2 (a int);
|
||||
INSERT INTO t1 VALUES (1),(2),(3);
|
||||
INSERT INTO t2 VALUES (4),(5),(6);
|
||||
--exec $MYSQL_DUMP --skip-comments --ignore-table=test.t1 test
|
||||
DROP TABLE t1;
|
||||
DROP TABLE t2;
|
||||
|
@ -389,3 +389,17 @@ set autocommit=1;
|
||||
alter table t1 engine=myisam;
|
||||
select * from t1 order by a;
|
||||
drop table t1;
|
||||
|
||||
# -- bug #7340 --
|
||||
create table t1 (
|
||||
id int(11) unsigned primary key NOT NULL auto_increment,
|
||||
msg text NOT NULL
|
||||
) engine=ndbcluster default charset=utf8;
|
||||
insert into t1 (msg) values(
|
||||
'Tries to validate (8 byte length + inline bytes) as UTF8 :(
|
||||
Fast fix: removed validation for Text. It is not yet indexable
|
||||
so bad data will not crash kernel.
|
||||
Proper fix: Set inline bytes to multiple of mbmaxlen and
|
||||
validate it (after the 8 byte length).');
|
||||
select * from t1;
|
||||
drop table t1;
|
||||
|
@ -894,7 +894,7 @@ drop table t1;
|
||||
#
|
||||
# IN optimisation test results
|
||||
#
|
||||
create table t1 (s1 char(5), index s1(s1));
|
||||
create table t1 (s1 char(5) not null, index s1(s1));
|
||||
create table t2 (s1 char(5), index s1(s1));
|
||||
insert into t1 values ('a1'),('a2'),('a3');
|
||||
insert into t2 values ('a1'),('a2');
|
||||
@ -1391,3 +1391,29 @@ INSERT INTO t1 VALUES ('UMI','United States Minor Outlying Islands','Oceania','M
|
||||
/*!40000 ALTER TABLE t1 ENABLE KEYS */;
|
||||
SELECT DISTINCT Continent AS c FROM t1 WHERE Code <> SOME ( SELECT Code FROM t1 WHERE Continent = c AND Population < 200);
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Test cases for bug #7351:
|
||||
# quantified predicate with subquery returning empty result set
|
||||
#
|
||||
|
||||
CREATE TABLE t1 ( f1 BIGINT );
|
||||
INSERT INTO t1 SET f1= NULL;
|
||||
INSERT INTO t1 SET f1= 1;
|
||||
CREATE TABLE t2 ( f1 BIGINT );
|
||||
|
||||
SELECT f1 FROM t1
|
||||
WHERE f1 <> ALL ( SELECT f1 FROM t2 );
|
||||
|
||||
INSERT INTO t2 VALUES (1), (2);
|
||||
|
||||
SELECT f1 FROM t1
|
||||
WHERE f1 <> ALL ( SELECT f1 FROM t2 WHERE f1 > 2 );
|
||||
|
||||
SELECT f1 FROM t1
|
||||
WHERE f1 <> ALL ( SELECT f1 FROM t2 WHERE f1 > 2
|
||||
UNION
|
||||
SELECT f1 FROM t2 WHERE f1 > 3);
|
||||
|
||||
SELECT f1 FROM t1
|
||||
WHERE f1 <> ALL ( SELECT SUM(f1) AS sf1 FROM t2 HAVING sf1 > 10000);
|
||||
|
@ -89,7 +89,7 @@ set global timed_mutexes=0;
|
||||
show variables like 'timed_mutexes';
|
||||
|
||||
|
||||
set storage_engine=MYISAM, storage_engine="HEAP", global storage_engine="INNODB";
|
||||
set storage_engine=MYISAM, storage_engine="HEAP", global storage_engine="MERGE";
|
||||
show local variables like 'storage_engine';
|
||||
show global variables like 'storage_engine';
|
||||
set GLOBAL query_cache_size=100000;
|
||||
@ -146,7 +146,7 @@ set max_join_size="hello";
|
||||
--error 1286
|
||||
set storage_engine=UNKNOWN_TABLE_TYPE;
|
||||
--error 1231
|
||||
set storage_engine=INNODB, big_tables=2;
|
||||
set storage_engine=MERGE, big_tables=2;
|
||||
show local variables like 'storage_engine';
|
||||
--error 1229
|
||||
set SESSION query_cache_size=10000;
|
||||
|
@ -5,7 +5,7 @@ LDADD += $(top_builddir)/ndb/test/src/libNDBT.a \
|
||||
$(top_builddir)/mysys/libmysys.a \
|
||||
$(top_builddir)/strings/libmystrings.a @NDB_SCI_LIBS@
|
||||
|
||||
INCLUDES += -I$(srcdir) -I$(top_srcdir)/include \
|
||||
INCLUDES += -I$(top_srcdir) -I$(top_srcdir)/include \
|
||||
-I$(top_srcdir)/ndb/include \
|
||||
-I$(top_srcdir)/ndb/include/ndbapi \
|
||||
-I$(top_srcdir)/ndb/include/util \
|
||||
|
@ -2,6 +2,7 @@
|
||||
include $(top_srcdir)/ndb/config/common.mk.am
|
||||
|
||||
ndbinclude_HEADERS = \
|
||||
ndb_init.h \
|
||||
ndb_types.h \
|
||||
ndb_version.h
|
||||
|
||||
|
@ -19,7 +19,6 @@
|
||||
|
||||
#include "Logger.hpp"
|
||||
|
||||
|
||||
/**
|
||||
* This class is the base class for all log handlers. A log handler is
|
||||
* responsible for formatting and writing log messages to a specific output.
|
||||
@ -68,7 +67,8 @@ public:
|
||||
/**
|
||||
* Append a log message to the output stream/file whatever.
|
||||
* append() will call writeHeader(), writeMessage() and writeFooter() for
|
||||
* a child class and in that order.
|
||||
* a child class and in that order. Append checks for repeated messages.
|
||||
* append_impl() does not check for repeats.
|
||||
*
|
||||
* @param pCategory the category/name to tag the log entry with.
|
||||
* @param level the log level.
|
||||
@ -76,6 +76,8 @@ public:
|
||||
*/
|
||||
void append(const char* pCategory, Logger::LoggerLevel level,
|
||||
const char* pMsg);
|
||||
void append_impl(const char* pCategory, Logger::LoggerLevel level,
|
||||
const char* pMsg);
|
||||
|
||||
/**
|
||||
* Returns a default formatted header. It currently has the
|
||||
@ -111,14 +113,6 @@ public:
|
||||
*/
|
||||
void setDateTimeFormat(const char* pFormat);
|
||||
|
||||
/**
|
||||
* Returns a string date and time string.
|
||||
*
|
||||
* @param pStr a string.
|
||||
* @return a string with date and time.
|
||||
*/
|
||||
char* getTimeAsString(char* pStr) const;
|
||||
|
||||
/**
|
||||
* Returns the error code.
|
||||
*/
|
||||
@ -185,6 +179,15 @@ protected:
|
||||
virtual void writeFooter() = 0;
|
||||
|
||||
private:
|
||||
/**
|
||||
* Returns a string date and time string.
|
||||
* @note does not update time, uses m_now as time
|
||||
* @param pStr a string.
|
||||
* @return a string with date and time.
|
||||
*/
|
||||
char* getTimeAsString(char* pStr) const;
|
||||
time_t m_now;
|
||||
|
||||
/** Prohibit */
|
||||
LogHandler(const LogHandler&);
|
||||
LogHandler* operator = (const LogHandler&);
|
||||
@ -192,6 +195,14 @@ private:
|
||||
|
||||
const char* m_pDateTimeFormat;
|
||||
int m_errorCode;
|
||||
|
||||
// for handling repeated messages
|
||||
unsigned m_count_repeated_messages;
|
||||
unsigned m_max_repeat_frequency;
|
||||
time_t m_last_log_time;
|
||||
char m_last_category[MAX_HEADER_LENGTH];
|
||||
char m_last_message[MAX_LOG_MESSAGE_SIZE];
|
||||
Logger::LoggerLevel m_last_level;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -20,6 +20,8 @@
|
||||
#include <ndb_global.h>
|
||||
#include <BaseString.hpp>
|
||||
|
||||
#define MAX_LOG_MESSAGE_SIZE 1024
|
||||
|
||||
class LogHandler;
|
||||
class LogHandlerList;
|
||||
|
||||
|
@ -1,3 +1,18 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#ifndef NDBGLOBAL_H
|
||||
#define NDBGLOBAL_H
|
||||
@ -96,15 +111,12 @@ extern "C" {
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
/* call in main() - does not return on error */
|
||||
extern int ndb_init(void);
|
||||
extern void ndb_end(int);
|
||||
#define NDB_INIT(prog_name) {my_progname=(prog_name); ndb_init();}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#include "ndb_init.h"
|
||||
|
||||
#ifdef SCO
|
||||
|
||||
#ifndef PATH_MAX
|
||||
|
32
ndb/include/ndb_init.h
Normal file
32
ndb/include/ndb_init.h
Normal file
@ -0,0 +1,32 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
|
||||
#ifndef NDB_INIT_H
|
||||
#define NDB_INIT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/* call in main() - does not return on error */
|
||||
extern int ndb_init(void);
|
||||
extern void ndb_end(int);
|
||||
#define NDB_INIT(prog_name) {my_progname=(prog_name); ndb_init();}
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -17,6 +17,8 @@
|
||||
#ifndef NdbApi_H
|
||||
#define NdbApi_H
|
||||
|
||||
#include "ndb_init.h"
|
||||
#include "ndb_cluster_connection.hpp"
|
||||
#include "ndbapi_limits.h"
|
||||
#include "Ndb.hpp"
|
||||
#include "NdbConnection.hpp"
|
||||
|
@ -182,27 +182,12 @@ public:
|
||||
/**
|
||||
* Get blob parts table name. Useful only to test programs.
|
||||
*/
|
||||
STATIC_CONST( BlobTableNameSize = 40 );
|
||||
static int getBlobTableName(char* btname, Ndb* anNdb, const char* tableName, const char* columnName);
|
||||
/**
|
||||
* Return error object. The error may be blob specific (below) or may
|
||||
* be copied from a failed implicit operation.
|
||||
*/
|
||||
const NdbError& getNdbError() const;
|
||||
// "Invalid blob attributes or invalid blob parts table"
|
||||
STATIC_CONST( ErrTable = 4263 );
|
||||
// "Invalid usage of blob attribute"
|
||||
STATIC_CONST( ErrUsage = 4264 );
|
||||
// "Method is not valid in current blob state"
|
||||
STATIC_CONST( ErrState = 4265 );
|
||||
// "Invalid blob seek position"
|
||||
STATIC_CONST( ErrSeek = 4266 );
|
||||
// "Corrupted blob value"
|
||||
STATIC_CONST( ErrCorrupt = 4267 );
|
||||
// "Error in blob head update forced rollback of transaction"
|
||||
STATIC_CONST( ErrAbort = 4268 );
|
||||
// "Unknown blob error"
|
||||
STATIC_CONST( ErrUnknown = 4269 );
|
||||
/**
|
||||
* Return info about all blobs in this operation.
|
||||
*/
|
||||
|
@ -19,7 +19,6 @@
|
||||
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL // Not part of public interface
|
||||
|
||||
#include <ndb_types.h>
|
||||
#include <ndb_global.h>
|
||||
|
||||
class Ndb;
|
||||
class NdbConnection;
|
||||
@ -131,7 +130,9 @@ int
|
||||
NdbReceiver::execTCOPCONF(Uint32 len){
|
||||
Uint32 tmp = m_received_result_length;
|
||||
m_expected_result_length = len;
|
||||
#ifdef assert
|
||||
assert(!(tmp && !len));
|
||||
#endif
|
||||
return ((bool)len ^ (bool)tmp ? 0 : 1);
|
||||
}
|
||||
|
||||
|
@ -18,28 +18,72 @@
|
||||
#ifndef CLUSTER_CONNECTION_HPP
|
||||
#define CLUSTER_CONNECTION_HPP
|
||||
|
||||
struct Ndb_cluster_connection_node_iter;
|
||||
|
||||
/**
|
||||
* @class Ndb_cluster_connection
|
||||
* @brief Represents a connection to a cluster of storage nodes
|
||||
*
|
||||
* Always start your application program by creating a
|
||||
* Ndb_cluster_connection object. Your application should contain
|
||||
* only one Ndb_cluster_connection. Your application connects to
|
||||
* a cluster management server when method connect() is called.
|
||||
* With the method wait_until_ready() it is possible to wait
|
||||
* for the connection to one or several storage nodes.
|
||||
*/
|
||||
class Ndb_cluster_connection {
|
||||
public:
|
||||
/**
|
||||
* Create a connection to a cluster of storage nodes
|
||||
*
|
||||
* @param specify the connectstring for where to find the
|
||||
* management server
|
||||
*/
|
||||
Ndb_cluster_connection(const char * connect_string = 0);
|
||||
~Ndb_cluster_connection();
|
||||
int connect(int no_retries, int retry_delay_in_seconds, int verbose);
|
||||
int start_connect_thread(int (*connect_callback)(void)= 0);
|
||||
|
||||
// add check coupled to init state of cluster connection
|
||||
// timeout_after_first_alive negative - ok only if all alive
|
||||
// timeout_after_first_alive positive - ok if some alive
|
||||
/**
|
||||
* Connect to a cluster management server
|
||||
*
|
||||
* @param no_retries specifies the number of retries to perform
|
||||
* if the connect fails, negative number results in infinite
|
||||
* number of retries
|
||||
* @param retry_delay_in_seconds specifies how often retries should
|
||||
* be performed
|
||||
* @param verbose specifies if the method should print progess
|
||||
*
|
||||
* @return 0 if success,
|
||||
* 1 if retriable error,
|
||||
* -1 if non-retriable error
|
||||
*/
|
||||
int connect(int no_retries=0, int retry_delay_in_seconds=1, int verbose=0);
|
||||
|
||||
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
|
||||
int start_connect_thread(int (*connect_callback)(void)= 0);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Wait until one or several storage nodes are connected
|
||||
*
|
||||
* @param time_out_for_first_alive number of seconds to wait until
|
||||
* first alive node is detected
|
||||
* @param timeout_after_first_alive number of seconds to wait after
|
||||
* first alive node is detected
|
||||
*
|
||||
* @return 0 all nodes alive,
|
||||
* > 0 at least one node alive,
|
||||
* < 0 error
|
||||
*/
|
||||
int wait_until_ready(int timeout_for_first_alive,
|
||||
int timeout_after_first_alive);
|
||||
|
||||
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
|
||||
const char *get_connectstring(char *buf, int buf_sz) const;
|
||||
int get_connected_port() const;
|
||||
const char *get_connected_host() const;
|
||||
|
||||
void set_optimized_node_selection(int val);
|
||||
|
||||
Uint32 no_db_nodes();
|
||||
unsigned no_db_nodes();
|
||||
#endif
|
||||
|
||||
private:
|
||||
friend class Ndb;
|
||||
|
@ -68,6 +68,8 @@ struct TCP_TransporterConfiguration {
|
||||
*/
|
||||
struct SHM_TransporterConfiguration {
|
||||
Uint32 port;
|
||||
const char *remoteHostName;
|
||||
const char *localHostName;
|
||||
NodeId remoteNodeId;
|
||||
NodeId localNodeId;
|
||||
bool checksum;
|
||||
|
@ -99,7 +99,12 @@ public:
|
||||
unsigned sizeOfLongSignalMemory = 100);
|
||||
|
||||
bool init(NodeId localNodeId);
|
||||
|
||||
|
||||
/**
|
||||
* after a connect from client, perform connection using correct transporter
|
||||
*/
|
||||
bool connect_server(NDB_SOCKET_TYPE sockfd);
|
||||
|
||||
/**
|
||||
* Remove all transporters
|
||||
*/
|
||||
|
@ -34,7 +34,7 @@ OPT_NDB_OPTIMIZED_NODE_SELECTION
|
||||
|
||||
#define OPT_NDB_CONNECTSTRING 'c'
|
||||
|
||||
#ifdef NDB_SHM_TRANSPORTER
|
||||
#if defined(NDB_SHM_TRANSPORTER) && MYSQL_VERSION_ID >= 50000
|
||||
#define OPT_NDB_SHM_DEFAULT 1
|
||||
#else
|
||||
#define OPT_NDB_SHM_DEFAULT 0
|
||||
|
@ -24,7 +24,13 @@
|
||||
LogHandler::LogHandler() :
|
||||
m_pDateTimeFormat("%d-%.2d-%.2d %.2d:%.2d:%.2d"),
|
||||
m_errorCode(0)
|
||||
{
|
||||
{
|
||||
m_max_repeat_frequency= 3; // repeat messages maximum every 3 seconds
|
||||
m_count_repeated_messages= 0;
|
||||
m_last_category[0]= 0;
|
||||
m_last_message[0]= 0;
|
||||
m_last_log_time= 0;
|
||||
m_now= 0;
|
||||
}
|
||||
|
||||
LogHandler::~LogHandler()
|
||||
@ -34,11 +40,53 @@ LogHandler::~LogHandler()
|
||||
void
|
||||
LogHandler::append(const char* pCategory, Logger::LoggerLevel level,
|
||||
const char* pMsg)
|
||||
{
|
||||
{
|
||||
time_t now;
|
||||
now= ::time((time_t*)NULL);
|
||||
|
||||
if (level != m_last_level ||
|
||||
strcmp(pCategory, m_last_category) ||
|
||||
strcmp(pMsg, m_last_message))
|
||||
{
|
||||
if (m_count_repeated_messages > 0) // print that message
|
||||
append_impl(m_last_category, m_last_level, m_last_message);
|
||||
|
||||
m_last_level= level;
|
||||
strncpy(m_last_category, pCategory, sizeof(m_last_category));
|
||||
strncpy(m_last_message, pMsg, sizeof(m_last_message));
|
||||
}
|
||||
else // repeated message
|
||||
{
|
||||
if (now < m_last_log_time+m_max_repeat_frequency)
|
||||
{
|
||||
m_count_repeated_messages++;
|
||||
m_now= now;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
m_now= now;
|
||||
|
||||
append_impl(pCategory, level, pMsg);
|
||||
m_last_log_time= now;
|
||||
}
|
||||
|
||||
void
|
||||
LogHandler::append_impl(const char* pCategory, Logger::LoggerLevel level,
|
||||
const char* pMsg)
|
||||
{
|
||||
writeHeader(pCategory, level);
|
||||
writeMessage(pMsg);
|
||||
if (m_count_repeated_messages == 0)
|
||||
writeMessage(pMsg);
|
||||
else
|
||||
{
|
||||
BaseString str(pMsg);
|
||||
str.appfmt(" - Repeated %d times", m_count_repeated_messages);
|
||||
writeMessage(str.c_str());
|
||||
m_count_repeated_messages= 0;
|
||||
}
|
||||
writeFooter();
|
||||
}
|
||||
}
|
||||
|
||||
const char*
|
||||
LogHandler::getDefaultHeader(char* pStr, const char* pCategory,
|
||||
@ -76,12 +124,10 @@ char*
|
||||
LogHandler::getTimeAsString(char* pStr) const
|
||||
{
|
||||
struct tm* tm_now;
|
||||
time_t now;
|
||||
now = ::time((time_t*)NULL);
|
||||
#ifdef NDB_WIN32
|
||||
tm_now = localtime(&now);
|
||||
tm_now = localtime(&m_now);
|
||||
#else
|
||||
tm_now = ::localtime(&now); //uses the "current" timezone
|
||||
tm_now = ::localtime(&m_now); //uses the "current" timezone
|
||||
#endif
|
||||
|
||||
BaseString::snprintf(pStr, MAX_DATE_TIME_HEADER_LENGTH,
|
||||
|
@ -355,11 +355,11 @@ Logger::log(LoggerLevel logLevel, const char* pMsg, va_list ap) const
|
||||
LogHandler* pHandler = NULL;
|
||||
while ( (pHandler = m_pHandlerList->next()) != NULL)
|
||||
{
|
||||
char buf[1024];
|
||||
char buf[MAX_LOG_MESSAGE_SIZE];
|
||||
BaseString::vsnprintf(buf, sizeof(buf), pMsg, ap);
|
||||
pHandler->append(m_pCategory, logLevel, buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -383,6 +383,8 @@ IPCConfig::configureTransporters(Uint32 nodeId,
|
||||
if(iter.get(CFG_SHM_BUFFER_MEM, &conf.shmSize)) break;
|
||||
|
||||
conf.port= server_port;
|
||||
conf.localHostName = localHostName;
|
||||
conf.remoteHostName = remoteHostName;
|
||||
|
||||
if(!tr.createTransporter(&conf)){
|
||||
DBUG_PRINT("error", ("Failed to create SHM Transporter from %d to %d",
|
||||
|
@ -13,7 +13,7 @@ EXTRA_libtransporter_la_SOURCES = SHM_Transporter.cpp SHM_Transporter.unix.cpp S
|
||||
libtransporter_la_LIBADD = @ndb_transporter_opt_objs@
|
||||
libtransporter_la_DEPENDENCIES = @ndb_transporter_opt_objs@
|
||||
|
||||
INCLUDES_LOC = -I$(top_srcdir)/ndb/include/kernel -I$(top_srcdir)/ndb/include/transporter @NDB_SCI_INCLUDES@
|
||||
INCLUDES_LOC = -I$(top_srcdir)/ndb/include/mgmapi -I$(top_srcdir)/ndb/include/debugger -I$(top_srcdir)/ndb/include/kernel -I$(top_srcdir)/ndb/include/transporter @NDB_SCI_INCLUDES@
|
||||
|
||||
include $(top_srcdir)/ndb/config/common.mk.am
|
||||
include $(top_srcdir)/ndb/config/type_util.mk.am
|
||||
|
@ -44,7 +44,8 @@ SCI_Transporter::SCI_Transporter(TransporterRegistry &t_reg,
|
||||
bool chksm,
|
||||
bool signalId,
|
||||
Uint32 reportFreq) :
|
||||
Transporter(t_reg, lHostName, rHostName, r_port, _localNodeId,
|
||||
Transporter(t_reg, tt_SCI_TRANSPORTER,
|
||||
lHostName, rHostName, r_port, _localNodeId,
|
||||
_remoteNodeId, 0, false, chksm, signalId)
|
||||
{
|
||||
DBUG_ENTER("SCI_Transporter::SCI_Transporter");
|
||||
|
@ -38,7 +38,8 @@ SHM_Transporter::SHM_Transporter(TransporterRegistry &t_reg,
|
||||
bool signalId,
|
||||
key_t _shmKey,
|
||||
Uint32 _shmSize) :
|
||||
Transporter(t_reg, lHostName, rHostName, r_port, lNodeId, rNodeId,
|
||||
Transporter(t_reg, tt_SHM_TRANSPORTER,
|
||||
lHostName, rHostName, r_port, lNodeId, rNodeId,
|
||||
0, false, checksum, signalId),
|
||||
shmKey(_shmKey),
|
||||
shmSize(_shmSize)
|
||||
@ -256,6 +257,9 @@ SHM_Transporter::connect_client_impl(NDB_SOCKET_TYPE sockfd)
|
||||
SocketOutputStream s_output(sockfd);
|
||||
char buf[256];
|
||||
|
||||
#if 1
|
||||
#endif
|
||||
|
||||
// Wait for server to create and attach
|
||||
if (s_input.gets(buf, 256) == 0) {
|
||||
NDB_CLOSE_SOCKET(sockfd);
|
||||
|
@ -72,7 +72,8 @@ TCP_Transporter::TCP_Transporter(TransporterRegistry &t_reg,
|
||||
NodeId rNodeId,
|
||||
bool chksm, bool signalId,
|
||||
Uint32 _reportFreq) :
|
||||
Transporter(t_reg, lHostName, rHostName, r_port, lNodeId, rNodeId,
|
||||
Transporter(t_reg, tt_TCP_TRANSPORTER,
|
||||
lHostName, rHostName, r_port, lNodeId, rNodeId,
|
||||
0, false, chksm, signalId),
|
||||
m_sendBuffer(sendBufSize)
|
||||
{
|
||||
|
@ -24,7 +24,11 @@
|
||||
#include <InputStream.hpp>
|
||||
#include <OutputStream.hpp>
|
||||
|
||||
#include <EventLogger.hpp>
|
||||
extern EventLogger g_eventLogger;
|
||||
|
||||
Transporter::Transporter(TransporterRegistry &t_reg,
|
||||
TransporterType _type,
|
||||
const char *lHostName,
|
||||
const char *rHostName,
|
||||
int r_port,
|
||||
@ -35,8 +39,10 @@ Transporter::Transporter(TransporterRegistry &t_reg,
|
||||
: m_r_port(r_port), remoteNodeId(rNodeId), localNodeId(lNodeId),
|
||||
isServer(lNodeId < rNodeId),
|
||||
m_packer(_signalId, _checksum),
|
||||
m_type(_type),
|
||||
m_transporter_registry(t_reg)
|
||||
{
|
||||
DBUG_ENTER("Transporter::Transporter");
|
||||
if (rHostName && strlen(rHostName) > 0){
|
||||
strncpy(remoteHostName, rHostName, sizeof(remoteHostName));
|
||||
Ndb_getInAddr(&remoteHostAddress, rHostName);
|
||||
@ -55,6 +61,11 @@ Transporter::Transporter(TransporterRegistry &t_reg,
|
||||
if (strlen(lHostName) > 0)
|
||||
Ndb_getInAddr(&localHostAddress, lHostName);
|
||||
|
||||
DBUG_PRINT("info",("rId=%d lId=%d isServer=%d rHost=%s lHost=%s r_port=%d",
|
||||
remoteNodeId, localNodeId, isServer,
|
||||
remoteHostName, localHostName,
|
||||
r_port));
|
||||
|
||||
byteOrder = _byteorder;
|
||||
compressionUsed = _compression;
|
||||
checksumUsed = _checksum;
|
||||
@ -67,7 +78,9 @@ Transporter::Transporter(TransporterRegistry &t_reg,
|
||||
m_socket_client= 0;
|
||||
else
|
||||
m_socket_client= new SocketClient(remoteHostName, r_port,
|
||||
new SocketAuthSimple("ndbd", "ndbd passwd"));
|
||||
new SocketAuthSimple("ndbd",
|
||||
"ndbd passwd"));
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
Transporter::~Transporter(){
|
||||
@ -77,8 +90,13 @@ Transporter::~Transporter(){
|
||||
|
||||
bool
|
||||
Transporter::connect_server(NDB_SOCKET_TYPE sockfd) {
|
||||
// all initial negotiation is done in TransporterRegistry::connect_server
|
||||
DBUG_ENTER("Transporter::connect_server");
|
||||
|
||||
if(m_connected)
|
||||
return true; // TODO assert(0);
|
||||
{
|
||||
DBUG_RETURN(true); // TODO assert(0);
|
||||
}
|
||||
|
||||
bool res = connect_server_impl(sockfd);
|
||||
if(res){
|
||||
@ -86,7 +104,7 @@ Transporter::connect_server(NDB_SOCKET_TYPE sockfd) {
|
||||
m_errorCount = 0;
|
||||
}
|
||||
|
||||
return res;
|
||||
DBUG_RETURN(res);
|
||||
}
|
||||
|
||||
bool
|
||||
@ -98,27 +116,60 @@ Transporter::connect_client() {
|
||||
if (sockfd == NDB_INVALID_SOCKET)
|
||||
return false;
|
||||
|
||||
// send info about own id
|
||||
DBUG_ENTER("Transporter::connect_client");
|
||||
|
||||
// send info about own id
|
||||
// send info about own transporter type
|
||||
SocketOutputStream s_output(sockfd);
|
||||
s_output.println("%d", localNodeId);
|
||||
s_output.println("%d %d", localNodeId, m_type);
|
||||
// get remote id
|
||||
int nodeId;
|
||||
int nodeId, remote_transporter_type= -1;
|
||||
SocketInputStream s_input(sockfd);
|
||||
char buf[256];
|
||||
if (s_input.gets(buf, 256) == 0) {
|
||||
NDB_CLOSE_SOCKET(sockfd);
|
||||
return false;
|
||||
DBUG_RETURN(false);
|
||||
}
|
||||
if (sscanf(buf, "%d", &nodeId) != 1) {
|
||||
|
||||
int r= sscanf(buf, "%d %d", &nodeId, &remote_transporter_type);
|
||||
switch (r) {
|
||||
case 2:
|
||||
break;
|
||||
case 1:
|
||||
// we're running version prior to 4.1.9
|
||||
// ok, but with no checks on transporter configuration compatability
|
||||
break;
|
||||
default:
|
||||
NDB_CLOSE_SOCKET(sockfd);
|
||||
return false;
|
||||
DBUG_RETURN(false);
|
||||
}
|
||||
|
||||
DBUG_PRINT("info", ("nodeId=%d remote_transporter_type=%d",
|
||||
nodeId, remote_transporter_type));
|
||||
|
||||
if (remote_transporter_type != -1)
|
||||
{
|
||||
if (remote_transporter_type != m_type)
|
||||
{
|
||||
DBUG_PRINT("error", ("Transporter types mismatch this=%d remote=%d",
|
||||
m_type, remote_transporter_type));
|
||||
NDB_CLOSE_SOCKET(sockfd);
|
||||
g_eventLogger.error("Incompatible configuration: transporter type "
|
||||
"mismatch with node %d", nodeId);
|
||||
DBUG_RETURN(false);
|
||||
}
|
||||
}
|
||||
else if (m_type == tt_SHM_TRANSPORTER)
|
||||
{
|
||||
g_eventLogger.warning("Unable to verify transporter compatability with node %d", nodeId);
|
||||
}
|
||||
|
||||
bool res = connect_client_impl(sockfd);
|
||||
if(res){
|
||||
m_connected = true;
|
||||
m_errorCount = 0;
|
||||
}
|
||||
return res;
|
||||
DBUG_RETURN(res);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -71,6 +71,7 @@ public:
|
||||
|
||||
protected:
|
||||
Transporter(TransporterRegistry &,
|
||||
TransporterType,
|
||||
const char *lHostName,
|
||||
const char *rHostName,
|
||||
int r_port,
|
||||
@ -127,6 +128,7 @@ protected:
|
||||
|
||||
protected:
|
||||
bool m_connected; // Are we connected
|
||||
TransporterType m_type;
|
||||
|
||||
TransporterRegistry &m_transporter_registry;
|
||||
void *get_callback_obj() { return m_transporter_registry.callbackObj; };
|
||||
@ -149,7 +151,7 @@ Transporter::getRemoteNodeId() const {
|
||||
inline
|
||||
NodeId
|
||||
Transporter::getLocalNodeId() const {
|
||||
return remoteNodeId;
|
||||
return localNodeId;
|
||||
}
|
||||
|
||||
inline
|
||||
|
@ -47,6 +47,9 @@
|
||||
#include <InputStream.hpp>
|
||||
#include <OutputStream.hpp>
|
||||
|
||||
#include <EventLogger.hpp>
|
||||
extern EventLogger g_eventLogger;
|
||||
|
||||
int g_shm_pid = 0;
|
||||
|
||||
SocketServer::Session * TransporterService::newSession(NDB_SOCKET_TYPE sockfd)
|
||||
@ -57,49 +60,10 @@ SocketServer::Session * TransporterService::newSession(NDB_SOCKET_TYPE sockfd)
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
if (!m_transporter_registry->connect_server(sockfd))
|
||||
{
|
||||
// read node id from client
|
||||
int nodeId;
|
||||
SocketInputStream s_input(sockfd);
|
||||
char buf[256];
|
||||
if (s_input.gets(buf, 256) == 0) {
|
||||
NDB_CLOSE_SOCKET(sockfd);
|
||||
DBUG_PRINT("error", ("Could not get node id from client"));
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
if (sscanf(buf, "%d", &nodeId) != 1) {
|
||||
NDB_CLOSE_SOCKET(sockfd);
|
||||
DBUG_PRINT("error", ("Error in node id from client"));
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
//check that nodeid is valid and that there is an allocated transporter
|
||||
if ( nodeId < 0 || nodeId >= (int)m_transporter_registry->maxTransporters) {
|
||||
NDB_CLOSE_SOCKET(sockfd);
|
||||
DBUG_PRINT("error", ("Node id out of range from client"));
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
if (m_transporter_registry->theTransporters[nodeId] == 0) {
|
||||
NDB_CLOSE_SOCKET(sockfd);
|
||||
DBUG_PRINT("error", ("No transporter for this node id from client"));
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
//check that the transporter should be connected
|
||||
if (m_transporter_registry->performStates[nodeId] != TransporterRegistry::CONNECTING) {
|
||||
NDB_CLOSE_SOCKET(sockfd);
|
||||
DBUG_PRINT("error", ("Transporter in wrong state for this node id from client"));
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
Transporter *t= m_transporter_registry->theTransporters[nodeId];
|
||||
|
||||
// send info about own id (just as response to acknowledge connection)
|
||||
SocketOutputStream s_output(sockfd);
|
||||
s_output.println("%d", t->getLocalNodeId());
|
||||
|
||||
// setup transporter (transporter responsible for closing sockfd)
|
||||
t->connect_server(sockfd);
|
||||
NDB_CLOSE_SOCKET(sockfd);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
DBUG_RETURN(0);
|
||||
@ -195,6 +159,91 @@ TransporterRegistry::init(NodeId nodeId) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TransporterRegistry::connect_server(NDB_SOCKET_TYPE sockfd)
|
||||
{
|
||||
DBUG_ENTER("TransporterRegistry::connect_server");
|
||||
|
||||
// read node id from client
|
||||
// read transporter type
|
||||
int nodeId, remote_transporter_type= -1;
|
||||
SocketInputStream s_input(sockfd);
|
||||
char buf[256];
|
||||
if (s_input.gets(buf, 256) == 0) {
|
||||
DBUG_PRINT("error", ("Could not get node id from client"));
|
||||
DBUG_RETURN(false);
|
||||
}
|
||||
int r= sscanf(buf, "%d %d", &nodeId, &remote_transporter_type);
|
||||
switch (r) {
|
||||
case 2:
|
||||
break;
|
||||
case 1:
|
||||
// we're running version prior to 4.1.9
|
||||
// ok, but with no checks on transporter configuration compatability
|
||||
break;
|
||||
default:
|
||||
DBUG_PRINT("error", ("Error in node id from client"));
|
||||
DBUG_RETURN(false);
|
||||
}
|
||||
|
||||
DBUG_PRINT("info", ("nodeId=%d remote_transporter_type=%d",
|
||||
nodeId,remote_transporter_type));
|
||||
|
||||
//check that nodeid is valid and that there is an allocated transporter
|
||||
if ( nodeId < 0 || nodeId >= (int)maxTransporters) {
|
||||
DBUG_PRINT("error", ("Node id out of range from client"));
|
||||
DBUG_RETURN(false);
|
||||
}
|
||||
if (theTransporters[nodeId] == 0) {
|
||||
DBUG_PRINT("error", ("No transporter for this node id from client"));
|
||||
DBUG_RETURN(false);
|
||||
}
|
||||
|
||||
//check that the transporter should be connected
|
||||
if (performStates[nodeId] != TransporterRegistry::CONNECTING) {
|
||||
DBUG_PRINT("error", ("Transporter in wrong state for this node id from client"));
|
||||
DBUG_RETURN(false);
|
||||
}
|
||||
|
||||
Transporter *t= theTransporters[nodeId];
|
||||
|
||||
// send info about own id (just as response to acknowledge connection)
|
||||
// send info on own transporter type
|
||||
SocketOutputStream s_output(sockfd);
|
||||
s_output.println("%d %d", t->getLocalNodeId(), t->m_type);
|
||||
|
||||
if (remote_transporter_type != -1)
|
||||
{
|
||||
if (remote_transporter_type != t->m_type)
|
||||
{
|
||||
DBUG_PRINT("error", ("Transporter types mismatch this=%d remote=%d",
|
||||
t->m_type, remote_transporter_type));
|
||||
g_eventLogger.error("Incompatible configuration: Transporter type "
|
||||
"mismatch with node %d", nodeId);
|
||||
|
||||
// wait for socket close for 1 second to let message arrive at client
|
||||
{
|
||||
fd_set a_set;
|
||||
FD_ZERO(&a_set);
|
||||
FD_SET(sockfd, &a_set);
|
||||
struct timeval timeout;
|
||||
timeout.tv_sec = 1; timeout.tv_usec = 0;
|
||||
select(sockfd+1, &a_set, 0, 0, &timeout);
|
||||
}
|
||||
DBUG_RETURN(false);
|
||||
}
|
||||
}
|
||||
else if (t->m_type == tt_SHM_TRANSPORTER)
|
||||
{
|
||||
g_eventLogger.warning("Unable to verify transporter compatability with node %d", nodeId);
|
||||
}
|
||||
|
||||
// setup transporter (transporter responsible for closing sockfd)
|
||||
t->connect_server(sockfd);
|
||||
|
||||
DBUG_RETURN(true);
|
||||
}
|
||||
|
||||
bool
|
||||
TransporterRegistry::createTransporter(TCP_TransporterConfiguration *config) {
|
||||
#ifdef NDB_TCP_TRANSPORTER
|
||||
@ -358,8 +407,8 @@ TransporterRegistry::createTransporter(SHM_TransporterConfiguration *config) {
|
||||
return false;
|
||||
|
||||
SHM_Transporter * t = new SHM_Transporter(*this,
|
||||
"localhost",
|
||||
"localhost",
|
||||
config->localHostName,
|
||||
config->remoteHostName,
|
||||
config->port,
|
||||
localNodeId,
|
||||
config->remoteNodeId,
|
||||
|
@ -58,7 +58,7 @@ int main(int argc, char** argv)
|
||||
// Print to stdout/console
|
||||
g_eventLogger.createConsoleHandler();
|
||||
g_eventLogger.setCategory("NDB");
|
||||
g_eventLogger.enable(Logger::LL_INFO, Logger::LL_ALERT); // Log INFO to ALERT
|
||||
g_eventLogger.enable(Logger::LL_ON, Logger::LL_ERROR);
|
||||
|
||||
globalEmulatorData.create();
|
||||
|
||||
|
@ -133,8 +133,7 @@ MgmtSrvr::signalRecvThreadRun()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
EventLogger g_EventLogger;
|
||||
extern EventLogger g_eventLogger;
|
||||
|
||||
static NdbOut&
|
||||
operator<<(NdbOut& out, const LogLevel & ll)
|
||||
@ -200,7 +199,7 @@ MgmtSrvr::logLevelThreadRun()
|
||||
void
|
||||
MgmtSrvr::startEventLog()
|
||||
{
|
||||
g_EventLogger.setCategory("MgmSrvr");
|
||||
g_eventLogger.setCategory("MgmSrvr");
|
||||
|
||||
ndb_mgm_configuration_iterator * iter = ndb_mgm_create_configuration_iterator
|
||||
((ndb_mgm_configuration*)_config->m_configValues, CFG_SECTION_NODE);
|
||||
@ -226,7 +225,7 @@ MgmtSrvr::startEventLog()
|
||||
logdest.assfmt("FILE:filename=%s,maxsize=1000000,maxfiles=6",
|
||||
clusterLog);
|
||||
}
|
||||
if(!g_EventLogger.addHandler(logdest)) {
|
||||
if(!g_eventLogger.addHandler(logdest)) {
|
||||
ndbout << "Warning: could not add log destination \""
|
||||
<< logdest.c_str() << "\"" << endl;
|
||||
}
|
||||
@ -250,21 +249,21 @@ MgmtSrvr::setEventLogFilter(int severity, int enable)
|
||||
{
|
||||
Logger::LoggerLevel level = (Logger::LoggerLevel)severity;
|
||||
if (enable > 0) {
|
||||
g_EventLogger.enable(level);
|
||||
g_eventLogger.enable(level);
|
||||
} else if (enable == 0) {
|
||||
g_EventLogger.disable(level);
|
||||
} else if (g_EventLogger.isEnable(level)) {
|
||||
g_EventLogger.disable(level);
|
||||
g_eventLogger.disable(level);
|
||||
} else if (g_eventLogger.isEnable(level)) {
|
||||
g_eventLogger.disable(level);
|
||||
} else {
|
||||
g_EventLogger.enable(level);
|
||||
g_eventLogger.enable(level);
|
||||
}
|
||||
return g_EventLogger.isEnable(level);
|
||||
return g_eventLogger.isEnable(level);
|
||||
}
|
||||
|
||||
bool
|
||||
MgmtSrvr::isEventLogFilterEnabled(int severity)
|
||||
{
|
||||
return g_EventLogger.isEnable((Logger::LoggerLevel)severity);
|
||||
return g_eventLogger.isEnable((Logger::LoggerLevel)severity);
|
||||
}
|
||||
|
||||
static ErrorItem errorTable[] =
|
||||
@ -1990,7 +1989,7 @@ MgmtSrvr::handleReceivedSignal(NdbApiSignal* signal)
|
||||
}
|
||||
|
||||
default:
|
||||
g_EventLogger.error("Unknown signal received. SignalNumber: "
|
||||
g_eventLogger.error("Unknown signal received. SignalNumber: "
|
||||
"%i from (%d, %x)",
|
||||
gsn,
|
||||
refToNode(signal->theSendersBlockRef),
|
||||
@ -2066,7 +2065,7 @@ MgmtSrvr::handleStopReply(NodeId nodeId, Uint32 errCode)
|
||||
|
||||
error:
|
||||
if(errCode != 0){
|
||||
g_EventLogger.error("Unexpected signal received. SignalNumber: %i from %d",
|
||||
g_eventLogger.error("Unexpected signal received. SignalNumber: %i from %d",
|
||||
GSN_STOP_REF, nodeId);
|
||||
}
|
||||
}
|
||||
@ -2286,7 +2285,7 @@ MgmtSrvr::alloc_node_id(NodeId * nodeId,
|
||||
m_reserved_nodes.set(id_found);
|
||||
char tmp_str[128];
|
||||
m_reserved_nodes.getText(tmp_str);
|
||||
g_EventLogger.info("Mgmt server state: nodeid %d reserved for ip %s, m_reserved_nodes %s.",
|
||||
g_eventLogger.info("Mgmt server state: nodeid %d reserved for ip %s, m_reserved_nodes %s.",
|
||||
id_found, get_connect_address(id_found), tmp_str);
|
||||
DBUG_RETURN(true);
|
||||
}
|
||||
@ -2346,7 +2345,7 @@ MgmtSrvr::alloc_node_id(NodeId * nodeId,
|
||||
*nodeId);
|
||||
}
|
||||
|
||||
g_EventLogger.warning("Allocate nodeid (%d) failed. Connection from ip %s. "
|
||||
g_eventLogger.warning("Allocate nodeid (%d) failed. Connection from ip %s. "
|
||||
"Returned error string \"%s\"",
|
||||
*nodeId,
|
||||
client_addr != 0 ? inet_ntoa(((struct sockaddr_in *)(client_addr))->sin_addr) : "<none>",
|
||||
@ -2369,10 +2368,10 @@ MgmtSrvr::alloc_node_id(NodeId * nodeId,
|
||||
}
|
||||
}
|
||||
if (tmp_connected.length() > 0)
|
||||
g_EventLogger.info("Mgmt server state: node id's %s connected but not reserved",
|
||||
g_eventLogger.info("Mgmt server state: node id's %s connected but not reserved",
|
||||
tmp_connected.c_str());
|
||||
if (tmp_not_connected.length() > 0)
|
||||
g_EventLogger.info("Mgmt server state: node id's %s not connected but reserved",
|
||||
g_eventLogger.info("Mgmt server state: node id's %s not connected but reserved",
|
||||
tmp_not_connected.c_str());
|
||||
}
|
||||
DBUG_RETURN(false);
|
||||
@ -2404,7 +2403,7 @@ MgmtSrvr::eventReport(NodeId nodeId, const Uint32 * theData)
|
||||
|
||||
EventReport::EventType type = eventReport->getEventType();
|
||||
// Log event
|
||||
g_EventLogger.log(type, theData, nodeId,
|
||||
g_eventLogger.log(type, theData, nodeId,
|
||||
&m_event_listner[0].m_logLevel);
|
||||
m_event_listner.log(type, theData, nodeId);
|
||||
}
|
||||
@ -2647,7 +2646,7 @@ MgmtSrvr::Allocated_resources::~Allocated_resources()
|
||||
|
||||
char tmp_str[128];
|
||||
m_mgmsrv.m_reserved_nodes.getText(tmp_str);
|
||||
g_EventLogger.info("Mgmt server state: nodeid %d freed, m_reserved_nodes %s.",
|
||||
g_eventLogger.info("Mgmt server state: nodeid %d freed, m_reserved_nodes %s.",
|
||||
get_nodeid(), tmp_str);
|
||||
}
|
||||
}
|
||||
|
@ -86,7 +86,7 @@ static MgmGlobals glob;
|
||||
* Global variables
|
||||
*/
|
||||
bool g_StopServer;
|
||||
extern EventLogger g_EventLogger;
|
||||
extern EventLogger g_eventLogger;
|
||||
|
||||
extern int global_mgmt_server_check;
|
||||
|
||||
@ -284,12 +284,12 @@ int main(int argc, char** argv)
|
||||
BaseString::snprintf(msg, sizeof(msg),
|
||||
"NDB Cluster Management Server. %s", NDB_VERSION_STRING);
|
||||
ndbout_c(msg);
|
||||
g_EventLogger.info(msg);
|
||||
g_eventLogger.info(msg);
|
||||
|
||||
BaseString::snprintf(msg, 256, "Id: %d, Command port: %d",
|
||||
glob.localNodeId, glob.port);
|
||||
ndbout_c(msg);
|
||||
g_EventLogger.info(msg);
|
||||
g_eventLogger.info(msg);
|
||||
|
||||
g_StopServer = false;
|
||||
glob.socketServer->startServer();
|
||||
@ -305,10 +305,10 @@ int main(int argc, char** argv)
|
||||
NdbSleep_MilliSleep(500);
|
||||
}
|
||||
|
||||
g_EventLogger.info("Shutting down server...");
|
||||
g_eventLogger.info("Shutting down server...");
|
||||
glob.socketServer->stopServer();
|
||||
glob.socketServer->stopSessions();
|
||||
g_EventLogger.info("Shutdown complete");
|
||||
g_eventLogger.info("Shutdown complete");
|
||||
return 0;
|
||||
error_end:
|
||||
return 1;
|
||||
|
@ -282,7 +282,7 @@ Ndb::waitUntilReady(int timeout)
|
||||
}
|
||||
|
||||
if (theImpl->m_ndb_cluster_connection.wait_until_ready
|
||||
(timeout-secondsCounter,30))
|
||||
(timeout-secondsCounter,30) < 0)
|
||||
{
|
||||
theError.code = 4009;
|
||||
DBUG_RETURN(-1);
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <NdbIndexOperation.hpp>
|
||||
#include <NdbRecAttr.hpp>
|
||||
#include <NdbBlob.hpp>
|
||||
#include "NdbBlobImpl.hpp"
|
||||
#include <NdbScanOperation.hpp>
|
||||
|
||||
#ifdef NDB_BLOB_DEBUG
|
||||
@ -85,14 +86,14 @@ void
|
||||
NdbBlob::getBlobTableName(char* btname, const NdbTableImpl* t, const NdbColumnImpl* c)
|
||||
{
|
||||
assert(t != 0 && c != 0 && c->getBlobType());
|
||||
memset(btname, 0, BlobTableNameSize);
|
||||
memset(btname, 0, NdbBlobImpl::BlobTableNameSize);
|
||||
sprintf(btname, "NDB$BLOB_%d_%d", (int)t->m_tableId, (int)c->m_attrId);
|
||||
}
|
||||
|
||||
void
|
||||
NdbBlob::getBlobTable(NdbTableImpl& bt, const NdbTableImpl* t, const NdbColumnImpl* c)
|
||||
{
|
||||
char btname[BlobTableNameSize];
|
||||
char btname[NdbBlobImpl::BlobTableNameSize];
|
||||
getBlobTableName(btname, t, c);
|
||||
bt.setName(btname);
|
||||
bt.setLogging(t->getLogging());
|
||||
@ -450,15 +451,15 @@ NdbBlob::getValue(void* data, Uint32 bytes)
|
||||
{
|
||||
DBG("getValue data=" << hex << data << " bytes=" << dec << bytes);
|
||||
if (theGetFlag || theState != Prepared) {
|
||||
setErrorCode(ErrState);
|
||||
setErrorCode(NdbBlobImpl::ErrState);
|
||||
return -1;
|
||||
}
|
||||
if (! isReadOp() && ! isScanOp()) {
|
||||
setErrorCode(ErrUsage);
|
||||
setErrorCode(NdbBlobImpl::ErrUsage);
|
||||
return -1;
|
||||
}
|
||||
if (data == NULL && bytes != 0) {
|
||||
setErrorCode(ErrUsage);
|
||||
setErrorCode(NdbBlobImpl::ErrUsage);
|
||||
return -1;
|
||||
}
|
||||
theGetFlag = true;
|
||||
@ -472,15 +473,15 @@ NdbBlob::setValue(const void* data, Uint32 bytes)
|
||||
{
|
||||
DBG("setValue data=" << hex << data << " bytes=" << dec << bytes);
|
||||
if (theSetFlag || theState != Prepared) {
|
||||
setErrorCode(ErrState);
|
||||
setErrorCode(NdbBlobImpl::ErrState);
|
||||
return -1;
|
||||
}
|
||||
if (! isInsertOp() && ! isUpdateOp() && ! isWriteOp()) {
|
||||
setErrorCode(ErrUsage);
|
||||
setErrorCode(NdbBlobImpl::ErrUsage);
|
||||
return -1;
|
||||
}
|
||||
if (data == NULL && bytes != 0) {
|
||||
setErrorCode(ErrUsage);
|
||||
setErrorCode(NdbBlobImpl::ErrUsage);
|
||||
return -1;
|
||||
}
|
||||
theSetFlag = true;
|
||||
@ -512,7 +513,7 @@ NdbBlob::setActiveHook(ActiveHook activeHook, void* arg)
|
||||
{
|
||||
DBG("setActiveHook hook=" << hex << (void*)activeHook << " arg=" << hex << arg);
|
||||
if (theState != Prepared) {
|
||||
setErrorCode(ErrState);
|
||||
setErrorCode(NdbBlobImpl::ErrState);
|
||||
return -1;
|
||||
}
|
||||
theActiveHook = activeHook;
|
||||
@ -531,7 +532,7 @@ NdbBlob::getNull(bool& isNull)
|
||||
return 0;
|
||||
}
|
||||
if (theNullFlag == -1) {
|
||||
setErrorCode(ErrState);
|
||||
setErrorCode(NdbBlobImpl::ErrState);
|
||||
return -1;
|
||||
}
|
||||
isNull = theNullFlag;
|
||||
@ -546,7 +547,7 @@ NdbBlob::setNull()
|
||||
if (theState == Prepared) {
|
||||
return setValue(0, 0);
|
||||
}
|
||||
setErrorCode(ErrState);
|
||||
setErrorCode(NdbBlobImpl::ErrState);
|
||||
return -1;
|
||||
}
|
||||
if (theNullFlag)
|
||||
@ -568,7 +569,7 @@ NdbBlob::getLength(Uint64& len)
|
||||
return 0;
|
||||
}
|
||||
if (theNullFlag == -1) {
|
||||
setErrorCode(ErrState);
|
||||
setErrorCode(NdbBlobImpl::ErrState);
|
||||
return -1;
|
||||
}
|
||||
len = theLength;
|
||||
@ -580,7 +581,7 @@ NdbBlob::truncate(Uint64 length)
|
||||
{
|
||||
DBG("truncate [in] length=" << length);
|
||||
if (theNullFlag == -1) {
|
||||
setErrorCode(ErrState);
|
||||
setErrorCode(NdbBlobImpl::ErrState);
|
||||
return -1;
|
||||
}
|
||||
if (theLength > length) {
|
||||
@ -608,7 +609,7 @@ NdbBlob::getPos(Uint64& pos)
|
||||
{
|
||||
DBG("getPos");
|
||||
if (theNullFlag == -1) {
|
||||
setErrorCode(ErrState);
|
||||
setErrorCode(NdbBlobImpl::ErrState);
|
||||
return -1;
|
||||
}
|
||||
pos = thePos;
|
||||
@ -620,11 +621,11 @@ NdbBlob::setPos(Uint64 pos)
|
||||
{
|
||||
DBG("setPos pos=" << pos);
|
||||
if (theNullFlag == -1) {
|
||||
setErrorCode(ErrState);
|
||||
setErrorCode(NdbBlobImpl::ErrState);
|
||||
return -1;
|
||||
}
|
||||
if (pos > theLength) {
|
||||
setErrorCode(ErrSeek);
|
||||
setErrorCode(NdbBlobImpl::ErrSeek);
|
||||
return -1;
|
||||
}
|
||||
thePos = pos;
|
||||
@ -637,7 +638,7 @@ int
|
||||
NdbBlob::readData(void* data, Uint32& bytes)
|
||||
{
|
||||
if (theState != Active) {
|
||||
setErrorCode(ErrState);
|
||||
setErrorCode(NdbBlobImpl::ErrState);
|
||||
return -1;
|
||||
}
|
||||
char* buf = static_cast<char*>(data);
|
||||
@ -666,7 +667,7 @@ NdbBlob::readDataPrivate(char* buf, Uint32& bytes)
|
||||
}
|
||||
}
|
||||
if (len > 0 && thePartSize == 0) {
|
||||
setErrorCode(ErrSeek);
|
||||
setErrorCode(NdbBlobImpl::ErrSeek);
|
||||
return -1;
|
||||
}
|
||||
if (len > 0) {
|
||||
@ -731,7 +732,7 @@ int
|
||||
NdbBlob::writeData(const void* data, Uint32 bytes)
|
||||
{
|
||||
if (theState != Active) {
|
||||
setErrorCode(ErrState);
|
||||
setErrorCode(NdbBlobImpl::ErrState);
|
||||
return -1;
|
||||
}
|
||||
const char* buf = static_cast<const char*>(data);
|
||||
@ -764,7 +765,7 @@ NdbBlob::writeDataPrivate(const char* buf, Uint32 bytes)
|
||||
}
|
||||
}
|
||||
if (len > 0 && thePartSize == 0) {
|
||||
setErrorCode(ErrSeek);
|
||||
setErrorCode(NdbBlobImpl::ErrSeek);
|
||||
return -1;
|
||||
}
|
||||
if (len > 0) {
|
||||
@ -1081,7 +1082,7 @@ NdbBlob::atPrepare(NdbConnection* aCon, NdbOperation* anOp, const NdbColumnImpl*
|
||||
theFillChar = 0x20;
|
||||
break;
|
||||
default:
|
||||
setErrorCode(ErrUsage);
|
||||
setErrorCode(NdbBlobImpl::ErrUsage);
|
||||
return -1;
|
||||
}
|
||||
// sizes
|
||||
@ -1099,7 +1100,7 @@ NdbBlob::atPrepare(NdbConnection* aCon, NdbOperation* anOp, const NdbColumnImpl*
|
||||
(bc = bt->getColumn("DATA")) == NULL ||
|
||||
bc->getType() != partType ||
|
||||
bc->getLength() != (int)thePartSize) {
|
||||
setErrorCode(ErrTable);
|
||||
setErrorCode(NdbBlobImpl::ErrTable);
|
||||
return -1;
|
||||
}
|
||||
theBlobTable = &NdbTableImpl::getImpl(*bt);
|
||||
@ -1120,7 +1121,7 @@ NdbBlob::atPrepare(NdbConnection* aCon, NdbOperation* anOp, const NdbColumnImpl*
|
||||
Uint32* data = (Uint32*)theKeyBuf.data;
|
||||
unsigned size = theTable->m_keyLenInWords;
|
||||
if (theNdbOp->getKeyFromTCREQ(data, size) == -1) {
|
||||
setErrorCode(ErrUsage);
|
||||
setErrorCode(NdbBlobImpl::ErrUsage);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@ -1129,7 +1130,7 @@ NdbBlob::atPrepare(NdbConnection* aCon, NdbOperation* anOp, const NdbColumnImpl*
|
||||
Uint32* data = (Uint32*)theAccessKeyBuf.data;
|
||||
unsigned size = theAccessTable->m_keyLenInWords;
|
||||
if (theNdbOp->getKeyFromTCREQ(data, size) == -1) {
|
||||
setErrorCode(ErrUsage);
|
||||
setErrorCode(NdbBlobImpl::ErrUsage);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@ -1158,7 +1159,7 @@ NdbBlob::atPrepare(NdbConnection* aCon, NdbOperation* anOp, const NdbColumnImpl*
|
||||
supportedOp = true;
|
||||
}
|
||||
if (! supportedOp) {
|
||||
setErrorCode(ErrUsage);
|
||||
setErrorCode(NdbBlobImpl::ErrUsage);
|
||||
return -1;
|
||||
}
|
||||
setState(Prepared);
|
||||
@ -1204,7 +1205,7 @@ NdbBlob::preExecute(ExecType anExecType, bool& batch)
|
||||
tOp->updateTuple() == -1 ||
|
||||
setTableKeyValue(tOp) == -1 ||
|
||||
setHeadInlineValue(tOp) == -1) {
|
||||
setErrorCode(ErrAbort);
|
||||
setErrorCode(NdbBlobImpl::ErrAbort);
|
||||
return -1;
|
||||
}
|
||||
DBG("add op to update head+inline");
|
||||
@ -1434,7 +1435,7 @@ NdbBlob::postExecute(ExecType anExecType)
|
||||
tOp->updateTuple() == -1 ||
|
||||
setTableKeyValue(tOp) == -1 ||
|
||||
setHeadInlineValue(tOp) == -1) {
|
||||
setErrorCode(ErrAbort);
|
||||
setErrorCode(NdbBlobImpl::ErrAbort);
|
||||
return -1;
|
||||
}
|
||||
tOp->m_abortOption = AbortOnError;
|
||||
@ -1464,7 +1465,7 @@ NdbBlob::preCommit()
|
||||
tOp->updateTuple() == -1 ||
|
||||
setTableKeyValue(tOp) == -1 ||
|
||||
setHeadInlineValue(tOp) == -1) {
|
||||
setErrorCode(ErrAbort);
|
||||
setErrorCode(NdbBlobImpl::ErrAbort);
|
||||
return -1;
|
||||
}
|
||||
tOp->m_abortOption = AbortOnError;
|
||||
@ -1489,7 +1490,7 @@ NdbBlob::atNextResult()
|
||||
{ Uint32* data = (Uint32*)theKeyBuf.data;
|
||||
unsigned size = theTable->m_keyLenInWords;
|
||||
if (((NdbScanOperation*)theNdbOp)->getKeyFromKEYINFO20(data, size) == -1) {
|
||||
setErrorCode(ErrUsage);
|
||||
setErrorCode(NdbBlobImpl::ErrUsage);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@ -1545,7 +1546,7 @@ NdbBlob::setErrorCode(NdbOperation* anOp, bool invalidFlag)
|
||||
else if ((code = theNdb->theError.code) != 0)
|
||||
;
|
||||
else
|
||||
code = ErrUnknown;
|
||||
code = NdbBlobImpl::ErrUnknown;
|
||||
setErrorCode(code, invalidFlag);
|
||||
}
|
||||
|
||||
@ -1558,7 +1559,7 @@ NdbBlob::setErrorCode(NdbConnection* aCon, bool invalidFlag)
|
||||
else if ((code = theNdb->theError.code) != 0)
|
||||
;
|
||||
else
|
||||
code = ErrUnknown;
|
||||
code = NdbBlobImpl::ErrUnknown;
|
||||
setErrorCode(code, invalidFlag);
|
||||
}
|
||||
|
||||
|
39
ndb/src/ndbapi/NdbBlobImpl.hpp
Normal file
39
ndb/src/ndbapi/NdbBlobImpl.hpp
Normal file
@ -0,0 +1,39 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#ifndef NdbBlobImpl_H
|
||||
#define NdbBlobImpl_H
|
||||
|
||||
class NdbBlobImpl {
|
||||
public:
|
||||
STATIC_CONST( BlobTableNameSize = 40 );
|
||||
// "Invalid blob attributes or invalid blob parts table"
|
||||
STATIC_CONST( ErrTable = 4263 );
|
||||
// "Invalid usage of blob attribute"
|
||||
STATIC_CONST( ErrUsage = 4264 );
|
||||
// "Method is not valid in current blob state"
|
||||
STATIC_CONST( ErrState = 4265 );
|
||||
// "Invalid blob seek position"
|
||||
STATIC_CONST( ErrSeek = 4266 );
|
||||
// "Corrupted blob value"
|
||||
STATIC_CONST( ErrCorrupt = 4267 );
|
||||
// "Error in blob head update forced rollback of transaction"
|
||||
STATIC_CONST( ErrAbort = 4268 );
|
||||
// "Unknown blob error"
|
||||
STATIC_CONST( ErrUnknown = 4269 );
|
||||
};
|
||||
|
||||
#endif
|
@ -361,11 +361,10 @@ NdbConnection::execute(ExecType aTypeOfExec,
|
||||
|
||||
if (executeNoBlobs(tExecType, abortOption, forceSend) == -1)
|
||||
ret = -1;
|
||||
#ifndef VM_TRACE
|
||||
// can happen in complex abort cases
|
||||
theFirstOpInList = theLastOpInList = NULL;
|
||||
#else
|
||||
#ifdef ndb_api_crash_on_complex_blob_abort
|
||||
assert(theFirstOpInList == NULL && theLastOpInList == NULL);
|
||||
#else
|
||||
theFirstOpInList = theLastOpInList = NULL;
|
||||
#endif
|
||||
|
||||
{
|
||||
|
@ -34,7 +34,8 @@
|
||||
#include <AttributeList.hpp>
|
||||
#include <NdbEventOperation.hpp>
|
||||
#include "NdbEventOperationImpl.hpp"
|
||||
#include "NdbBlob.hpp"
|
||||
#include <NdbBlob.hpp>
|
||||
#include "NdbBlobImpl.hpp"
|
||||
#include <AttributeHeader.hpp>
|
||||
#include <my_sys.h>
|
||||
|
||||
@ -1381,7 +1382,7 @@ NdbDictionaryImpl::addBlobTables(NdbTableImpl &t)
|
||||
if (! c.getBlobType() || c.getPartSize() == 0)
|
||||
continue;
|
||||
n--;
|
||||
char btname[NdbBlob::BlobTableNameSize];
|
||||
char btname[NdbBlobImpl::BlobTableNameSize];
|
||||
NdbBlob::getBlobTableName(btname, &t, &c);
|
||||
// Save BLOB table handle
|
||||
NdbTableImpl * cachedBlobTable = getTable(btname);
|
||||
@ -1789,7 +1790,7 @@ NdbDictionaryImpl::dropBlobTables(NdbTableImpl & t)
|
||||
NdbColumnImpl & c = *t.m_columns[i];
|
||||
if (! c.getBlobType() || c.getPartSize() == 0)
|
||||
continue;
|
||||
char btname[NdbBlob::BlobTableNameSize];
|
||||
char btname[NdbBlobImpl::BlobTableNameSize];
|
||||
NdbBlob::getBlobTableName(btname, &t, &c);
|
||||
if (dropTable(btname) != 0) {
|
||||
if (m_error.code != 709){
|
||||
|
@ -523,7 +523,9 @@ NdbOperation::setValue( const NdbColumnImpl* tAttrInfo,
|
||||
CHARSET_INFO* cs = tAttrInfo->m_cs;
|
||||
// invalid data can crash kernel
|
||||
if (cs != NULL &&
|
||||
(*cs->cset->well_formed_len)(cs,
|
||||
// fast fix bug#7340
|
||||
tAttrInfo->m_type != NdbDictionary::Column::Text &&
|
||||
(*cs->cset->well_formed_len)(cs,
|
||||
aValue,
|
||||
aValue + sizeInBytes,
|
||||
sizeInBytes) != sizeInBytes) {
|
||||
|
@ -15,21 +15,11 @@
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
|
||||
/************************************************************************************************
|
||||
Name: NdbOperationInt.C
|
||||
Include:
|
||||
Link:
|
||||
Author: UABRONM Mikael Ronström UAB/M/MT
|
||||
Date: 991029
|
||||
Version: 0.1
|
||||
Description: Interpreted operations in NDB API
|
||||
Documentation:
|
||||
Adjust: 991029 UABRONM First version.
|
||||
************************************************************************************************/
|
||||
#include "NdbOperation.hpp"
|
||||
#include <ndb_global.h>
|
||||
#include <NdbOperation.hpp>
|
||||
#include "NdbApiSignal.hpp"
|
||||
#include "NdbConnection.hpp"
|
||||
#include "Ndb.hpp"
|
||||
#include <NdbConnection.hpp>
|
||||
#include <Ndb.hpp>
|
||||
#include "NdbRecAttr.hpp"
|
||||
#include "NdbUtil.hpp"
|
||||
#include "Interpreter.hpp"
|
||||
|
@ -204,14 +204,6 @@ Ndb::~Ndb()
|
||||
TransporterFacade::instance()->close(theNdbBlockNumber, theFirstTransId);
|
||||
}
|
||||
|
||||
if (global_ndb_cluster_connection != 0) {
|
||||
theNoOfNdbObjects--;
|
||||
if(theNoOfNdbObjects == 0){
|
||||
delete global_ndb_cluster_connection;
|
||||
global_ndb_cluster_connection= 0;
|
||||
}
|
||||
}//if
|
||||
|
||||
// if (theSchemaConToNdbList != NULL)
|
||||
// closeSchemaTransaction(theSchemaConToNdbList);
|
||||
while ( theConIdleList != NULL )
|
||||
@ -249,6 +241,19 @@ Ndb::~Ndb()
|
||||
|
||||
delete theImpl;
|
||||
|
||||
/**
|
||||
* This needs to be put after delete theImpl
|
||||
* as TransporterFacade::instance is delete by global_ndb_cluster_connection
|
||||
* and used by theImpl
|
||||
*/
|
||||
if (global_ndb_cluster_connection != 0) {
|
||||
theNoOfNdbObjects--;
|
||||
if(theNoOfNdbObjects == 0){
|
||||
delete global_ndb_cluster_connection;
|
||||
global_ndb_cluster_connection= 0;
|
||||
}
|
||||
}//if
|
||||
|
||||
/**
|
||||
* This sleep is to make sure that the transporter
|
||||
* send thread will come in and send any
|
||||
|
@ -31,6 +31,9 @@
|
||||
#include <Vector.hpp>
|
||||
#include <md5_hash.hpp>
|
||||
|
||||
#include <EventLogger.hpp>
|
||||
EventLogger g_eventLogger;
|
||||
|
||||
static int g_run_connect_thread= 0;
|
||||
|
||||
#include <NdbMutex.h>
|
||||
@ -174,7 +177,7 @@ Ndb_cluster_connection_impl::get_next_node(Ndb_cluster_connection_node_iter &ite
|
||||
return node.id;
|
||||
}
|
||||
|
||||
Uint32
|
||||
unsigned
|
||||
Ndb_cluster_connection::no_db_nodes()
|
||||
{
|
||||
return m_impl.m_all_nodes.size();
|
||||
@ -219,16 +222,8 @@ Ndb_cluster_connection::wait_until_ready(int timeout,
|
||||
else if (foundAliveNode > 0)
|
||||
{
|
||||
noChecksSinceFirstAliveFound++;
|
||||
if (timeout_after_first_alive >= 0)
|
||||
{
|
||||
if (noChecksSinceFirstAliveFound > timeout_after_first_alive)
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
else // timeout_after_first_alive < 0
|
||||
{
|
||||
if (noChecksSinceFirstAliveFound > -timeout_after_first_alive)
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
if (noChecksSinceFirstAliveFound > timeout_after_first_alive)
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
else if (secondsCounter >= timeout)
|
||||
{ // no alive nodes and timed out
|
||||
@ -256,6 +251,11 @@ Ndb_cluster_connection_impl::Ndb_cluster_connection_impl(const char *
|
||||
{
|
||||
DBUG_ENTER("Ndb_cluster_connection");
|
||||
DBUG_PRINT("enter",("Ndb_cluster_connection this=0x%x", this));
|
||||
|
||||
g_eventLogger.createConsoleHandler();
|
||||
g_eventLogger.setCategory("NdbApi");
|
||||
g_eventLogger.enable(Logger::LL_ON, Logger::LL_ERROR);
|
||||
|
||||
m_transporter_facade=
|
||||
TransporterFacade::theFacadeInstance= new TransporterFacade();
|
||||
|
||||
|
@ -23,13 +23,14 @@
|
||||
#include <NdbOut.hpp>
|
||||
#include <NdbTest.hpp>
|
||||
#include <NdbTick.h>
|
||||
#include <ndb/src/ndbapi/NdbBlobImpl.hpp>
|
||||
|
||||
struct Bcol {
|
||||
bool m_nullable;
|
||||
unsigned m_inline;
|
||||
unsigned m_partsize;
|
||||
unsigned m_stripe;
|
||||
char m_btname[NdbBlob::BlobTableNameSize];
|
||||
char m_btname[NdbBlobImpl::BlobTableNameSize];
|
||||
Bcol(bool a, unsigned b, unsigned c, unsigned d) :
|
||||
m_nullable(a),
|
||||
m_inline(b),
|
||||
@ -153,6 +154,7 @@ testcase(char x)
|
||||
(g_opt.m_skip == 0 || strchr(g_opt.m_skip, x) == 0);
|
||||
}
|
||||
|
||||
static Ndb_cluster_connection* g_ncc = 0;
|
||||
static Ndb* g_ndb = 0;
|
||||
static NdbDictionary::Dictionary* g_dic = 0;
|
||||
static NdbConnection* g_con = 0;
|
||||
@ -1258,7 +1260,7 @@ deleteScan(bool idx)
|
||||
static int
|
||||
testmain()
|
||||
{
|
||||
g_ndb = new Ndb("TEST_DB");
|
||||
g_ndb = new Ndb(g_ncc, "TEST_DB");
|
||||
CHK(g_ndb->init() == 0);
|
||||
CHK(g_ndb->waitUntilReady() == 0);
|
||||
g_dic = g_ndb->getDictionary();
|
||||
@ -1447,7 +1449,7 @@ testperf()
|
||||
if (! testcase('p'))
|
||||
return 0;
|
||||
DBG("=== perf test ===");
|
||||
g_ndb = new Ndb("TEST_DB");
|
||||
g_ndb = new Ndb(g_ncc, "TEST_DB");
|
||||
CHK(g_ndb->init() == 0);
|
||||
CHK(g_ndb->waitUntilReady() == 0);
|
||||
g_dic = g_ndb->getDictionary();
|
||||
@ -1859,10 +1861,13 @@ NDB_COMMAND(testOdbcDriver, "testBlobs", "testBlobs", "testBlobs", 65535)
|
||||
strcat(b, "r");
|
||||
g_opt.m_skip = strdup(b);
|
||||
}
|
||||
if (testmain() == -1 || testperf() == -1) {
|
||||
g_ncc = new Ndb_cluster_connection();
|
||||
if (g_ncc->connect(30) != 0 || testmain() == -1 || testperf() == -1) {
|
||||
ndbout << "line " << __LINE__ << " FAIL loop=" << g_loop << endl;
|
||||
return NDBT_ProgramExit(NDBT_FAILED);
|
||||
}
|
||||
delete g_ncc;
|
||||
g_ncc = 0;
|
||||
return NDBT_ProgramExit(NDBT_OK);
|
||||
}
|
||||
|
||||
|
@ -59,7 +59,7 @@ struct Opt {
|
||||
unsigned m_subloop;
|
||||
const char* m_table;
|
||||
unsigned m_threads;
|
||||
unsigned m_v;
|
||||
int m_v;
|
||||
Opt() :
|
||||
m_batch(32),
|
||||
m_bound("01234"),
|
||||
@ -672,6 +672,8 @@ tabcount = sizeof(tablist) / sizeof(tablist[0]);
|
||||
|
||||
// connections
|
||||
|
||||
static Ndb_cluster_connection* g_ncc = 0;
|
||||
|
||||
struct Con {
|
||||
Ndb* m_ndb;
|
||||
NdbDictionary::Dictionary* m_dic;
|
||||
@ -720,7 +722,7 @@ int
|
||||
Con::connect()
|
||||
{
|
||||
assert(m_ndb == 0);
|
||||
m_ndb = new Ndb("TEST_DB");
|
||||
m_ndb = new Ndb(g_ncc, "TEST_DB");
|
||||
CHKCON(m_ndb->init() == 0, *this);
|
||||
CHKCON(m_ndb->waitUntilReady(30) == 0, *this);
|
||||
m_tx = 0, m_op = 0;
|
||||
@ -3514,8 +3516,11 @@ NDB_COMMAND(testOIBasic, "testOIBasic", "testOIBasic", "testOIBasic", 65535)
|
||||
}
|
||||
{
|
||||
Par par(g_opt);
|
||||
if (runtest(par) < 0)
|
||||
g_ncc = new Ndb_cluster_connection();
|
||||
if (g_ncc->connect(30) != 0 || runtest(par) < 0)
|
||||
goto failed;
|
||||
delete g_ncc;
|
||||
g_ncc = 0;
|
||||
}
|
||||
// always exit with NDBT code
|
||||
ok:
|
||||
|
@ -275,6 +275,7 @@ parse_args(int argc, const char** argv){
|
||||
int tmp = Logger::LL_WARNING - g_verbosity;
|
||||
tmp = (tmp < Logger::LL_DEBUG ? Logger::LL_DEBUG : tmp);
|
||||
g_logger.disable(Logger::LL_ALL);
|
||||
g_logger.enable(Logger::LL_ON);
|
||||
g_logger.enable((Logger::LoggerLevel)tmp, Logger::LL_ALERT);
|
||||
}
|
||||
|
||||
|
@ -393,6 +393,7 @@ HANDLE create_shared_memory(MYSQL *mysql,NET *net, uint connect_timeout)
|
||||
HANDLE event_server_read = NULL;
|
||||
HANDLE event_client_wrote = NULL;
|
||||
HANDLE event_client_read = NULL;
|
||||
HANDLE event_conn_closed = NULL;
|
||||
HANDLE handle_file_map = NULL;
|
||||
ulong connect_number;
|
||||
char connect_number_char[22], *p;
|
||||
@ -505,6 +506,13 @@ HANDLE create_shared_memory(MYSQL *mysql,NET *net, uint connect_timeout)
|
||||
error_allow = CR_SHARED_MEMORY_EVENT_ERROR;
|
||||
goto err2;
|
||||
}
|
||||
|
||||
strmov(suffix_pos, "CONNECTION_CLOSED");
|
||||
if ((event_conn_closed = OpenEvent(EVENT_ALL_ACCESS,FALSE,tmp)) == NULL)
|
||||
{
|
||||
error_allow = CR_SHARED_MEMORY_EVENT_ERROR;
|
||||
goto err2;
|
||||
}
|
||||
/*
|
||||
Set event that server should send data
|
||||
*/
|
||||
@ -514,9 +522,9 @@ err2:
|
||||
if (error_allow == 0)
|
||||
{
|
||||
net->vio= vio_new_win32shared_memory(net,handle_file_map,handle_map,
|
||||
event_server_wrote,
|
||||
event_server_wrote,
|
||||
event_server_read,event_client_wrote,
|
||||
event_client_read);
|
||||
event_client_read,event_conn_closed);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -529,6 +537,8 @@ err2:
|
||||
CloseHandle(event_client_read);
|
||||
if (event_client_wrote)
|
||||
CloseHandle(event_client_wrote);
|
||||
if (event_conn_closed)
|
||||
CloseHandle(event_conn_closed);
|
||||
if (handle_map)
|
||||
UnmapViewOfFile(handle_map);
|
||||
if (handle_file_map)
|
||||
|
@ -380,15 +380,15 @@ convert_error_code_to_mysql(
|
||||
|
||||
} else if (error == (int) DB_LOCK_WAIT_TIMEOUT) {
|
||||
|
||||
/* Since we rolled back the whole transaction, we must
|
||||
tell it also to MySQL so that MySQL knows to empty the
|
||||
cached binlog for this transaction */
|
||||
/* Since we rolled back the whole transaction, we must
|
||||
tell it also to MySQL so that MySQL knows to empty the
|
||||
cached binlog for this transaction */
|
||||
|
||||
if (thd) {
|
||||
ha_rollback(thd);
|
||||
}
|
||||
if (thd) {
|
||||
ha_rollback(thd);
|
||||
}
|
||||
|
||||
return(HA_ERR_LOCK_WAIT_TIMEOUT);
|
||||
return(HA_ERR_LOCK_WAIT_TIMEOUT);
|
||||
|
||||
} else if (error == (int) DB_NO_REFERENCED_ROW) {
|
||||
|
||||
@ -4075,11 +4075,9 @@ ha_innobase::discard_or_import_tablespace(
|
||||
err = row_import_tablespace_for_mysql(dict_table->name, trx);
|
||||
}
|
||||
|
||||
if (err == DB_SUCCESS) {
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
err = convert_error_code_to_mysql(err, NULL);
|
||||
|
||||
DBUG_RETURN(-1);
|
||||
DBUG_RETURN(err);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
@ -5215,19 +5213,6 @@ ha_innobase::external_lock(
|
||||
|
||||
update_thd(thd);
|
||||
|
||||
if (prebuilt->table->ibd_file_missing && !current_thd->tablespace_op) {
|
||||
ut_print_timestamp(stderr);
|
||||
fprintf(stderr, " InnoDB error:\n"
|
||||
"MySQL is trying to use a table handle but the .ibd file for\n"
|
||||
"table %s does not exist.\n"
|
||||
"Have you deleted the .ibd file from the database directory under\n"
|
||||
"the MySQL datadir, or have you used DISCARD TABLESPACE?\n"
|
||||
"Look from section 15.1 of http://www.innodb.com/ibman.html\n"
|
||||
"how you can resolve the problem.\n",
|
||||
prebuilt->table->name);
|
||||
DBUG_RETURN(HA_ERR_CRASHED);
|
||||
}
|
||||
|
||||
trx = prebuilt->trx;
|
||||
|
||||
prebuilt->sql_stat_start = TRUE;
|
||||
@ -5276,9 +5261,18 @@ ha_innobase::external_lock(
|
||||
prebuilt->select_lock_type = LOCK_S;
|
||||
}
|
||||
|
||||
/* Starting from 4.1.9, no InnoDB table lock is taken in LOCK
|
||||
TABLES if AUTOCOMMIT=1. It does not make much sense to acquire
|
||||
an InnoDB table lock if it is released immediately at the end
|
||||
of LOCK TABLES, and InnoDB's table locks in that case cause
|
||||
VERY easily deadlocks. */
|
||||
|
||||
if (prebuilt->select_lock_type != LOCK_NONE) {
|
||||
|
||||
if (thd->in_lock_tables &&
|
||||
thd->variables.innodb_table_locks) {
|
||||
thd->variables.innodb_table_locks &&
|
||||
(thd->options & OPTION_NOT_AUTOCOMMIT)) {
|
||||
|
||||
ulint error;
|
||||
error = row_lock_table_for_mysql(prebuilt,
|
||||
NULL, LOCK_TABLE_EXP);
|
||||
|
@ -661,12 +661,13 @@ longlong Item_in_optimizer::val_int()
|
||||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
cache->store(args[0]);
|
||||
longlong tmp= args[1]->val_int_result();
|
||||
if (cache->null_value)
|
||||
{
|
||||
null_value= 1;
|
||||
if (tmp)
|
||||
null_value= 1;
|
||||
return 0;
|
||||
}
|
||||
longlong tmp= args[1]->val_int_result();
|
||||
null_value= args[1]->null_value;
|
||||
return tmp;
|
||||
}
|
||||
|
@ -1187,7 +1187,8 @@ double Item_func_round::val_real()
|
||||
bool Item_func_rand::fix_fields(THD *thd, struct st_table_list *tables,
|
||||
Item **ref)
|
||||
{
|
||||
Item_real_func::fix_fields(thd, tables, ref);
|
||||
if (Item_real_func::fix_fields(thd, tables, ref))
|
||||
return TRUE;
|
||||
used_tables_cache|= RAND_TABLE_BIT;
|
||||
if (arg_count)
|
||||
{ // Only use argument once in query
|
||||
|
@ -1302,9 +1302,18 @@ String *Item_func_trim::val_str(String *str)
|
||||
return 0; /* purecov: inspected */
|
||||
char buff[MAX_FIELD_WIDTH];
|
||||
String tmp(buff,sizeof(buff),res->charset());
|
||||
String *remove_str= (arg_count==2) ? args[1]->val_str(&tmp) : &remove;
|
||||
uint remove_length;
|
||||
LINT_INIT(remove_length);
|
||||
String *remove_str; /* The string to remove from res. */
|
||||
|
||||
if (arg_count == 2)
|
||||
{
|
||||
remove_str= args[1]->val_str(&tmp);
|
||||
if ((null_value= args[1]->null_value))
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
remove_str= &remove; /* Default value. */
|
||||
|
||||
if (!remove_str || (remove_length=remove_str->length()) == 0 ||
|
||||
remove_length > res->length())
|
||||
@ -2608,16 +2617,16 @@ String *Item_func_quote::val_str(String *str)
|
||||
|
||||
/*
|
||||
We have to use realloc() instead of alloc() as we want to keep the
|
||||
old result in str
|
||||
old result in arg
|
||||
*/
|
||||
if (str->realloc(new_length))
|
||||
if (arg->realloc(new_length))
|
||||
goto null;
|
||||
|
||||
/*
|
||||
As 'arg' and 'str' may be the same string, we must replace characters
|
||||
from the end to the beginning
|
||||
*/
|
||||
to= (char*) str->ptr() + new_length - 1;
|
||||
to= (char*) arg->ptr() + new_length - 1;
|
||||
*to--= '\'';
|
||||
for (start= (char*) arg->ptr(),end= start + arg_length; end-- != start; to--)
|
||||
{
|
||||
@ -2645,10 +2654,10 @@ String *Item_func_quote::val_str(String *str)
|
||||
}
|
||||
}
|
||||
*to= '\'';
|
||||
str->length(new_length);
|
||||
arg->length(new_length);
|
||||
str->set_charset(collation.collation);
|
||||
null_value= 0;
|
||||
return str;
|
||||
return arg;
|
||||
|
||||
null:
|
||||
null_value= 1;
|
||||
|
@ -830,6 +830,8 @@ Item_in_subselect::single_value_transformer(JOIN *join,
|
||||
ref_pointer_array,
|
||||
(char *)"<ref>",
|
||||
this->full_name()));
|
||||
if (!abort_on_null && left_expr->maybe_null)
|
||||
item= new Item_cond_or(new Item_func_isnull(left_expr), item);
|
||||
/*
|
||||
AND and comparison functions can't be changed during fix_fields()
|
||||
we can assign select_lex->having here, and pass 0 as last
|
||||
@ -874,6 +876,8 @@ Item_in_subselect::single_value_transformer(JOIN *join,
|
||||
goto err;
|
||||
item= new Item_cond_or(item,
|
||||
new Item_func_isnull(orig_item));
|
||||
if (left_expr->maybe_null)
|
||||
item= new Item_cond_or(new Item_func_isnull(left_expr), item);
|
||||
}
|
||||
item->name= (char *)in_additional_cond;
|
||||
/*
|
||||
@ -895,12 +899,13 @@ Item_in_subselect::single_value_transformer(JOIN *join,
|
||||
we can assign select_lex->having here, and pass 0 as last
|
||||
argument (reference) to fix_fields()
|
||||
*/
|
||||
select_lex->having=
|
||||
join->having=
|
||||
func->create(expr,
|
||||
item= func->create(expr,
|
||||
new Item_null_helper(this, item,
|
||||
(char *)"<no matter>",
|
||||
(char *)"<result>"));
|
||||
if (!abort_on_null && left_expr->maybe_null)
|
||||
item= new Item_cond_or(new Item_func_isnull(left_expr), item);
|
||||
select_lex->having= join->having= item;
|
||||
select_lex->having_fix_field= 1;
|
||||
tmp= join->having->fix_fields(thd, join->tables_list, 0);
|
||||
select_lex->having_fix_field= 0;
|
||||
|
@ -149,6 +149,9 @@ static DATE_TIME_FORMAT time_24hrs_format= {{0}, '\0', 0,
|
||||
conversion specifiers that can be used in such sub-patterns is limited.
|
||||
Also most of checks are skipped in this case.
|
||||
|
||||
If one adds new format specifiers to this function he should also
|
||||
consider adding them to get_date_time_result_type() function.
|
||||
|
||||
RETURN
|
||||
0 ok
|
||||
1 error
|
||||
@ -2821,25 +2824,31 @@ void Item_func_get_format::print(String *str)
|
||||
|
||||
|
||||
/*
|
||||
check_result_type(s, l) returns DATE/TIME type
|
||||
according to format string
|
||||
Get type of datetime value (DATE/TIME/...) which will be produced
|
||||
according to format string.
|
||||
|
||||
s: DATE/TIME format string
|
||||
l: length of s
|
||||
Result: date_time_format_types value:
|
||||
DATE_TIME_MICROSECOND, DATE_TIME,
|
||||
TIME_MICROSECOND, TIME_ONLY
|
||||
SYNOPSIS
|
||||
get_date_time_result_type()
|
||||
format - format string
|
||||
length - length of format string
|
||||
|
||||
We don't process day format's characters('D', 'd', 'e')
|
||||
because day may be a member of all date/time types.
|
||||
If only day format's character and no time part present
|
||||
the result type is MYSQL_TYPE_DATE
|
||||
NOTE
|
||||
We don't process day format's characters('D', 'd', 'e') because day
|
||||
may be a member of all date/time types.
|
||||
|
||||
Format specifiers supported by this function should be in sync with
|
||||
specifiers supported by extract_date_time() function.
|
||||
|
||||
RETURN VALUE
|
||||
One of date_time_format_types values:
|
||||
DATE_TIME_MICROSECOND, DATE_TIME, DATE_ONLY, TIME_MICROSECOND, TIME_ONLY
|
||||
*/
|
||||
|
||||
date_time_format_types check_result_type(const char *format, uint length)
|
||||
static date_time_format_types
|
||||
get_date_time_result_type(const char *format, uint length)
|
||||
{
|
||||
const char *time_part_frms= "HISThiklrs";
|
||||
const char *date_part_frms= "MUYWabcjmuyw";
|
||||
const char *date_part_frms= "MVUXYWabcjmvuxyw";
|
||||
bool date_part_used= 0, time_part_used= 0, frac_second_used= 0;
|
||||
|
||||
const char *val= format;
|
||||
@ -2850,22 +2859,30 @@ date_time_format_types check_result_type(const char *format, uint length)
|
||||
if (*val == '%' && val+1 != end)
|
||||
{
|
||||
val++;
|
||||
if ((frac_second_used= (*val == 'f')) ||
|
||||
(!time_part_used && strchr(time_part_frms, *val)))
|
||||
if (*val == 'f')
|
||||
frac_second_used= time_part_used= 1;
|
||||
else if (!time_part_used && strchr(time_part_frms, *val))
|
||||
time_part_used= 1;
|
||||
else if (!date_part_used && strchr(date_part_frms, *val))
|
||||
date_part_used= 1;
|
||||
if (time_part_used && date_part_used && frac_second_used)
|
||||
if (date_part_used && frac_second_used)
|
||||
{
|
||||
/*
|
||||
frac_second_used implies time_part_used, and thus we already
|
||||
have all types of date-time components and can end our search.
|
||||
*/
|
||||
return DATE_TIME_MICROSECOND;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* We don't have all three types of date-time components */
|
||||
if (frac_second_used)
|
||||
return TIME_MICROSECOND;
|
||||
if (time_part_used)
|
||||
{
|
||||
if (date_part_used)
|
||||
return DATE_TIME;
|
||||
if (frac_second_used)
|
||||
return TIME_MICROSECOND;
|
||||
return TIME_ONLY;
|
||||
}
|
||||
return DATE_ONLY;
|
||||
@ -2896,7 +2913,8 @@ void Item_func_str_to_date::fix_length_and_dec()
|
||||
if ((const_item= args[1]->const_item()))
|
||||
{
|
||||
format= args[1]->val_str(&format_str);
|
||||
cached_format_type= check_result_type(format->ptr(), format->length());
|
||||
cached_format_type= get_date_time_result_type(format->ptr(),
|
||||
format->length());
|
||||
switch (cached_format_type) {
|
||||
case DATE_ONLY:
|
||||
cached_timestamp_type= MYSQL_TIMESTAMP_DATE;
|
||||
|
@ -2046,6 +2046,7 @@ bool flush_error_log()
|
||||
char err_renamed[FN_REFLEN], *end;
|
||||
end= strmake(err_renamed,log_error_file,FN_REFLEN-4);
|
||||
strmov(end, "-old");
|
||||
VOID(pthread_mutex_lock(&LOCK_error_log));
|
||||
#ifdef __WIN__
|
||||
char err_temp[FN_REFLEN+4];
|
||||
/*
|
||||
@ -2066,7 +2067,7 @@ bool flush_error_log()
|
||||
if ((fd = my_open(err_temp, O_RDONLY, MYF(0))) >= 0)
|
||||
{
|
||||
while ((bytes = (int) my_read(fd, (byte*) buf, IO_SIZE, MYF(0))) > 0)
|
||||
my_fwrite(stderr, (byte*) buf, (uint) strlen(buf),MYF(0));
|
||||
my_fwrite(stderr, (byte*) buf, bytes, MYF(0));
|
||||
my_close(fd, MYF(0));
|
||||
}
|
||||
(void) my_delete(err_temp, MYF(0));
|
||||
@ -2080,6 +2081,7 @@ bool flush_error_log()
|
||||
else
|
||||
result= 1;
|
||||
#endif
|
||||
VOID(pthread_mutex_unlock(&LOCK_error_log));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -939,6 +939,7 @@ ulonglong find_set(TYPELIB *lib, const char *x, uint length, CHARSET_INFO *cs,
|
||||
char **err_pos, uint *err_len, bool *set_warning);
|
||||
uint find_type(TYPELIB *lib, const char *find, uint length, bool part_match);
|
||||
uint find_type2(TYPELIB *lib, const char *find, uint length, CHARSET_INFO *cs);
|
||||
void unhex_type2(TYPELIB *lib);
|
||||
uint check_word(TYPELIB *lib, const char *val, const char *end,
|
||||
const char **end_of_word);
|
||||
|
||||
|
@ -54,7 +54,7 @@
|
||||
#endif
|
||||
#ifdef HAVE_NDBCLUSTER_DB
|
||||
#define OPT_NDBCLUSTER_DEFAULT 0
|
||||
#ifdef NDB_SHM_TRANSPORTER
|
||||
#if defined(NDB_SHM_TRANSPORTER) && MYSQL_VERSION_ID >= 50000
|
||||
#define OPT_NDB_SHM_DEFAULT 1
|
||||
#else
|
||||
#define OPT_NDB_SHM_DEFAULT 0
|
||||
@ -141,15 +141,6 @@ extern "C" { // Because of SCO 3.2V4.2
|
||||
int allow_severity = LOG_INFO;
|
||||
int deny_severity = LOG_WARNING;
|
||||
|
||||
#ifdef __STDC__
|
||||
#define my_fromhost(A) fromhost(A)
|
||||
#define my_hosts_access(A) hosts_access(A)
|
||||
#define my_eval_client(A) eval_client(A)
|
||||
#else
|
||||
#define my_fromhost(A) fromhost()
|
||||
#define my_hosts_access(A) hosts_access()
|
||||
#define my_eval_client(A) eval_client()
|
||||
#endif /* __STDC__ */
|
||||
#endif /* HAVE_LIBWRAP */
|
||||
|
||||
#ifdef HAVE_SYS_MMAN_H
|
||||
@ -3689,8 +3680,8 @@ extern "C" pthread_handler_decl(handle_connections_sockets,
|
||||
struct request_info req;
|
||||
signal(SIGCHLD, SIG_DFL);
|
||||
request_init(&req, RQ_DAEMON, libwrapName, RQ_FILE, new_sock, NULL);
|
||||
my_fromhost(&req);
|
||||
if (!my_hosts_access(&req))
|
||||
fromhost(&req);
|
||||
if (!hosts_access(&req))
|
||||
{
|
||||
/*
|
||||
This may be stupid but refuse() includes an exit(0)
|
||||
@ -3698,7 +3689,7 @@ extern "C" pthread_handler_decl(handle_connections_sockets,
|
||||
clean_exit() - same stupid thing ...
|
||||
*/
|
||||
syslog(deny_severity, "refused connect from %s",
|
||||
my_eval_client(&req));
|
||||
eval_client(&req));
|
||||
|
||||
/*
|
||||
C++ sucks (the gibberish in front just translates the supplied
|
||||
@ -3939,6 +3930,7 @@ pthread_handler_decl(handle_connections_shared_memory,arg)
|
||||
HANDLE event_client_read= 0; // for transfer data server <-> client
|
||||
HANDLE event_server_wrote= 0;
|
||||
HANDLE event_server_read= 0;
|
||||
HANDLE event_conn_closed= 0;
|
||||
THD *thd= 0;
|
||||
|
||||
p= int10_to_str(connect_number, connect_number_char, 10);
|
||||
@ -3969,29 +3961,35 @@ pthread_handler_decl(handle_connections_shared_memory,arg)
|
||||
goto errorconn;
|
||||
}
|
||||
strmov(suffix_pos, "CLIENT_WROTE");
|
||||
if ((event_client_wrote= CreateEvent(0,FALSE,FALSE,tmp)) == 0)
|
||||
if ((event_client_wrote= CreateEvent(0, FALSE, FALSE, tmp)) == 0)
|
||||
{
|
||||
errmsg= "Could not create client write event";
|
||||
goto errorconn;
|
||||
}
|
||||
strmov(suffix_pos, "CLIENT_READ");
|
||||
if ((event_client_read= CreateEvent(0,FALSE,FALSE,tmp)) == 0)
|
||||
if ((event_client_read= CreateEvent(0, FALSE, FALSE, tmp)) == 0)
|
||||
{
|
||||
errmsg= "Could not create client read event";
|
||||
goto errorconn;
|
||||
}
|
||||
strmov(suffix_pos, "SERVER_READ");
|
||||
if ((event_server_read= CreateEvent(0,FALSE,FALSE,tmp)) == 0)
|
||||
if ((event_server_read= CreateEvent(0, FALSE, FALSE, tmp)) == 0)
|
||||
{
|
||||
errmsg= "Could not create server read event";
|
||||
goto errorconn;
|
||||
}
|
||||
strmov(suffix_pos, "SERVER_WROTE");
|
||||
if ((event_server_wrote= CreateEvent(0,FALSE,FALSE,tmp)) == 0)
|
||||
if ((event_server_wrote= CreateEvent(0, FALSE, FALSE, tmp)) == 0)
|
||||
{
|
||||
errmsg= "Could not create server write event";
|
||||
goto errorconn;
|
||||
}
|
||||
strmov(suffix_pos, "CONNECTION_CLOSED");
|
||||
if ((event_conn_closed= CreateEvent(0, TRUE , FALSE, tmp)) == 0)
|
||||
{
|
||||
errmsg= "Could not create closed connection event";
|
||||
goto errorconn;
|
||||
}
|
||||
if (abort_loop)
|
||||
goto errorconn;
|
||||
if (!(thd= new THD))
|
||||
@ -4010,13 +4008,14 @@ pthread_handler_decl(handle_connections_shared_memory,arg)
|
||||
goto errorconn;
|
||||
}
|
||||
if (!(thd->net.vio= vio_new_win32shared_memory(&thd->net,
|
||||
handle_client_file_map,
|
||||
handle_client_map,
|
||||
event_client_wrote,
|
||||
event_client_read,
|
||||
event_server_wrote,
|
||||
event_server_read)) ||
|
||||
my_net_init(&thd->net, thd->net.vio))
|
||||
handle_client_file_map,
|
||||
handle_client_map,
|
||||
event_client_wrote,
|
||||
event_client_read,
|
||||
event_server_wrote,
|
||||
event_server_read,
|
||||
event_conn_closed)) ||
|
||||
my_net_init(&thd->net, thd->net.vio))
|
||||
{
|
||||
close_connection(thd, ER_OUT_OF_RESOURCES, 1);
|
||||
errmsg= 0;
|
||||
@ -4036,12 +4035,20 @@ errorconn:
|
||||
NullS);
|
||||
sql_perror(buff);
|
||||
}
|
||||
if (handle_client_file_map) CloseHandle(handle_client_file_map);
|
||||
if (handle_client_map) UnmapViewOfFile(handle_client_map);
|
||||
if (event_server_wrote) CloseHandle(event_server_wrote);
|
||||
if (event_server_read) CloseHandle(event_server_read);
|
||||
if (event_client_wrote) CloseHandle(event_client_wrote);
|
||||
if (event_client_read) CloseHandle(event_client_read);
|
||||
if (handle_client_file_map)
|
||||
CloseHandle(handle_client_file_map);
|
||||
if (handle_client_map)
|
||||
UnmapViewOfFile(handle_client_map);
|
||||
if (event_server_wrote)
|
||||
CloseHandle(event_server_wrote);
|
||||
if (event_server_read)
|
||||
CloseHandle(event_server_read);
|
||||
if (event_client_wrote)
|
||||
CloseHandle(event_client_wrote);
|
||||
if (event_client_read)
|
||||
CloseHandle(event_client_read);
|
||||
if (event_conn_closed)
|
||||
CloseHandle(event_conn_closed);
|
||||
delete thd;
|
||||
}
|
||||
|
||||
|
@ -3051,9 +3051,11 @@ bool sys_var_thd_storage_engine::check(THD *thd, set_var *var)
|
||||
|
||||
if (var->value->result_type() == STRING_RESULT)
|
||||
{
|
||||
enum db_type db_type;
|
||||
if (!(res=var->value->val_str(&str)) ||
|
||||
!(var->save_result.ulong_value=
|
||||
(ulong) ha_resolve_by_name(res->ptr(), res->length())))
|
||||
(ulong) db_type= ha_resolve_by_name(res->ptr(), res->length())) ||
|
||||
ha_checktype(db_type) != db_type)
|
||||
{
|
||||
value= res ? res->c_ptr() : "NULL";
|
||||
goto err;
|
||||
|
160
sql/sql_acl.cc
160
sql/sql_acl.cc
@ -1644,6 +1644,7 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo,
|
||||
|
||||
Field **tmp_field;
|
||||
ulong priv;
|
||||
uint next_field;
|
||||
for (tmp_field= table->field+3, priv = SELECT_ACL;
|
||||
*tmp_field && (*tmp_field)->real_type() == FIELD_TYPE_ENUM &&
|
||||
((Field_enum*) (*tmp_field))->typelib->count == 2 ;
|
||||
@ -1652,59 +1653,60 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo,
|
||||
if (priv & rights) // set requested privileges
|
||||
(*tmp_field)->store(&what, 1, &my_charset_latin1);
|
||||
}
|
||||
rights=get_access(table,3);
|
||||
rights= get_access(table, 3, &next_field);
|
||||
DBUG_PRINT("info",("table->fields: %d",table->fields));
|
||||
if (table->fields >= 31) /* From 4.0.0 we have more fields */
|
||||
{
|
||||
/* We write down SSL related ACL stuff */
|
||||
switch (lex->ssl_type) {
|
||||
case SSL_TYPE_ANY:
|
||||
table->field[24]->store("ANY",3, &my_charset_latin1);
|
||||
table->field[25]->store("", 0, &my_charset_latin1);
|
||||
table->field[26]->store("", 0, &my_charset_latin1);
|
||||
table->field[27]->store("", 0, &my_charset_latin1);
|
||||
table->field[next_field]->store("ANY", 3, &my_charset_latin1);
|
||||
table->field[next_field+1]->store("", 0, &my_charset_latin1);
|
||||
table->field[next_field+2]->store("", 0, &my_charset_latin1);
|
||||
table->field[next_field+3]->store("", 0, &my_charset_latin1);
|
||||
break;
|
||||
case SSL_TYPE_X509:
|
||||
table->field[24]->store("X509",4, &my_charset_latin1);
|
||||
table->field[25]->store("", 0, &my_charset_latin1);
|
||||
table->field[26]->store("", 0, &my_charset_latin1);
|
||||
table->field[27]->store("", 0, &my_charset_latin1);
|
||||
table->field[next_field]->store("X509", 4, &my_charset_latin1);
|
||||
table->field[next_field+1]->store("", 0, &my_charset_latin1);
|
||||
table->field[next_field+2]->store("", 0, &my_charset_latin1);
|
||||
table->field[next_field+3]->store("", 0, &my_charset_latin1);
|
||||
break;
|
||||
case SSL_TYPE_SPECIFIED:
|
||||
table->field[24]->store("SPECIFIED",9, &my_charset_latin1);
|
||||
table->field[25]->store("", 0, &my_charset_latin1);
|
||||
table->field[26]->store("", 0, &my_charset_latin1);
|
||||
table->field[27]->store("", 0, &my_charset_latin1);
|
||||
table->field[next_field]->store("SPECIFIED", 9, &my_charset_latin1);
|
||||
table->field[next_field+1]->store("", 0, &my_charset_latin1);
|
||||
table->field[next_field+2]->store("", 0, &my_charset_latin1);
|
||||
table->field[next_field+3]->store("", 0, &my_charset_latin1);
|
||||
if (lex->ssl_cipher)
|
||||
table->field[25]->store(lex->ssl_cipher,
|
||||
strlen(lex->ssl_cipher), system_charset_info);
|
||||
table->field[next_field+1]->store(lex->ssl_cipher,
|
||||
strlen(lex->ssl_cipher), system_charset_info);
|
||||
if (lex->x509_issuer)
|
||||
table->field[26]->store(lex->x509_issuer,
|
||||
strlen(lex->x509_issuer), system_charset_info);
|
||||
table->field[next_field+2]->store(lex->x509_issuer,
|
||||
strlen(lex->x509_issuer), system_charset_info);
|
||||
if (lex->x509_subject)
|
||||
table->field[27]->store(lex->x509_subject,
|
||||
strlen(lex->x509_subject), system_charset_info);
|
||||
table->field[next_field+3]->store(lex->x509_subject,
|
||||
strlen(lex->x509_subject), system_charset_info);
|
||||
break;
|
||||
case SSL_TYPE_NOT_SPECIFIED:
|
||||
break;
|
||||
case SSL_TYPE_NONE:
|
||||
table->field[24]->store("", 0, &my_charset_latin1);
|
||||
table->field[25]->store("", 0, &my_charset_latin1);
|
||||
table->field[26]->store("", 0, &my_charset_latin1);
|
||||
table->field[27]->store("", 0, &my_charset_latin1);
|
||||
table->field[next_field]->store("", 0, &my_charset_latin1);
|
||||
table->field[next_field+1]->store("", 0, &my_charset_latin1);
|
||||
table->field[next_field+2]->store("", 0, &my_charset_latin1);
|
||||
table->field[next_field+3]->store("", 0, &my_charset_latin1);
|
||||
break;
|
||||
}
|
||||
next_field+=4;
|
||||
|
||||
USER_RESOURCES mqh= lex->mqh;
|
||||
if (mqh.specified_limits & USER_RESOURCES::QUERIES_PER_HOUR)
|
||||
table->field[28]->store((longlong) mqh.questions);
|
||||
table->field[next_field]->store((longlong) mqh.questions);
|
||||
if (mqh.specified_limits & USER_RESOURCES::UPDATES_PER_HOUR)
|
||||
table->field[29]->store((longlong) mqh.updates);
|
||||
table->field[next_field+1]->store((longlong) mqh.updates);
|
||||
if (mqh.specified_limits & USER_RESOURCES::CONNECTIONS_PER_HOUR)
|
||||
table->field[30]->store((longlong) mqh.conn_per_hour);
|
||||
table->field[next_field+2]->store((longlong) mqh.conn_per_hour);
|
||||
if (table->fields >= 36 &&
|
||||
(mqh.specified_limits & USER_RESOURCES::USER_CONNECTIONS))
|
||||
table->field[33]->store((longlong) mqh.user_conn);
|
||||
table->field[next_field+3]->store((longlong) mqh.user_conn);
|
||||
mqh_used= mqh_used || mqh.questions || mqh.updates || mqh.conn_per_hour;
|
||||
}
|
||||
if (old_row_exists)
|
||||
@ -2587,41 +2589,59 @@ bool mysql_table_grant(THD *thd, TABLE_LIST *table_list,
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
|
||||
if (columns.elements && !revoke_grant)
|
||||
if (!revoke_grant)
|
||||
{
|
||||
class LEX_COLUMN *column;
|
||||
List_iterator <LEX_COLUMN> column_iter(columns);
|
||||
int res;
|
||||
if (columns.elements)
|
||||
{
|
||||
class LEX_COLUMN *column;
|
||||
List_iterator <LEX_COLUMN> column_iter(columns);
|
||||
int res;
|
||||
|
||||
if (open_and_lock_tables(thd, table_list))
|
||||
DBUG_RETURN(TRUE);
|
||||
|
||||
while ((column = column_iter++))
|
||||
{
|
||||
uint unused_field_idx= NO_CACHED_FIELD_INDEX;
|
||||
if (!find_field_in_table(thd, table_list, column->column.ptr(),
|
||||
column->column.ptr(),
|
||||
column->column.length(), 0, 0, 0, 0,
|
||||
&unused_field_idx, FALSE))
|
||||
if (open_and_lock_tables(thd, table_list))
|
||||
DBUG_RETURN(TRUE);
|
||||
|
||||
while ((column = column_iter++))
|
||||
{
|
||||
my_error(ER_BAD_FIELD_ERROR, MYF(0),
|
||||
column->column.c_ptr(), table_list->alias);
|
||||
DBUG_RETURN(TRUE);
|
||||
uint unused_field_idx= NO_CACHED_FIELD_INDEX;
|
||||
Field *f=find_field_in_table(thd, table_list, column->column.ptr(),
|
||||
column->column.ptr(),
|
||||
column->column.length(), 0, 0, 0, 0,
|
||||
&unused_field_idx, FALSE);
|
||||
if (f == (Field*)0)
|
||||
{
|
||||
my_error(ER_BAD_FIELD_ERROR, MYF(0),
|
||||
column->column.c_ptr(), table_list->alias);
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
if (f == (Field *)-1)
|
||||
DBUG_RETURN(TRUE);
|
||||
column_priv|= column->rights;
|
||||
}
|
||||
column_priv|= column->rights;
|
||||
close_thread_tables(thd);
|
||||
}
|
||||
close_thread_tables(thd);
|
||||
}
|
||||
else if (!(rights & CREATE_ACL) && !revoke_grant)
|
||||
{
|
||||
char buf[FN_REFLEN];
|
||||
sprintf(buf,"%s/%s/%s.frm",mysql_data_home, table_list->db,
|
||||
table_list->real_name);
|
||||
fn_format(buf,buf,"","",4+16+32);
|
||||
if (access(buf,F_OK))
|
||||
else
|
||||
{
|
||||
my_error(ER_NO_SUCH_TABLE, MYF(0), table_list->db, table_list->alias);
|
||||
DBUG_RETURN(TRUE);
|
||||
if (!(rights & CREATE_ACL))
|
||||
{
|
||||
char buf[FN_REFLEN];
|
||||
sprintf(buf,"%s/%s/%s.frm",mysql_data_home, table_list->db,
|
||||
table_list->real_name);
|
||||
fn_format(buf,buf,"","",4+16+32);
|
||||
if (access(buf,F_OK))
|
||||
{
|
||||
my_error(ER_NO_SUCH_TABLE, MYF(0), table_list->db, table_list->alias);
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
}
|
||||
if (table_list->grant.want_privilege)
|
||||
{
|
||||
char command[128];
|
||||
get_privilege_desc(command, sizeof(command),
|
||||
table_list->grant.want_privilege);
|
||||
my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0),
|
||||
command, thd->priv_user, thd->host_or_ip, table_list->alias);
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -3337,25 +3357,8 @@ err:
|
||||
rw_unlock(&LOCK_grant);
|
||||
if (!no_errors) // Not a silent skip of table
|
||||
{
|
||||
const char *command="";
|
||||
if (want_access & SELECT_ACL)
|
||||
command= "select";
|
||||
else if (want_access & INSERT_ACL)
|
||||
command= "insert";
|
||||
else if (want_access & UPDATE_ACL)
|
||||
command= "update";
|
||||
else if (want_access & DELETE_ACL)
|
||||
command= "delete";
|
||||
else if (want_access & DROP_ACL)
|
||||
command= "drop";
|
||||
else if (want_access & CREATE_ACL)
|
||||
command= "create";
|
||||
else if (want_access & ALTER_ACL)
|
||||
command= "alter";
|
||||
else if (want_access & INDEX_ACL)
|
||||
command= "index";
|
||||
else if (want_access & GRANT_ACL)
|
||||
command= "grant";
|
||||
char command[128];
|
||||
get_privilege_desc(command, sizeof(command), want_access);
|
||||
else if (want_access & CREATE_VIEW_ACL)
|
||||
command= "create view";
|
||||
else if (want_access & SHOW_VIEW_ACL)
|
||||
@ -3473,11 +3476,8 @@ bool check_grant_all_columns(THD *thd, ulong want_access, GRANT_INFO *grant,
|
||||
err:
|
||||
rw_unlock(&LOCK_grant);
|
||||
err2:
|
||||
const char *command= "";
|
||||
if (want_access & SELECT_ACL)
|
||||
command= "select";
|
||||
else if (want_access & INSERT_ACL)
|
||||
command= "insert";
|
||||
char command[128];
|
||||
get_privilege_desc(command, sizeof(command), want_access);
|
||||
my_error(ER_COLUMNACCESS_DENIED_ERROR, MYF(0),
|
||||
command,
|
||||
thd->priv_user,
|
||||
|
@ -702,9 +702,7 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, TABLE *table,
|
||||
if (!table)
|
||||
table= table_list->table;
|
||||
|
||||
if ((thd->lex->sql_command == SQLCOM_INSERT ||
|
||||
thd->lex->sql_command == SQLCOM_REPLACE) &&
|
||||
unique_table(table_list, table_list->next_global))
|
||||
if (!select_insert && unique_table(table_list, table_list->next_global))
|
||||
{
|
||||
my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->real_name);
|
||||
DBUG_RETURN(TRUE);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user